diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index a280a2ac4..000000000 --- a/.coveragerc +++ /dev/null @@ -1,3 +0,0 @@ -[run] -omit = - *test* diff --git a/.github/workflows/check-python.yml b/.github/workflows/check-python.yml deleted file mode 100644 index b58cd3bdb..000000000 --- a/.github/workflows/check-python.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: Check Python code - -on: [push, pull_request] - -jobs: - build: - - runs-on: ubuntu-latest - strategy: - matrix: - python-version: ["3.10"] - - steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -r 00_Utilities/python/ci-requirements.txt - - name: Test with mypy - run: | - mypy . --exclude 79_Slalom --exclude 27_Civil_War --exclude 38_Fur_Trader --exclude 81_Splat --exclude 09_Battle --exclude 40_Gomoko --exclude 36_Flip_Flop --exclude 43_Hammurabi --exclude 04_Awari --exclude 78_Sine_Wave --exclude 77_Salvo --exclude 34_Digits --exclude 17_Bullfight --exclude 16_Bug - - name: Test with flake8 - run: | - flake8 . --ignore E501,W503,E203,E731,B011,SIM119,SIM106 diff --git a/.github/workflows/file-size.yml b/.github/workflows/file-size.yml deleted file mode 100644 index 70eb6563d..000000000 --- a/.github/workflows/file-size.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: File Size Check - -on: [push, pull_request] - -jobs: - build: - - runs-on: ubuntu-latest - strategy: - matrix: - python-version: ["3.10"] - - steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - name: Get changed files - id: changed-files - uses: tj-actions/changed-files@v18.4 - - name: List all changed files - run: | - # MAXSIZE is 1 MB - MAXSIZE=1000000 - for FILENAME in ${{ steps.changed-files.outputs.all_changed_files }}; do - FILESIZE=$(stat -c%s "$FILENAME") - echo "Size of $FILENAME = $FILESIZE bytes." - if (( FILESIZE > MAXSIZE)); then - echo "$FILENAME is too big. Only $MAXSIZE bytes allowed." - exit 1 - fi - done diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml deleted file mode 100644 index f4be2fd6a..000000000 --- a/.github/workflows/rust.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: Rust - -on: - push: - branches: [ "main" ] - pull_request: - branches: [ "main" ] - -env: - CARGO_TERM_COLOR: always - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - - name: Build All - run: find */rust/Cargo.toml|xargs -I {} dirname {}|xargs -I {} bash -c 'cd {} && cargo build --verbose' - - - name: Run All tests - run: find */rust/Cargo.toml|xargs -I {} dirname {}|xargs -I {} bash -c 'cd {} && cargo test --verbose' diff --git a/.gitignore b/.gitignore index 878190440..3412076c6 100644 --- a/.gitignore +++ b/.gitignore @@ -2,8 +2,9 @@ .vscode/ .gradle/ node_modules/ -buildJvm/bin -buildJvm/*/build/ +buildJvm/ + +build.gradle .classpath .project @@ -26,17 +27,9 @@ obj/ out/ *.py[co] -.python-version + Pipfile -venv/ -.coverage .DS_Store -.vs/ -**/target/ -**/*.rs.bk -/target -todo.md - -.fake -.fake \ No newline at end of file +/.vs/basic-computer-games/v16 +/.vs diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml deleted file mode 100644 index 5d2ff6948..000000000 --- a/.pre-commit-config.yaml +++ /dev/null @@ -1,35 +0,0 @@ -# pre-commit run --all-files -repos: -- repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.1.0 - hooks: - - id: check-ast - - id: check-case-conflict - - id: check-docstring-first - - id: check-executables-have-shebangs - - id: check-json - - id: check-yaml - - id: debug-statements - - id: end-of-file-fixer - - id: trailing-whitespace - - id: mixed-line-ending - - id: check-added-large-files - args: ['--maxkb=1000'] -- repo: https://github.com/pre-commit/mirrors-isort - rev: v5.10.1 - hooks: - - id: isort -- repo: https://github.com/psf/black - rev: 22.1.0 - hooks: - - id: black -- repo: https://github.com/asottile/pyupgrade - rev: v2.31.1 - hooks: - - id: pyupgrade - args: [--py37-plus] -- repo: https://github.com/asottile/blacken-docs - rev: v1.12.1 - hooks: - - id: blacken-docs - additional_dependencies: [black==22.1.0] diff --git a/00_Alternate_Languages/01_Acey_Ducey/MiniScript/README.md b/00_Alternate_Languages/01_Acey_Ducey/MiniScript/README.md deleted file mode 100644 index 06640e03b..000000000 --- a/00_Alternate_Languages/01_Acey_Ducey/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript aceyducey.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "aceyducey" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/01_Acey_Ducey/MiniScript/aceyducey.ms b/00_Alternate_Languages/01_Acey_Ducey/MiniScript/aceyducey.ms deleted file mode 100644 index c00684ce7..000000000 --- a/00_Alternate_Languages/01_Acey_Ducey/MiniScript/aceyducey.ms +++ /dev/null @@ -1,59 +0,0 @@ -print " "*26 + "Acey Ducey Card Game" -print " "*15 + "Creative Computing Morristown, New Jersey" -print -print -print "Acey-ducey is played in the following manner." -print "The dealer (computer) deals two cards face up." -print "You have an option to bet or not bet depending" -print "on whether or not you feel the card will have" -print "a value between the first two." -print "If you do not want to bet, input a 0." - -cards = range(2,10) + ["Jack", "Queen", "King", "Ace"] - -while true - money = 100 - - while true - print "You now have " + money + " dollars." - print - print "Here are your next two cards:" - while true - A = floor(rnd * cards.len) - B = floor(rnd * cards.len) - if B > A then break - end while - print cards[A] - print cards[B] - bet = input("What is your bet? ").val - while bet > money - print "Sorry, my friend, but you bet too much." - print "You have only " + money + " dollars to bet." - bet = input("What is your bet? ").val - end while - if bet == 0 then - print "Chicken!!" - continue - end if - C = floor(rnd * cards.len) - print cards[C] - - if C <= A or C >= B then - print "Sorry, you lose." - money -= bet - if money <= 0 then break - else - print "You win!!!" - money += bet - end if - end while - - print - print - print "Sorry, friend, but you blew your wad." - print; print - again = input("Try again (yes or no)? ").lower - if again and again[0] == "n" then break -end while - -print "O.K., hope you had fun!" \ No newline at end of file diff --git a/00_Alternate_Languages/01_Acey_Ducey/README.md b/00_Alternate_Languages/01_Acey_Ducey/README.md deleted file mode 100644 index 07ac752bb..000000000 --- a/00_Alternate_Languages/01_Acey_Ducey/README.md +++ /dev/null @@ -1,13 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. - -#### 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 diff --git a/00_Alternate_Languages/01_Acey_Ducey/aceyducey.bas b/00_Alternate_Languages/01_Acey_Ducey/aceyducey.bas deleted file mode 100644 index 0b6f72db3..000000000 --- a/00_Alternate_Languages/01_Acey_Ducey/aceyducey.bas +++ /dev/null @@ -1,100 +0,0 @@ -10 PRINT TAB(26);"ACEY DUCEY CARD GAME" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -21 PRINT -22 PRINT -30 PRINT"ACEY-DUCEY IS PLAYED IN THE FOLLOWING MANNER " -40 PRINT"THE DEALER (COMPUTER) DEALS TWO CARDS FACE UP" -50 PRINT"YOU HAVE AN OPTION TO BET OR NOT BET DEPENDING" -60 PRINT"ON WHETHER OR NOT YOU FEEL THE CARD WILL HAVE" -70 PRINT"A VALUE BETWEEN THE FIRST TWO." -80 PRINT"IF YOU DO NOT WANT TO BET, INPUT A 0" -100 N=100 -110 Q=100 -120 PRINT "YOU NOW HAVE ";Q;" DOLLARS." -130 PRINT -140 GOTO 260 -210 Q=Q+M -220 GOTO 120 -240 Q=Q-M -250 GOTO 120 -260 PRINT"HERE ARE YOUR NEXT TWO CARDS: " -270 A=INT(14*RND(1))+2 -280 IF A<2 THEN 270 -290 IF A>14 THEN 270 -300 B=INT(14*RND(1))+2 -310 IF B<2 THEN 300 -320 IF B>14 THEN 300 -330 IF A>=B THEN 270 -350 IF A<11 THEN 400 -360 IF A=11 THEN 420 -370 IF A=12 THEN 440 -380 IF A=13 THEN 460 -390 IF A=14 THEN 480 -400 PRINT A -410 GOTO 500 -420 PRINT"JACK" -430 GOTO 500 -440 PRINT"QUEEN" -450 GOTO 500 -460 PRINT"KING" -470 GOTO 500 -480 PRINT"ACE" -500 IF B<11 THEN 550 -510 IF B=11 THEN 570 -520 IF B=12 THEN 590 -530 IF B=13 THEN 610 -540 IF B=14 THEN 630 -550 PRINT B -560 GOTO 650 -570 PRINT"JACK" -580 GOTO 650 -590 PRINT"QUEEN" -600 GOTO 650 -610 PRINT"KING" -620 GOTO 650 -630 PRINT"ACE" -640 PRINT -650 PRINT -660 INPUT"WHAT IS YOUR BET";M -670 IF M<>0 THEN 680 -675 PRINT"CHICKEN!!" -676 PRINT -677 GOTO 260 -680 IF M<=Q THEN 730 -690 PRINT"SORRY, MY FRIEND, BUT YOU BET TOO MUCH." -700 PRINT"YOU HAVE ONLY ";Q;" DOLLARS TO BET." -710 GOTO 650 -730 C=INT(14*RND(1))+2 -740 IF C<2 THEN 730 -750 IF C>14 THEN 730 -760 IF C<11 THEN 810 -770 IF C=11 THEN 830 -780 IF C=12 THEN 850 -790 IF C=13 THEN 870 -800 IF C=14 THEN 890 -810 PRINT C -820 GOTO 910 -830 PRINT"JACK" -840 GOTO 910 -850 PRINT"QUEEN" -860 GOTO 910 -870 PRINT"KING" -880 GOTO 910 -890 PRINT "ACE" -900 PRINT -910 IF C>A THEN 930 -920 GOTO 970 -930 IF C>=B THEN 970 -950 PRINT"YOU WIN!!!" -960 GOTO 210 -970 PRINT"SORRY, YOU LOSE" -980 IF M -#include -#include "Aceyducey.h" - - -int main() -{ - //Setting Seed for the Random Generator - srand((unsigned int)time(NULL)); - bool isPlaying(true); - Money = 100; - WelcomeMessage(); - while (isPlaying) - { - Play(isPlaying); - } - printf("O.K., HOPE YOU HAD FUN!\n"); -} - -void WelcomeMessage() -{ - for (int i = 0; i < 25; i++) - { - printf(" "); - } - printf("ACEY DUCEY CARD GAME\n"); - for (int i = 0; i < 14; i++) - { - printf(" "); - } - printf("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n\n\nACEY-DUCEY IS PLAYED IN THE FOLLOWING MANNER \n"); - printf("THE DEALER (COMPUTER) DEALS TWO CARDS FACE UP\nYOU HAVE AN OPTION TO BET OR NOT BET DEPENDING\n"); - printf("ON WHETHER OR NOT YOU FEEL THE CARD WILL HAVE\nA VALUE BETWEEN THE FIRST TWO.\n"); - printf("IF YOU DO NOT WANT TO BET, INPUT A 0\n"); -} - -void Play(bool& isPlaying) -{ - short int DealerCards[2]; - int Bet; - short int CurrentCard; - printf("YOU NOW HAVE %d DOLLARS.\n\n", Money); - printf("HERE ARE YOUR NEXT TWO CARDS: \n"); - - //Draw Dealers Cards - DrawCard(DealerCards[0]); - printf("\n"); - DrawCard(DealerCards[1]); - printf("\n\n\n"); - - //Check if Bet is Valid - do { - printf("WHAT IS YOUR BET: "); - std::cin >> Bet; - if (Bet == 0) - { - printf("CHICKEN!!\n\n"); - } - } while (Bet > Money || Bet < 0); - - //Draw Players Card - DrawCard(CurrentCard); - printf("\n"); - if (CurrentCard > DealerCards[0] && CurrentCard < DealerCards[1]) - { - printf("YOU WIN!!!\n"); - Money += Bet; - return; - } - else - { - printf("SORRY, YOU LOSE\n"); - Money -= Bet; - } - if (isGameOver()) - { - printf("TRY AGAIN (YES OR NO)\n\n"); - std::string response; - std::cin >> response; - if (response != "YES") - { - isPlaying = false; - } - Money = 100; - } -} - -bool isGameOver() -{ - if (Money <= 0) - { - printf("\n\n"); - printf("SORRY, FRIEND, BUT YOU BLEW YOUR WAD.\n\n"); - return true; - } - return false; -} - -void DrawCard(short int& Card) -{ - //Basically generate 2 numbers first one is between 2-11 and second one 0-3 - short int RandomNum1 = (rand() % 10) + 2; - short int RandomNum2 = rand() % 4; - Card = RandomNum1 + RandomNum2; - - switch (Card) - { - case 11: - printf("JACK"); - break; - case 12: - printf("QUEEN"); - break; - case 13: - printf("KING"); - break; - case 14: - printf("ACE"); - break; - default: - printf("%d", Card); - } -} \ No newline at end of file diff --git a/00_Alternate_Languages/01_Acey_Ducey/c++/source/Aceyducey.h b/00_Alternate_Languages/01_Acey_Ducey/c++/source/Aceyducey.h deleted file mode 100644 index 67c56d7e6..000000000 --- a/00_Alternate_Languages/01_Acey_Ducey/c++/source/Aceyducey.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -void WelcomeMessage(); -void DrawCard(short int& Card); -void Play(bool& isPlaying); -bool isGameOver(); -int Money; \ No newline at end of file diff --git a/00_Alternate_Languages/01_Acey_Ducey/elm/.gitignore b/00_Alternate_Languages/01_Acey_Ducey/elm/.gitignore deleted file mode 100644 index 54912b8d6..000000000 --- a/00_Alternate_Languages/01_Acey_Ducey/elm/.gitignore +++ /dev/null @@ -1,206 +0,0 @@ - -# Created by https://www.toptal.com/developers/gitignore/api/macos,visualstudiocode,elm -# Edit at https://www.toptal.com/developers/gitignore?templates=macos,visualstudiocode,elm - -### Elm ### -# elm-package generated files -elm-stuff -# elm-repl generated files -repl-temp-* - -### macOS ### -# General -.DS_Store -.AppleDouble -.LSOverride - -# Icon must end with two \r -Icon - - -# Thumbnails -._* - -# Files that might appear in the root of a volume -.DocumentRevisions-V100 -.fseventsd -.Spotlight-V100 -.TemporaryItems -.Trashes -.VolumeIcon.icns -.com.apple.timemachine.donotpresent - -# Directories potentially created on remote AFP share -.AppleDB -.AppleDesktop -Network Trash Folder -Temporary Items -.apdisk - -### 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 - -# End of https://www.toptal.com/developers/gitignore/api/macos,visualstudiocode,elm - -# Created by https://www.toptal.com/developers/gitignore/api/node -# Edit at https://www.toptal.com/developers/gitignore?templates=node - -### Node ### -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* -.pnpm-debug.log* - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage -*.lcov - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# Snowpack dependency directory (https://snowpack.dev/) -web_modules/ - -# TypeScript cache -*.tsbuildinfo - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Optional stylelint cache -.stylelintcache - -# Microbundle cache -.rpt2_cache/ -.rts2_cache_cjs/ -.rts2_cache_es/ -.rts2_cache_umd/ - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variable files -.env -.env.development.local -.env.test.local -.env.production.local -.env.local - -# parcel-bundler cache (https://parceljs.org/) -.cache -.parcel-cache - -# Next.js build output -.next -out - -# Nuxt.js build / generate output -.nuxt -dist - -# Gatsby files -.cache/ -# Comment in the public line in if your project uses Gatsby and not Next.js -# https://nextjs.org/blog/next-9-1#public-directory-support -# public - -# vuepress build output -.vuepress/dist - -# vuepress v2.x temp and cache directory -.temp - -# Docusaurus cache and generated files -.docusaurus - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -# TernJS port file -.tern-port - -# Stores VSCode versions used for testing VSCode extensions -.vscode-test - -# yarn v2 -.yarn/cache -.yarn/unplugged -.yarn/build-state.yml -.yarn/install-state.gz -.pnp.* - -### Node Patch ### -# Serverless Webpack directories -.webpack/ - -# Optional stylelint cache - -# SvelteKit build / generate output -.svelte-kit - -# End of https://www.toptal.com/developers/gitignore/api/node diff --git a/00_Alternate_Languages/01_Acey_Ducey/elm/README.md b/00_Alternate_Languages/01_Acey_Ducey/elm/README.md deleted file mode 100644 index 23ea3cefc..000000000 --- a/00_Alternate_Languages/01_Acey_Ducey/elm/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# Acey Ducey - -This is an Elm implementation of the `Basic Compouter Games` Game Acey Ducey. - -## Build App - -- install elm - -```bash -yarn -yarn build -``` diff --git a/00_Alternate_Languages/01_Acey_Ducey/elm/docs/app.js b/00_Alternate_Languages/01_Acey_Ducey/elm/docs/app.js deleted file mode 100644 index d2946a198..000000000 --- a/00_Alternate_Languages/01_Acey_Ducey/elm/docs/app.js +++ /dev/null @@ -1,5909 +0,0 @@ -(function(scope){ -'use strict'; - -function F(arity, fun, wrapper) { - wrapper.a = arity; - wrapper.f = fun; - return wrapper; -} - -function F2(fun) { - return F(2, fun, function(a) { return function(b) { return fun(a,b); }; }) -} -function F3(fun) { - return F(3, fun, function(a) { - return function(b) { return function(c) { return fun(a, b, c); }; }; - }); -} -function F4(fun) { - return F(4, fun, function(a) { return function(b) { return function(c) { - return function(d) { return fun(a, b, c, d); }; }; }; - }); -} -function F5(fun) { - return F(5, fun, function(a) { return function(b) { return function(c) { - return function(d) { return function(e) { return fun(a, b, c, d, e); }; }; }; }; - }); -} -function F6(fun) { - return F(6, fun, function(a) { return function(b) { return function(c) { - return function(d) { return function(e) { return function(f) { - return fun(a, b, c, d, e, f); }; }; }; }; }; - }); -} -function F7(fun) { - return F(7, fun, function(a) { return function(b) { return function(c) { - return function(d) { return function(e) { return function(f) { - return function(g) { return fun(a, b, c, d, e, f, g); }; }; }; }; }; }; - }); -} -function F8(fun) { - return F(8, fun, function(a) { return function(b) { return function(c) { - return function(d) { return function(e) { return function(f) { - return function(g) { return function(h) { - return fun(a, b, c, d, e, f, g, h); }; }; }; }; }; }; }; - }); -} -function F9(fun) { - return F(9, fun, function(a) { return function(b) { return function(c) { - return function(d) { return function(e) { return function(f) { - return function(g) { return function(h) { return function(i) { - return fun(a, b, c, d, e, f, g, h, i); }; }; }; }; }; }; }; }; - }); -} - -function A2(fun, a, b) { - return fun.a === 2 ? fun.f(a, b) : fun(a)(b); -} -function A3(fun, a, b, c) { - return fun.a === 3 ? fun.f(a, b, c) : fun(a)(b)(c); -} -function A4(fun, a, b, c, d) { - return fun.a === 4 ? fun.f(a, b, c, d) : fun(a)(b)(c)(d); -} -function A5(fun, a, b, c, d, e) { - return fun.a === 5 ? fun.f(a, b, c, d, e) : fun(a)(b)(c)(d)(e); -} -function A6(fun, a, b, c, d, e, f) { - return fun.a === 6 ? fun.f(a, b, c, d, e, f) : fun(a)(b)(c)(d)(e)(f); -} -function A7(fun, a, b, c, d, e, f, g) { - return fun.a === 7 ? fun.f(a, b, c, d, e, f, g) : fun(a)(b)(c)(d)(e)(f)(g); -} -function A8(fun, a, b, c, d, e, f, g, h) { - return fun.a === 8 ? fun.f(a, b, c, d, e, f, g, h) : fun(a)(b)(c)(d)(e)(f)(g)(h); -} -function A9(fun, a, b, c, d, e, f, g, h, i) { - return fun.a === 9 ? fun.f(a, b, c, d, e, f, g, h, i) : fun(a)(b)(c)(d)(e)(f)(g)(h)(i); -} - - - - -// EQUALITY - -function _Utils_eq(x, y) -{ - for ( - var pair, stack = [], isEqual = _Utils_eqHelp(x, y, 0, stack); - isEqual && (pair = stack.pop()); - isEqual = _Utils_eqHelp(pair.a, pair.b, 0, stack) - ) - {} - - return isEqual; -} - -function _Utils_eqHelp(x, y, depth, stack) -{ - if (x === y) - { - return true; - } - - if (typeof x !== 'object' || x === null || y === null) - { - typeof x === 'function' && _Debug_crash(5); - return false; - } - - if (depth > 100) - { - stack.push(_Utils_Tuple2(x,y)); - return true; - } - - /**_UNUSED/ - if (x.$ === 'Set_elm_builtin') - { - x = $elm$core$Set$toList(x); - y = $elm$core$Set$toList(y); - } - if (x.$ === 'RBNode_elm_builtin' || x.$ === 'RBEmpty_elm_builtin') - { - x = $elm$core$Dict$toList(x); - y = $elm$core$Dict$toList(y); - } - //*/ - - /**/ - if (x.$ < 0) - { - x = $elm$core$Dict$toList(x); - y = $elm$core$Dict$toList(y); - } - //*/ - - for (var key in x) - { - if (!_Utils_eqHelp(x[key], y[key], depth + 1, stack)) - { - return false; - } - } - return true; -} - -var _Utils_equal = F2(_Utils_eq); -var _Utils_notEqual = F2(function(a, b) { return !_Utils_eq(a,b); }); - - - -// COMPARISONS - -// Code in Generate/JavaScript.hs, Basics.js, and List.js depends on -// the particular integer values assigned to LT, EQ, and GT. - -function _Utils_cmp(x, y, ord) -{ - if (typeof x !== 'object') - { - return x === y ? /*EQ*/ 0 : x < y ? /*LT*/ -1 : /*GT*/ 1; - } - - /**_UNUSED/ - if (x instanceof String) - { - var a = x.valueOf(); - var b = y.valueOf(); - return a === b ? 0 : a < b ? -1 : 1; - } - //*/ - - /**/ - if (typeof x.$ === 'undefined') - //*/ - /**_UNUSED/ - if (x.$[0] === '#') - //*/ - { - return (ord = _Utils_cmp(x.a, y.a)) - ? ord - : (ord = _Utils_cmp(x.b, y.b)) - ? ord - : _Utils_cmp(x.c, y.c); - } - - // traverse conses until end of a list or a mismatch - for (; x.b && y.b && !(ord = _Utils_cmp(x.a, y.a)); x = x.b, y = y.b) {} // WHILE_CONSES - return ord || (x.b ? /*GT*/ 1 : y.b ? /*LT*/ -1 : /*EQ*/ 0); -} - -var _Utils_lt = F2(function(a, b) { return _Utils_cmp(a, b) < 0; }); -var _Utils_le = F2(function(a, b) { return _Utils_cmp(a, b) < 1; }); -var _Utils_gt = F2(function(a, b) { return _Utils_cmp(a, b) > 0; }); -var _Utils_ge = F2(function(a, b) { return _Utils_cmp(a, b) >= 0; }); - -var _Utils_compare = F2(function(x, y) -{ - var n = _Utils_cmp(x, y); - return n < 0 ? $elm$core$Basics$LT : n ? $elm$core$Basics$GT : $elm$core$Basics$EQ; -}); - - -// COMMON VALUES - -var _Utils_Tuple0 = 0; -var _Utils_Tuple0_UNUSED = { $: '#0' }; - -function _Utils_Tuple2(a, b) { return { a: a, b: b }; } -function _Utils_Tuple2_UNUSED(a, b) { return { $: '#2', a: a, b: b }; } - -function _Utils_Tuple3(a, b, c) { return { a: a, b: b, c: c }; } -function _Utils_Tuple3_UNUSED(a, b, c) { return { $: '#3', a: a, b: b, c: c }; } - -function _Utils_chr(c) { return c; } -function _Utils_chr_UNUSED(c) { return new String(c); } - - -// RECORDS - -function _Utils_update(oldRecord, updatedFields) -{ - var newRecord = {}; - - for (var key in oldRecord) - { - newRecord[key] = oldRecord[key]; - } - - for (var key in updatedFields) - { - newRecord[key] = updatedFields[key]; - } - - return newRecord; -} - - -// APPEND - -var _Utils_append = F2(_Utils_ap); - -function _Utils_ap(xs, ys) -{ - // append Strings - if (typeof xs === 'string') - { - return xs + ys; - } - - // append Lists - if (!xs.b) - { - return ys; - } - var root = _List_Cons(xs.a, ys); - xs = xs.b - for (var curr = root; xs.b; xs = xs.b) // WHILE_CONS - { - curr = curr.b = _List_Cons(xs.a, ys); - } - return root; -} - - - -var _List_Nil = { $: 0 }; -var _List_Nil_UNUSED = { $: '[]' }; - -function _List_Cons(hd, tl) { return { $: 1, a: hd, b: tl }; } -function _List_Cons_UNUSED(hd, tl) { return { $: '::', a: hd, b: tl }; } - - -var _List_cons = F2(_List_Cons); - -function _List_fromArray(arr) -{ - var out = _List_Nil; - for (var i = arr.length; i--; ) - { - out = _List_Cons(arr[i], out); - } - return out; -} - -function _List_toArray(xs) -{ - for (var out = []; xs.b; xs = xs.b) // WHILE_CONS - { - out.push(xs.a); - } - return out; -} - -var _List_map2 = F3(function(f, xs, ys) -{ - for (var arr = []; xs.b && ys.b; xs = xs.b, ys = ys.b) // WHILE_CONSES - { - arr.push(A2(f, xs.a, ys.a)); - } - return _List_fromArray(arr); -}); - -var _List_map3 = F4(function(f, xs, ys, zs) -{ - for (var arr = []; xs.b && ys.b && zs.b; xs = xs.b, ys = ys.b, zs = zs.b) // WHILE_CONSES - { - arr.push(A3(f, xs.a, ys.a, zs.a)); - } - return _List_fromArray(arr); -}); - -var _List_map4 = F5(function(f, ws, xs, ys, zs) -{ - for (var arr = []; ws.b && xs.b && ys.b && zs.b; ws = ws.b, xs = xs.b, ys = ys.b, zs = zs.b) // WHILE_CONSES - { - arr.push(A4(f, ws.a, xs.a, ys.a, zs.a)); - } - return _List_fromArray(arr); -}); - -var _List_map5 = F6(function(f, vs, ws, xs, ys, zs) -{ - for (var arr = []; vs.b && ws.b && xs.b && ys.b && zs.b; vs = vs.b, ws = ws.b, xs = xs.b, ys = ys.b, zs = zs.b) // WHILE_CONSES - { - arr.push(A5(f, vs.a, ws.a, xs.a, ys.a, zs.a)); - } - return _List_fromArray(arr); -}); - -var _List_sortBy = F2(function(f, xs) -{ - return _List_fromArray(_List_toArray(xs).sort(function(a, b) { - return _Utils_cmp(f(a), f(b)); - })); -}); - -var _List_sortWith = F2(function(f, xs) -{ - return _List_fromArray(_List_toArray(xs).sort(function(a, b) { - var ord = A2(f, a, b); - return ord === $elm$core$Basics$EQ ? 0 : ord === $elm$core$Basics$LT ? -1 : 1; - })); -}); - - - -var _JsArray_empty = []; - -function _JsArray_singleton(value) -{ - return [value]; -} - -function _JsArray_length(array) -{ - return array.length; -} - -var _JsArray_initialize = F3(function(size, offset, func) -{ - var result = new Array(size); - - for (var i = 0; i < size; i++) - { - result[i] = func(offset + i); - } - - return result; -}); - -var _JsArray_initializeFromList = F2(function (max, ls) -{ - var result = new Array(max); - - for (var i = 0; i < max && ls.b; i++) - { - result[i] = ls.a; - ls = ls.b; - } - - result.length = i; - return _Utils_Tuple2(result, ls); -}); - -var _JsArray_unsafeGet = F2(function(index, array) -{ - return array[index]; -}); - -var _JsArray_unsafeSet = F3(function(index, value, array) -{ - var length = array.length; - var result = new Array(length); - - for (var i = 0; i < length; i++) - { - result[i] = array[i]; - } - - result[index] = value; - return result; -}); - -var _JsArray_push = F2(function(value, array) -{ - var length = array.length; - var result = new Array(length + 1); - - for (var i = 0; i < length; i++) - { - result[i] = array[i]; - } - - result[length] = value; - return result; -}); - -var _JsArray_foldl = F3(function(func, acc, array) -{ - var length = array.length; - - for (var i = 0; i < length; i++) - { - acc = A2(func, array[i], acc); - } - - return acc; -}); - -var _JsArray_foldr = F3(function(func, acc, array) -{ - for (var i = array.length - 1; i >= 0; i--) - { - acc = A2(func, array[i], acc); - } - - return acc; -}); - -var _JsArray_map = F2(function(func, array) -{ - var length = array.length; - var result = new Array(length); - - for (var i = 0; i < length; i++) - { - result[i] = func(array[i]); - } - - return result; -}); - -var _JsArray_indexedMap = F3(function(func, offset, array) -{ - var length = array.length; - var result = new Array(length); - - for (var i = 0; i < length; i++) - { - result[i] = A2(func, offset + i, array[i]); - } - - return result; -}); - -var _JsArray_slice = F3(function(from, to, array) -{ - return array.slice(from, to); -}); - -var _JsArray_appendN = F3(function(n, dest, source) -{ - var destLen = dest.length; - var itemsToCopy = n - destLen; - - if (itemsToCopy > source.length) - { - itemsToCopy = source.length; - } - - var size = destLen + itemsToCopy; - var result = new Array(size); - - for (var i = 0; i < destLen; i++) - { - result[i] = dest[i]; - } - - for (var i = 0; i < itemsToCopy; i++) - { - result[i + destLen] = source[i]; - } - - return result; -}); - - - -// LOG - -var _Debug_log = F2(function(tag, value) -{ - return value; -}); - -var _Debug_log_UNUSED = F2(function(tag, value) -{ - console.log(tag + ': ' + _Debug_toString(value)); - return value; -}); - - -// TODOS - -function _Debug_todo(moduleName, region) -{ - return function(message) { - _Debug_crash(8, moduleName, region, message); - }; -} - -function _Debug_todoCase(moduleName, region, value) -{ - return function(message) { - _Debug_crash(9, moduleName, region, value, message); - }; -} - - -// TO STRING - -function _Debug_toString(value) -{ - return ''; -} - -function _Debug_toString_UNUSED(value) -{ - return _Debug_toAnsiString(false, value); -} - -function _Debug_toAnsiString(ansi, value) -{ - if (typeof value === 'function') - { - return _Debug_internalColor(ansi, ''); - } - - if (typeof value === 'boolean') - { - return _Debug_ctorColor(ansi, value ? 'True' : 'False'); - } - - if (typeof value === 'number') - { - return _Debug_numberColor(ansi, value + ''); - } - - if (value instanceof String) - { - return _Debug_charColor(ansi, "'" + _Debug_addSlashes(value, true) + "'"); - } - - if (typeof value === 'string') - { - return _Debug_stringColor(ansi, '"' + _Debug_addSlashes(value, false) + '"'); - } - - if (typeof value === 'object' && '$' in value) - { - var tag = value.$; - - if (typeof tag === 'number') - { - return _Debug_internalColor(ansi, ''); - } - - if (tag[0] === '#') - { - var output = []; - for (var k in value) - { - if (k === '$') continue; - output.push(_Debug_toAnsiString(ansi, value[k])); - } - return '(' + output.join(',') + ')'; - } - - if (tag === 'Set_elm_builtin') - { - return _Debug_ctorColor(ansi, 'Set') - + _Debug_fadeColor(ansi, '.fromList') + ' ' - + _Debug_toAnsiString(ansi, $elm$core$Set$toList(value)); - } - - if (tag === 'RBNode_elm_builtin' || tag === 'RBEmpty_elm_builtin') - { - return _Debug_ctorColor(ansi, 'Dict') - + _Debug_fadeColor(ansi, '.fromList') + ' ' - + _Debug_toAnsiString(ansi, $elm$core$Dict$toList(value)); - } - - if (tag === 'Array_elm_builtin') - { - return _Debug_ctorColor(ansi, 'Array') - + _Debug_fadeColor(ansi, '.fromList') + ' ' - + _Debug_toAnsiString(ansi, $elm$core$Array$toList(value)); - } - - if (tag === '::' || tag === '[]') - { - var output = '['; - - value.b && (output += _Debug_toAnsiString(ansi, value.a), value = value.b) - - for (; value.b; value = value.b) // WHILE_CONS - { - output += ',' + _Debug_toAnsiString(ansi, value.a); - } - return output + ']'; - } - - var output = ''; - for (var i in value) - { - if (i === '$') continue; - var str = _Debug_toAnsiString(ansi, value[i]); - var c0 = str[0]; - var parenless = c0 === '{' || c0 === '(' || c0 === '[' || c0 === '<' || c0 === '"' || str.indexOf(' ') < 0; - output += ' ' + (parenless ? str : '(' + str + ')'); - } - return _Debug_ctorColor(ansi, tag) + output; - } - - if (typeof DataView === 'function' && value instanceof DataView) - { - return _Debug_stringColor(ansi, '<' + value.byteLength + ' bytes>'); - } - - if (typeof File !== 'undefined' && value instanceof File) - { - return _Debug_internalColor(ansi, '<' + value.name + '>'); - } - - if (typeof value === 'object') - { - var output = []; - for (var key in value) - { - var field = key[0] === '_' ? key.slice(1) : key; - output.push(_Debug_fadeColor(ansi, field) + ' = ' + _Debug_toAnsiString(ansi, value[key])); - } - if (output.length === 0) - { - return '{}'; - } - return '{ ' + output.join(', ') + ' }'; - } - - return _Debug_internalColor(ansi, ''); -} - -function _Debug_addSlashes(str, isChar) -{ - var s = str - .replace(/\\/g, '\\\\') - .replace(/\n/g, '\\n') - .replace(/\t/g, '\\t') - .replace(/\r/g, '\\r') - .replace(/\v/g, '\\v') - .replace(/\0/g, '\\0'); - - if (isChar) - { - return s.replace(/\'/g, '\\\''); - } - else - { - return s.replace(/\"/g, '\\"'); - } -} - -function _Debug_ctorColor(ansi, string) -{ - return ansi ? '\x1b[96m' + string + '\x1b[0m' : string; -} - -function _Debug_numberColor(ansi, string) -{ - return ansi ? '\x1b[95m' + string + '\x1b[0m' : string; -} - -function _Debug_stringColor(ansi, string) -{ - return ansi ? '\x1b[93m' + string + '\x1b[0m' : string; -} - -function _Debug_charColor(ansi, string) -{ - return ansi ? '\x1b[92m' + string + '\x1b[0m' : string; -} - -function _Debug_fadeColor(ansi, string) -{ - return ansi ? '\x1b[37m' + string + '\x1b[0m' : string; -} - -function _Debug_internalColor(ansi, string) -{ - return ansi ? '\x1b[36m' + string + '\x1b[0m' : string; -} - -function _Debug_toHexDigit(n) -{ - return String.fromCharCode(n < 10 ? 48 + n : 55 + n); -} - - -// CRASH - - -function _Debug_crash(identifier) -{ - throw new Error('https://github.com/elm/core/blob/1.0.0/hints/' + identifier + '.md'); -} - - -function _Debug_crash_UNUSED(identifier, fact1, fact2, fact3, fact4) -{ - switch(identifier) - { - case 0: - throw new Error('What node should I take over? In JavaScript I need something like:\n\n Elm.Main.init({\n node: document.getElementById("elm-node")\n })\n\nYou need to do this with any Browser.sandbox or Browser.element program.'); - - case 1: - throw new Error('Browser.application programs cannot handle URLs like this:\n\n ' + document.location.href + '\n\nWhat is the root? The root of your file system? Try looking at this program with `elm reactor` or some other server.'); - - case 2: - var jsonErrorString = fact1; - throw new Error('Problem with the flags given to your Elm program on initialization.\n\n' + jsonErrorString); - - case 3: - var portName = fact1; - throw new Error('There can only be one port named `' + portName + '`, but your program has multiple.'); - - case 4: - var portName = fact1; - var problem = fact2; - throw new Error('Trying to send an unexpected type of value through port `' + portName + '`:\n' + problem); - - case 5: - throw new Error('Trying to use `(==)` on functions.\nThere is no way to know if functions are "the same" in the Elm sense.\nRead more about this at https://package.elm-lang.org/packages/elm/core/latest/Basics#== which describes why it is this way and what the better version will look like.'); - - case 6: - var moduleName = fact1; - throw new Error('Your page is loading multiple Elm scripts with a module named ' + moduleName + '. Maybe a duplicate script is getting loaded accidentally? If not, rename one of them so I know which is which!'); - - case 8: - var moduleName = fact1; - var region = fact2; - var message = fact3; - throw new Error('TODO in module `' + moduleName + '` ' + _Debug_regionToString(region) + '\n\n' + message); - - case 9: - var moduleName = fact1; - var region = fact2; - var value = fact3; - var message = fact4; - throw new Error( - 'TODO in module `' + moduleName + '` from the `case` expression ' - + _Debug_regionToString(region) + '\n\nIt received the following value:\n\n ' - + _Debug_toString(value).replace('\n', '\n ') - + '\n\nBut the branch that handles it says:\n\n ' + message.replace('\n', '\n ') - ); - - case 10: - throw new Error('Bug in https://github.com/elm/virtual-dom/issues'); - - case 11: - throw new Error('Cannot perform mod 0. Division by zero error.'); - } -} - -function _Debug_regionToString(region) -{ - if (region.Q.H === region.V.H) - { - return 'on line ' + region.Q.H; - } - return 'on lines ' + region.Q.H + ' through ' + region.V.H; -} - - - -// MATH - -var _Basics_add = F2(function(a, b) { return a + b; }); -var _Basics_sub = F2(function(a, b) { return a - b; }); -var _Basics_mul = F2(function(a, b) { return a * b; }); -var _Basics_fdiv = F2(function(a, b) { return a / b; }); -var _Basics_idiv = F2(function(a, b) { return (a / b) | 0; }); -var _Basics_pow = F2(Math.pow); - -var _Basics_remainderBy = F2(function(b, a) { return a % b; }); - -// https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/divmodnote-letter.pdf -var _Basics_modBy = F2(function(modulus, x) -{ - var answer = x % modulus; - return modulus === 0 - ? _Debug_crash(11) - : - ((answer > 0 && modulus < 0) || (answer < 0 && modulus > 0)) - ? answer + modulus - : answer; -}); - - -// TRIGONOMETRY - -var _Basics_pi = Math.PI; -var _Basics_e = Math.E; -var _Basics_cos = Math.cos; -var _Basics_sin = Math.sin; -var _Basics_tan = Math.tan; -var _Basics_acos = Math.acos; -var _Basics_asin = Math.asin; -var _Basics_atan = Math.atan; -var _Basics_atan2 = F2(Math.atan2); - - -// MORE MATH - -function _Basics_toFloat(x) { return x; } -function _Basics_truncate(n) { return n | 0; } -function _Basics_isInfinite(n) { return n === Infinity || n === -Infinity; } - -var _Basics_ceiling = Math.ceil; -var _Basics_floor = Math.floor; -var _Basics_round = Math.round; -var _Basics_sqrt = Math.sqrt; -var _Basics_log = Math.log; -var _Basics_isNaN = isNaN; - - -// BOOLEANS - -function _Basics_not(bool) { return !bool; } -var _Basics_and = F2(function(a, b) { return a && b; }); -var _Basics_or = F2(function(a, b) { return a || b; }); -var _Basics_xor = F2(function(a, b) { return a !== b; }); - - - -var _String_cons = F2(function(chr, str) -{ - return chr + str; -}); - -function _String_uncons(string) -{ - var word = string.charCodeAt(0); - return !isNaN(word) - ? $elm$core$Maybe$Just( - 0xD800 <= word && word <= 0xDBFF - ? _Utils_Tuple2(_Utils_chr(string[0] + string[1]), string.slice(2)) - : _Utils_Tuple2(_Utils_chr(string[0]), string.slice(1)) - ) - : $elm$core$Maybe$Nothing; -} - -var _String_append = F2(function(a, b) -{ - return a + b; -}); - -function _String_length(str) -{ - return str.length; -} - -var _String_map = F2(function(func, string) -{ - var len = string.length; - var array = new Array(len); - var i = 0; - while (i < len) - { - var word = string.charCodeAt(i); - if (0xD800 <= word && word <= 0xDBFF) - { - array[i] = func(_Utils_chr(string[i] + string[i+1])); - i += 2; - continue; - } - array[i] = func(_Utils_chr(string[i])); - i++; - } - return array.join(''); -}); - -var _String_filter = F2(function(isGood, str) -{ - var arr = []; - var len = str.length; - var i = 0; - while (i < len) - { - var char = str[i]; - var word = str.charCodeAt(i); - i++; - if (0xD800 <= word && word <= 0xDBFF) - { - char += str[i]; - i++; - } - - if (isGood(_Utils_chr(char))) - { - arr.push(char); - } - } - return arr.join(''); -}); - -function _String_reverse(str) -{ - var len = str.length; - var arr = new Array(len); - var i = 0; - while (i < len) - { - var word = str.charCodeAt(i); - if (0xD800 <= word && word <= 0xDBFF) - { - arr[len - i] = str[i + 1]; - i++; - arr[len - i] = str[i - 1]; - i++; - } - else - { - arr[len - i] = str[i]; - i++; - } - } - return arr.join(''); -} - -var _String_foldl = F3(function(func, state, string) -{ - var len = string.length; - var i = 0; - while (i < len) - { - var char = string[i]; - var word = string.charCodeAt(i); - i++; - if (0xD800 <= word && word <= 0xDBFF) - { - char += string[i]; - i++; - } - state = A2(func, _Utils_chr(char), state); - } - return state; -}); - -var _String_foldr = F3(function(func, state, string) -{ - var i = string.length; - while (i--) - { - var char = string[i]; - var word = string.charCodeAt(i); - if (0xDC00 <= word && word <= 0xDFFF) - { - i--; - char = string[i] + char; - } - state = A2(func, _Utils_chr(char), state); - } - return state; -}); - -var _String_split = F2(function(sep, str) -{ - return str.split(sep); -}); - -var _String_join = F2(function(sep, strs) -{ - return strs.join(sep); -}); - -var _String_slice = F3(function(start, end, str) { - return str.slice(start, end); -}); - -function _String_trim(str) -{ - return str.trim(); -} - -function _String_trimLeft(str) -{ - return str.replace(/^\s+/, ''); -} - -function _String_trimRight(str) -{ - return str.replace(/\s+$/, ''); -} - -function _String_words(str) -{ - return _List_fromArray(str.trim().split(/\s+/g)); -} - -function _String_lines(str) -{ - return _List_fromArray(str.split(/\r\n|\r|\n/g)); -} - -function _String_toUpper(str) -{ - return str.toUpperCase(); -} - -function _String_toLower(str) -{ - return str.toLowerCase(); -} - -var _String_any = F2(function(isGood, string) -{ - var i = string.length; - while (i--) - { - var char = string[i]; - var word = string.charCodeAt(i); - if (0xDC00 <= word && word <= 0xDFFF) - { - i--; - char = string[i] + char; - } - if (isGood(_Utils_chr(char))) - { - return true; - } - } - return false; -}); - -var _String_all = F2(function(isGood, string) -{ - var i = string.length; - while (i--) - { - var char = string[i]; - var word = string.charCodeAt(i); - if (0xDC00 <= word && word <= 0xDFFF) - { - i--; - char = string[i] + char; - } - if (!isGood(_Utils_chr(char))) - { - return false; - } - } - return true; -}); - -var _String_contains = F2(function(sub, str) -{ - return str.indexOf(sub) > -1; -}); - -var _String_startsWith = F2(function(sub, str) -{ - return str.indexOf(sub) === 0; -}); - -var _String_endsWith = F2(function(sub, str) -{ - return str.length >= sub.length && - str.lastIndexOf(sub) === str.length - sub.length; -}); - -var _String_indexes = F2(function(sub, str) -{ - var subLen = sub.length; - - if (subLen < 1) - { - return _List_Nil; - } - - var i = 0; - var is = []; - - while ((i = str.indexOf(sub, i)) > -1) - { - is.push(i); - i = i + subLen; - } - - return _List_fromArray(is); -}); - - -// TO STRING - -function _String_fromNumber(number) -{ - return number + ''; -} - - -// INT CONVERSIONS - -function _String_toInt(str) -{ - var total = 0; - var code0 = str.charCodeAt(0); - var start = code0 == 0x2B /* + */ || code0 == 0x2D /* - */ ? 1 : 0; - - for (var i = start; i < str.length; ++i) - { - var code = str.charCodeAt(i); - if (code < 0x30 || 0x39 < code) - { - return $elm$core$Maybe$Nothing; - } - total = 10 * total + code - 0x30; - } - - return i == start - ? $elm$core$Maybe$Nothing - : $elm$core$Maybe$Just(code0 == 0x2D ? -total : total); -} - - -// FLOAT CONVERSIONS - -function _String_toFloat(s) -{ - // check if it is a hex, octal, or binary number - if (s.length === 0 || /[\sxbo]/.test(s)) - { - return $elm$core$Maybe$Nothing; - } - var n = +s; - // faster isNaN check - return n === n ? $elm$core$Maybe$Just(n) : $elm$core$Maybe$Nothing; -} - -function _String_fromList(chars) -{ - return _List_toArray(chars).join(''); -} - - - - -function _Char_toCode(char) -{ - var code = char.charCodeAt(0); - if (0xD800 <= code && code <= 0xDBFF) - { - return (code - 0xD800) * 0x400 + char.charCodeAt(1) - 0xDC00 + 0x10000 - } - return code; -} - -function _Char_fromCode(code) -{ - return _Utils_chr( - (code < 0 || 0x10FFFF < code) - ? '\uFFFD' - : - (code <= 0xFFFF) - ? String.fromCharCode(code) - : - (code -= 0x10000, - String.fromCharCode(Math.floor(code / 0x400) + 0xD800, code % 0x400 + 0xDC00) - ) - ); -} - -function _Char_toUpper(char) -{ - return _Utils_chr(char.toUpperCase()); -} - -function _Char_toLower(char) -{ - return _Utils_chr(char.toLowerCase()); -} - -function _Char_toLocaleUpper(char) -{ - return _Utils_chr(char.toLocaleUpperCase()); -} - -function _Char_toLocaleLower(char) -{ - return _Utils_chr(char.toLocaleLowerCase()); -} - - - -/**_UNUSED/ -function _Json_errorToString(error) -{ - return $elm$json$Json$Decode$errorToString(error); -} -//*/ - - -// CORE DECODERS - -function _Json_succeed(msg) -{ - return { - $: 0, - a: msg - }; -} - -function _Json_fail(msg) -{ - return { - $: 1, - a: msg - }; -} - -function _Json_decodePrim(decoder) -{ - return { $: 2, b: decoder }; -} - -var _Json_decodeInt = _Json_decodePrim(function(value) { - return (typeof value !== 'number') - ? _Json_expecting('an INT', value) - : - (-2147483647 < value && value < 2147483647 && (value | 0) === value) - ? $elm$core$Result$Ok(value) - : - (isFinite(value) && !(value % 1)) - ? $elm$core$Result$Ok(value) - : _Json_expecting('an INT', value); -}); - -var _Json_decodeBool = _Json_decodePrim(function(value) { - return (typeof value === 'boolean') - ? $elm$core$Result$Ok(value) - : _Json_expecting('a BOOL', value); -}); - -var _Json_decodeFloat = _Json_decodePrim(function(value) { - return (typeof value === 'number') - ? $elm$core$Result$Ok(value) - : _Json_expecting('a FLOAT', value); -}); - -var _Json_decodeValue = _Json_decodePrim(function(value) { - return $elm$core$Result$Ok(_Json_wrap(value)); -}); - -var _Json_decodeString = _Json_decodePrim(function(value) { - return (typeof value === 'string') - ? $elm$core$Result$Ok(value) - : (value instanceof String) - ? $elm$core$Result$Ok(value + '') - : _Json_expecting('a STRING', value); -}); - -function _Json_decodeList(decoder) { return { $: 3, b: decoder }; } -function _Json_decodeArray(decoder) { return { $: 4, b: decoder }; } - -function _Json_decodeNull(value) { return { $: 5, c: value }; } - -var _Json_decodeField = F2(function(field, decoder) -{ - return { - $: 6, - d: field, - b: decoder - }; -}); - -var _Json_decodeIndex = F2(function(index, decoder) -{ - return { - $: 7, - e: index, - b: decoder - }; -}); - -function _Json_decodeKeyValuePairs(decoder) -{ - return { - $: 8, - b: decoder - }; -} - -function _Json_mapMany(f, decoders) -{ - return { - $: 9, - f: f, - g: decoders - }; -} - -var _Json_andThen = F2(function(callback, decoder) -{ - return { - $: 10, - b: decoder, - h: callback - }; -}); - -function _Json_oneOf(decoders) -{ - return { - $: 11, - g: decoders - }; -} - - -// DECODING OBJECTS - -var _Json_map1 = F2(function(f, d1) -{ - return _Json_mapMany(f, [d1]); -}); - -var _Json_map2 = F3(function(f, d1, d2) -{ - return _Json_mapMany(f, [d1, d2]); -}); - -var _Json_map3 = F4(function(f, d1, d2, d3) -{ - return _Json_mapMany(f, [d1, d2, d3]); -}); - -var _Json_map4 = F5(function(f, d1, d2, d3, d4) -{ - return _Json_mapMany(f, [d1, d2, d3, d4]); -}); - -var _Json_map5 = F6(function(f, d1, d2, d3, d4, d5) -{ - return _Json_mapMany(f, [d1, d2, d3, d4, d5]); -}); - -var _Json_map6 = F7(function(f, d1, d2, d3, d4, d5, d6) -{ - return _Json_mapMany(f, [d1, d2, d3, d4, d5, d6]); -}); - -var _Json_map7 = F8(function(f, d1, d2, d3, d4, d5, d6, d7) -{ - return _Json_mapMany(f, [d1, d2, d3, d4, d5, d6, d7]); -}); - -var _Json_map8 = F9(function(f, d1, d2, d3, d4, d5, d6, d7, d8) -{ - return _Json_mapMany(f, [d1, d2, d3, d4, d5, d6, d7, d8]); -}); - - -// DECODE - -var _Json_runOnString = F2(function(decoder, string) -{ - try - { - var value = JSON.parse(string); - return _Json_runHelp(decoder, value); - } - catch (e) - { - return $elm$core$Result$Err(A2($elm$json$Json$Decode$Failure, 'This is not valid JSON! ' + e.message, _Json_wrap(string))); - } -}); - -var _Json_run = F2(function(decoder, value) -{ - return _Json_runHelp(decoder, _Json_unwrap(value)); -}); - -function _Json_runHelp(decoder, value) -{ - switch (decoder.$) - { - case 2: - return decoder.b(value); - - case 5: - return (value === null) - ? $elm$core$Result$Ok(decoder.c) - : _Json_expecting('null', value); - - case 3: - if (!_Json_isArray(value)) - { - return _Json_expecting('a LIST', value); - } - return _Json_runArrayDecoder(decoder.b, value, _List_fromArray); - - case 4: - if (!_Json_isArray(value)) - { - return _Json_expecting('an ARRAY', value); - } - return _Json_runArrayDecoder(decoder.b, value, _Json_toElmArray); - - case 6: - var field = decoder.d; - if (typeof value !== 'object' || value === null || !(field in value)) - { - return _Json_expecting('an OBJECT with a field named `' + field + '`', value); - } - var result = _Json_runHelp(decoder.b, value[field]); - return ($elm$core$Result$isOk(result)) ? result : $elm$core$Result$Err(A2($elm$json$Json$Decode$Field, field, result.a)); - - case 7: - var index = decoder.e; - if (!_Json_isArray(value)) - { - return _Json_expecting('an ARRAY', value); - } - if (index >= value.length) - { - return _Json_expecting('a LONGER array. Need index ' + index + ' but only see ' + value.length + ' entries', value); - } - var result = _Json_runHelp(decoder.b, value[index]); - return ($elm$core$Result$isOk(result)) ? result : $elm$core$Result$Err(A2($elm$json$Json$Decode$Index, index, result.a)); - - case 8: - if (typeof value !== 'object' || value === null || _Json_isArray(value)) - { - return _Json_expecting('an OBJECT', value); - } - - var keyValuePairs = _List_Nil; - // TODO test perf of Object.keys and switch when support is good enough - for (var key in value) - { - if (value.hasOwnProperty(key)) - { - var result = _Json_runHelp(decoder.b, value[key]); - if (!$elm$core$Result$isOk(result)) - { - return $elm$core$Result$Err(A2($elm$json$Json$Decode$Field, key, result.a)); - } - keyValuePairs = _List_Cons(_Utils_Tuple2(key, result.a), keyValuePairs); - } - } - return $elm$core$Result$Ok($elm$core$List$reverse(keyValuePairs)); - - case 9: - var answer = decoder.f; - var decoders = decoder.g; - for (var i = 0; i < decoders.length; i++) - { - var result = _Json_runHelp(decoders[i], value); - if (!$elm$core$Result$isOk(result)) - { - return result; - } - answer = answer(result.a); - } - return $elm$core$Result$Ok(answer); - - case 10: - var result = _Json_runHelp(decoder.b, value); - return (!$elm$core$Result$isOk(result)) - ? result - : _Json_runHelp(decoder.h(result.a), value); - - case 11: - var errors = _List_Nil; - for (var temp = decoder.g; temp.b; temp = temp.b) // WHILE_CONS - { - var result = _Json_runHelp(temp.a, value); - if ($elm$core$Result$isOk(result)) - { - return result; - } - errors = _List_Cons(result.a, errors); - } - return $elm$core$Result$Err($elm$json$Json$Decode$OneOf($elm$core$List$reverse(errors))); - - case 1: - return $elm$core$Result$Err(A2($elm$json$Json$Decode$Failure, decoder.a, _Json_wrap(value))); - - case 0: - return $elm$core$Result$Ok(decoder.a); - } -} - -function _Json_runArrayDecoder(decoder, value, toElmValue) -{ - var len = value.length; - var array = new Array(len); - for (var i = 0; i < len; i++) - { - var result = _Json_runHelp(decoder, value[i]); - if (!$elm$core$Result$isOk(result)) - { - return $elm$core$Result$Err(A2($elm$json$Json$Decode$Index, i, result.a)); - } - array[i] = result.a; - } - return $elm$core$Result$Ok(toElmValue(array)); -} - -function _Json_isArray(value) -{ - return Array.isArray(value) || (typeof FileList !== 'undefined' && value instanceof FileList); -} - -function _Json_toElmArray(array) -{ - return A2($elm$core$Array$initialize, array.length, function(i) { return array[i]; }); -} - -function _Json_expecting(type, value) -{ - return $elm$core$Result$Err(A2($elm$json$Json$Decode$Failure, 'Expecting ' + type, _Json_wrap(value))); -} - - -// EQUALITY - -function _Json_equality(x, y) -{ - if (x === y) - { - return true; - } - - if (x.$ !== y.$) - { - return false; - } - - switch (x.$) - { - case 0: - case 1: - return x.a === y.a; - - case 2: - return x.b === y.b; - - case 5: - return x.c === y.c; - - case 3: - case 4: - case 8: - return _Json_equality(x.b, y.b); - - case 6: - return x.d === y.d && _Json_equality(x.b, y.b); - - case 7: - return x.e === y.e && _Json_equality(x.b, y.b); - - case 9: - return x.f === y.f && _Json_listEquality(x.g, y.g); - - case 10: - return x.h === y.h && _Json_equality(x.b, y.b); - - case 11: - return _Json_listEquality(x.g, y.g); - } -} - -function _Json_listEquality(aDecoders, bDecoders) -{ - var len = aDecoders.length; - if (len !== bDecoders.length) - { - return false; - } - for (var i = 0; i < len; i++) - { - if (!_Json_equality(aDecoders[i], bDecoders[i])) - { - return false; - } - } - return true; -} - - -// ENCODE - -var _Json_encode = F2(function(indentLevel, value) -{ - return JSON.stringify(_Json_unwrap(value), null, indentLevel) + ''; -}); - -function _Json_wrap_UNUSED(value) { return { $: 0, a: value }; } -function _Json_unwrap_UNUSED(value) { return value.a; } - -function _Json_wrap(value) { return value; } -function _Json_unwrap(value) { return value; } - -function _Json_emptyArray() { return []; } -function _Json_emptyObject() { return {}; } - -var _Json_addField = F3(function(key, value, object) -{ - object[key] = _Json_unwrap(value); - return object; -}); - -function _Json_addEntry(func) -{ - return F2(function(entry, array) - { - array.push(_Json_unwrap(func(entry))); - return array; - }); -} - -var _Json_encodeNull = _Json_wrap(null); - - - -// TASKS - -function _Scheduler_succeed(value) -{ - return { - $: 0, - a: value - }; -} - -function _Scheduler_fail(error) -{ - return { - $: 1, - a: error - }; -} - -function _Scheduler_binding(callback) -{ - return { - $: 2, - b: callback, - c: null - }; -} - -var _Scheduler_andThen = F2(function(callback, task) -{ - return { - $: 3, - b: callback, - d: task - }; -}); - -var _Scheduler_onError = F2(function(callback, task) -{ - return { - $: 4, - b: callback, - d: task - }; -}); - -function _Scheduler_receive(callback) -{ - return { - $: 5, - b: callback - }; -} - - -// PROCESSES - -var _Scheduler_guid = 0; - -function _Scheduler_rawSpawn(task) -{ - var proc = { - $: 0, - e: _Scheduler_guid++, - f: task, - g: null, - h: [] - }; - - _Scheduler_enqueue(proc); - - return proc; -} - -function _Scheduler_spawn(task) -{ - return _Scheduler_binding(function(callback) { - callback(_Scheduler_succeed(_Scheduler_rawSpawn(task))); - }); -} - -function _Scheduler_rawSend(proc, msg) -{ - proc.h.push(msg); - _Scheduler_enqueue(proc); -} - -var _Scheduler_send = F2(function(proc, msg) -{ - return _Scheduler_binding(function(callback) { - _Scheduler_rawSend(proc, msg); - callback(_Scheduler_succeed(_Utils_Tuple0)); - }); -}); - -function _Scheduler_kill(proc) -{ - return _Scheduler_binding(function(callback) { - var task = proc.f; - if (task.$ === 2 && task.c) - { - task.c(); - } - - proc.f = null; - - callback(_Scheduler_succeed(_Utils_Tuple0)); - }); -} - - -/* STEP PROCESSES - -type alias Process = - { $ : tag - , id : unique_id - , root : Task - , stack : null | { $: SUCCEED | FAIL, a: callback, b: stack } - , mailbox : [msg] - } - -*/ - - -var _Scheduler_working = false; -var _Scheduler_queue = []; - - -function _Scheduler_enqueue(proc) -{ - _Scheduler_queue.push(proc); - if (_Scheduler_working) - { - return; - } - _Scheduler_working = true; - while (proc = _Scheduler_queue.shift()) - { - _Scheduler_step(proc); - } - _Scheduler_working = false; -} - - -function _Scheduler_step(proc) -{ - while (proc.f) - { - var rootTag = proc.f.$; - if (rootTag === 0 || rootTag === 1) - { - while (proc.g && proc.g.$ !== rootTag) - { - proc.g = proc.g.i; - } - if (!proc.g) - { - return; - } - proc.f = proc.g.b(proc.f.a); - proc.g = proc.g.i; - } - else if (rootTag === 2) - { - proc.f.c = proc.f.b(function(newRoot) { - proc.f = newRoot; - _Scheduler_enqueue(proc); - }); - return; - } - else if (rootTag === 5) - { - if (proc.h.length === 0) - { - return; - } - proc.f = proc.f.b(proc.h.shift()); - } - else // if (rootTag === 3 || rootTag === 4) - { - proc.g = { - $: rootTag === 3 ? 0 : 1, - b: proc.f.b, - i: proc.g - }; - proc.f = proc.f.d; - } - } -} - - - -function _Process_sleep(time) -{ - return _Scheduler_binding(function(callback) { - var id = setTimeout(function() { - callback(_Scheduler_succeed(_Utils_Tuple0)); - }, time); - - return function() { clearTimeout(id); }; - }); -} - - - - -// PROGRAMS - - -var _Platform_worker = F4(function(impl, flagDecoder, debugMetadata, args) -{ - return _Platform_initialize( - flagDecoder, - args, - impl.aB, - impl.aJ, - impl.aH, - function() { return function() {} } - ); -}); - - - -// INITIALIZE A PROGRAM - - -function _Platform_initialize(flagDecoder, args, init, update, subscriptions, stepperBuilder) -{ - var result = A2(_Json_run, flagDecoder, _Json_wrap(args ? args['flags'] : undefined)); - $elm$core$Result$isOk(result) || _Debug_crash(2 /**_UNUSED/, _Json_errorToString(result.a) /**/); - var managers = {}; - var initPair = init(result.a); - var model = initPair.a; - var stepper = stepperBuilder(sendToApp, model); - var ports = _Platform_setupEffects(managers, sendToApp); - - function sendToApp(msg, viewMetadata) - { - var pair = A2(update, msg, model); - stepper(model = pair.a, viewMetadata); - _Platform_enqueueEffects(managers, pair.b, subscriptions(model)); - } - - _Platform_enqueueEffects(managers, initPair.b, subscriptions(model)); - - return ports ? { ports: ports } : {}; -} - - - -// TRACK PRELOADS -// -// This is used by code in elm/browser and elm/http -// to register any HTTP requests that are triggered by init. -// - - -var _Platform_preload; - - -function _Platform_registerPreload(url) -{ - _Platform_preload.add(url); -} - - - -// EFFECT MANAGERS - - -var _Platform_effectManagers = {}; - - -function _Platform_setupEffects(managers, sendToApp) -{ - var ports; - - // setup all necessary effect managers - for (var key in _Platform_effectManagers) - { - var manager = _Platform_effectManagers[key]; - - if (manager.a) - { - ports = ports || {}; - ports[key] = manager.a(key, sendToApp); - } - - managers[key] = _Platform_instantiateManager(manager, sendToApp); - } - - return ports; -} - - -function _Platform_createManager(init, onEffects, onSelfMsg, cmdMap, subMap) -{ - return { - b: init, - c: onEffects, - d: onSelfMsg, - e: cmdMap, - f: subMap - }; -} - - -function _Platform_instantiateManager(info, sendToApp) -{ - var router = { - g: sendToApp, - h: undefined - }; - - var onEffects = info.c; - var onSelfMsg = info.d; - var cmdMap = info.e; - var subMap = info.f; - - function loop(state) - { - return A2(_Scheduler_andThen, loop, _Scheduler_receive(function(msg) - { - var value = msg.a; - - if (msg.$ === 0) - { - return A3(onSelfMsg, router, value, state); - } - - return cmdMap && subMap - ? A4(onEffects, router, value.i, value.j, state) - : A3(onEffects, router, cmdMap ? value.i : value.j, state); - })); - } - - return router.h = _Scheduler_rawSpawn(A2(_Scheduler_andThen, loop, info.b)); -} - - - -// ROUTING - - -var _Platform_sendToApp = F2(function(router, msg) -{ - return _Scheduler_binding(function(callback) - { - router.g(msg); - callback(_Scheduler_succeed(_Utils_Tuple0)); - }); -}); - - -var _Platform_sendToSelf = F2(function(router, msg) -{ - return A2(_Scheduler_send, router.h, { - $: 0, - a: msg - }); -}); - - - -// BAGS - - -function _Platform_leaf(home) -{ - return function(value) - { - return { - $: 1, - k: home, - l: value - }; - }; -} - - -function _Platform_batch(list) -{ - return { - $: 2, - m: list - }; -} - - -var _Platform_map = F2(function(tagger, bag) -{ - return { - $: 3, - n: tagger, - o: bag - } -}); - - - -// PIPE BAGS INTO EFFECT MANAGERS -// -// Effects must be queued! -// -// Say your init contains a synchronous command, like Time.now or Time.here -// -// - This will produce a batch of effects (FX_1) -// - The synchronous task triggers the subsequent `update` call -// - This will produce a batch of effects (FX_2) -// -// If we just start dispatching FX_2, subscriptions from FX_2 can be processed -// before subscriptions from FX_1. No good! Earlier versions of this code had -// this problem, leading to these reports: -// -// https://github.com/elm/core/issues/980 -// https://github.com/elm/core/pull/981 -// https://github.com/elm/compiler/issues/1776 -// -// The queue is necessary to avoid ordering issues for synchronous commands. - - -// Why use true/false here? Why not just check the length of the queue? -// The goal is to detect "are we currently dispatching effects?" If we -// are, we need to bail and let the ongoing while loop handle things. -// -// Now say the queue has 1 element. When we dequeue the final element, -// the queue will be empty, but we are still actively dispatching effects. -// So you could get queue jumping in a really tricky category of cases. -// -var _Platform_effectsQueue = []; -var _Platform_effectsActive = false; - - -function _Platform_enqueueEffects(managers, cmdBag, subBag) -{ - _Platform_effectsQueue.push({ p: managers, q: cmdBag, r: subBag }); - - if (_Platform_effectsActive) return; - - _Platform_effectsActive = true; - for (var fx; fx = _Platform_effectsQueue.shift(); ) - { - _Platform_dispatchEffects(fx.p, fx.q, fx.r); - } - _Platform_effectsActive = false; -} - - -function _Platform_dispatchEffects(managers, cmdBag, subBag) -{ - var effectsDict = {}; - _Platform_gatherEffects(true, cmdBag, effectsDict, null); - _Platform_gatherEffects(false, subBag, effectsDict, null); - - for (var home in managers) - { - _Scheduler_rawSend(managers[home], { - $: 'fx', - a: effectsDict[home] || { i: _List_Nil, j: _List_Nil } - }); - } -} - - -function _Platform_gatherEffects(isCmd, bag, effectsDict, taggers) -{ - switch (bag.$) - { - case 1: - var home = bag.k; - var effect = _Platform_toEffect(isCmd, home, taggers, bag.l); - effectsDict[home] = _Platform_insert(isCmd, effect, effectsDict[home]); - return; - - case 2: - for (var list = bag.m; list.b; list = list.b) // WHILE_CONS - { - _Platform_gatherEffects(isCmd, list.a, effectsDict, taggers); - } - return; - - case 3: - _Platform_gatherEffects(isCmd, bag.o, effectsDict, { - s: bag.n, - t: taggers - }); - return; - } -} - - -function _Platform_toEffect(isCmd, home, taggers, value) -{ - function applyTaggers(x) - { - for (var temp = taggers; temp; temp = temp.t) - { - x = temp.s(x); - } - return x; - } - - var map = isCmd - ? _Platform_effectManagers[home].e - : _Platform_effectManagers[home].f; - - return A2(map, applyTaggers, value) -} - - -function _Platform_insert(isCmd, newEffect, effects) -{ - effects = effects || { i: _List_Nil, j: _List_Nil }; - - isCmd - ? (effects.i = _List_Cons(newEffect, effects.i)) - : (effects.j = _List_Cons(newEffect, effects.j)); - - return effects; -} - - - -// PORTS - - -function _Platform_checkPortName(name) -{ - if (_Platform_effectManagers[name]) - { - _Debug_crash(3, name) - } -} - - - -// OUTGOING PORTS - - -function _Platform_outgoingPort(name, converter) -{ - _Platform_checkPortName(name); - _Platform_effectManagers[name] = { - e: _Platform_outgoingPortMap, - u: converter, - a: _Platform_setupOutgoingPort - }; - return _Platform_leaf(name); -} - - -var _Platform_outgoingPortMap = F2(function(tagger, value) { return value; }); - - -function _Platform_setupOutgoingPort(name) -{ - var subs = []; - var converter = _Platform_effectManagers[name].u; - - // CREATE MANAGER - - var init = _Process_sleep(0); - - _Platform_effectManagers[name].b = init; - _Platform_effectManagers[name].c = F3(function(router, cmdList, state) - { - for ( ; cmdList.b; cmdList = cmdList.b) // WHILE_CONS - { - // grab a separate reference to subs in case unsubscribe is called - var currentSubs = subs; - var value = _Json_unwrap(converter(cmdList.a)); - for (var i = 0; i < currentSubs.length; i++) - { - currentSubs[i](value); - } - } - return init; - }); - - // PUBLIC API - - function subscribe(callback) - { - subs.push(callback); - } - - function unsubscribe(callback) - { - // copy subs into a new array in case unsubscribe is called within a - // subscribed callback - subs = subs.slice(); - var index = subs.indexOf(callback); - if (index >= 0) - { - subs.splice(index, 1); - } - } - - return { - subscribe: subscribe, - unsubscribe: unsubscribe - }; -} - - - -// INCOMING PORTS - - -function _Platform_incomingPort(name, converter) -{ - _Platform_checkPortName(name); - _Platform_effectManagers[name] = { - f: _Platform_incomingPortMap, - u: converter, - a: _Platform_setupIncomingPort - }; - return _Platform_leaf(name); -} - - -var _Platform_incomingPortMap = F2(function(tagger, finalTagger) -{ - return function(value) - { - return tagger(finalTagger(value)); - }; -}); - - -function _Platform_setupIncomingPort(name, sendToApp) -{ - var subs = _List_Nil; - var converter = _Platform_effectManagers[name].u; - - // CREATE MANAGER - - var init = _Scheduler_succeed(null); - - _Platform_effectManagers[name].b = init; - _Platform_effectManagers[name].c = F3(function(router, subList, state) - { - subs = subList; - return init; - }); - - // PUBLIC API - - function send(incomingValue) - { - var result = A2(_Json_run, converter, _Json_wrap(incomingValue)); - - $elm$core$Result$isOk(result) || _Debug_crash(4, name, result.a); - - var value = result.a; - for (var temp = subs; temp.b; temp = temp.b) // WHILE_CONS - { - sendToApp(temp.a(value)); - } - } - - return { send: send }; -} - - - -// EXPORT ELM MODULES -// -// Have DEBUG and PROD versions so that we can (1) give nicer errors in -// debug mode and (2) not pay for the bits needed for that in prod mode. -// - - -function _Platform_export(exports) -{ - scope['Elm'] - ? _Platform_mergeExportsProd(scope['Elm'], exports) - : scope['Elm'] = exports; -} - - -function _Platform_mergeExportsProd(obj, exports) -{ - for (var name in exports) - { - (name in obj) - ? (name == 'init') - ? _Debug_crash(6) - : _Platform_mergeExportsProd(obj[name], exports[name]) - : (obj[name] = exports[name]); - } -} - - -function _Platform_export_UNUSED(exports) -{ - scope['Elm'] - ? _Platform_mergeExportsDebug('Elm', scope['Elm'], exports) - : scope['Elm'] = exports; -} - - -function _Platform_mergeExportsDebug(moduleName, obj, exports) -{ - for (var name in exports) - { - (name in obj) - ? (name == 'init') - ? _Debug_crash(6, moduleName) - : _Platform_mergeExportsDebug(moduleName + '.' + name, obj[name], exports[name]) - : (obj[name] = exports[name]); - } -} - - - - -// HELPERS - - -var _VirtualDom_divertHrefToApp; - -var _VirtualDom_doc = typeof document !== 'undefined' ? document : {}; - - -function _VirtualDom_appendChild(parent, child) -{ - parent.appendChild(child); -} - -var _VirtualDom_init = F4(function(virtualNode, flagDecoder, debugMetadata, args) -{ - // NOTE: this function needs _Platform_export available to work - - /**/ - var node = args['node']; - //*/ - /**_UNUSED/ - var node = args && args['node'] ? args['node'] : _Debug_crash(0); - //*/ - - node.parentNode.replaceChild( - _VirtualDom_render(virtualNode, function() {}), - node - ); - - return {}; -}); - - - -// TEXT - - -function _VirtualDom_text(string) -{ - return { - $: 0, - a: string - }; -} - - - -// NODE - - -var _VirtualDom_nodeNS = F2(function(namespace, tag) -{ - return F2(function(factList, kidList) - { - for (var kids = [], descendantsCount = 0; kidList.b; kidList = kidList.b) // WHILE_CONS - { - var kid = kidList.a; - descendantsCount += (kid.b || 0); - kids.push(kid); - } - descendantsCount += kids.length; - - return { - $: 1, - c: tag, - d: _VirtualDom_organizeFacts(factList), - e: kids, - f: namespace, - b: descendantsCount - }; - }); -}); - - -var _VirtualDom_node = _VirtualDom_nodeNS(undefined); - - - -// KEYED NODE - - -var _VirtualDom_keyedNodeNS = F2(function(namespace, tag) -{ - return F2(function(factList, kidList) - { - for (var kids = [], descendantsCount = 0; kidList.b; kidList = kidList.b) // WHILE_CONS - { - var kid = kidList.a; - descendantsCount += (kid.b.b || 0); - kids.push(kid); - } - descendantsCount += kids.length; - - return { - $: 2, - c: tag, - d: _VirtualDom_organizeFacts(factList), - e: kids, - f: namespace, - b: descendantsCount - }; - }); -}); - - -var _VirtualDom_keyedNode = _VirtualDom_keyedNodeNS(undefined); - - - -// CUSTOM - - -function _VirtualDom_custom(factList, model, render, diff) -{ - return { - $: 3, - d: _VirtualDom_organizeFacts(factList), - g: model, - h: render, - i: diff - }; -} - - - -// MAP - - -var _VirtualDom_map = F2(function(tagger, node) -{ - return { - $: 4, - j: tagger, - k: node, - b: 1 + (node.b || 0) - }; -}); - - - -// LAZY - - -function _VirtualDom_thunk(refs, thunk) -{ - return { - $: 5, - l: refs, - m: thunk, - k: undefined - }; -} - -var _VirtualDom_lazy = F2(function(func, a) -{ - return _VirtualDom_thunk([func, a], function() { - return func(a); - }); -}); - -var _VirtualDom_lazy2 = F3(function(func, a, b) -{ - return _VirtualDom_thunk([func, a, b], function() { - return A2(func, a, b); - }); -}); - -var _VirtualDom_lazy3 = F4(function(func, a, b, c) -{ - return _VirtualDom_thunk([func, a, b, c], function() { - return A3(func, a, b, c); - }); -}); - -var _VirtualDom_lazy4 = F5(function(func, a, b, c, d) -{ - return _VirtualDom_thunk([func, a, b, c, d], function() { - return A4(func, a, b, c, d); - }); -}); - -var _VirtualDom_lazy5 = F6(function(func, a, b, c, d, e) -{ - return _VirtualDom_thunk([func, a, b, c, d, e], function() { - return A5(func, a, b, c, d, e); - }); -}); - -var _VirtualDom_lazy6 = F7(function(func, a, b, c, d, e, f) -{ - return _VirtualDom_thunk([func, a, b, c, d, e, f], function() { - return A6(func, a, b, c, d, e, f); - }); -}); - -var _VirtualDom_lazy7 = F8(function(func, a, b, c, d, e, f, g) -{ - return _VirtualDom_thunk([func, a, b, c, d, e, f, g], function() { - return A7(func, a, b, c, d, e, f, g); - }); -}); - -var _VirtualDom_lazy8 = F9(function(func, a, b, c, d, e, f, g, h) -{ - return _VirtualDom_thunk([func, a, b, c, d, e, f, g, h], function() { - return A8(func, a, b, c, d, e, f, g, h); - }); -}); - - - -// FACTS - - -var _VirtualDom_on = F2(function(key, handler) -{ - return { - $: 'a0', - n: key, - o: handler - }; -}); -var _VirtualDom_style = F2(function(key, value) -{ - return { - $: 'a1', - n: key, - o: value - }; -}); -var _VirtualDom_property = F2(function(key, value) -{ - return { - $: 'a2', - n: key, - o: value - }; -}); -var _VirtualDom_attribute = F2(function(key, value) -{ - return { - $: 'a3', - n: key, - o: value - }; -}); -var _VirtualDom_attributeNS = F3(function(namespace, key, value) -{ - return { - $: 'a4', - n: key, - o: { f: namespace, o: value } - }; -}); - - - -// XSS ATTACK VECTOR CHECKS - - -function _VirtualDom_noScript(tag) -{ - return tag == 'script' ? 'p' : tag; -} - -function _VirtualDom_noOnOrFormAction(key) -{ - return /^(on|formAction$)/i.test(key) ? 'data-' + key : key; -} - -function _VirtualDom_noInnerHtmlOrFormAction(key) -{ - return key == 'innerHTML' || key == 'formAction' ? 'data-' + key : key; -} - -function _VirtualDom_noJavaScriptUri(value) -{ - return /^javascript:/i.test(value.replace(/\s/g,'')) ? '' : value; -} - -function _VirtualDom_noJavaScriptUri_UNUSED(value) -{ - return /^javascript:/i.test(value.replace(/\s/g,'')) - ? 'javascript:alert("This is an XSS vector. Please use ports or web components instead.")' - : value; -} - -function _VirtualDom_noJavaScriptOrHtmlUri(value) -{ - return /^\s*(javascript:|data:text\/html)/i.test(value) ? '' : value; -} - -function _VirtualDom_noJavaScriptOrHtmlUri_UNUSED(value) -{ - return /^\s*(javascript:|data:text\/html)/i.test(value) - ? 'javascript:alert("This is an XSS vector. Please use ports or web components instead.")' - : value; -} - - - -// MAP FACTS - - -var _VirtualDom_mapAttribute = F2(function(func, attr) -{ - return (attr.$ === 'a0') - ? A2(_VirtualDom_on, attr.n, _VirtualDom_mapHandler(func, attr.o)) - : attr; -}); - -function _VirtualDom_mapHandler(func, handler) -{ - var tag = $elm$virtual_dom$VirtualDom$toHandlerInt(handler); - - // 0 = Normal - // 1 = MayStopPropagation - // 2 = MayPreventDefault - // 3 = Custom - - return { - $: handler.$, - a: - !tag - ? A2($elm$json$Json$Decode$map, func, handler.a) - : - A3($elm$json$Json$Decode$map2, - tag < 3 - ? _VirtualDom_mapEventTuple - : _VirtualDom_mapEventRecord, - $elm$json$Json$Decode$succeed(func), - handler.a - ) - }; -} - -var _VirtualDom_mapEventTuple = F2(function(func, tuple) -{ - return _Utils_Tuple2(func(tuple.a), tuple.b); -}); - -var _VirtualDom_mapEventRecord = F2(function(func, record) -{ - return { - t: func(record.t), - R: record.R, - O: record.O - } -}); - - - -// ORGANIZE FACTS - - -function _VirtualDom_organizeFacts(factList) -{ - for (var facts = {}; factList.b; factList = factList.b) // WHILE_CONS - { - var entry = factList.a; - - var tag = entry.$; - var key = entry.n; - var value = entry.o; - - if (tag === 'a2') - { - (key === 'className') - ? _VirtualDom_addClass(facts, key, _Json_unwrap(value)) - : facts[key] = _Json_unwrap(value); - - continue; - } - - var subFacts = facts[tag] || (facts[tag] = {}); - (tag === 'a3' && key === 'class') - ? _VirtualDom_addClass(subFacts, key, value) - : subFacts[key] = value; - } - - return facts; -} - -function _VirtualDom_addClass(object, key, newClass) -{ - var classes = object[key]; - object[key] = classes ? classes + ' ' + newClass : newClass; -} - - - -// RENDER - - -function _VirtualDom_render(vNode, eventNode) -{ - var tag = vNode.$; - - if (tag === 5) - { - return _VirtualDom_render(vNode.k || (vNode.k = vNode.m()), eventNode); - } - - if (tag === 0) - { - return _VirtualDom_doc.createTextNode(vNode.a); - } - - if (tag === 4) - { - var subNode = vNode.k; - var tagger = vNode.j; - - while (subNode.$ === 4) - { - typeof tagger !== 'object' - ? tagger = [tagger, subNode.j] - : tagger.push(subNode.j); - - subNode = subNode.k; - } - - var subEventRoot = { j: tagger, p: eventNode }; - var domNode = _VirtualDom_render(subNode, subEventRoot); - domNode.elm_event_node_ref = subEventRoot; - return domNode; - } - - if (tag === 3) - { - var domNode = vNode.h(vNode.g); - _VirtualDom_applyFacts(domNode, eventNode, vNode.d); - return domNode; - } - - // at this point `tag` must be 1 or 2 - - var domNode = vNode.f - ? _VirtualDom_doc.createElementNS(vNode.f, vNode.c) - : _VirtualDom_doc.createElement(vNode.c); - - if (_VirtualDom_divertHrefToApp && vNode.c == 'a') - { - domNode.addEventListener('click', _VirtualDom_divertHrefToApp(domNode)); - } - - _VirtualDom_applyFacts(domNode, eventNode, vNode.d); - - for (var kids = vNode.e, i = 0; i < kids.length; i++) - { - _VirtualDom_appendChild(domNode, _VirtualDom_render(tag === 1 ? kids[i] : kids[i].b, eventNode)); - } - - return domNode; -} - - - -// APPLY FACTS - - -function _VirtualDom_applyFacts(domNode, eventNode, facts) -{ - for (var key in facts) - { - var value = facts[key]; - - key === 'a1' - ? _VirtualDom_applyStyles(domNode, value) - : - key === 'a0' - ? _VirtualDom_applyEvents(domNode, eventNode, value) - : - key === 'a3' - ? _VirtualDom_applyAttrs(domNode, value) - : - key === 'a4' - ? _VirtualDom_applyAttrsNS(domNode, value) - : - ((key !== 'value' && key !== 'checked') || domNode[key] !== value) && (domNode[key] = value); - } -} - - - -// APPLY STYLES - - -function _VirtualDom_applyStyles(domNode, styles) -{ - var domNodeStyle = domNode.style; - - for (var key in styles) - { - domNodeStyle[key] = styles[key]; - } -} - - - -// APPLY ATTRS - - -function _VirtualDom_applyAttrs(domNode, attrs) -{ - for (var key in attrs) - { - var value = attrs[key]; - typeof value !== 'undefined' - ? domNode.setAttribute(key, value) - : domNode.removeAttribute(key); - } -} - - - -// APPLY NAMESPACED ATTRS - - -function _VirtualDom_applyAttrsNS(domNode, nsAttrs) -{ - for (var key in nsAttrs) - { - var pair = nsAttrs[key]; - var namespace = pair.f; - var value = pair.o; - - typeof value !== 'undefined' - ? domNode.setAttributeNS(namespace, key, value) - : domNode.removeAttributeNS(namespace, key); - } -} - - - -// APPLY EVENTS - - -function _VirtualDom_applyEvents(domNode, eventNode, events) -{ - var allCallbacks = domNode.elmFs || (domNode.elmFs = {}); - - for (var key in events) - { - var newHandler = events[key]; - var oldCallback = allCallbacks[key]; - - if (!newHandler) - { - domNode.removeEventListener(key, oldCallback); - allCallbacks[key] = undefined; - continue; - } - - if (oldCallback) - { - var oldHandler = oldCallback.q; - if (oldHandler.$ === newHandler.$) - { - oldCallback.q = newHandler; - continue; - } - domNode.removeEventListener(key, oldCallback); - } - - oldCallback = _VirtualDom_makeCallback(eventNode, newHandler); - domNode.addEventListener(key, oldCallback, - _VirtualDom_passiveSupported - && { passive: $elm$virtual_dom$VirtualDom$toHandlerInt(newHandler) < 2 } - ); - allCallbacks[key] = oldCallback; - } -} - - - -// PASSIVE EVENTS - - -var _VirtualDom_passiveSupported; - -try -{ - window.addEventListener('t', null, Object.defineProperty({}, 'passive', { - get: function() { _VirtualDom_passiveSupported = true; } - })); -} -catch(e) {} - - - -// EVENT HANDLERS - - -function _VirtualDom_makeCallback(eventNode, initialHandler) -{ - function callback(event) - { - var handler = callback.q; - var result = _Json_runHelp(handler.a, event); - - if (!$elm$core$Result$isOk(result)) - { - return; - } - - var tag = $elm$virtual_dom$VirtualDom$toHandlerInt(handler); - - // 0 = Normal - // 1 = MayStopPropagation - // 2 = MayPreventDefault - // 3 = Custom - - var value = result.a; - var message = !tag ? value : tag < 3 ? value.a : value.t; - var stopPropagation = tag == 1 ? value.b : tag == 3 && value.R; - var currentEventNode = ( - stopPropagation && event.stopPropagation(), - (tag == 2 ? value.b : tag == 3 && value.O) && event.preventDefault(), - eventNode - ); - var tagger; - var i; - while (tagger = currentEventNode.j) - { - if (typeof tagger == 'function') - { - message = tagger(message); - } - else - { - for (var i = tagger.length; i--; ) - { - message = tagger[i](message); - } - } - currentEventNode = currentEventNode.p; - } - currentEventNode(message, stopPropagation); // stopPropagation implies isSync - } - - callback.q = initialHandler; - - return callback; -} - -function _VirtualDom_equalEvents(x, y) -{ - return x.$ == y.$ && _Json_equality(x.a, y.a); -} - - - -// DIFF - - -// TODO: Should we do patches like in iOS? -// -// type Patch -// = At Int Patch -// | Batch (List Patch) -// | Change ... -// -// How could it not be better? -// -function _VirtualDom_diff(x, y) -{ - var patches = []; - _VirtualDom_diffHelp(x, y, patches, 0); - return patches; -} - - -function _VirtualDom_pushPatch(patches, type, index, data) -{ - var patch = { - $: type, - r: index, - s: data, - t: undefined, - u: undefined - }; - patches.push(patch); - return patch; -} - - -function _VirtualDom_diffHelp(x, y, patches, index) -{ - if (x === y) - { - return; - } - - var xType = x.$; - var yType = y.$; - - // Bail if you run into different types of nodes. Implies that the - // structure has changed significantly and it's not worth a diff. - if (xType !== yType) - { - if (xType === 1 && yType === 2) - { - y = _VirtualDom_dekey(y); - yType = 1; - } - else - { - _VirtualDom_pushPatch(patches, 0, index, y); - return; - } - } - - // Now we know that both nodes are the same $. - switch (yType) - { - case 5: - var xRefs = x.l; - var yRefs = y.l; - var i = xRefs.length; - var same = i === yRefs.length; - while (same && i--) - { - same = xRefs[i] === yRefs[i]; - } - if (same) - { - y.k = x.k; - return; - } - y.k = y.m(); - var subPatches = []; - _VirtualDom_diffHelp(x.k, y.k, subPatches, 0); - subPatches.length > 0 && _VirtualDom_pushPatch(patches, 1, index, subPatches); - return; - - case 4: - // gather nested taggers - var xTaggers = x.j; - var yTaggers = y.j; - var nesting = false; - - var xSubNode = x.k; - while (xSubNode.$ === 4) - { - nesting = true; - - typeof xTaggers !== 'object' - ? xTaggers = [xTaggers, xSubNode.j] - : xTaggers.push(xSubNode.j); - - xSubNode = xSubNode.k; - } - - var ySubNode = y.k; - while (ySubNode.$ === 4) - { - nesting = true; - - typeof yTaggers !== 'object' - ? yTaggers = [yTaggers, ySubNode.j] - : yTaggers.push(ySubNode.j); - - ySubNode = ySubNode.k; - } - - // Just bail if different numbers of taggers. This implies the - // structure of the virtual DOM has changed. - if (nesting && xTaggers.length !== yTaggers.length) - { - _VirtualDom_pushPatch(patches, 0, index, y); - return; - } - - // check if taggers are "the same" - if (nesting ? !_VirtualDom_pairwiseRefEqual(xTaggers, yTaggers) : xTaggers !== yTaggers) - { - _VirtualDom_pushPatch(patches, 2, index, yTaggers); - } - - // diff everything below the taggers - _VirtualDom_diffHelp(xSubNode, ySubNode, patches, index + 1); - return; - - case 0: - if (x.a !== y.a) - { - _VirtualDom_pushPatch(patches, 3, index, y.a); - } - return; - - case 1: - _VirtualDom_diffNodes(x, y, patches, index, _VirtualDom_diffKids); - return; - - case 2: - _VirtualDom_diffNodes(x, y, patches, index, _VirtualDom_diffKeyedKids); - return; - - case 3: - if (x.h !== y.h) - { - _VirtualDom_pushPatch(patches, 0, index, y); - return; - } - - var factsDiff = _VirtualDom_diffFacts(x.d, y.d); - factsDiff && _VirtualDom_pushPatch(patches, 4, index, factsDiff); - - var patch = y.i(x.g, y.g); - patch && _VirtualDom_pushPatch(patches, 5, index, patch); - - return; - } -} - -// assumes the incoming arrays are the same length -function _VirtualDom_pairwiseRefEqual(as, bs) -{ - for (var i = 0; i < as.length; i++) - { - if (as[i] !== bs[i]) - { - return false; - } - } - - return true; -} - -function _VirtualDom_diffNodes(x, y, patches, index, diffKids) -{ - // Bail if obvious indicators have changed. Implies more serious - // structural changes such that it's not worth it to diff. - if (x.c !== y.c || x.f !== y.f) - { - _VirtualDom_pushPatch(patches, 0, index, y); - return; - } - - var factsDiff = _VirtualDom_diffFacts(x.d, y.d); - factsDiff && _VirtualDom_pushPatch(patches, 4, index, factsDiff); - - diffKids(x, y, patches, index); -} - - - -// DIFF FACTS - - -// TODO Instead of creating a new diff object, it's possible to just test if -// there *is* a diff. During the actual patch, do the diff again and make the -// modifications directly. This way, there's no new allocations. Worth it? -function _VirtualDom_diffFacts(x, y, category) -{ - var diff; - - // look for changes and removals - for (var xKey in x) - { - if (xKey === 'a1' || xKey === 'a0' || xKey === 'a3' || xKey === 'a4') - { - var subDiff = _VirtualDom_diffFacts(x[xKey], y[xKey] || {}, xKey); - if (subDiff) - { - diff = diff || {}; - diff[xKey] = subDiff; - } - continue; - } - - // remove if not in the new facts - if (!(xKey in y)) - { - diff = diff || {}; - diff[xKey] = - !category - ? (typeof x[xKey] === 'string' ? '' : null) - : - (category === 'a1') - ? '' - : - (category === 'a0' || category === 'a3') - ? undefined - : - { f: x[xKey].f, o: undefined }; - - continue; - } - - var xValue = x[xKey]; - var yValue = y[xKey]; - - // reference equal, so don't worry about it - if (xValue === yValue && xKey !== 'value' && xKey !== 'checked' - || category === 'a0' && _VirtualDom_equalEvents(xValue, yValue)) - { - continue; - } - - diff = diff || {}; - diff[xKey] = yValue; - } - - // add new stuff - for (var yKey in y) - { - if (!(yKey in x)) - { - diff = diff || {}; - diff[yKey] = y[yKey]; - } - } - - return diff; -} - - - -// DIFF KIDS - - -function _VirtualDom_diffKids(xParent, yParent, patches, index) -{ - var xKids = xParent.e; - var yKids = yParent.e; - - var xLen = xKids.length; - var yLen = yKids.length; - - // FIGURE OUT IF THERE ARE INSERTS OR REMOVALS - - if (xLen > yLen) - { - _VirtualDom_pushPatch(patches, 6, index, { - v: yLen, - i: xLen - yLen - }); - } - else if (xLen < yLen) - { - _VirtualDom_pushPatch(patches, 7, index, { - v: xLen, - e: yKids - }); - } - - // PAIRWISE DIFF EVERYTHING ELSE - - for (var minLen = xLen < yLen ? xLen : yLen, i = 0; i < minLen; i++) - { - var xKid = xKids[i]; - _VirtualDom_diffHelp(xKid, yKids[i], patches, ++index); - index += xKid.b || 0; - } -} - - - -// KEYED DIFF - - -function _VirtualDom_diffKeyedKids(xParent, yParent, patches, rootIndex) -{ - var localPatches = []; - - var changes = {}; // Dict String Entry - var inserts = []; // Array { index : Int, entry : Entry } - // type Entry = { tag : String, vnode : VNode, index : Int, data : _ } - - var xKids = xParent.e; - var yKids = yParent.e; - var xLen = xKids.length; - var yLen = yKids.length; - var xIndex = 0; - var yIndex = 0; - - var index = rootIndex; - - while (xIndex < xLen && yIndex < yLen) - { - var x = xKids[xIndex]; - var y = yKids[yIndex]; - - var xKey = x.a; - var yKey = y.a; - var xNode = x.b; - var yNode = y.b; - - var newMatch = undefined; - var oldMatch = undefined; - - // check if keys match - - if (xKey === yKey) - { - index++; - _VirtualDom_diffHelp(xNode, yNode, localPatches, index); - index += xNode.b || 0; - - xIndex++; - yIndex++; - continue; - } - - // look ahead 1 to detect insertions and removals. - - var xNext = xKids[xIndex + 1]; - var yNext = yKids[yIndex + 1]; - - if (xNext) - { - var xNextKey = xNext.a; - var xNextNode = xNext.b; - oldMatch = yKey === xNextKey; - } - - if (yNext) - { - var yNextKey = yNext.a; - var yNextNode = yNext.b; - newMatch = xKey === yNextKey; - } - - - // swap x and y - if (newMatch && oldMatch) - { - index++; - _VirtualDom_diffHelp(xNode, yNextNode, localPatches, index); - _VirtualDom_insertNode(changes, localPatches, xKey, yNode, yIndex, inserts); - index += xNode.b || 0; - - index++; - _VirtualDom_removeNode(changes, localPatches, xKey, xNextNode, index); - index += xNextNode.b || 0; - - xIndex += 2; - yIndex += 2; - continue; - } - - // insert y - if (newMatch) - { - index++; - _VirtualDom_insertNode(changes, localPatches, yKey, yNode, yIndex, inserts); - _VirtualDom_diffHelp(xNode, yNextNode, localPatches, index); - index += xNode.b || 0; - - xIndex += 1; - yIndex += 2; - continue; - } - - // remove x - if (oldMatch) - { - index++; - _VirtualDom_removeNode(changes, localPatches, xKey, xNode, index); - index += xNode.b || 0; - - index++; - _VirtualDom_diffHelp(xNextNode, yNode, localPatches, index); - index += xNextNode.b || 0; - - xIndex += 2; - yIndex += 1; - continue; - } - - // remove x, insert y - if (xNext && xNextKey === yNextKey) - { - index++; - _VirtualDom_removeNode(changes, localPatches, xKey, xNode, index); - _VirtualDom_insertNode(changes, localPatches, yKey, yNode, yIndex, inserts); - index += xNode.b || 0; - - index++; - _VirtualDom_diffHelp(xNextNode, yNextNode, localPatches, index); - index += xNextNode.b || 0; - - xIndex += 2; - yIndex += 2; - continue; - } - - break; - } - - // eat up any remaining nodes with removeNode and insertNode - - while (xIndex < xLen) - { - index++; - var x = xKids[xIndex]; - var xNode = x.b; - _VirtualDom_removeNode(changes, localPatches, x.a, xNode, index); - index += xNode.b || 0; - xIndex++; - } - - while (yIndex < yLen) - { - var endInserts = endInserts || []; - var y = yKids[yIndex]; - _VirtualDom_insertNode(changes, localPatches, y.a, y.b, undefined, endInserts); - yIndex++; - } - - if (localPatches.length > 0 || inserts.length > 0 || endInserts) - { - _VirtualDom_pushPatch(patches, 8, rootIndex, { - w: localPatches, - x: inserts, - y: endInserts - }); - } -} - - - -// CHANGES FROM KEYED DIFF - - -var _VirtualDom_POSTFIX = '_elmW6BL'; - - -function _VirtualDom_insertNode(changes, localPatches, key, vnode, yIndex, inserts) -{ - var entry = changes[key]; - - // never seen this key before - if (!entry) - { - entry = { - c: 0, - z: vnode, - r: yIndex, - s: undefined - }; - - inserts.push({ r: yIndex, A: entry }); - changes[key] = entry; - - return; - } - - // this key was removed earlier, a match! - if (entry.c === 1) - { - inserts.push({ r: yIndex, A: entry }); - - entry.c = 2; - var subPatches = []; - _VirtualDom_diffHelp(entry.z, vnode, subPatches, entry.r); - entry.r = yIndex; - entry.s.s = { - w: subPatches, - A: entry - }; - - return; - } - - // this key has already been inserted or moved, a duplicate! - _VirtualDom_insertNode(changes, localPatches, key + _VirtualDom_POSTFIX, vnode, yIndex, inserts); -} - - -function _VirtualDom_removeNode(changes, localPatches, key, vnode, index) -{ - var entry = changes[key]; - - // never seen this key before - if (!entry) - { - var patch = _VirtualDom_pushPatch(localPatches, 9, index, undefined); - - changes[key] = { - c: 1, - z: vnode, - r: index, - s: patch - }; - - return; - } - - // this key was inserted earlier, a match! - if (entry.c === 0) - { - entry.c = 2; - var subPatches = []; - _VirtualDom_diffHelp(vnode, entry.z, subPatches, index); - - _VirtualDom_pushPatch(localPatches, 9, index, { - w: subPatches, - A: entry - }); - - return; - } - - // this key has already been removed or moved, a duplicate! - _VirtualDom_removeNode(changes, localPatches, key + _VirtualDom_POSTFIX, vnode, index); -} - - - -// ADD DOM NODES -// -// Each DOM node has an "index" assigned in order of traversal. It is important -// to minimize our crawl over the actual DOM, so these indexes (along with the -// descendantsCount of virtual nodes) let us skip touching entire subtrees of -// the DOM if we know there are no patches there. - - -function _VirtualDom_addDomNodes(domNode, vNode, patches, eventNode) -{ - _VirtualDom_addDomNodesHelp(domNode, vNode, patches, 0, 0, vNode.b, eventNode); -} - - -// assumes `patches` is non-empty and indexes increase monotonically. -function _VirtualDom_addDomNodesHelp(domNode, vNode, patches, i, low, high, eventNode) -{ - var patch = patches[i]; - var index = patch.r; - - while (index === low) - { - var patchType = patch.$; - - if (patchType === 1) - { - _VirtualDom_addDomNodes(domNode, vNode.k, patch.s, eventNode); - } - else if (patchType === 8) - { - patch.t = domNode; - patch.u = eventNode; - - var subPatches = patch.s.w; - if (subPatches.length > 0) - { - _VirtualDom_addDomNodesHelp(domNode, vNode, subPatches, 0, low, high, eventNode); - } - } - else if (patchType === 9) - { - patch.t = domNode; - patch.u = eventNode; - - var data = patch.s; - if (data) - { - data.A.s = domNode; - var subPatches = data.w; - if (subPatches.length > 0) - { - _VirtualDom_addDomNodesHelp(domNode, vNode, subPatches, 0, low, high, eventNode); - } - } - } - else - { - patch.t = domNode; - patch.u = eventNode; - } - - i++; - - if (!(patch = patches[i]) || (index = patch.r) > high) - { - return i; - } - } - - var tag = vNode.$; - - if (tag === 4) - { - var subNode = vNode.k; - - while (subNode.$ === 4) - { - subNode = subNode.k; - } - - return _VirtualDom_addDomNodesHelp(domNode, subNode, patches, i, low + 1, high, domNode.elm_event_node_ref); - } - - // tag must be 1 or 2 at this point - - var vKids = vNode.e; - var childNodes = domNode.childNodes; - for (var j = 0; j < vKids.length; j++) - { - low++; - var vKid = tag === 1 ? vKids[j] : vKids[j].b; - var nextLow = low + (vKid.b || 0); - if (low <= index && index <= nextLow) - { - i = _VirtualDom_addDomNodesHelp(childNodes[j], vKid, patches, i, low, nextLow, eventNode); - if (!(patch = patches[i]) || (index = patch.r) > high) - { - return i; - } - } - low = nextLow; - } - return i; -} - - - -// APPLY PATCHES - - -function _VirtualDom_applyPatches(rootDomNode, oldVirtualNode, patches, eventNode) -{ - if (patches.length === 0) - { - return rootDomNode; - } - - _VirtualDom_addDomNodes(rootDomNode, oldVirtualNode, patches, eventNode); - return _VirtualDom_applyPatchesHelp(rootDomNode, patches); -} - -function _VirtualDom_applyPatchesHelp(rootDomNode, patches) -{ - for (var i = 0; i < patches.length; i++) - { - var patch = patches[i]; - var localDomNode = patch.t - var newNode = _VirtualDom_applyPatch(localDomNode, patch); - if (localDomNode === rootDomNode) - { - rootDomNode = newNode; - } - } - return rootDomNode; -} - -function _VirtualDom_applyPatch(domNode, patch) -{ - switch (patch.$) - { - case 0: - return _VirtualDom_applyPatchRedraw(domNode, patch.s, patch.u); - - case 4: - _VirtualDom_applyFacts(domNode, patch.u, patch.s); - return domNode; - - case 3: - domNode.replaceData(0, domNode.length, patch.s); - return domNode; - - case 1: - return _VirtualDom_applyPatchesHelp(domNode, patch.s); - - case 2: - if (domNode.elm_event_node_ref) - { - domNode.elm_event_node_ref.j = patch.s; - } - else - { - domNode.elm_event_node_ref = { j: patch.s, p: patch.u }; - } - return domNode; - - case 6: - var data = patch.s; - for (var i = 0; i < data.i; i++) - { - domNode.removeChild(domNode.childNodes[data.v]); - } - return domNode; - - case 7: - var data = patch.s; - var kids = data.e; - var i = data.v; - var theEnd = domNode.childNodes[i]; - for (; i < kids.length; i++) - { - domNode.insertBefore(_VirtualDom_render(kids[i], patch.u), theEnd); - } - return domNode; - - case 9: - var data = patch.s; - if (!data) - { - domNode.parentNode.removeChild(domNode); - return domNode; - } - var entry = data.A; - if (typeof entry.r !== 'undefined') - { - domNode.parentNode.removeChild(domNode); - } - entry.s = _VirtualDom_applyPatchesHelp(domNode, data.w); - return domNode; - - case 8: - return _VirtualDom_applyPatchReorder(domNode, patch); - - case 5: - return patch.s(domNode); - - default: - _Debug_crash(10); // 'Ran into an unknown patch!' - } -} - - -function _VirtualDom_applyPatchRedraw(domNode, vNode, eventNode) -{ - var parentNode = domNode.parentNode; - var newNode = _VirtualDom_render(vNode, eventNode); - - if (!newNode.elm_event_node_ref) - { - newNode.elm_event_node_ref = domNode.elm_event_node_ref; - } - - if (parentNode && newNode !== domNode) - { - parentNode.replaceChild(newNode, domNode); - } - return newNode; -} - - -function _VirtualDom_applyPatchReorder(domNode, patch) -{ - var data = patch.s; - - // remove end inserts - var frag = _VirtualDom_applyPatchReorderEndInsertsHelp(data.y, patch); - - // removals - domNode = _VirtualDom_applyPatchesHelp(domNode, data.w); - - // inserts - var inserts = data.x; - for (var i = 0; i < inserts.length; i++) - { - var insert = inserts[i]; - var entry = insert.A; - var node = entry.c === 2 - ? entry.s - : _VirtualDom_render(entry.z, patch.u); - domNode.insertBefore(node, domNode.childNodes[insert.r]); - } - - // add end inserts - if (frag) - { - _VirtualDom_appendChild(domNode, frag); - } - - return domNode; -} - - -function _VirtualDom_applyPatchReorderEndInsertsHelp(endInserts, patch) -{ - if (!endInserts) - { - return; - } - - var frag = _VirtualDom_doc.createDocumentFragment(); - for (var i = 0; i < endInserts.length; i++) - { - var insert = endInserts[i]; - var entry = insert.A; - _VirtualDom_appendChild(frag, entry.c === 2 - ? entry.s - : _VirtualDom_render(entry.z, patch.u) - ); - } - return frag; -} - - -function _VirtualDom_virtualize(node) -{ - // TEXT NODES - - if (node.nodeType === 3) - { - return _VirtualDom_text(node.textContent); - } - - - // WEIRD NODES - - if (node.nodeType !== 1) - { - return _VirtualDom_text(''); - } - - - // ELEMENT NODES - - var attrList = _List_Nil; - var attrs = node.attributes; - for (var i = attrs.length; i--; ) - { - var attr = attrs[i]; - var name = attr.name; - var value = attr.value; - attrList = _List_Cons( A2(_VirtualDom_attribute, name, value), attrList ); - } - - var tag = node.tagName.toLowerCase(); - var kidList = _List_Nil; - var kids = node.childNodes; - - for (var i = kids.length; i--; ) - { - kidList = _List_Cons(_VirtualDom_virtualize(kids[i]), kidList); - } - return A3(_VirtualDom_node, tag, attrList, kidList); -} - -function _VirtualDom_dekey(keyedNode) -{ - var keyedKids = keyedNode.e; - var len = keyedKids.length; - var kids = new Array(len); - for (var i = 0; i < len; i++) - { - kids[i] = keyedKids[i].b; - } - - return { - $: 1, - c: keyedNode.c, - d: keyedNode.d, - e: kids, - f: keyedNode.f, - b: keyedNode.b - }; -} - - - - -// ELEMENT - - -var _Debugger_element; - -var _Browser_element = _Debugger_element || F4(function(impl, flagDecoder, debugMetadata, args) -{ - return _Platform_initialize( - flagDecoder, - args, - impl.aB, - impl.aJ, - impl.aH, - function(sendToApp, initialModel) { - var view = impl.aK; - /**/ - var domNode = args['node']; - //*/ - /**_UNUSED/ - var domNode = args && args['node'] ? args['node'] : _Debug_crash(0); - //*/ - var currNode = _VirtualDom_virtualize(domNode); - - return _Browser_makeAnimator(initialModel, function(model) - { - var nextNode = view(model); - var patches = _VirtualDom_diff(currNode, nextNode); - domNode = _VirtualDom_applyPatches(domNode, currNode, patches, sendToApp); - currNode = nextNode; - }); - } - ); -}); - - - -// DOCUMENT - - -var _Debugger_document; - -var _Browser_document = _Debugger_document || F4(function(impl, flagDecoder, debugMetadata, args) -{ - return _Platform_initialize( - flagDecoder, - args, - impl.aB, - impl.aJ, - impl.aH, - function(sendToApp, initialModel) { - var divertHrefToApp = impl.P && impl.P(sendToApp) - var view = impl.aK; - var title = _VirtualDom_doc.title; - var bodyNode = _VirtualDom_doc.body; - var currNode = _VirtualDom_virtualize(bodyNode); - return _Browser_makeAnimator(initialModel, function(model) - { - _VirtualDom_divertHrefToApp = divertHrefToApp; - var doc = view(model); - var nextNode = _VirtualDom_node('body')(_List_Nil)(doc.au); - var patches = _VirtualDom_diff(currNode, nextNode); - bodyNode = _VirtualDom_applyPatches(bodyNode, currNode, patches, sendToApp); - currNode = nextNode; - _VirtualDom_divertHrefToApp = 0; - (title !== doc.aI) && (_VirtualDom_doc.title = title = doc.aI); - }); - } - ); -}); - - - -// ANIMATION - - -var _Browser_cancelAnimationFrame = - typeof cancelAnimationFrame !== 'undefined' - ? cancelAnimationFrame - : function(id) { clearTimeout(id); }; - -var _Browser_requestAnimationFrame = - typeof requestAnimationFrame !== 'undefined' - ? requestAnimationFrame - : function(callback) { return setTimeout(callback, 1000 / 60); }; - - -function _Browser_makeAnimator(model, draw) -{ - draw(model); - - var state = 0; - - function updateIfNeeded() - { - state = state === 1 - ? 0 - : ( _Browser_requestAnimationFrame(updateIfNeeded), draw(model), 1 ); - } - - return function(nextModel, isSync) - { - model = nextModel; - - isSync - ? ( draw(model), - state === 2 && (state = 1) - ) - : ( state === 0 && _Browser_requestAnimationFrame(updateIfNeeded), - state = 2 - ); - }; -} - - - -// APPLICATION - - -function _Browser_application(impl) -{ - var onUrlChange = impl.aD; - var onUrlRequest = impl.aE; - var key = function() { key.a(onUrlChange(_Browser_getUrl())); }; - - return _Browser_document({ - P: function(sendToApp) - { - key.a = sendToApp; - _Browser_window.addEventListener('popstate', key); - _Browser_window.navigator.userAgent.indexOf('Trident') < 0 || _Browser_window.addEventListener('hashchange', key); - - return F2(function(domNode, event) - { - if (!event.ctrlKey && !event.metaKey && !event.shiftKey && event.button < 1 && !domNode.target && !domNode.hasAttribute('download')) - { - event.preventDefault(); - var href = domNode.href; - var curr = _Browser_getUrl(); - var next = $elm$url$Url$fromString(href).a; - sendToApp(onUrlRequest( - (next - && curr.ah === next.ah - && curr.Z === next.Z - && curr.ae.a === next.ae.a - ) - ? $elm$browser$Browser$Internal(next) - : $elm$browser$Browser$External(href) - )); - } - }); - }, - aB: function(flags) - { - return A3(impl.aB, flags, _Browser_getUrl(), key); - }, - aK: impl.aK, - aJ: impl.aJ, - aH: impl.aH - }); -} - -function _Browser_getUrl() -{ - return $elm$url$Url$fromString(_VirtualDom_doc.location.href).a || _Debug_crash(1); -} - -var _Browser_go = F2(function(key, n) -{ - return A2($elm$core$Task$perform, $elm$core$Basics$never, _Scheduler_binding(function() { - n && history.go(n); - key(); - })); -}); - -var _Browser_pushUrl = F2(function(key, url) -{ - return A2($elm$core$Task$perform, $elm$core$Basics$never, _Scheduler_binding(function() { - history.pushState({}, '', url); - key(); - })); -}); - -var _Browser_replaceUrl = F2(function(key, url) -{ - return A2($elm$core$Task$perform, $elm$core$Basics$never, _Scheduler_binding(function() { - history.replaceState({}, '', url); - key(); - })); -}); - - - -// GLOBAL EVENTS - - -var _Browser_fakeNode = { addEventListener: function() {}, removeEventListener: function() {} }; -var _Browser_doc = typeof document !== 'undefined' ? document : _Browser_fakeNode; -var _Browser_window = typeof window !== 'undefined' ? window : _Browser_fakeNode; - -var _Browser_on = F3(function(node, eventName, sendToSelf) -{ - return _Scheduler_spawn(_Scheduler_binding(function(callback) - { - function handler(event) { _Scheduler_rawSpawn(sendToSelf(event)); } - node.addEventListener(eventName, handler, _VirtualDom_passiveSupported && { passive: true }); - return function() { node.removeEventListener(eventName, handler); }; - })); -}); - -var _Browser_decodeEvent = F2(function(decoder, event) -{ - var result = _Json_runHelp(decoder, event); - return $elm$core$Result$isOk(result) ? $elm$core$Maybe$Just(result.a) : $elm$core$Maybe$Nothing; -}); - - - -// PAGE VISIBILITY - - -function _Browser_visibilityInfo() -{ - return (typeof _VirtualDom_doc.hidden !== 'undefined') - ? { az: 'hidden', av: 'visibilitychange' } - : - (typeof _VirtualDom_doc.mozHidden !== 'undefined') - ? { az: 'mozHidden', av: 'mozvisibilitychange' } - : - (typeof _VirtualDom_doc.msHidden !== 'undefined') - ? { az: 'msHidden', av: 'msvisibilitychange' } - : - (typeof _VirtualDom_doc.webkitHidden !== 'undefined') - ? { az: 'webkitHidden', av: 'webkitvisibilitychange' } - : { az: 'hidden', av: 'visibilitychange' }; -} - - - -// ANIMATION FRAMES - - -function _Browser_rAF() -{ - return _Scheduler_binding(function(callback) - { - var id = _Browser_requestAnimationFrame(function() { - callback(_Scheduler_succeed(Date.now())); - }); - - return function() { - _Browser_cancelAnimationFrame(id); - }; - }); -} - - -function _Browser_now() -{ - return _Scheduler_binding(function(callback) - { - callback(_Scheduler_succeed(Date.now())); - }); -} - - - -// DOM STUFF - - -function _Browser_withNode(id, doStuff) -{ - return _Scheduler_binding(function(callback) - { - _Browser_requestAnimationFrame(function() { - var node = document.getElementById(id); - callback(node - ? _Scheduler_succeed(doStuff(node)) - : _Scheduler_fail($elm$browser$Browser$Dom$NotFound(id)) - ); - }); - }); -} - - -function _Browser_withWindow(doStuff) -{ - return _Scheduler_binding(function(callback) - { - _Browser_requestAnimationFrame(function() { - callback(_Scheduler_succeed(doStuff())); - }); - }); -} - - -// FOCUS and BLUR - - -var _Browser_call = F2(function(functionName, id) -{ - return _Browser_withNode(id, function(node) { - node[functionName](); - return _Utils_Tuple0; - }); -}); - - - -// WINDOW VIEWPORT - - -function _Browser_getViewport() -{ - return { - al: _Browser_getScene(), - ao: { - aq: _Browser_window.pageXOffset, - ar: _Browser_window.pageYOffset, - ap: _Browser_doc.documentElement.clientWidth, - Y: _Browser_doc.documentElement.clientHeight - } - }; -} - -function _Browser_getScene() -{ - var body = _Browser_doc.body; - var elem = _Browser_doc.documentElement; - return { - ap: Math.max(body.scrollWidth, body.offsetWidth, elem.scrollWidth, elem.offsetWidth, elem.clientWidth), - Y: Math.max(body.scrollHeight, body.offsetHeight, elem.scrollHeight, elem.offsetHeight, elem.clientHeight) - }; -} - -var _Browser_setViewport = F2(function(x, y) -{ - return _Browser_withWindow(function() - { - _Browser_window.scroll(x, y); - return _Utils_Tuple0; - }); -}); - - - -// ELEMENT VIEWPORT - - -function _Browser_getViewportOf(id) -{ - return _Browser_withNode(id, function(node) - { - return { - al: { - ap: node.scrollWidth, - Y: node.scrollHeight - }, - ao: { - aq: node.scrollLeft, - ar: node.scrollTop, - ap: node.clientWidth, - Y: node.clientHeight - } - }; - }); -} - - -var _Browser_setViewportOf = F3(function(id, x, y) -{ - return _Browser_withNode(id, function(node) - { - node.scrollLeft = x; - node.scrollTop = y; - return _Utils_Tuple0; - }); -}); - - - -// ELEMENT - - -function _Browser_getElement(id) -{ - return _Browser_withNode(id, function(node) - { - var rect = node.getBoundingClientRect(); - var x = _Browser_window.pageXOffset; - var y = _Browser_window.pageYOffset; - return { - al: _Browser_getScene(), - ao: { - aq: x, - ar: y, - ap: _Browser_doc.documentElement.clientWidth, - Y: _Browser_doc.documentElement.clientHeight - }, - ax: { - aq: x + rect.left, - ar: y + rect.top, - ap: rect.width, - Y: rect.height - } - }; - }); -} - - - -// LOAD and RELOAD - - -function _Browser_reload(skipCache) -{ - return A2($elm$core$Task$perform, $elm$core$Basics$never, _Scheduler_binding(function(callback) - { - _VirtualDom_doc.location.reload(skipCache); - })); -} - -function _Browser_load(url) -{ - return A2($elm$core$Task$perform, $elm$core$Basics$never, _Scheduler_binding(function(callback) - { - try - { - _Browser_window.location = url; - } - catch(err) - { - // Only Firefox can throw a NS_ERROR_MALFORMED_URI exception here. - // Other browsers reload the page, so let's be consistent about that. - _VirtualDom_doc.location.reload(false); - } - })); -} - - - -var _Bitwise_and = F2(function(a, b) -{ - return a & b; -}); - -var _Bitwise_or = F2(function(a, b) -{ - return a | b; -}); - -var _Bitwise_xor = F2(function(a, b) -{ - return a ^ b; -}); - -function _Bitwise_complement(a) -{ - return ~a; -}; - -var _Bitwise_shiftLeftBy = F2(function(offset, a) -{ - return a << offset; -}); - -var _Bitwise_shiftRightBy = F2(function(offset, a) -{ - return a >> offset; -}); - -var _Bitwise_shiftRightZfBy = F2(function(offset, a) -{ - return a >>> offset; -}); - - - -function _Time_now(millisToPosix) -{ - return _Scheduler_binding(function(callback) - { - callback(_Scheduler_succeed(millisToPosix(Date.now()))); - }); -} - -var _Time_setInterval = F2(function(interval, task) -{ - return _Scheduler_binding(function(callback) - { - var id = setInterval(function() { _Scheduler_rawSpawn(task); }, interval); - return function() { clearInterval(id); }; - }); -}); - -function _Time_here() -{ - return _Scheduler_binding(function(callback) - { - callback(_Scheduler_succeed( - A2($elm$time$Time$customZone, -(new Date().getTimezoneOffset()), _List_Nil) - )); - }); -} - - -function _Time_getZoneName() -{ - return _Scheduler_binding(function(callback) - { - try - { - var name = $elm$time$Time$Name(Intl.DateTimeFormat().resolvedOptions().timeZone); - } - catch (e) - { - var name = $elm$time$Time$Offset(new Date().getTimezoneOffset()); - } - callback(_Scheduler_succeed(name)); - }); -} -var $elm$core$Basics$EQ = 1; -var $elm$core$Basics$GT = 2; -var $elm$core$Basics$LT = 0; -var $elm$core$List$cons = _List_cons; -var $elm$core$Dict$foldr = F3( - function (func, acc, t) { - foldr: - while (true) { - if (t.$ === -2) { - return acc; - } else { - var key = t.b; - var value = t.c; - var left = t.d; - var right = t.e; - var $temp$func = func, - $temp$acc = A3( - func, - key, - value, - A3($elm$core$Dict$foldr, func, acc, right)), - $temp$t = left; - func = $temp$func; - acc = $temp$acc; - t = $temp$t; - continue foldr; - } - } - }); -var $elm$core$Dict$toList = function (dict) { - return A3( - $elm$core$Dict$foldr, - F3( - function (key, value, list) { - return A2( - $elm$core$List$cons, - _Utils_Tuple2(key, value), - list); - }), - _List_Nil, - dict); -}; -var $elm$core$Dict$keys = function (dict) { - return A3( - $elm$core$Dict$foldr, - F3( - function (key, value, keyList) { - return A2($elm$core$List$cons, key, keyList); - }), - _List_Nil, - dict); -}; -var $elm$core$Set$toList = function (_v0) { - var dict = _v0; - return $elm$core$Dict$keys(dict); -}; -var $elm$core$Elm$JsArray$foldr = _JsArray_foldr; -var $elm$core$Array$foldr = F3( - function (func, baseCase, _v0) { - var tree = _v0.c; - var tail = _v0.d; - var helper = F2( - function (node, acc) { - if (!node.$) { - var subTree = node.a; - return A3($elm$core$Elm$JsArray$foldr, helper, acc, subTree); - } else { - var values = node.a; - return A3($elm$core$Elm$JsArray$foldr, func, acc, values); - } - }); - return A3( - $elm$core$Elm$JsArray$foldr, - helper, - A3($elm$core$Elm$JsArray$foldr, func, baseCase, tail), - tree); - }); -var $elm$core$Array$toList = function (array) { - return A3($elm$core$Array$foldr, $elm$core$List$cons, _List_Nil, array); -}; -var $elm$core$Result$Err = function (a) { - return {$: 1, a: a}; -}; -var $elm$json$Json$Decode$Failure = F2( - function (a, b) { - return {$: 3, a: a, b: b}; - }); -var $elm$json$Json$Decode$Field = F2( - function (a, b) { - return {$: 0, a: a, b: b}; - }); -var $elm$json$Json$Decode$Index = F2( - function (a, b) { - return {$: 1, a: a, b: b}; - }); -var $elm$core$Result$Ok = function (a) { - return {$: 0, a: a}; -}; -var $elm$json$Json$Decode$OneOf = function (a) { - return {$: 2, a: a}; -}; -var $elm$core$Basics$False = 1; -var $elm$core$Basics$add = _Basics_add; -var $elm$core$Maybe$Just = function (a) { - return {$: 0, a: a}; -}; -var $elm$core$Maybe$Nothing = {$: 1}; -var $elm$core$String$all = _String_all; -var $elm$core$Basics$and = _Basics_and; -var $elm$core$Basics$append = _Utils_append; -var $elm$json$Json$Encode$encode = _Json_encode; -var $elm$core$String$fromInt = _String_fromNumber; -var $elm$core$String$join = F2( - function (sep, chunks) { - return A2( - _String_join, - sep, - _List_toArray(chunks)); - }); -var $elm$core$String$split = F2( - function (sep, string) { - return _List_fromArray( - A2(_String_split, sep, string)); - }); -var $elm$json$Json$Decode$indent = function (str) { - return A2( - $elm$core$String$join, - '\n ', - A2($elm$core$String$split, '\n', str)); -}; -var $elm$core$List$foldl = F3( - function (func, acc, list) { - foldl: - while (true) { - if (!list.b) { - return acc; - } else { - var x = list.a; - var xs = list.b; - var $temp$func = func, - $temp$acc = A2(func, x, acc), - $temp$list = xs; - func = $temp$func; - acc = $temp$acc; - list = $temp$list; - continue foldl; - } - } - }); -var $elm$core$List$length = function (xs) { - return A3( - $elm$core$List$foldl, - F2( - function (_v0, i) { - return i + 1; - }), - 0, - xs); -}; -var $elm$core$List$map2 = _List_map2; -var $elm$core$Basics$le = _Utils_le; -var $elm$core$Basics$sub = _Basics_sub; -var $elm$core$List$rangeHelp = F3( - function (lo, hi, list) { - rangeHelp: - while (true) { - if (_Utils_cmp(lo, hi) < 1) { - var $temp$lo = lo, - $temp$hi = hi - 1, - $temp$list = A2($elm$core$List$cons, hi, list); - lo = $temp$lo; - hi = $temp$hi; - list = $temp$list; - continue rangeHelp; - } else { - return list; - } - } - }); -var $elm$core$List$range = F2( - function (lo, hi) { - return A3($elm$core$List$rangeHelp, lo, hi, _List_Nil); - }); -var $elm$core$List$indexedMap = F2( - function (f, xs) { - return A3( - $elm$core$List$map2, - f, - A2( - $elm$core$List$range, - 0, - $elm$core$List$length(xs) - 1), - xs); - }); -var $elm$core$Char$toCode = _Char_toCode; -var $elm$core$Char$isLower = function (_char) { - var code = $elm$core$Char$toCode(_char); - return (97 <= code) && (code <= 122); -}; -var $elm$core$Char$isUpper = function (_char) { - var code = $elm$core$Char$toCode(_char); - return (code <= 90) && (65 <= code); -}; -var $elm$core$Basics$or = _Basics_or; -var $elm$core$Char$isAlpha = function (_char) { - return $elm$core$Char$isLower(_char) || $elm$core$Char$isUpper(_char); -}; -var $elm$core$Char$isDigit = function (_char) { - var code = $elm$core$Char$toCode(_char); - return (code <= 57) && (48 <= code); -}; -var $elm$core$Char$isAlphaNum = function (_char) { - return $elm$core$Char$isLower(_char) || ($elm$core$Char$isUpper(_char) || $elm$core$Char$isDigit(_char)); -}; -var $elm$core$List$reverse = function (list) { - return A3($elm$core$List$foldl, $elm$core$List$cons, _List_Nil, list); -}; -var $elm$core$String$uncons = _String_uncons; -var $elm$json$Json$Decode$errorOneOf = F2( - function (i, error) { - return '\n\n(' + ($elm$core$String$fromInt(i + 1) + (') ' + $elm$json$Json$Decode$indent( - $elm$json$Json$Decode$errorToString(error)))); - }); -var $elm$json$Json$Decode$errorToString = function (error) { - return A2($elm$json$Json$Decode$errorToStringHelp, error, _List_Nil); -}; -var $elm$json$Json$Decode$errorToStringHelp = F2( - function (error, context) { - errorToStringHelp: - while (true) { - switch (error.$) { - case 0: - var f = error.a; - var err = error.b; - var isSimple = function () { - var _v1 = $elm$core$String$uncons(f); - if (_v1.$ === 1) { - return false; - } else { - var _v2 = _v1.a; - var _char = _v2.a; - var rest = _v2.b; - return $elm$core$Char$isAlpha(_char) && A2($elm$core$String$all, $elm$core$Char$isAlphaNum, rest); - } - }(); - var fieldName = isSimple ? ('.' + f) : ('[\'' + (f + '\']')); - var $temp$error = err, - $temp$context = A2($elm$core$List$cons, fieldName, context); - error = $temp$error; - context = $temp$context; - continue errorToStringHelp; - case 1: - var i = error.a; - var err = error.b; - var indexName = '[' + ($elm$core$String$fromInt(i) + ']'); - var $temp$error = err, - $temp$context = A2($elm$core$List$cons, indexName, context); - error = $temp$error; - context = $temp$context; - continue errorToStringHelp; - case 2: - var errors = error.a; - if (!errors.b) { - return 'Ran into a Json.Decode.oneOf with no possibilities' + function () { - if (!context.b) { - return '!'; - } else { - return ' at json' + A2( - $elm$core$String$join, - '', - $elm$core$List$reverse(context)); - } - }(); - } else { - if (!errors.b.b) { - var err = errors.a; - var $temp$error = err, - $temp$context = context; - error = $temp$error; - context = $temp$context; - continue errorToStringHelp; - } else { - var starter = function () { - if (!context.b) { - return 'Json.Decode.oneOf'; - } else { - return 'The Json.Decode.oneOf at json' + A2( - $elm$core$String$join, - '', - $elm$core$List$reverse(context)); - } - }(); - var introduction = starter + (' failed in the following ' + ($elm$core$String$fromInt( - $elm$core$List$length(errors)) + ' ways:')); - return A2( - $elm$core$String$join, - '\n\n', - A2( - $elm$core$List$cons, - introduction, - A2($elm$core$List$indexedMap, $elm$json$Json$Decode$errorOneOf, errors))); - } - } - default: - var msg = error.a; - var json = error.b; - var introduction = function () { - if (!context.b) { - return 'Problem with the given value:\n\n'; - } else { - return 'Problem with the value at json' + (A2( - $elm$core$String$join, - '', - $elm$core$List$reverse(context)) + ':\n\n '); - } - }(); - return introduction + ($elm$json$Json$Decode$indent( - A2($elm$json$Json$Encode$encode, 4, json)) + ('\n\n' + msg)); - } - } - }); -var $elm$core$Array$branchFactor = 32; -var $elm$core$Array$Array_elm_builtin = F4( - function (a, b, c, d) { - return {$: 0, a: a, b: b, c: c, d: d}; - }); -var $elm$core$Elm$JsArray$empty = _JsArray_empty; -var $elm$core$Basics$ceiling = _Basics_ceiling; -var $elm$core$Basics$fdiv = _Basics_fdiv; -var $elm$core$Basics$logBase = F2( - function (base, number) { - return _Basics_log(number) / _Basics_log(base); - }); -var $elm$core$Basics$toFloat = _Basics_toFloat; -var $elm$core$Array$shiftStep = $elm$core$Basics$ceiling( - A2($elm$core$Basics$logBase, 2, $elm$core$Array$branchFactor)); -var $elm$core$Array$empty = A4($elm$core$Array$Array_elm_builtin, 0, $elm$core$Array$shiftStep, $elm$core$Elm$JsArray$empty, $elm$core$Elm$JsArray$empty); -var $elm$core$Elm$JsArray$initialize = _JsArray_initialize; -var $elm$core$Array$Leaf = function (a) { - return {$: 1, a: a}; -}; -var $elm$core$Basics$apL = F2( - function (f, x) { - return f(x); - }); -var $elm$core$Basics$apR = F2( - function (x, f) { - return f(x); - }); -var $elm$core$Basics$eq = _Utils_equal; -var $elm$core$Basics$floor = _Basics_floor; -var $elm$core$Elm$JsArray$length = _JsArray_length; -var $elm$core$Basics$gt = _Utils_gt; -var $elm$core$Basics$max = F2( - function (x, y) { - return (_Utils_cmp(x, y) > 0) ? x : y; - }); -var $elm$core$Basics$mul = _Basics_mul; -var $elm$core$Array$SubTree = function (a) { - return {$: 0, a: a}; -}; -var $elm$core$Elm$JsArray$initializeFromList = _JsArray_initializeFromList; -var $elm$core$Array$compressNodes = F2( - function (nodes, acc) { - compressNodes: - while (true) { - var _v0 = A2($elm$core$Elm$JsArray$initializeFromList, $elm$core$Array$branchFactor, nodes); - var node = _v0.a; - var remainingNodes = _v0.b; - var newAcc = A2( - $elm$core$List$cons, - $elm$core$Array$SubTree(node), - acc); - if (!remainingNodes.b) { - return $elm$core$List$reverse(newAcc); - } else { - var $temp$nodes = remainingNodes, - $temp$acc = newAcc; - nodes = $temp$nodes; - acc = $temp$acc; - continue compressNodes; - } - } - }); -var $elm$core$Tuple$first = function (_v0) { - var x = _v0.a; - return x; -}; -var $elm$core$Array$treeFromBuilder = F2( - function (nodeList, nodeListSize) { - treeFromBuilder: - while (true) { - var newNodeSize = $elm$core$Basics$ceiling(nodeListSize / $elm$core$Array$branchFactor); - if (newNodeSize === 1) { - return A2($elm$core$Elm$JsArray$initializeFromList, $elm$core$Array$branchFactor, nodeList).a; - } else { - var $temp$nodeList = A2($elm$core$Array$compressNodes, nodeList, _List_Nil), - $temp$nodeListSize = newNodeSize; - nodeList = $temp$nodeList; - nodeListSize = $temp$nodeListSize; - continue treeFromBuilder; - } - } - }); -var $elm$core$Array$builderToArray = F2( - function (reverseNodeList, builder) { - if (!builder.b) { - return A4( - $elm$core$Array$Array_elm_builtin, - $elm$core$Elm$JsArray$length(builder.e), - $elm$core$Array$shiftStep, - $elm$core$Elm$JsArray$empty, - builder.e); - } else { - var treeLen = builder.b * $elm$core$Array$branchFactor; - var depth = $elm$core$Basics$floor( - A2($elm$core$Basics$logBase, $elm$core$Array$branchFactor, treeLen - 1)); - var correctNodeList = reverseNodeList ? $elm$core$List$reverse(builder.f) : builder.f; - var tree = A2($elm$core$Array$treeFromBuilder, correctNodeList, builder.b); - return A4( - $elm$core$Array$Array_elm_builtin, - $elm$core$Elm$JsArray$length(builder.e) + treeLen, - A2($elm$core$Basics$max, 5, depth * $elm$core$Array$shiftStep), - tree, - builder.e); - } - }); -var $elm$core$Basics$idiv = _Basics_idiv; -var $elm$core$Basics$lt = _Utils_lt; -var $elm$core$Array$initializeHelp = F5( - function (fn, fromIndex, len, nodeList, tail) { - initializeHelp: - while (true) { - if (fromIndex < 0) { - return A2( - $elm$core$Array$builderToArray, - false, - {f: nodeList, b: (len / $elm$core$Array$branchFactor) | 0, e: tail}); - } else { - var leaf = $elm$core$Array$Leaf( - A3($elm$core$Elm$JsArray$initialize, $elm$core$Array$branchFactor, fromIndex, fn)); - var $temp$fn = fn, - $temp$fromIndex = fromIndex - $elm$core$Array$branchFactor, - $temp$len = len, - $temp$nodeList = A2($elm$core$List$cons, leaf, nodeList), - $temp$tail = tail; - fn = $temp$fn; - fromIndex = $temp$fromIndex; - len = $temp$len; - nodeList = $temp$nodeList; - tail = $temp$tail; - continue initializeHelp; - } - } - }); -var $elm$core$Basics$remainderBy = _Basics_remainderBy; -var $elm$core$Array$initialize = F2( - function (len, fn) { - if (len <= 0) { - return $elm$core$Array$empty; - } else { - var tailLen = len % $elm$core$Array$branchFactor; - var tail = A3($elm$core$Elm$JsArray$initialize, tailLen, len - tailLen, fn); - var initialFromIndex = (len - tailLen) - $elm$core$Array$branchFactor; - return A5($elm$core$Array$initializeHelp, fn, initialFromIndex, len, _List_Nil, tail); - } - }); -var $elm$core$Basics$True = 0; -var $elm$core$Result$isOk = function (result) { - if (!result.$) { - return true; - } else { - return false; - } -}; -var $elm$json$Json$Decode$map = _Json_map1; -var $elm$json$Json$Decode$map2 = _Json_map2; -var $elm$json$Json$Decode$succeed = _Json_succeed; -var $elm$virtual_dom$VirtualDom$toHandlerInt = function (handler) { - switch (handler.$) { - case 0: - return 0; - case 1: - return 1; - case 2: - return 2; - default: - return 3; - } -}; -var $elm$browser$Browser$External = function (a) { - return {$: 1, a: a}; -}; -var $elm$browser$Browser$Internal = function (a) { - return {$: 0, a: a}; -}; -var $elm$core$Basics$identity = function (x) { - return x; -}; -var $elm$browser$Browser$Dom$NotFound = $elm$core$Basics$identity; -var $elm$url$Url$Http = 0; -var $elm$url$Url$Https = 1; -var $elm$url$Url$Url = F6( - function (protocol, host, port_, path, query, fragment) { - return {X: fragment, Z: host, ac: path, ae: port_, ah: protocol, ai: query}; - }); -var $elm$core$String$contains = _String_contains; -var $elm$core$String$length = _String_length; -var $elm$core$String$slice = _String_slice; -var $elm$core$String$dropLeft = F2( - function (n, string) { - return (n < 1) ? string : A3( - $elm$core$String$slice, - n, - $elm$core$String$length(string), - string); - }); -var $elm$core$String$indexes = _String_indexes; -var $elm$core$String$isEmpty = function (string) { - return string === ''; -}; -var $elm$core$String$left = F2( - function (n, string) { - return (n < 1) ? '' : A3($elm$core$String$slice, 0, n, string); - }); -var $elm$core$String$toInt = _String_toInt; -var $elm$url$Url$chompBeforePath = F5( - function (protocol, path, params, frag, str) { - if ($elm$core$String$isEmpty(str) || A2($elm$core$String$contains, '@', str)) { - return $elm$core$Maybe$Nothing; - } else { - var _v0 = A2($elm$core$String$indexes, ':', str); - if (!_v0.b) { - return $elm$core$Maybe$Just( - A6($elm$url$Url$Url, protocol, str, $elm$core$Maybe$Nothing, path, params, frag)); - } else { - if (!_v0.b.b) { - var i = _v0.a; - var _v1 = $elm$core$String$toInt( - A2($elm$core$String$dropLeft, i + 1, str)); - if (_v1.$ === 1) { - return $elm$core$Maybe$Nothing; - } else { - var port_ = _v1; - return $elm$core$Maybe$Just( - A6( - $elm$url$Url$Url, - protocol, - A2($elm$core$String$left, i, str), - port_, - path, - params, - frag)); - } - } else { - return $elm$core$Maybe$Nothing; - } - } - } - }); -var $elm$url$Url$chompBeforeQuery = F4( - function (protocol, params, frag, str) { - if ($elm$core$String$isEmpty(str)) { - return $elm$core$Maybe$Nothing; - } else { - var _v0 = A2($elm$core$String$indexes, '/', str); - if (!_v0.b) { - return A5($elm$url$Url$chompBeforePath, protocol, '/', params, frag, str); - } else { - var i = _v0.a; - return A5( - $elm$url$Url$chompBeforePath, - protocol, - A2($elm$core$String$dropLeft, i, str), - params, - frag, - A2($elm$core$String$left, i, str)); - } - } - }); -var $elm$url$Url$chompBeforeFragment = F3( - function (protocol, frag, str) { - if ($elm$core$String$isEmpty(str)) { - return $elm$core$Maybe$Nothing; - } else { - var _v0 = A2($elm$core$String$indexes, '?', str); - if (!_v0.b) { - return A4($elm$url$Url$chompBeforeQuery, protocol, $elm$core$Maybe$Nothing, frag, str); - } else { - var i = _v0.a; - return A4( - $elm$url$Url$chompBeforeQuery, - protocol, - $elm$core$Maybe$Just( - A2($elm$core$String$dropLeft, i + 1, str)), - frag, - A2($elm$core$String$left, i, str)); - } - } - }); -var $elm$url$Url$chompAfterProtocol = F2( - function (protocol, str) { - if ($elm$core$String$isEmpty(str)) { - return $elm$core$Maybe$Nothing; - } else { - var _v0 = A2($elm$core$String$indexes, '#', str); - if (!_v0.b) { - return A3($elm$url$Url$chompBeforeFragment, protocol, $elm$core$Maybe$Nothing, str); - } else { - var i = _v0.a; - return A3( - $elm$url$Url$chompBeforeFragment, - protocol, - $elm$core$Maybe$Just( - A2($elm$core$String$dropLeft, i + 1, str)), - A2($elm$core$String$left, i, str)); - } - } - }); -var $elm$core$String$startsWith = _String_startsWith; -var $elm$url$Url$fromString = function (str) { - return A2($elm$core$String$startsWith, 'http://', str) ? A2( - $elm$url$Url$chompAfterProtocol, - 0, - A2($elm$core$String$dropLeft, 7, str)) : (A2($elm$core$String$startsWith, 'https://', str) ? A2( - $elm$url$Url$chompAfterProtocol, - 1, - A2($elm$core$String$dropLeft, 8, str)) : $elm$core$Maybe$Nothing); -}; -var $elm$core$Basics$never = function (_v0) { - never: - while (true) { - var nvr = _v0; - var $temp$_v0 = nvr; - _v0 = $temp$_v0; - continue never; - } -}; -var $elm$core$Task$Perform = $elm$core$Basics$identity; -var $elm$core$Task$succeed = _Scheduler_succeed; -var $elm$core$Task$init = $elm$core$Task$succeed(0); -var $elm$core$List$foldrHelper = F4( - function (fn, acc, ctr, ls) { - if (!ls.b) { - return acc; - } else { - var a = ls.a; - var r1 = ls.b; - if (!r1.b) { - return A2(fn, a, acc); - } else { - var b = r1.a; - var r2 = r1.b; - if (!r2.b) { - return A2( - fn, - a, - A2(fn, b, acc)); - } else { - var c = r2.a; - var r3 = r2.b; - if (!r3.b) { - return A2( - fn, - a, - A2( - fn, - b, - A2(fn, c, acc))); - } else { - var d = r3.a; - var r4 = r3.b; - var res = (ctr > 500) ? A3( - $elm$core$List$foldl, - fn, - acc, - $elm$core$List$reverse(r4)) : A4($elm$core$List$foldrHelper, fn, acc, ctr + 1, r4); - return A2( - fn, - a, - A2( - fn, - b, - A2( - fn, - c, - A2(fn, d, res)))); - } - } - } - } - }); -var $elm$core$List$foldr = F3( - function (fn, acc, ls) { - return A4($elm$core$List$foldrHelper, fn, acc, 0, ls); - }); -var $elm$core$List$map = F2( - function (f, xs) { - return A3( - $elm$core$List$foldr, - F2( - function (x, acc) { - return A2( - $elm$core$List$cons, - f(x), - acc); - }), - _List_Nil, - xs); - }); -var $elm$core$Task$andThen = _Scheduler_andThen; -var $elm$core$Task$map = F2( - function (func, taskA) { - return A2( - $elm$core$Task$andThen, - function (a) { - return $elm$core$Task$succeed( - func(a)); - }, - taskA); - }); -var $elm$core$Task$map2 = F3( - function (func, taskA, taskB) { - return A2( - $elm$core$Task$andThen, - function (a) { - return A2( - $elm$core$Task$andThen, - function (b) { - return $elm$core$Task$succeed( - A2(func, a, b)); - }, - taskB); - }, - taskA); - }); -var $elm$core$Task$sequence = function (tasks) { - return A3( - $elm$core$List$foldr, - $elm$core$Task$map2($elm$core$List$cons), - $elm$core$Task$succeed(_List_Nil), - tasks); -}; -var $elm$core$Platform$sendToApp = _Platform_sendToApp; -var $elm$core$Task$spawnCmd = F2( - function (router, _v0) { - var task = _v0; - return _Scheduler_spawn( - A2( - $elm$core$Task$andThen, - $elm$core$Platform$sendToApp(router), - task)); - }); -var $elm$core$Task$onEffects = F3( - function (router, commands, state) { - return A2( - $elm$core$Task$map, - function (_v0) { - return 0; - }, - $elm$core$Task$sequence( - A2( - $elm$core$List$map, - $elm$core$Task$spawnCmd(router), - commands))); - }); -var $elm$core$Task$onSelfMsg = F3( - function (_v0, _v1, _v2) { - return $elm$core$Task$succeed(0); - }); -var $elm$core$Task$cmdMap = F2( - function (tagger, _v0) { - var task = _v0; - return A2($elm$core$Task$map, tagger, task); - }); -_Platform_effectManagers['Task'] = _Platform_createManager($elm$core$Task$init, $elm$core$Task$onEffects, $elm$core$Task$onSelfMsg, $elm$core$Task$cmdMap); -var $elm$core$Task$command = _Platform_leaf('Task'); -var $elm$core$Task$perform = F2( - function (toMessage, task) { - return $elm$core$Task$command( - A2($elm$core$Task$map, toMessage, task)); - }); -var $elm$browser$Browser$element = _Browser_element; -var $author$project$Main$NewCard = function (a) { - return {$: 2, a: a}; -}; -var $elm$random$Random$Generate = $elm$core$Basics$identity; -var $elm$random$Random$Seed = F2( - function (a, b) { - return {$: 0, a: a, b: b}; - }); -var $elm$core$Bitwise$shiftRightZfBy = _Bitwise_shiftRightZfBy; -var $elm$random$Random$next = function (_v0) { - var state0 = _v0.a; - var incr = _v0.b; - return A2($elm$random$Random$Seed, ((state0 * 1664525) + incr) >>> 0, incr); -}; -var $elm$random$Random$initialSeed = function (x) { - var _v0 = $elm$random$Random$next( - A2($elm$random$Random$Seed, 0, 1013904223)); - var state1 = _v0.a; - var incr = _v0.b; - var state2 = (state1 + x) >>> 0; - return $elm$random$Random$next( - A2($elm$random$Random$Seed, state2, incr)); -}; -var $elm$time$Time$Name = function (a) { - return {$: 0, a: a}; -}; -var $elm$time$Time$Offset = function (a) { - return {$: 1, a: a}; -}; -var $elm$time$Time$Zone = F2( - function (a, b) { - return {$: 0, a: a, b: b}; - }); -var $elm$time$Time$customZone = $elm$time$Time$Zone; -var $elm$time$Time$Posix = $elm$core$Basics$identity; -var $elm$time$Time$millisToPosix = $elm$core$Basics$identity; -var $elm$time$Time$now = _Time_now($elm$time$Time$millisToPosix); -var $elm$time$Time$posixToMillis = function (_v0) { - var millis = _v0; - return millis; -}; -var $elm$random$Random$init = A2( - $elm$core$Task$andThen, - function (time) { - return $elm$core$Task$succeed( - $elm$random$Random$initialSeed( - $elm$time$Time$posixToMillis(time))); - }, - $elm$time$Time$now); -var $elm$random$Random$step = F2( - function (_v0, seed) { - var generator = _v0; - return generator(seed); - }); -var $elm$random$Random$onEffects = F3( - function (router, commands, seed) { - if (!commands.b) { - return $elm$core$Task$succeed(seed); - } else { - var generator = commands.a; - var rest = commands.b; - var _v1 = A2($elm$random$Random$step, generator, seed); - var value = _v1.a; - var newSeed = _v1.b; - return A2( - $elm$core$Task$andThen, - function (_v2) { - return A3($elm$random$Random$onEffects, router, rest, newSeed); - }, - A2($elm$core$Platform$sendToApp, router, value)); - } - }); -var $elm$random$Random$onSelfMsg = F3( - function (_v0, _v1, seed) { - return $elm$core$Task$succeed(seed); - }); -var $elm$random$Random$Generator = $elm$core$Basics$identity; -var $elm$random$Random$map = F2( - function (func, _v0) { - var genA = _v0; - return function (seed0) { - var _v1 = genA(seed0); - var a = _v1.a; - var seed1 = _v1.b; - return _Utils_Tuple2( - func(a), - seed1); - }; - }); -var $elm$random$Random$cmdMap = F2( - function (func, _v0) { - var generator = _v0; - return A2($elm$random$Random$map, func, generator); - }); -_Platform_effectManagers['Random'] = _Platform_createManager($elm$random$Random$init, $elm$random$Random$onEffects, $elm$random$Random$onSelfMsg, $elm$random$Random$cmdMap); -var $elm$random$Random$command = _Platform_leaf('Random'); -var $elm$random$Random$generate = F2( - function (tagger, generator) { - return $elm$random$Random$command( - A2($elm$random$Random$map, tagger, generator)); - }); -var $elm$core$Bitwise$and = _Bitwise_and; -var $elm$core$Basics$negate = function (n) { - return -n; -}; -var $elm$core$Bitwise$xor = _Bitwise_xor; -var $elm$random$Random$peel = function (_v0) { - var state = _v0.a; - var word = (state ^ (state >>> ((state >>> 28) + 4))) * 277803737; - return ((word >>> 22) ^ word) >>> 0; -}; -var $elm$random$Random$int = F2( - function (a, b) { - return function (seed0) { - var _v0 = (_Utils_cmp(a, b) < 0) ? _Utils_Tuple2(a, b) : _Utils_Tuple2(b, a); - var lo = _v0.a; - var hi = _v0.b; - var range = (hi - lo) + 1; - if (!((range - 1) & range)) { - return _Utils_Tuple2( - (((range - 1) & $elm$random$Random$peel(seed0)) >>> 0) + lo, - $elm$random$Random$next(seed0)); - } else { - var threshhold = (((-range) >>> 0) % range) >>> 0; - var accountForBias = function (seed) { - accountForBias: - while (true) { - var x = $elm$random$Random$peel(seed); - var seedN = $elm$random$Random$next(seed); - if (_Utils_cmp(x, threshhold) < 0) { - var $temp$seed = seedN; - seed = $temp$seed; - continue accountForBias; - } else { - return _Utils_Tuple2((x % range) + lo, seedN); - } - } - }; - return accountForBias(seed0); - } - }; - }); -var $author$project$Main$newCard = A2($elm$random$Random$int, 2, 14); -var $author$project$Main$init = function (_v0) { - return _Utils_Tuple2( - { - a: {d: $elm$core$Maybe$Nothing, g: $elm$core$Maybe$Nothing, w: $elm$core$Maybe$Nothing}, - C: $elm$core$Maybe$Nothing, - D: $elm$core$Maybe$Nothing, - i: 100, - j: 0 - }, - A2($elm$random$Random$generate, $author$project$Main$NewCard, $author$project$Main$newCard)); -}; -var $elm$core$Platform$Sub$batch = _Platform_batch; -var $elm$core$Platform$Sub$none = $elm$core$Platform$Sub$batch(_List_Nil); -var $author$project$Main$subscriptions = function (_v0) { - return $elm$core$Platform$Sub$none; -}; -var $author$project$Main$NewCardC = function (a) { - return {$: 3, a: a}; -}; -var $elm$core$Platform$Cmd$batch = _Platform_batch; -var $elm$core$Platform$Cmd$none = $elm$core$Platform$Cmd$batch(_List_Nil); -var $author$project$Main$calculateNewState = F2( - function (cardC, model) { - var _v0 = model.a.d; - if (!_v0.$) { - var cardA = _v0.a; - var _v1 = model.a.g; - if (!_v1.$) { - var cardB = _v1.a; - var currentGame = model.a; - return (_Utils_eq(cardC, cardA) || _Utils_eq(cardC, cardB)) ? _Utils_Tuple2( - model, - A2($elm$random$Random$generate, $author$project$Main$NewCardC, $author$project$Main$newCard)) : (((_Utils_cmp(cardA, cardC) < 0) && (_Utils_cmp(cardC, cardB) < 0)) ? _Utils_Tuple2( - _Utils_update( - model, - { - a: _Utils_update( - currentGame, - {d: $elm$core$Maybe$Nothing, g: $elm$core$Maybe$Nothing}), - D: $elm$core$Maybe$Just( - { - d: model.a.d, - g: model.a.g, - w: $elm$core$Maybe$Just(cardC) - }), - i: model.i + model.j - }), - A2($elm$random$Random$generate, $author$project$Main$NewCard, $author$project$Main$newCard)) : ((_Utils_cmp(model.j, model.i - model.j) > 0) ? _Utils_Tuple2( - _Utils_update( - model, - { - a: _Utils_update( - currentGame, - {d: $elm$core$Maybe$Nothing, g: $elm$core$Maybe$Nothing}), - D: $elm$core$Maybe$Just( - { - d: model.a.d, - g: model.a.g, - w: $elm$core$Maybe$Just(cardC) - }), - i: model.i - model.j, - j: model.i - model.j - }), - A2($elm$random$Random$generate, $author$project$Main$NewCard, $author$project$Main$newCard)) : _Utils_Tuple2( - _Utils_update( - model, - { - a: _Utils_update( - currentGame, - {d: $elm$core$Maybe$Nothing, g: $elm$core$Maybe$Nothing}), - D: $elm$core$Maybe$Just( - { - d: model.a.d, - g: model.a.g, - w: $elm$core$Maybe$Just(cardC) - }), - i: model.i - model.j - }), - A2($elm$random$Random$generate, $author$project$Main$NewCard, $author$project$Main$newCard)))); - } else { - return _Utils_Tuple2(model, $elm$core$Platform$Cmd$none); - } - } else { - return _Utils_Tuple2(model, $elm$core$Platform$Cmd$none); - } - }); -var $author$project$Main$update = F2( - function (msg, model) { - switch (msg.$) { - case 0: - var bet = msg.a; - return _Utils_Tuple2( - _Utils_update( - model, - {j: bet}), - $elm$core$Platform$Cmd$none); - case 1: - var value = msg.a; - var _v1 = $elm$core$String$toInt(value); - if (!_v1.$) { - var newValue = _v1.a; - return (_Utils_cmp(newValue, model.i) > 0) ? _Utils_Tuple2( - _Utils_update( - model, - { - C: $elm$core$Maybe$Just('You cannot bet more than you have'), - j: model.i - }), - $elm$core$Platform$Cmd$none) : _Utils_Tuple2( - _Utils_update( - model, - {C: $elm$core$Maybe$Nothing, j: newValue}), - $elm$core$Platform$Cmd$none); - } else { - return _Utils_Tuple2( - _Utils_update( - model, - { - C: $elm$core$Maybe$Just('Wrong input for bet') - }), - $elm$core$Platform$Cmd$none); - } - case 2: - var card = msg.a; - var _v2 = model.a.d; - if (_v2.$ === 1) { - var currentGame = model.a; - return (card > 13) ? _Utils_Tuple2( - model, - A2($elm$random$Random$generate, $author$project$Main$NewCard, $author$project$Main$newCard)) : _Utils_Tuple2( - _Utils_update( - model, - { - a: _Utils_update( - currentGame, - { - d: $elm$core$Maybe$Just(card) - }) - }), - A2($elm$random$Random$generate, $author$project$Main$NewCard, $author$project$Main$newCard)); - } else { - var cardA = _v2.a; - var currentGame = model.a; - return (_Utils_cmp(card, cardA) < 1) ? _Utils_Tuple2( - _Utils_update( - model, - { - a: _Utils_update( - currentGame, - { - d: $elm$core$Maybe$Just(card) - }) - }), - A2($elm$random$Random$generate, $author$project$Main$NewCard, $author$project$Main$newCard)) : _Utils_Tuple2( - _Utils_update( - model, - { - a: _Utils_update( - currentGame, - { - g: $elm$core$Maybe$Just(card) - }) - }), - $elm$core$Platform$Cmd$none); - } - case 4: - return _Utils_Tuple2( - model, - A2($elm$random$Random$generate, $author$project$Main$NewCardC, $author$project$Main$newCard)); - case 3: - var card = msg.a; - return A2($author$project$Main$calculateNewState, card, model); - default: - return $author$project$Main$init(0); - } - }); -var $elm$virtual_dom$VirtualDom$style = _VirtualDom_style; -var $elm$html$Html$Attributes$style = $elm$virtual_dom$VirtualDom$style; -var $author$project$Main$centerHeadlineStyle = _List_fromArray( - [ - A2($elm$html$Html$Attributes$style, 'display', 'grid'), - A2($elm$html$Html$Attributes$style, 'place-items', 'center'), - A2($elm$html$Html$Attributes$style, 'margin', '2rem') - ]); -var $elm$html$Html$div = _VirtualDom_node('div'); -var $author$project$Main$NewGame = {$: 5}; -var $author$project$Main$Play = {$: 4}; -var $author$project$Main$UpdateBetValue = function (a) { - return {$: 1, a: a}; -}; -var $elm$html$Html$article = _VirtualDom_node('article'); -var $elm$html$Html$button = _VirtualDom_node('button'); -var $author$project$Main$cardContentPStyle = _List_fromArray( - [ - A2($elm$html$Html$Attributes$style, 'font-size', '2rem') - ]); -var $author$project$Main$cardToString = function (card) { - if (!card.$) { - var value = card.a; - if (value < 11) { - return $elm$core$String$fromInt(value); - } else { - switch (value) { - case 11: - return 'Jack'; - case 12: - return 'Queen'; - case 13: - return 'King'; - case 14: - return 'Ace'; - default: - return 'impossible value'; - } - } - } else { - return '-'; - } -}; -var $author$project$Main$gameStyle = _List_fromArray( - [ - A2($elm$html$Html$Attributes$style, 'width', '100%'), - A2($elm$html$Html$Attributes$style, 'max-width', '70rem') - ]); -var $elm$html$Html$input = _VirtualDom_node('input'); -var $elm$json$Json$Encode$string = _Json_wrap; -var $elm$html$Html$Attributes$stringProperty = F2( - function (key, string) { - return A2( - _VirtualDom_property, - key, - $elm$json$Json$Encode$string(string)); - }); -var $elm$html$Html$Attributes$max = $elm$html$Html$Attributes$stringProperty('max'); -var $elm$html$Html$Attributes$min = $elm$html$Html$Attributes$stringProperty('min'); -var $elm$virtual_dom$VirtualDom$Normal = function (a) { - return {$: 0, a: a}; -}; -var $elm$virtual_dom$VirtualDom$on = _VirtualDom_on; -var $elm$html$Html$Events$on = F2( - function (event, decoder) { - return A2( - $elm$virtual_dom$VirtualDom$on, - event, - $elm$virtual_dom$VirtualDom$Normal(decoder)); - }); -var $elm$html$Html$Events$onClick = function (msg) { - return A2( - $elm$html$Html$Events$on, - 'click', - $elm$json$Json$Decode$succeed(msg)); -}; -var $elm$html$Html$Events$alwaysStop = function (x) { - return _Utils_Tuple2(x, true); -}; -var $elm$virtual_dom$VirtualDom$MayStopPropagation = function (a) { - return {$: 1, a: a}; -}; -var $elm$html$Html$Events$stopPropagationOn = F2( - function (event, decoder) { - return A2( - $elm$virtual_dom$VirtualDom$on, - event, - $elm$virtual_dom$VirtualDom$MayStopPropagation(decoder)); - }); -var $elm$json$Json$Decode$field = _Json_decodeField; -var $elm$json$Json$Decode$at = F2( - function (fields, decoder) { - return A3($elm$core$List$foldr, $elm$json$Json$Decode$field, decoder, fields); - }); -var $elm$json$Json$Decode$string = _Json_decodeString; -var $elm$html$Html$Events$targetValue = A2( - $elm$json$Json$Decode$at, - _List_fromArray( - ['target', 'value']), - $elm$json$Json$Decode$string); -var $elm$html$Html$Events$onInput = function (tagger) { - return A2( - $elm$html$Html$Events$stopPropagationOn, - 'input', - A2( - $elm$json$Json$Decode$map, - $elm$html$Html$Events$alwaysStop, - A2($elm$json$Json$Decode$map, tagger, $elm$html$Html$Events$targetValue))); -}; -var $elm$html$Html$p = _VirtualDom_node('p'); -var $author$project$Main$standardFontSize = A2($elm$html$Html$Attributes$style, 'font-size', '2rem'); -var $elm$virtual_dom$VirtualDom$text = _VirtualDom_text; -var $elm$html$Html$text = $elm$virtual_dom$VirtualDom$text; -var $author$project$Main$showError = function (value) { - if (!value.$) { - var string = value.a; - return A2( - $elm$html$Html$p, - _List_fromArray( - [$author$project$Main$standardFontSize]), - _List_fromArray( - [ - $elm$html$Html$text(string) - ])); - } else { - return A2($elm$html$Html$div, _List_Nil, _List_Nil); - } -}; -var $author$project$Main$getGameStateMessage = F3( - function (cardA, cardB, cardC) { - return ((_Utils_cmp(cardA, cardC) < 0) && (_Utils_cmp(cardB, cardC) > 0)) ? A2( - $elm$html$Html$div, - _List_fromArray( - [$author$project$Main$standardFontSize]), - _List_fromArray( - [ - $elm$html$Html$text('You won :)') - ])) : A2( - $elm$html$Html$div, - _List_fromArray( - [$author$project$Main$standardFontSize]), - _List_fromArray( - [ - $elm$html$Html$text('You loose :(') - ])); - }); -var $elm$core$Maybe$map3 = F4( - function (func, ma, mb, mc) { - if (ma.$ === 1) { - return $elm$core$Maybe$Nothing; - } else { - var a = ma.a; - if (mb.$ === 1) { - return $elm$core$Maybe$Nothing; - } else { - var b = mb.a; - if (mc.$ === 1) { - return $elm$core$Maybe$Nothing; - } else { - var c = mc.a; - return $elm$core$Maybe$Just( - A3(func, a, b, c)); - } - } - } - }); -var $elm$core$Maybe$withDefault = F2( - function (_default, maybe) { - if (!maybe.$) { - var value = maybe.a; - return value; - } else { - return _default; - } - }); -var $author$project$Main$showLastWinLose = function (game) { - return A2( - $elm$core$Maybe$withDefault, - $elm$html$Html$text('something is wrong'), - A4($elm$core$Maybe$map3, $author$project$Main$getGameStateMessage, game.d, game.g, game.w)); -}; -var $author$project$Main$showLastGame = function (game) { - if (game.$ === 1) { - return A2( - $elm$html$Html$div, - _List_fromArray( - [$author$project$Main$standardFontSize]), - _List_fromArray( - [ - $elm$html$Html$text('This is your first game') - ])); - } else { - var value = game.a; - return A2( - $elm$html$Html$div, - _List_Nil, - _List_fromArray( - [ - $author$project$Main$showLastWinLose(value), - A2( - $elm$html$Html$p, - $author$project$Main$cardContentPStyle, - _List_fromArray( - [ - $elm$html$Html$text( - 'Card 1: ' + $author$project$Main$cardToString(value.d)) - ])), - A2( - $elm$html$Html$p, - $author$project$Main$cardContentPStyle, - _List_fromArray( - [ - $elm$html$Html$text( - 'Card 2: ' + $author$project$Main$cardToString(value.g)) - ])), - A2( - $elm$html$Html$p, - $author$project$Main$cardContentPStyle, - _List_fromArray( - [ - $elm$html$Html$text( - 'Drawn Card: ' + $author$project$Main$cardToString(value.w)) - ])) - ])); - } -}; -var $elm$html$Html$Attributes$type_ = $elm$html$Html$Attributes$stringProperty('type'); -var $elm$html$Html$Attributes$value = $elm$html$Html$Attributes$stringProperty('value'); -var $author$project$Main$showGame = function (model) { - return (model.i <= 0) ? A2( - $elm$html$Html$article, - $author$project$Main$gameStyle, - _List_fromArray( - [ - A2( - $elm$html$Html$p, - $author$project$Main$cardContentPStyle, - _List_fromArray( - [ - $elm$html$Html$text('You lose all you money') - ])), - A2( - $elm$html$Html$button, - _List_fromArray( - [ - $elm$html$Html$Events$onClick($author$project$Main$NewGame), - $author$project$Main$standardFontSize - ]), - _List_fromArray( - [ - $elm$html$Html$text('Again') - ])) - ])) : A2( - $elm$html$Html$article, - $author$project$Main$gameStyle, - _List_fromArray( - [ - A2( - $elm$html$Html$p, - $author$project$Main$cardContentPStyle, - _List_fromArray( - [ - $elm$html$Html$text( - 'Currently you have ' + ($elm$core$String$fromInt(model.i) + ' in your pocket.')) - ])), - A2( - $elm$html$Html$p, - $author$project$Main$cardContentPStyle, - _List_fromArray( - [ - $elm$html$Html$text( - 'Card 1: ' + $author$project$Main$cardToString(model.a.d)) - ])), - A2( - $elm$html$Html$p, - $author$project$Main$cardContentPStyle, - _List_fromArray( - [ - $elm$html$Html$text( - 'Card 2: ' + $author$project$Main$cardToString(model.a.g)) - ])), - A2( - $elm$html$Html$p, - $author$project$Main$cardContentPStyle, - _List_fromArray( - [ - $elm$html$Html$text( - 'Your current bet is ' + $elm$core$String$fromInt(model.j)) - ])), - A2( - $elm$html$Html$input, - _List_fromArray( - [ - $elm$html$Html$Attributes$type_('range'), - $elm$html$Html$Attributes$max( - $elm$core$String$fromInt(model.i)), - $elm$html$Html$Attributes$min('0'), - $elm$html$Html$Attributes$value( - $elm$core$String$fromInt(model.j)), - $elm$html$Html$Events$onInput($author$project$Main$UpdateBetValue) - ]), - _List_Nil), - A2( - $elm$html$Html$button, - _List_fromArray( - [ - $elm$html$Html$Events$onClick($author$project$Main$Play), - $author$project$Main$standardFontSize - ]), - _List_fromArray( - [ - $elm$html$Html$text('Play') - ])), - $author$project$Main$showLastGame(model.D), - $author$project$Main$showError(model.C) - ])); -}; -var $elm$html$Html$h1 = _VirtualDom_node('h1'); -var $author$project$Main$headerStyle = _List_fromArray( - [ - A2($elm$html$Html$Attributes$style, 'font-size', '2rem'), - A2($elm$html$Html$Attributes$style, 'text-align', 'center') - ]); -var $author$project$Main$showHeader = A2( - $elm$html$Html$div, - $author$project$Main$headerStyle, - _List_fromArray( - [ - A2( - $elm$html$Html$h1, - _List_fromArray( - [ - A2($elm$html$Html$Attributes$style, 'font-size', '4rem') - ]), - _List_fromArray( - [ - $elm$html$Html$text('ACEY DUCEY CARD GAME') - ])), - A2( - $elm$html$Html$div, - _List_Nil, - _List_fromArray( - [ - $elm$html$Html$text('Creative Computing Morristown, New Jersey') - ])), - A2( - $elm$html$Html$div, - _List_Nil, - _List_fromArray( - [ - $elm$html$Html$text('\n Acey-Ducey is played in the following manner. The Dealer (Computer) deals two cards face up. \n 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.\n If you do not want to bet, bet 0.\n ') - ])) - ])); -var $author$project$Main$view = function (model) { - return A2( - $elm$html$Html$div, - $author$project$Main$centerHeadlineStyle, - _List_fromArray( - [ - $author$project$Main$showHeader, - $author$project$Main$showGame(model) - ])); -}; -var $author$project$Main$main = $elm$browser$Browser$element( - {aB: $author$project$Main$init, aH: $author$project$Main$subscriptions, aJ: $author$project$Main$update, aK: $author$project$Main$view}); -_Platform_export({'Main':{'init':$author$project$Main$main( - $elm$json$Json$Decode$succeed(0))(0)}});}(this)); \ No newline at end of file diff --git a/00_Alternate_Languages/01_Acey_Ducey/elm/docs/app.min.js b/00_Alternate_Languages/01_Acey_Ducey/elm/docs/app.min.js deleted file mode 100644 index 99e5603cd..000000000 --- a/00_Alternate_Languages/01_Acey_Ducey/elm/docs/app.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(q){"use strict";function B(n,r,t){return t.a=n,t.f=r,t}function r(t){return B(2,t,function(r){return function(n){return t(r,n)}})}function t(e){return B(3,e,function(t){return function(r){return function(n){return e(t,r,n)}}})}function F(u){return B(4,u,function(e){return function(t){return function(r){return function(n){return u(e,t,r,n)}}}})}function J(a){return B(5,a,function(u){return function(e){return function(t){return function(r){return function(n){return a(u,e,t,r,n)}}}}})}function s(n,r,t){return 2===n.a?n.f(r,t):n(r)(t)}function v(n,r,t,e){return 3===n.a?n.f(r,t,e):n(r)(t)(e)}function b(n,r,t,e,u){return 4===n.a?n.f(r,t,e,u):n(r)(t)(e)(u)}function M(n,r,t,e,u,a){return 5===n.a?n.f(r,t,e,u,a):n(r)(t)(e)(u)(a)}function O(n,r){for(var t,e=[],u=S(n,r,0,e);u&&(t=e.pop());u=S(t.a,t.b,0,e));return u}function S(n,r,t,e){if(n===r)return!0;if("object"!=typeof n||null===n||null===r)return"function"==typeof n&&H(5),!1;if(100i)return u}var b=t.$;if(4===b){for(var l=t.k;4===l.$;)l=l.k;return n(r,l,e,u,a+1,i,r.elm_event_node_ref)}var d=t.e;var h=r.childNodes;for(var g=0;gi))return u;a=p}return u}(n,r,t,0,0,r.b,e)}function Pn(n,r,t,e){return 0===t.length?n:(Sn(n,r,t,e),Gn(n,t))}function Gn(n,r){for(var t=0;t>>0,r)}var o=n,Vn=t(function(n,r,t){for(;;){if(-2===t.$)return r;var e=t.d,u=n,a=v(n,t.b,t.c,v(Vn,n,r,t.e));n=u,r=a,t=e}}),Xn=function(n){return v(Vn,t(function(n,r,t){return s(o,{a:n,b:r},t)}),d,n)},y=function(n){return{$:1,a:n}},Zn=r(function(n,r){return{$:3,a:n,b:r}}),nr=r(function(n,r){return{$:0,a:n,b:r}}),rr=r(function(n,r){return{$:1,a:n,b:r}}),w=function(n){return{$:0,a:n}},tr=function(n){return{$:2,a:n}},j=function(n){return{$:0,a:n}},A={$:1},er=function(n){return n+""},ur=t(function(n,r,t){for(;;){if(!t.b)return r;var e=t.b,u=n,a=s(n,t.a,r);n=u,r=a,t=e}}),ar=function(n){return v(ur,o,d,n)},ir=F(function(n,r,t,e){return{$:0,a:n,b:r,c:t,d:e}}),or=[],fr=W,cr=r(function(n,r){return U(r)/U(n)}),vr=fr(s(cr,2,32)),sr=b(ir,0,vr,or,or),br=I,lr=Q,dr=function(n){return n.length},hr=r(function(n,r){return 0>>4+(n>>>28)))>>>22^n)>>>0}function Yr(n){return{a:{a:{d:A,g:A,w:A},C:A,D:A,i:100,j:0},b:s(E,i,N)}}function qr(n){return{$:3,a:n}}function Br(n){return{a:n,b:!0}}var Fr,Q=s(_,function(n){return k(function(n){var r=Un(s(zr,0,1013904223));return Un(s(zr,r.a+n>>>0,r.b))}(n))},{$:2,b:function(n){n({$:0,a:Fr(Date.now())})},c:null}),Jr=r(function(n,r){return n(r)}),Mr=t(function(r,n,t){var e,u;return n.b?(e=n.b,u=(n=s(Jr,n.a,t)).b,s(_,function(n){return v(Mr,r,e,u)},s(Lr,r,n.a))):k(t)}),K=t(function(n,r,t){return k(t)}),Or=r(function(t,n){var e=n;return function(n){var n=e(n),r=n.b;return{a:t(n.a),b:r}}}),Sr=(p.Random={b:Q,c:Mr,d:K,e:r(function(n,r){return s(Or,n,r)}),f:void 0},$n("Random")),E=r(function(n,r){return Sr(s(Or,n,r))}),N=s(r(function(f,c){return function(n){var r=l(f,c)<0?{a:f,b:c}:{a:c,b:f},t=r.a,e=r.b-t+1;if(!(e-1&e))return{a:((e-1&Rr(n))>>>0)+t,b:Un(n)};for(var u=(-e>>>0)%e>>>0,a=n;;){var i=Rr(a),o=Un(a);if(l(i,u)>=0)return{a:i%e+t,b:o};a=o}}}),2,14),Pr=pn(d),L=pn(d),Gr=r(function(n,r){var t,e,u=r.a.d;return u.$?{a:r,b:L}:(u=u.a,(t=r.a.g).$?{a:r,b:L}:(t=t.a,e=r.a,O(n,u)||O(n,t)?{a:r,b:s(E,qr,N)}:l(u,n)<0&&l(n,t)<0?{a:a(r,{a:a(e,{d:A,g:A}),D:j({d:r.a.d,g:r.a.g,w:j(n)}),i:r.i+r.j}),b:s(E,i,N)}:0 - - - - - - - -
- - - - - \ No newline at end of file diff --git a/00_Alternate_Languages/01_Acey_Ducey/elm/elm.json b/00_Alternate_Languages/01_Acey_Ducey/elm/elm.json deleted file mode 100644 index fff60a17f..000000000 --- a/00_Alternate_Languages/01_Acey_Ducey/elm/elm.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "type": "application", - "source-directories": [ - "src" - ], - "elm-version": "0.19.1", - "dependencies": { - "direct": { - "elm/browser": "1.0.2", - "elm/core": "1.0.5", - "elm/html": "1.0.0", - "elm/random": "1.0.0" - }, - "indirect": { - "elm/json": "1.1.3", - "elm/time": "1.0.0", - "elm/url": "1.0.0", - "elm/virtual-dom": "1.0.2" - } - }, - "test-dependencies": { - "direct": {}, - "indirect": {} - } -} diff --git a/00_Alternate_Languages/01_Acey_Ducey/elm/package-lock.json b/00_Alternate_Languages/01_Acey_Ducey/elm/package-lock.json deleted file mode 100644 index ea71f1cf7..000000000 --- a/00_Alternate_Languages/01_Acey_Ducey/elm/package-lock.json +++ /dev/null @@ -1,1733 +0,0 @@ -{ - "name": "01_Acey_Ducey", - "version": "1.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "01_Acey_Ducey", - "version": "1.0.0", - "license": "MIT", - "devDependencies": { - "elm-live": "^4.0.2", - "uglify-js": "^3.15.3" - } - }, - "node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "dev": true - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/charenc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/chokidar": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.0.2.tgz", - "integrity": "sha512-c4PR2egjNjI1um6bamCQ6bUNPDiyofNQruHvKgHQ4gDUP/ITSVSzNsiI5OWtHOsX323i5ha/kk4YmOZ1Ktg7KA==", - "dev": true, - "dependencies": { - "anymatch": "^3.0.1", - "braces": "^3.0.2", - "glob-parent": "^5.0.0", - "is-binary-path": "^2.1.0", - "is-glob": "^4.0.1", - "normalize-path": "^3.0.0", - "readdirp": "^3.1.1" - }, - "engines": { - "node": ">= 8" - }, - "optionalDependencies": { - "fsevents": "^2.0.6" - } - }, - "node_modules/commander": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", - "dev": true - }, - "node_modules/crocks": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/crocks/-/crocks-0.12.1.tgz", - "integrity": "sha512-2qCRJwBmPlRQXzd50k9gt9PaItultOP8lj/cKSH2Eai9aeBuNqAnDuyolAm9TGn6Pw/4BgbxtPJLU1S+tQ4WMQ==", - "dev": true - }, - "node_modules/cross-spawn": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.0.1.tgz", - "integrity": "sha1-o7uzAtsil8vqPATt82lB9GE6o5k=", - "dev": true, - "dependencies": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "node_modules/crypt": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/default-gateway": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", - "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", - "dev": true, - "dependencies": { - "execa": "^1.0.0", - "ip-regex": "^2.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, - "node_modules/elm-hot": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/elm-hot/-/elm-hot-1.1.4.tgz", - "integrity": "sha512-qPDP/o/Fkifriaxaf3E7hHFB5L6Ijihyg8is4A6xna6/h/zebUiNssbQrxywI2oxNUkr6W/leEu/WlIC1tmVnw==", - "dev": true - }, - "node_modules/elm-live": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/elm-live/-/elm-live-4.0.2.tgz", - "integrity": "sha512-4I3UvJxF6MubC14VsgtV11B0zBxaaKtdKKsWquoaa5a3UHBIGW83qgTnt/NxOj4omOLfupaftmDaE4yRMTgTcw==", - "dev": true, - "dependencies": { - "chalk": "^1.1.1", - "chokidar": "3.0.2", - "commander": "2.17.1", - "crocks": "0.12.1", - "cross-spawn": "5.0.1", - "elm-hot": "1.1.4", - "finalhandler": "1.1.2", - "http-proxy": "1.17.0", - "internal-ip": "4.3.0", - "mime": "2.4.3", - "open": "6.4.0", - "pem": "1.14.2", - "serve-static": "1.14.1", - "ws": "7.1.1" - }, - "bin": { - "elm-live": "bin/elm-live.js" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/es6-promisify": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-6.1.1.tgz", - "integrity": "sha512-HBL8I3mIki5C1Cc9QjKUenHtnG0A5/xA8Q/AllRcfiwl2CZFXGK7ddBiCoRwAix4i2KxcQfjtIVcrVbB3vbmwg==", - "dev": true - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", - "dev": true - }, - "node_modules/execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "dependencies": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/execa/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dev": true, - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/follow-redirects": { - "version": "1.14.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", - "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/http-errors": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", - "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", - "dev": true, - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/http-proxy": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", - "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", - "dev": true, - "dependencies": { - "eventemitter3": "^3.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/internal-ip": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", - "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", - "dev": true, - "dependencies": { - "default-gateway": "^4.2.0", - "ipaddr.js": "^1.9.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ip-regex": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "node_modules/lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "node_modules/md5": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", - "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", - "dev": true, - "dependencies": { - "charenc": "0.0.2", - "crypt": "0.0.2", - "is-buffer": "~1.1.6" - } - }, - "node_modules/mime": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.3.tgz", - "integrity": "sha512-QgrPRJfE+riq5TPZMcHZOtm8c6K/yYrMbKIoRfapfiGLxS8OTeIfRhUGW5LU7MlRa52KOAGCfUNruqLrIBvWZw==", - "dev": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "dependencies": { - "path-key": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/open": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/open/-/open-6.4.0.tgz", - "integrity": "sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==", - "dev": true, - "dependencies": { - "is-wsl": "^1.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/pem": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/pem/-/pem-1.14.2.tgz", - "integrity": "sha512-TOnPtq3ZFnCniOZ+rka4pk8UIze9xG1qI+wNE7EmkiR/cg+53uVvk5QbkWZ7M6RsuOxzz62FW1hlAobJr/lTOA==", - "dev": true, - "dependencies": { - "es6-promisify": "^6.0.0", - "md5": "^2.2.1", - "os-tmpdir": "^1.0.1", - "which": "^1.3.1" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", - "dev": true, - "dependencies": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "node_modules/serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", - "dev": true, - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", - "dev": true - }, - "node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/uglify-js": { - "version": "3.15.3", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.3.tgz", - "integrity": "sha512-6iCVm2omGJbsu3JWac+p6kUiOpg3wFO2f8lIXjfEb8RrmLjzog1wTPMmwKB7swfzzqxj9YM+sGUM++u1qN4qJg==", - "dev": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "node_modules/ws": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.1.1.tgz", - "integrity": "sha512-o41D/WmDeca0BqYhsr3nJzQyg9NF5X8l/UdnFNux9cS3lwB+swm8qGWX5rn+aD6xfBU3rGmtHij7g7x6LxFU3A==", - "dev": true, - "dependencies": { - "async-limiter": "^1.0.0" - } - }, - "node_modules/yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - } - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "dev": true - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "charenc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=", - "dev": true - }, - "chokidar": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.0.2.tgz", - "integrity": "sha512-c4PR2egjNjI1um6bamCQ6bUNPDiyofNQruHvKgHQ4gDUP/ITSVSzNsiI5OWtHOsX323i5ha/kk4YmOZ1Ktg7KA==", - "dev": true, - "requires": { - "anymatch": "^3.0.1", - "braces": "^3.0.2", - "fsevents": "^2.0.6", - "glob-parent": "^5.0.0", - "is-binary-path": "^2.1.0", - "is-glob": "^4.0.1", - "normalize-path": "^3.0.0", - "readdirp": "^3.1.1" - } - }, - "commander": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", - "dev": true - }, - "crocks": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/crocks/-/crocks-0.12.1.tgz", - "integrity": "sha512-2qCRJwBmPlRQXzd50k9gt9PaItultOP8lj/cKSH2Eai9aeBuNqAnDuyolAm9TGn6Pw/4BgbxtPJLU1S+tQ4WMQ==", - "dev": true - }, - "cross-spawn": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.0.1.tgz", - "integrity": "sha1-o7uzAtsil8vqPATt82lB9GE6o5k=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "crypt": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=", - "dev": true - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "default-gateway": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", - "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", - "dev": true, - "requires": { - "execa": "^1.0.0", - "ip-regex": "^2.1.0" - } - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, - "elm-hot": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/elm-hot/-/elm-hot-1.1.4.tgz", - "integrity": "sha512-qPDP/o/Fkifriaxaf3E7hHFB5L6Ijihyg8is4A6xna6/h/zebUiNssbQrxywI2oxNUkr6W/leEu/WlIC1tmVnw==", - "dev": true - }, - "elm-live": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/elm-live/-/elm-live-4.0.2.tgz", - "integrity": "sha512-4I3UvJxF6MubC14VsgtV11B0zBxaaKtdKKsWquoaa5a3UHBIGW83qgTnt/NxOj4omOLfupaftmDaE4yRMTgTcw==", - "dev": true, - "requires": { - "chalk": "^1.1.1", - "chokidar": "3.0.2", - "commander": "2.17.1", - "crocks": "0.12.1", - "cross-spawn": "5.0.1", - "elm-hot": "1.1.4", - "finalhandler": "1.1.2", - "http-proxy": "1.17.0", - "internal-ip": "4.3.0", - "mime": "2.4.3", - "open": "6.4.0", - "pem": "1.14.2", - "serve-static": "1.14.1", - "ws": "7.1.1" - } - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "es6-promisify": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-6.1.1.tgz", - "integrity": "sha512-HBL8I3mIki5C1Cc9QjKUenHtnG0A5/xA8Q/AllRcfiwl2CZFXGK7ddBiCoRwAix4i2KxcQfjtIVcrVbB3vbmwg==", - "dev": true - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "dev": true - }, - "eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", - "dev": true - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "dependencies": { - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - } - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - } - }, - "follow-redirects": { - "version": "1.14.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", - "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==", - "dev": true - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "http-errors": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", - "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - } - }, - "http-proxy": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", - "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", - "dev": true, - "requires": { - "eventemitter3": "^3.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "internal-ip": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", - "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", - "dev": true, - "requires": { - "default-gateway": "^4.2.0", - "ipaddr.js": "^1.9.0" - } - }, - "ip-regex": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", - "dev": true - }, - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "md5": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", - "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", - "dev": true, - "requires": { - "charenc": "0.0.2", - "crypt": "0.0.2", - "is-buffer": "~1.1.6" - } - }, - "mime": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.3.tgz", - "integrity": "sha512-QgrPRJfE+riq5TPZMcHZOtm8c6K/yYrMbKIoRfapfiGLxS8OTeIfRhUGW5LU7MlRa52KOAGCfUNruqLrIBvWZw==", - "dev": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "requires": { - "path-key": "^2.0.0" - } - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "open": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/open/-/open-6.4.0.tgz", - "integrity": "sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==", - "dev": true, - "requires": { - "is-wsl": "^1.1.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "pem": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/pem/-/pem-1.14.2.tgz", - "integrity": "sha512-TOnPtq3ZFnCniOZ+rka4pk8UIze9xG1qI+wNE7EmkiR/cg+53uVvk5QbkWZ7M6RsuOxzz62FW1hlAobJr/lTOA==", - "dev": true, - "requires": { - "es6-promisify": "^6.0.0", - "md5": "^2.2.1", - "os-tmpdir": "^1.0.1", - "which": "^1.3.1" - } - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", - "dev": true, - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "dependencies": { - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - } - } - }, - "serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", - "dev": true, - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - } - }, - "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", - "dev": true - }, - "uglify-js": { - "version": "3.15.3", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.3.tgz", - "integrity": "sha512-6iCVm2omGJbsu3JWac+p6kUiOpg3wFO2f8lIXjfEb8RrmLjzog1wTPMmwKB7swfzzqxj9YM+sGUM++u1qN4qJg==", - "dev": true - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "ws": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.1.1.tgz", - "integrity": "sha512-o41D/WmDeca0BqYhsr3nJzQyg9NF5X8l/UdnFNux9cS3lwB+swm8qGWX5rn+aD6xfBU3rGmtHij7g7x6LxFU3A==", - "dev": true, - "requires": { - "async-limiter": "^1.0.0" - } - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - } - } -} diff --git a/00_Alternate_Languages/01_Acey_Ducey/elm/package.json b/00_Alternate_Languages/01_Acey_Ducey/elm/package.json deleted file mode 100644 index 4e418f779..000000000 --- a/00_Alternate_Languages/01_Acey_Ducey/elm/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "01_Acey_Ducey", - "version": "1.0.0", - "main": "index.js", - "repository": "https://github.com/auryn31/01_Acey_Ducey.git", - "author": "Auryn Engel ", - "license": "MIT", - "scripts": { - "live": "elm-live src/Main.elm --proxy-prefix=/api --proxy-host=http://localhost:8080/api --open --start-page=resources/index.html -- --output=app.js", - "build": "elm make src/Main.elm --optimize --output docs/app.js && cp -R resources/ docs/" - }, - "devDependencies": { - "elm-live": "^4.0.2", - "uglify-js": "^3.15.3" - } -} diff --git a/00_Alternate_Languages/01_Acey_Ducey/elm/resources/index.html b/00_Alternate_Languages/01_Acey_Ducey/elm/resources/index.html deleted file mode 100644 index 7a609ec3a..000000000 --- a/00_Alternate_Languages/01_Acey_Ducey/elm/resources/index.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - -
- - - - - \ No newline at end of file diff --git a/00_Alternate_Languages/01_Acey_Ducey/elm/src/Main.elm b/00_Alternate_Languages/01_Acey_Ducey/elm/src/Main.elm deleted file mode 100644 index 689b69209..000000000 --- a/00_Alternate_Languages/01_Acey_Ducey/elm/src/Main.elm +++ /dev/null @@ -1,308 +0,0 @@ -module Main exposing (..) - -import Browser -import Html exposing (..) -import Html.Attributes exposing (style, type_, value) -import Html.Events exposing (onInput) -import Random - - -main : Program () Model Msg -main = - Browser.element - { init = init - , view = view - , update = update - , subscriptions = subscriptions - } - - - --- Models - - -type alias Model = - { money : Int - , currentGame : Game - , lastGame : Maybe Game - , moneyBet : Int - , error : Maybe String - } - - -type alias Game = - { cardA : Maybe Int - , cardB : Maybe Int - , cardC : Maybe Int - } - - - --- Init - - -init : () -> ( Model, Cmd Msg ) -init _ = - ( { money = 100, currentGame = { cardA = Nothing, cardB = Nothing, cardC = Nothing }, lastGame = Nothing, moneyBet = 0, error = Nothing }, Random.generate NewCard newCard ) - - - --- Messages - - -type Msg - = BetMoney Int - | UpdateBetValue String - | NewCard Int - | NewCardC Int - | Play - | NewGame - - - --- Update - - -update : Msg -> Model -> ( Model, Cmd Msg ) -update msg model = - case msg of - BetMoney bet -> - ( { model | moneyBet = bet }, Cmd.none ) - - UpdateBetValue value -> - case String.toInt value of - Just newValue -> - if newValue > model.money then - ( { model | error = Just "You cannot bet more than you have", moneyBet = model.money }, Cmd.none ) - - else - ( { model | moneyBet = newValue, error = Nothing }, Cmd.none ) - - Nothing -> - ( { model | error = Just "Wrong input for bet" }, Cmd.none ) - - NewCard card -> - case model.currentGame.cardA of - Nothing -> - let - currentGame = - model.currentGame - in - if card > 13 then - ( model, Random.generate NewCard newCard ) - - else - ( { model | currentGame = { currentGame | cardA = Just card } }, Random.generate NewCard newCard ) - - Just cardA -> - let - currentGame = - model.currentGame - in - if card <= cardA then - ( { model | currentGame = { currentGame | cardA = Just card } }, Random.generate NewCard newCard ) - - else - ( { model | currentGame = { currentGame | cardB = Just card } }, Cmd.none ) - - Play -> - ( model, Random.generate NewCardC newCard ) - - NewCardC card -> - calculateNewState card model - - NewGame -> - init () - - -calculateNewState : Int -> Model -> ( Model, Cmd Msg ) -calculateNewState cardC model = - case model.currentGame.cardA of - Just cardA -> - case model.currentGame.cardB of - Just cardB -> - let - currentGame = - model.currentGame - in - if cardC == cardA || cardC == cardB then - ( model, Random.generate NewCardC newCard ) - - else if cardA < cardC && cardC < cardB then - ( { model | money = model.money + model.moneyBet, currentGame = { currentGame | cardA = Nothing, cardB = Nothing }, lastGame = Just { cardA = model.currentGame.cardA, cardB = model.currentGame.cardB, cardC = Just cardC } }, Random.generate NewCard newCard ) - - else if model.moneyBet > model.money - model.moneyBet then - ( { model | money = model.money - model.moneyBet, moneyBet = model.money - model.moneyBet, currentGame = { currentGame | cardA = Nothing, cardB = Nothing }, lastGame = Just { cardA = model.currentGame.cardA, cardB = model.currentGame.cardB, cardC = Just cardC } }, Random.generate NewCard newCard ) - - else - ( { model | money = model.money - model.moneyBet, currentGame = { currentGame | cardA = Nothing, cardB = Nothing }, lastGame = Just { cardA = model.currentGame.cardA, cardB = model.currentGame.cardB, cardC = Just cardC } }, Random.generate NewCard newCard ) - - Nothing -> - ( model, Cmd.none ) - - Nothing -> - ( model, Cmd.none ) - - -subscriptions : Model -> Sub Msg -subscriptions _ = - Sub.none - - - --- Views - - -view : Model -> Html Msg -view model = - div centerHeadlineStyle - [ showHeader - , showGame model - ] - - -showHeader : Html msg -showHeader = - div headerStyle - [ h1 [ style "font-size" "4rem" ] [ text "ACEY DUCEY CARD GAME" ] - , div [] [ text "Creative Computing Morristown, New Jersey" ] - , div [] - [ text """ - 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, bet 0. - """ - ] - ] - - -showGame : Model -> Html Msg -showGame model = - if model.money <= 0 then - article gameStyle - [ p cardContentPStyle [ text "You lose all you money" ] - , button [ Html.Events.onClick NewGame, standardFontSize ] [ text "Again" ] - ] - - else - article gameStyle - [ p cardContentPStyle [ text ("Currently you have " ++ String.fromInt model.money ++ " in your pocket.") ] - , p cardContentPStyle [ text ("Card 1: " ++ cardToString model.currentGame.cardA) ] - , p cardContentPStyle [ text ("Card 2: " ++ cardToString model.currentGame.cardB) ] - , p cardContentPStyle [ text ("Your current bet is " ++ String.fromInt model.moneyBet) ] - , input [ type_ "range", Html.Attributes.max (String.fromInt model.money), Html.Attributes.min "0", Html.Attributes.value (String.fromInt model.moneyBet), onInput UpdateBetValue ] [] - , button [ Html.Events.onClick Play, standardFontSize ] [ text "Play" ] - , showLastGame model.lastGame - , showError model.error - ] - - -showLastGame : Maybe Game -> Html Msg -showLastGame game = - case game of - Nothing -> - div [ standardFontSize ] [ text "This is your first game" ] - - Just value -> - div [] - [ showLastWinLose value - , p cardContentPStyle [ text ("Card 1: " ++ cardToString value.cardA) ] - , p cardContentPStyle [ text ("Card 2: " ++ cardToString value.cardB) ] - , p cardContentPStyle [ text ("Drawn Card: " ++ cardToString value.cardC) ] - ] - - -showLastWinLose : Game -> Html Msg -showLastWinLose game = - Maybe.map3 getGameStateMessage game.cardA game.cardB game.cardC |> Maybe.withDefault (text "something is wrong") - - -getGameStateMessage : Int -> Int -> Int -> Html Msg -getGameStateMessage cardA cardB cardC = - if cardA < cardC && cardB > cardC then - div [ standardFontSize ] [ text "You won :)" ] - - else - div [ standardFontSize ] [ text "You loose :(" ] - - -showError : Maybe String -> Html Msg -showError value = - case value of - Just string -> - p [ standardFontSize ] [ text string ] - - Nothing -> - div [] [] - - - --- Helper - - -cardToString : Maybe Int -> String -cardToString card = - case card of - Just value -> - if value < 11 then - String.fromInt value - - else - case value of - 11 -> - "Jack" - - 12 -> - "Queen" - - 13 -> - "King" - - 14 -> - "Ace" - - _ -> - "impossible value" - - Nothing -> - "-" - - -newCard : Random.Generator Int -newCard = - Random.int 2 14 - - - --- Styles - - -headerStyle : List (Attribute msg) -headerStyle = - [ style "font-size" "2rem", style "text-align" "center" ] - - -cardContentPStyle : List (Attribute msg) -cardContentPStyle = - [ style "font-size" "2rem" - ] - - -gameStyle : List (Attribute msg) -gameStyle = - [ style "width" "100%" - , style "max-width" "70rem" - ] - - -centerHeadlineStyle : List (Attribute msg) -centerHeadlineStyle = - [ style "display" "grid" - , style "place-items" "center" - , style "margin" "2rem" - ] - - -standardFontSize : Attribute msg -standardFontSize = - style "font-size" "2rem" diff --git a/00_Alternate_Languages/01_Acey_Ducey/go/main.go b/00_Alternate_Languages/01_Acey_Ducey/go/main.go deleted file mode 100644 index 10e965898..000000000 --- a/00_Alternate_Languages/01_Acey_Ducey/go/main.go +++ /dev/null @@ -1,112 +0,0 @@ -package main - -import ( - "bufio" - "fmt" - "math/rand" - "os" - "sort" - "strconv" - "strings" - "time" -) - -var welcome = ` -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 - ` - -func main() { - rand.Seed(time.Now().UnixNano()) - scanner := bufio.NewScanner(os.Stdin) - - fmt.Println(welcome) - - for { - play(100) - fmt.Println("TRY AGAIN (YES OR NO)") - scanner.Scan() - response := scanner.Text() - if strings.ToUpper(response) != "YES" { - break - } - } - - fmt.Println("O.K., HOPE YOU HAD FUN!") -} - -func play(money int) { - scanner := bufio.NewScanner(os.Stdin) - var bet int - - for { - // Shuffle the cards - cards := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14} - rand.Shuffle(len(cards), func(i, j int) { cards[i], cards[j] = cards[j], cards[i] }) - - // Take the first two for the dealer and sort - dealerCards := cards[0:2] - sort.Ints(dealerCards) - - fmt.Printf("YOU NOW HAVE %d DOLLARS.\n\n", money) - fmt.Printf("HERE ARE YOUR NEXT TWO CARDS:\n%s\n%s", getCardName(dealerCards[0]), getCardName(dealerCards[1])) - fmt.Printf("\n\n") - - //Check if Bet is Valid - for { - fmt.Println("WHAT IS YOUR BET:") - scanner.Scan() - b, err := strconv.Atoi(scanner.Text()) - if err != nil { - fmt.Println("PLEASE ENTER A POSITIVE NUMBER") - continue - } - bet = b - - if bet == 0 { - fmt.Printf("CHICKEN!\n\n") - goto there - } - - if (bet > 0) && (bet <= money) { - break - } - } - - // Draw Players Card - fmt.Printf("YOUR CARD: %s\n", getCardName(cards[2])) - if (cards[2] > dealerCards[0]) && (cards[2] < dealerCards[1]) { - fmt.Println("YOU WIN!!!") - money = money + bet - } else { - fmt.Println("SORRY, YOU LOSE") - money = money - bet - } - fmt.Println() - - if money <= 0 { - fmt.Printf("%s\n", "SORRY, FRIEND, BUT YOU BLEW YOUR WAD.") - return - } - there: - } -} - -func getCardName(c int) string { - switch c { - case 11: - return "JACK" - case 12: - return "QUEEN" - case 13: - return "KING" - case 14: - return "ACE" - default: - return strconv.Itoa(c) - } -} diff --git a/00_Alternate_Languages/01_Acey_Ducey/nim/aceyducey.nim b/00_Alternate_Languages/01_Acey_Ducey/nim/aceyducey.nim deleted file mode 100644 index abc03defc..000000000 --- a/00_Alternate_Languages/01_Acey_Ducey/nim/aceyducey.nim +++ /dev/null @@ -1,89 +0,0 @@ -import std/[random,strutils] - -var - bet, cardA, cardB, cardC, stash: int - retry: bool = true - -randomize() # Seed the random number generator - -proc printGreeting() = - echo spaces(26),"ACEY DUCEY CARD GAME" - echo spaces(15),"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" - echo """ - -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 - -""" - -proc printBalance() = - echo "YOU NOW HAVE ", stash," DOLLARS." - echo "" - -proc printCard(aCard: int) = - case aCard: - of 11: echo "=== JACK ===" - of 12: echo "=== QUEEN ===" - of 13: echo "=== KING ===" - of 14: echo "=== ACE ===" - else: echo "=== ", aCard, " ===" - -proc drawDealerCards() = - echo "HERE ARE YOUR NEXT TWO CARDS: " - cardA = rand 2..14 - cardB = cardA # Copy cardA, so we can test cardB to be different - while cardB == cardA: - cardB = rand 2..14 - if cardA > cardB: # Make sure cardA is the smaller card - swap cardA, cardB - echo "" - printCard cardA - echo "" - printCard cardB - echo "" - -proc drawPlayerCard() = - cardC = rand 2..14 - printCard cardC - echo "" - -proc getBet(): int = - result = stash + 1 #ensure we enter the loop - while (result < 0) or (result > stash): - echo "WHAT IS YOUR BET: " - result = readLine(stdin).parseInt() - if result > stash: - echo "SORRY, MY FRIEND, BUT YOU BET TOO MUCH." - echo "YOU HAVE ONLY ", stash, " DOLLARS TO BET." - if result == 0: - echo "CHICKEN!!" - -proc tryAgain(): bool = - echo "TRY AGAIN (YES OR NO)" - var answer = readLine(stdin).normalize() - result = (answer == "y") or (answer == "yes") - -printGreeting() -while retry: - stash = 100 - while stash > 0: - printBalance() - drawDealerCards() - bet = getBet() - echo "" - drawPlayerCard() - if (cardC >= cardA) and (cardC <= cardB): - echo "YOU WIN!!!" - stash += bet - else: - if bet > 0: - echo "SORRY, YOU LOSE" - stash -= bet - echo "SORRY, FRIEND, BUT YOU BLEW YOUR WAD." - echo "" - retry = tryAgain() -echo "O.K., HOPE YOU HAD FUN!" diff --git a/00_Alternate_Languages/01_Acey_Ducey/pascal/object-pascal/aceyducey.pas b/00_Alternate_Languages/01_Acey_Ducey/pascal/object-pascal/aceyducey.pas deleted file mode 100644 index a57df2cf0..000000000 --- a/00_Alternate_Languages/01_Acey_Ducey/pascal/object-pascal/aceyducey.pas +++ /dev/null @@ -1,18 +0,0 @@ -program aceyducey; - -{$IFDEF FPC} -{$mode objfpc}{$H+} -{$ENDIF} - -uses - Game -, Deck -; - -var - Acey_Ducey: TGame; - -begin - Acey_Ducey:= TGame.Create; - Acey_Ducey.Run; -end. diff --git a/00_Alternate_Languages/01_Acey_Ducey/pascal/simple/aceyducey.pas b/00_Alternate_Languages/01_Acey_Ducey/pascal/simple/aceyducey.pas deleted file mode 100644 index 3fad87bf7..000000000 --- a/00_Alternate_Languages/01_Acey_Ducey/pascal/simple/aceyducey.pas +++ /dev/null @@ -1,151 +0,0 @@ -program aceyducey; - -{$IFDEF FPC} -{$mode objfpc}{$H+} -{$ENDIF} - -uses - Crt; - -var - Stash: Integer; - CardA: Integer; - CardB: Integer; - CardC: Integer; - Bet: Integer; - -procedure PrintGreeting; -begin - WriteLN(' ':26, 'ACEY DUCEY CARD GAME'); - WriteLN(' ':15, 'CREATIVE COMPUTING MORRISTOWN, NEW JERSEY'); - WriteLN; - WriteLN; - WriteLN('ACEY-DUCEY IS PLAYED IN THE FOLLOWING MANNER '); - WriteLN('THE DEALER (COMPUTER) DEALS TWO CARDS FACE UP'); - WriteLN('YOU HAVE AN OPTION TO BET OR NOT BET DEPENDING'); - WriteLN('ON WHETHER OR NOT YOU FEEL THE CARD WILL HAVE'); - WriteLN('A VALUE BETWEEN THE FIRST TWO.'); - WriteLN('IF YOU DO NOT WANT TO BET, INPUT A 0'); - WriteLN; -end; - -procedure PrintBalance; -begin - WriteLN('YOU NOW HAVE ', Stash,' DOLLARS.'); - WriteLN; -end; - -procedure PrintCard(const ACard: Integer); -begin - if ACard < 11 then - begin - Write(ACard); - end; - if ACard = 11 then - begin - Write('JACK'); - end; - if ACard = 12 then - begin - Write('QUEEN'); - end; - if ACard = 13 then - begin - Write('KING'); - end; - if ACard = 14 then - begin - Write('ACE'); - end; -end; - -procedure DrawDealerCards; -var - tmp: Integer; -begin - Write('HERE ARE YOUR NEXT TWO CARDS: '); - repeat - CardA:= Random(14) + 2; - until (CardA >= 2) and (CardA <= 14); - repeat - CardB:= Random(14) + 2; - until (CardB >= 2) and (CardB <= 14) and (CardA <> CardB); - if CardA > CardB then - begin - tmp:= CardB; - CardB:= CardA; - CardA:= tmp; - end; - PrintCard(CardA); - Write(' '); - PrintCard(CardB); - WriteLN; - WriteLN; -end; - -procedure DrawPlayerCard; -begin - repeat - CardC:= Random(14) + 2; - until (CardC >= 2) and (CardC <= 14); - PrintCard(CardC); - WriteLN; - WriteLN; -end; - -function GetBet: Integer; -begin - Result:= 0; - repeat - Write('WHAT IS YOUR BET: '); - ReadLN(Result); - if Result > Stash then - begin - WriteLn('SORRY, MY FRIEND, BUT YOU BET TOO MUCH.'); - WriteLn('YOU HAVE ONLY ', Stash,' DOLLARS TO BET.'); - end; - until (Result >=0) and (Result <= Stash); -end; - -function TryAgain: Boolean; -var - answer: String; -begin - Result:= False; - Write('TRY AGAIN (YES OR NO)'); - ReadLn(answer); - Result:= (LowerCase(answer)='yes') or (LowerCase(answer)='y'); -end; - -begin - Randomize; - ClrScr; - PrintGreeting; - repeat - Stash:= 100; - repeat - PrintBalance; - DrawDealerCards; - Bet:= GetBet; - if Bet = 0 then - begin - WriteLN('CHICKEN!!'); - continue; - end; - DrawPlayerCard; - if (CardC > CardA) and (CardC < CardB) then - begin - WriteLN('YOU WIN!!!'); - Inc(Stash, Bet) - end - else - begin - WriteLN('SORRY, YOU LOSE'); - Dec(Stash, Bet) - end; - until Stash = 0; - WriteLN('SORRY, FRIEND, BUT YOU BLEW YOUR WAD.'); - WriteLN; - until not TryAgain; - WriteLN('O.K., HOPE YOU HAD FUN!'); -end. diff --git a/00_Alternate_Languages/02_Amazing/MiniScript/README.md b/00_Alternate_Languages/02_Amazing/MiniScript/README.md deleted file mode 100644 index 35d818ef5..000000000 --- a/00_Alternate_Languages/02_Amazing/MiniScript/README.md +++ /dev/null @@ -1,21 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript amazing.ms -``` -Note that because this program imports "listUtil", you will need to have a the standard MiniScript libraries somewhere in your import path. - -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "amazing" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/02_Amazing/MiniScript/amazing.ms b/00_Alternate_Languages/02_Amazing/MiniScript/amazing.ms deleted file mode 100644 index 3c3589791..000000000 --- a/00_Alternate_Languages/02_Amazing/MiniScript/amazing.ms +++ /dev/null @@ -1,108 +0,0 @@ -import "listUtil" -print " "*28 + "Amazing Program" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print; print -while true - inp = input("What and your width and length? ") - inp = inp.replace(",", " ") - fields = inp.split - h = fields[0].val; v = fields[-1].val - if h > 1 and v > 1 then break - print "Meaningless dimensions. Try again." -end while - -// order: keeps track of the order in which each cell was -// visited as we built the maze. 0 means not explored yet. Indexed in [column][row] order. -// (This is W in the original BASIC program.) -order = list.init2d(h,v, 0) - -// walls: keeps track of the walls below and to the right of each cell: -// 0: walls below and to the right -// 1: wall to the right -// 2: wall below -// 3: neither wall -// (This is V in the original BASIC program.) -// Note that a wall to the right can be removed from a -// valid entry by adding 2; a wall below can be removed -// by adding 1. -walls = list.init2d(h,v, 0) -print -print -print -print - -// pick an exit at the top of the maze, -// and print the maze top -x = floor(rnd * h) -for i in range(0, h-1) - if i == x then print ". ","" else print ".--","" -end for -print "." - -// walk from our starting position (by the exit) around -// the maze, clearing a wall on each step -c = 1 // current step number -order[x][0] = c; c += 1 -r = x; s = 0 // [r][s] is our current position in the maze -while true - // collect the set of directions we can move in - dirs = [] - if r > 0 and order[r-1][s] == 0 then dirs.push "left" - if s > 0 and order[r][s-1] == 0 then dirs.push "up" - if r+1 < h and order[r+1][s] == 0 then dirs.push "right" - if s+1 < v and order[r][s+1] == 0 then dirs.push "down" - if not dirs then - //print "Uh-oh, I'm stuck at " + r + "," + s - // couldn't find any directions for this cell; - // find the next already-explored cell - while true - r += 1 - if r >= h then - r = 0 - s += 1 - if s >= v then s = 0 - end if - if order[r][s] != 0 then break - end while - continue - end if - - // pick a random available direction; move there, - // clearing the wall in between and updating order - d = dirs.any - if d == "left" then - walls[r-1][s] += 2 - r = r-1 - else if d == "up" then - walls[r][s-1] += 1 - s = s-1 - else if d == "right" then - walls[r][s] += 2 - r = r+1 - else if d == "down" then - walls[r][s] += 1 - s = s+1 - end if - - //print "At step " + c + ", at " + r + "," + s - order[r][s] = c - c += 1 - if c > h*v then break -end while - -// pick an exit at the bottom of the maze -x = floor(rnd * h) -walls[x][v-1] += 1 - -// print the (rest of the) maze -for j in range(0, v-1) - print "I", "" - for i in range(0, h-1) - if walls[i][j] < 2 then print " I", "" else print " ", "" - end for - print - for i in range(0, h-1) - if walls[i][j] % 2 == 0 then print ":--", "" else print ": ", "" - end for - print "." -end for diff --git a/00_Alternate_Languages/02_Amazing/README.md b/00_Alternate_Languages/02_Amazing/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/02_Amazing/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/02_Amazing/amazing.bas b/00_Alternate_Languages/02_Amazing/amazing.bas deleted file mode 100644 index 3b39c93af..000000000 --- a/00_Alternate_Languages/02_Amazing/amazing.bas +++ /dev/null @@ -1,143 +0,0 @@ -10 PRINT TAB(28);"AMAZING PROGRAM" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT:PRINT:PRINT:PRINT -100 INPUT "WHAT ARE YOUR WIDTH AND LENGTH";H,V -102 IF H<>1 AND V<>1 THEN 110 -104 PRINT "MEANINGLESS DIMENSIONS. TRY AGAIN.":GOTO 100 -110 DIM W(H,V),V(H,V) -120 PRINT -130 PRINT -140 PRINT -150 PRINT -160 Q=0:Z=0:X=INT(RND(1)*H+1) -165 FOR I=1 TO H -170 IF I=X THEN 173 -171 PRINT ".--";:GOTO 180 -173 PRINT ". "; -180 NEXT I -190 PRINT "." -195 C=1:W(X,1)=C:C=C+1 -200 R=X:S=1:GOTO 260 -210 IF R<>H THEN 240 -215 IF S<>V THEN 230 -220 R=1:S=1:GOTO 250 -230 R=1:S=S+1:GOTO 250 -240 R=R+1 -250 IF W(R,S)=0 THEN 210 -260 IF R-1=0 THEN 530 -265 IF W(R-1,S)<>0 THEN 530 -270 IF S-1=0 THEN 390 -280 IF W(R,S-1)<>0 THEN 390 -290 IF R=H THEN 330 -300 IF W(R+1,S)<>0 THEN 330 -310 X=INT(RND(1)*3+1) -320 ON X GOTO 790,820,860 -330 IF S<>V THEN 340 -334 IF Z=1 THEN 370 -338 Q=1:GOTO 350 -340 IF W(R,S+1)<>0 THEN 370 -350 X=INT(RND(1)*3+1) -360 ON X GOTO 790,820,910 -370 X=INT(RND(1)*2+1) -380 ON X GOTO 790,820 -390 IF R=H THEN 470 -400 IF W(R+1,S)<>0 THEN 470 -405 IF S<>V THEN 420 -410 IF Z=1 THEN 450 -415 Q=1:GOTO 430 -420 IF W(R,S+1)<>0 THEN 450 -430 X=INT(RND(1)*3+1) -440 ON X GOTO 790,860,910 -450 X=INT(RND(1)*2+1) -460 ON X GOTO 790,860 -470 IF S<>V THEN 490 -480 IF Z=1 THEN 520 -485 Q=1:GOTO 500 -490 IF W(R,S+1)<>0 THEN 520 -500 X=INT(RND(1)*2+1) -510 ON X GOTO 790,910 -520 GOTO 790 -530 IF S-1=0 THEN 670 -540 IF W(R,S-1)<>0 THEN 670 -545 IF R=H THEN 610 -547 IF W(R+1,S)<>0 THEN 610 -550 IF S<>V THEN 560 -552 IF Z=1 THEN 590 -554 Q=1:GOTO 570 -560 IF W(R,S+1)<>0 THEN 590 -570 X=INT(RND(1)*3+1) -580 ON X GOTO 820,860,910 -590 X=INT(RND(1)*2+1) -600 ON X GOTO 820,860 -610 IF S<>V THEN 630 -620 IF Z=1 THEN 660 -625 Q=1:GOTO 640 -630 IF W(R,S+1)<>0 THEN 660 -640 X=INT(RND(1)*2+1) -650 ON X GOTO 820,910 -660 GOTO 820 -670 IF R=H THEN 740 -680 IF W(R+1,S)<>0 THEN 740 -685 IF S<>V THEN 700 -690 IF Z=1 THEN 730 -695 Q=1:GOTO 710 -700 IF W(R,S+1)<>0 THEN 730 -710 X=INT(RND(1)*2+1) -720 ON X GOTO 860,910 -730 GOTO 860 -740 IF S<>V THEN 760 -750 IF Z=1 THEN 780 -755 Q=1:GOTO 770 -760 IF W(R,S+1)<>0 THEN 780 -770 GOTO 910 -780 GOTO 1000 -790 W(R-1,S)=C -800 C=C+1:V(R-1,S)=2:R=R-1 -810 IF C=H*V+1 THEN 1010 -815 Q=0:GOTO 260 -820 W(R,S-1)=C -830 C=C+1 -840 V(R,S-1)=1:S=S-1:IF C=H*V+1 THEN 1010 -850 Q=0:GOTO 260 -860 W(R+1,S)=C -870 C=C+1:IF V(R,S)=0 THEN 880 -875 V(R,S)=3:GOTO 890 -880 V(R,S)=2 -890 R=R+1 -900 IF C=H*V+1 THEN 1010 -905 GOTO 530 -910 IF Q=1 THEN 960 -920 W(R,S+1)=C:C=C+1:IF V(R,S)=0 THEN 940 -930 V(R,S)=3:GOTO 950 -940 V(R,S)=1 -950 S=S+1:IF C=H*V+1 THEN 1010 -955 GOTO 260 -960 Z=1 -970 IF V(R,S)=0 THEN 980 -975 V(R,S)=3:Q=0:GOTO 1000 -980 V(R,S)=1:Q=0:R=1:S=1:GOTO 250 -1000 GOTO 210 -1010 IF Z=1 THEN 1015 -1011 X=INT(RND(1)*H+1) -1012 IF V(X,V)=0 THEN 1014 -1013 V(X,V)=3: GOTO 1015 -1014 V(X,V)=1 -1015 FOR J=1 TO V -1016 PRINT "I"; -1017 FOR I=1 TO H -1018 IF V(I,J)<2 THEN 1030 -1020 PRINT " "; -1021 GOTO 1040 -1030 PRINT " I"; -1040 NEXT I -1041 PRINT -1043 FOR I=1 TO H -1045 IF V(I,J)=0 THEN 1060 -1050 IF V(I,J)=2 THEN 1060 -1051 PRINT ": "; -1052 GOTO 1070 -1060 PRINT ":--"; -1070 NEXT I -1071 PRINT "." -1072 NEXT J -1073 END diff --git a/00_Alternate_Languages/02_Amazing/go/main.go b/00_Alternate_Languages/02_Amazing/go/main.go deleted file mode 100644 index 11b027ef1..000000000 --- a/00_Alternate_Languages/02_Amazing/go/main.go +++ /dev/null @@ -1,217 +0,0 @@ -package main - -import ( - "bufio" - "fmt" - "log" - "math/rand" - "os" - "strconv" - "time" -) - -func main() { - rand.Seed(time.Now().UnixNano()) - - printWelcome() - - h, w := getDimensions() - m := NewMaze(h, w) - m.draw() -} - -type direction int64 - -const ( - LEFT direction = iota - UP - RIGHT - DOWN -) - -const ( - EXIT_DOWN = 1 - EXIT_RIGHT = 2 -) - -type maze struct { - width int - length int - used [][]int - walls [][]int - enterCol int -} - -func NewMaze(w, l int) maze { - if (w < 2) || (l < 2) { - log.Fatal("invalid dimensions supplied") - } - - m := maze{width: w, length: l} - - m.used = make([][]int, l) - for i := range m.used { - m.used[i] = make([]int, w) - } - - m.walls = make([][]int, l) - for i := range m.walls { - m.walls[i] = make([]int, w) - } - - // randomly determine the entry column - m.enterCol = rand.Intn(w) - - // determine layout of walls - m.build() - - // add an exit - col := rand.Intn(m.width - 1) - row := m.length - 1 - m.walls[row][col] = m.walls[row][col] + 1 - - return m -} - -func (m *maze) build() { - row := 0 - col := 0 - count := 2 - - for { - possibleDirs := m.getPossibleDirections(row, col) - - if len(possibleDirs) != 0 { - row, col, count = m.makeOpening(possibleDirs, row, col, count) - } else { - for { - if col != m.width-1 { - col = col + 1 - } else if row != m.length-1 { - row = row + 1 - col = 0 - } else { - row = 0 - col = 0 - } - - if m.used[row][col] != 0 { - break - } - } - } - - if count == (m.width*m.length)+1 { - break - } - } - -} - -func (m *maze) getPossibleDirections(row, col int) []direction { - possible_dirs := make(map[direction]bool, 4) - possible_dirs[LEFT] = true - possible_dirs[UP] = true - possible_dirs[RIGHT] = true - possible_dirs[DOWN] = true - - if (col == 0) || (m.used[row][col-1] != 0) { - possible_dirs[LEFT] = false - } - if (row == 0) || (m.used[row-1][col] != 0) { - possible_dirs[UP] = false - } - if (col == m.width-1) || (m.used[row][col+1] != 0) { - possible_dirs[RIGHT] = false - } - if (row == m.length-1) || (m.used[row+1][col] != 0) { - possible_dirs[DOWN] = false - } - - ret := make([]direction, 0) - for d, v := range possible_dirs { - if v { - ret = append(ret, d) - } - } - return ret -} - -func (m *maze) makeOpening(dirs []direction, row, col, count int) (int, int, int) { - dir := rand.Intn(len(dirs)) - - if dirs[dir] == LEFT { - col = col - 1 - m.walls[row][col] = int(EXIT_RIGHT) - } else if dirs[dir] == UP { - row = row - 1 - m.walls[row][col] = int(EXIT_DOWN) - } else if dirs[dir] == RIGHT { - m.walls[row][col] = m.walls[row][col] + EXIT_RIGHT - col = col + 1 - } else if dirs[dir] == DOWN { - m.walls[row][col] = m.walls[row][col] + EXIT_DOWN - row = row + 1 - } - - m.used[row][col] = count - count = count + 1 - return row, col, count -} - -// draw the maze -func (m *maze) draw() { - for col := 0; col < m.width; col++ { - if col == m.enterCol { - fmt.Print(". ") - } else { - fmt.Print(".--") - } - } - fmt.Println(".") - - for row := 0; row < m.length; row++ { - fmt.Print("|") - for col := 0; col < m.width; col++ { - if m.walls[row][col] < 2 { - fmt.Print(" |") - } else { - fmt.Print(" ") - } - } - fmt.Println() - for col := 0; col < m.width; col++ { - if (m.walls[row][col] == 0) || (m.walls[row][col] == 2) { - fmt.Print(":--") - } else { - fmt.Print(": ") - } - } - fmt.Println(".") - } -} - -func printWelcome() { - fmt.Println(" AMAZING PROGRAM") - fmt.Print(" CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n\n\n") -} - -func getDimensions() (int, int) { - scanner := bufio.NewScanner(os.Stdin) - - fmt.Println("Enter a width ( > 1 ):") - scanner.Scan() - w, err := strconv.Atoi(scanner.Text()) - if err != nil { - log.Fatal("invalid dimension") - } - - fmt.Println("Enter a height ( > 1 ):") - scanner.Scan() - h, err := strconv.Atoi(scanner.Text()) - if err != nil { - log.Fatal("invalid dimension") - } - - return w, h -} diff --git a/00_Alternate_Languages/02_Amazing/pascal/object-pascal/amazing.pas b/00_Alternate_Languages/02_Amazing/pascal/object-pascal/amazing.pas deleted file mode 100644 index 1833076c6..000000000 --- a/00_Alternate_Languages/02_Amazing/pascal/object-pascal/amazing.pas +++ /dev/null @@ -1,16 +0,0 @@ -program amazing; - -{$IFDEF FPC} -{$mode ObjFPC}{$H+} -{$ENDIF} - -uses - AmazingApplication, maze, Room; - -var - AmazingApp: TAmazingApplication; - -begin - AmazingApp:= TAmazingApplication.Create; - AmazingApp.Run; -end. diff --git a/00_Alternate_Languages/02_Amazing/pascal/simple/amazing.pas b/00_Alternate_Languages/02_Amazing/pascal/simple/amazing.pas deleted file mode 100644 index 285fafa1e..000000000 --- a/00_Alternate_Languages/02_Amazing/pascal/simple/amazing.pas +++ /dev/null @@ -1,283 +0,0 @@ -program Amazing; - -{$IFDEF FPC} -{$mode objfpc}{$H+} -{$ENDIF} - -uses - Crt; - -type - TDirection = (dUp, dRight, dDown, dLeft); - TDirections = set of TDirection; - -var - Width: Integer; // H - Length: Integer; // V - Entry: Integer; - MatrixWalls: Array of Array of Integer; - MatrixVisited: Array of Array of Integer; - -const - EXIT_DOWN = 1; - EXIT_RIGHT = 2; - -procedure PrintGreeting; -begin - WriteLN(' ':28, 'AMAZING PROGRAM'); - WriteLN(' ':15, 'CREATIVE COMPUTING MORRISTOWN, NEW JERSEY'); - WriteLN; - WriteLN; - WriteLN; - WriteLN; -end; - -procedure GetDimensions; -begin - repeat - Write('WHAT ARE YOUR WIDTH AND LENGTH (SPACE IN BETWEEN): '); - ReadLN(Width, Length); - if (Width = 1) or (Length = 1) then - begin - WriteLN('MEANINGLESS DIMENSIONS. TRY AGAIN.'); - end; - until (Width > 1) and (Length > 1); - WriteLN; - WriteLN; - WriteLN; - WriteLN; -end; - -procedure ClearMatrices; -var - indexW: Integer; - indexL: Integer; -begin - SetLength(MatrixWalls, Width, Length); - SetLength(MatrixVisited, Width, Length); - for indexW:= 0 to Pred(Width) do - begin - for indexL:= 0 to Pred(Length) do - begin - MatrixWalls[indexW][indexL]:= 0; - MatrixVisited[indexW][indexL]:= 0; - end; - end; -end; - -function GetRandomDirection(const ADirections: TDirections): TDirection; -var - count: Integer; - position: Integer; - directions: array [0..3] of TDirection; -begin - count:= 0; - position:= 0; - if dUp in ADirections then - begin - Inc(count); - directions[position]:= dUp; - Inc(position); - end; - if dRight in ADirections then - begin - Inc(count); - directions[position]:= dRight; - Inc(position); - end; - if dDown in ADirections then - begin - Inc(count); - directions[position]:= dDown; - Inc(position); - end; - if dLeft in ADirections then - begin - Inc(count); - directions[position]:= dLeft; - Inc(position); - end; - Result:= directions[Random(count)]; -end; - -procedure BuildMaze; -var - indexW: Integer; - indexL: Integer; - direction: TDirection; - directions: TDirections; - count: Integer; -begin - Entry:= Random(Width); - indexW:= Entry; - indexL:= 0; - count:= 1; - MatrixVisited[indexW][indexL]:= count; - Inc(count); - repeat - directions:= [dUp, dRight, dDown, dLeft]; - if (indexW = 0) or (MatrixVisited[Pred(indexW)][indexL] <> 0) then - begin - Exclude(directions, dLeft); - end; - if (indexL = 0) or (MatrixVisited[indexW][Pred(indexL)] <> 0) then - begin - Exclude(directions, dUp); - end; - if (indexW = Pred(Width)) or (MatrixVisited[Succ(indexW)][indexL] <> 0) then - begin - Exclude(directions, dRight); - end; - if (indexL = Pred(Length)) or (MatrixVisited[indexW][Succ(indexL)] <> 0) then - begin - Exclude(directions, dDown); - end; - - if directions <> [] then - begin - direction:= GetRandomDirection(directions); - case direction of - dLeft:begin - Dec(indexW); - MatrixWalls[indexW][indexL]:= EXIT_RIGHT; - end; - dUp:begin - Dec(indexL); - MatrixWalls[indexW][indexL]:= EXIT_DOWN; - end; - dRight:begin - Inc(MatrixWalls[indexW][indexL], EXIT_RIGHT); - Inc(indexW); - end; - dDown:begin - Inc(MatrixWalls[indexW][indexL], EXIT_DOWN); - Inc(indexL); - end; - end; - MatrixVisited[indexW][indexL]:= count; - Inc(count); - end - else - begin - while True do - begin - if indexW <> Pred(Width) then - begin - Inc(indexW); - end - else if indexL <> Pred(Length) then - begin - Inc(indexL); - indexW:= 0; - end - else - begin - indexW:= 0; - indexL:= 0; - end; - if MatrixVisited[indexW][indexL] <> 0 then - begin - break; - end; - end; - end; - until count = (Width * Length) + 1; - indexW:= Random(Width); - indexL:= Pred(Length); - Inc(MatrixWalls[indexW][indexL]); -end; - -procedure DegubVisited; -var - indexW: Integer; - indexL: Integer; -begin - WriteLN('Visited'); - for indexL:= 0 to Pred(Length) do - begin - for indexW:= 0 to Pred(Width) do - begin - Write(MatrixVisited[indexW][indexL]:2,' '); - end; - WriteLN; - end; - WriteLN; -end; - -procedure DebugWalls; -var - indexW: Integer; - indexL: Integer; -begin - WriteLN('Walls'); - for indexL:= 0 to Pred(Length) do - begin - for indexW:= 0 to Pred(Width) do - begin - Write(MatrixWalls[indexW, indexL]:2, ' '); - end; - WriteLN; - end; - WriteLN; -end; - -procedure PrintMaze; -var - indexW: Integer; - indexL: Integer; -begin - - for indexW:= 0 to Pred(Width) do - begin - if indexW = Entry then - begin - Write('. '); - end - else - begin - Write('.--'); - end; - end; - WriteLN('.'); - for indexL:= 0 to Pred(Length) do - begin - Write('I'); - for indexW:= 0 to Pred(Width) do - begin - if MatrixWalls[indexW, indexL] < 2 then - begin - Write(' I'); - end - else - begin - Write(' '); - end; - end; - WriteLN; - for indexW:= 0 to Pred(Width) do - begin - if (MatrixWalls[indexW, indexL] = 0) or (MatrixWalls[indexW, indexL] = 2) then - begin - Write(':--'); - end - else - begin - Write(': '); - end; - end; - WriteLN('.'); - end; - WriteLN; -end; - -begin - Randomize; - ClrScr; - PrintGreeting; - GetDimensions; - ClearMatrices; - BuildMaze; - //DegubVisited; - //DebugWalls; - PrintMaze; -end. diff --git a/00_Alternate_Languages/03_Animal/MiniScript/README.md b/00_Alternate_Languages/03_Animal/MiniScript/README.md deleted file mode 100644 index 1e48ea49c..000000000 --- a/00_Alternate_Languages/03_Animal/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript animal.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "animal" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/03_Animal/MiniScript/animal.ms b/00_Alternate_Languages/03_Animal/MiniScript/animal.ms deleted file mode 100644 index 5aafdddb4..000000000 --- a/00_Alternate_Languages/03_Animal/MiniScript/animal.ms +++ /dev/null @@ -1,90 +0,0 @@ -print " "*32 + "Animal" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print -print "Play 'Guess the Animal'" -print -print "Think of an animal and the computer will try to guess it." -print - -// Ask a yes/no question, and return "Y" or "N". -getYesNo = function(prompt) - while true - inp = input(prompt + "? ").upper - if inp and (inp[0] == "Y" or inp[0] == "N") then return inp[0] - print "Please answer Yes or No." - end while -end function - -// Our data is stored as a list of little maps. -// Answers have only an "answer" key. -// Questions have a "question" key, plus "ifYes" and "ifNo" -// keys which map to the index of the next question or answer. -data = [ - {"question":"Does it swim", "ifYes":1, "ifNo":2}, - {"answer":"fish"}, - {"answer":"bird"}] - -// List all known animals. -listKnown = function - print; print "Animals I already know are:" - for item in data - if item.hasIndex("answer") then print (item.answer + " "*17)[:17], "" - end for - print; print -end function - -// Ask the question at curIndex, and handle the user's response. -doQuestion = function - q = data[curIndex] - if getYesNo(q.question) == "Y" then - globals.curIndex = q.ifYes - else - globals.curIndex = q.ifNo - end if -end function - -// Check the answer at curIndex. If incorrect, get a new question -// to put at that point in our data. -checkAnswer = function - node = data[curIndex] - inp = getYesNo("Is it a " + node.answer) - if inp == "Y" then - print "Why not try another animal?" - else - actual = input("The animal you were thinking of was a? ").lower - print "Please type in a question that would distinguish a" - print actual + " from a " + node.answer - q = {} - q.question = input - q.question = q.question[0].upper + q.question[1:] - "?" - data[curIndex] = q - k = data.len - data.push node // old answer at index k - data.push {"answer":actual} // new answer at index k+1 - if getYesNo("For a " + actual + " the answer would be") == "Y" then - data[curIndex].ifYes = k+1 - data[curIndex].ifNo = k - else - data[curIndex].ifNo = k+1 - data[curIndex].ifYes = k - end if - end if -end function - -// Main loop. (Press Control-C to break.) -while true - while true - inp = input("Are you thinking of an animal? ").upper - if inp == "LIST" then listKnown - if inp and inp[0] == "Y" then break - end while - curIndex = 0 - while true - if data[curIndex].hasIndex("question") then - doQuestion - else - checkAnswer - break - end if - end while -end while diff --git a/00_Alternate_Languages/03_Animal/README.md b/00_Alternate_Languages/03_Animal/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/03_Animal/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/03_Animal/animal.bas b/00_Alternate_Languages/03_Animal/animal.bas deleted file mode 100644 index 271eb0d0c..000000000 --- a/00_Alternate_Languages/03_Animal/animal.bas +++ /dev/null @@ -1,71 +0,0 @@ -10 PRINT TAB(32);"ANIMAL" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT: PRINT: PRINT -40 PRINT "PLAY 'GUESS THE ANIMAL'" -45 PRINT -50 PRINT "THINK OF AN ANIMAL AND THE COMPUTER WILL TRY TO GUESS IT." -60 PRINT -70 DIM A$(200) -80 FOR I=0 TO 3 -90 READ A$(I) -100 NEXT I -110 N=VAL(A$(0)) -120 REM MAIN CONTROL SECTION -130 INPUT "ARE YOU THINKING OF AN ANIMAL";A$ -140 IF A$="LIST" THEN 600 -150 IF LEFT$(A$,1)<>"Y" THEN 120 -160 K=1 -170 GOSUB 390 -180 IF LEN(A$(K))=0 THEN 999 -190 IF LEFT$(A$(K),2)="\Q" THEN 170 -200 PRINT "IS IT A ";RIGHT$(A$(K),LEN(A$(K))-2); -210 INPUT A$ -220 A$=LEFT$(A$,1) -230 IF LEFT$(A$,1)="Y" THEN PRINT "WHY NOT TRY ANOTHER ANIMAL?": GOTO 120 -240 INPUT "THE ANIMAL YOU WERE THINKING OF WAS A ";V$ -250 PRINT "PLEASE TYPE IN A QUESTION THAT WOULD DISTINGUISH A" -260 PRINT V$;" FROM A ";RIGHT$(A$(K),LEN(A$(K))-2) -270 INPUT X$ -280 PRINT "FOR A ";V$;" THE ANSWER WOULD BE "; -290 INPUT A$ -300 A$=LEFT$(A$,1): IF A$<>"Y" AND A$<>"N" THEN 280 -310 IF A$="Y" THEN B$="N" -320 IF A$="N" THEN B$="Y" -330 Z1=VAL(A$(0)) -340 A$(0)=STR$(Z1+2) -350 A$(Z1)=A$(K) -360 A$(Z1+1)="\A"+V$ -370 A$(K)="\Q"+X$+"\"+A$+STR$(Z1+1)+"\"+B$+STR$(Z1)+"\" -380 GOTO 120 -390 REM SUBROUTINE TO PRINT QUESTIONS -400 Q$=A$(K) -410 FOR Z=3 TO LEN(Q$) -415 IF MID$(Q$,Z,1)<>"\" THEN PRINT MID$(Q$,Z,1);: NEXT Z -420 INPUT C$ -430 C$=LEFT$(C$,1) -440 IF C$<>"Y" AND C$<>"N" THEN 410 -450 T$="\"+C$ -455 FOR X=3 TO LEN(Q$)-1 -460 IF MID$(Q$,X,2)=T$ THEN 480 -470 NEXT X -475 STOP -480 FOR Y=X+1 TO LEN(Q$) -490 IF MID$(Q$,Y,1)="\" THEN 510 -500 NEXT Y -505 STOP -510 K=VAL(MID$(Q$,X+2,Y-X-2)) -520 RETURN -530 DATA "4","\QDOES IT SWIM\Y2\N3\","\AFISH","\ABIRD" -600 PRINT:PRINT "ANIMALS I ALREADY KNOW ARE:" -605 X=0 -610 FOR I=1 TO 200 -620 IF LEFT$(A$(I),2)<>"\A" THEN 650 -624 PRINT TAB(15*X); -630 FOR Z=3 TO LEN(A$(I)) -640 IF MID$(A$(I),Z,1)<>"\" THEN PRINT MID$(A$(I),Z,1);: NEXT Z -645 X=X+1: IF X=4 THEN X=0: PRINT -650 NEXT I -660 PRINT -670 PRINT -680 GOTO 120 -999 END diff --git a/00_Alternate_Languages/03_Animal/go/main.go b/00_Alternate_Languages/03_Animal/go/main.go deleted file mode 100644 index 2eb0904eb..000000000 --- a/00_Alternate_Languages/03_Animal/go/main.go +++ /dev/null @@ -1,159 +0,0 @@ -package main - -import ( - "bufio" - "fmt" - "log" - "os" - "strings" -) - -type node struct { - text string - yesNode *node - noNode *node -} - -func newNode(text string, yes_node, no_node *node) *node { - n := node{text: text} - if yes_node != nil { - n.yesNode = yes_node - } - if no_node != nil { - n.noNode = no_node - } - return &n -} - -func (n *node) update(newQuestion, newAnswer, newAnimal string) { - oldAnimal := n.text - - n.text = newQuestion - - if newAnswer == "y" { - n.yesNode = newNode(newAnimal, nil, nil) - n.noNode = newNode(oldAnimal, nil, nil) - } else { - n.yesNode = newNode(oldAnimal, nil, nil) - n.noNode = newNode(newAnimal, nil, nil) - } -} - -func (n *node) isLeaf() bool { - return (n.yesNode == nil) && (n.noNode == nil) -} - -func listKnownAnimals(root *node) { - if root == nil { - return - } - - if root.isLeaf() { - fmt.Printf("%s ", root.text) - return - } - - if root.yesNode != nil { - listKnownAnimals(root.yesNode) - } - - if root.noNode != nil { - listKnownAnimals(root.noNode) - } -} - -func parseInput(message string, checkList bool, rootNode *node) string { - scanner := bufio.NewScanner(os.Stdin) - token := "" - - for { - fmt.Println(message) - scanner.Scan() - inp := strings.ToLower(scanner.Text()) - - if checkList && inp == "list" { - fmt.Println("Animals I already know are:") - listKnownAnimals(rootNode) - fmt.Println() - } - - if len(inp) > 0 { - token = inp - } else { - token = "" - } - - if token == "y" || token == "n" { - break - } - } - return token -} - -func avoidVoidInput(message string) string { - scanner := bufio.NewScanner(os.Stdin) - answer := "" - for { - fmt.Println(message) - scanner.Scan() - answer = scanner.Text() - - if answer != "" { - break - } - } - return answer -} - -func printIntro() { - fmt.Println(" Animal") - fmt.Println(" Creative Computing Morristown, New Jersey") - fmt.Println("\nPlay 'Guess the Animal'") - fmt.Println("Think of an animal and the computer will try to guess it") -} - -func main() { - yesChild := newNode("Fish", nil, nil) - noChild := newNode("Bird", nil, nil) - rootNode := newNode("Does it swim?", yesChild, noChild) - - printIntro() - - keepPlaying := (parseInput("Are you thinking of an animal?", true, rootNode) == "y") - - for keepPlaying { - keepAsking := true - - actualNode := rootNode - - for keepAsking { - if !actualNode.isLeaf() { - answer := parseInput(actualNode.text, false, nil) - - if answer == "y" { - if actualNode.yesNode == nil { - log.Fatal("invalid node") - } - actualNode = actualNode.yesNode - } else { - if actualNode.noNode == nil { - log.Fatal("invalid node") - } - actualNode = actualNode.noNode - } - } else { - answer := parseInput(fmt.Sprintf("Is it a %s?", actualNode.text), false, nil) - if answer == "n" { - newAnimal := avoidVoidInput("The animal you were thinking of was a ?") - newQuestion := avoidVoidInput(fmt.Sprintf("Please type in a question that would distinguish a '%s' from a '%s':", newAnimal, actualNode.text)) - newAnswer := parseInput(fmt.Sprintf("For a '%s' the answer would be", newAnimal), false, nil) - actualNode.update(newQuestion+"?", newAnswer, newAnimal) - } else { - fmt.Println("Why not try another animal?") - } - keepAsking = false - } - } - keepPlaying = (parseInput("Are you thinking of an animal?", true, rootNode) == "y") - } -} diff --git a/00_Alternate_Languages/04_Awari/MiniScript/README.md b/00_Alternate_Languages/04_Awari/MiniScript/README.md deleted file mode 100644 index f2b6dfe50..000000000 --- a/00_Alternate_Languages/04_Awari/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript awari.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "awari" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/04_Awari/MiniScript/awari.ms b/00_Alternate_Languages/04_Awari/MiniScript/awari.ms deleted file mode 100644 index e01c2d6cc..000000000 --- a/00_Alternate_Languages/04_Awari/MiniScript/awari.ms +++ /dev/null @@ -1,146 +0,0 @@ -print " "*34 + "Awari" -print " "*15 + "Creative Computing Morristown, New Jersey" - -// Keep a list of the opening moves (up to 8) of previously lost or drawn games. -// These will be used to penalize repeating the same moves again. -badGames = [] - -printQty = function(qty) - print (" " + qty)[-2:], " " -end function - -printBoard = function - print; print " ", "" - for i in range(12, 7); printQty board[i]; end for - print; printQty board[13] - print " " * 6, ""; printQty board[6] - print; print " ", "" - for i in range(0, 5); printQty board[i]; end for - print; print -end function - -// Redistribute the stones starting at position. -// If the last one ends by itself, opposite some nonzero -// stones on the other side, then capture them into homePos. -// Return true if the last stone ended at homePos, false otherwise. -moveStones = function(board, position, homePos) - p = board[position]; board[position] = 0 - while p - position = (position + 1) % 14 - board[position] += 1 - p -= 1 - end while - if board[position] == 1 and position != 6 and position != 13 and board[12-position] then - board[homePos] += board[12-position] + 1 - board[position] = 0 - board[12-position] = 0 - end if - globals.gameOver = board[0:6].sum == 0 or board[7:13].sum == 0 - return position == homePos -end function - -// Get the player move. Note that the player inputs their move as a number -// from 1-6, but we return it as an actual board position index 0-6. -getPlayerMove = function(prompt="Your move") - while true - pos = input(prompt + "? ").val - if 0 < pos < 7 and board[pos-1] then return pos - 1 - print "Illegal move." - end while -end function - -getComputerMove = function - // Copy the board for safekeeping - boardCopy = board[:] - bestScore = -99; bestMove = 0 - for j in range(7, 12) - if board[j] == 0 then continue // can't move from an empty spot - // suppose we move at position j... - moveStones board, j, 13 - // consider each possible response the player could make - bestPlayerScore = 0 - for i in range(0, 5) - if board[i] == 0 then continue - landPos = board[i] + i // figure the landing position - score = floor(landPos / 14); landPos %= 14 - if board[landPos] == 0 and landPos != 6 and landPos != 13 then - score += board[12 - landPos] // points for capturing stones - end if - if score > bestPlayerScore then bestPlayerScore = score - end for - // figure our own score as our points, minus player points, minus best player score - ourScore = board[13] - board[6] - bestPlayerScore - if gameMoves.len < 8 then - // subtract 2 points if current series of moves is in our bad-games list - proposed = gameMoves + [j] - for badGame in badGames - if badGame[:proposed.len] == proposed then ourScore -= 2 - end for - end if - if ourScore > bestScore then - bestScore = ourScore - bestMove = j - end if - // restore the board - globals.board = boardCopy[:] - end for - print char(42+bestMove) // (labels computer spots as 1-6 from right to left) - return bestMove -end function - -// The game is over when either side has 0 stones left. -isGameOver = function - return board[0:6].sum == 0 or board[7:13].sum == 0 -end function - -// Play one game to completion. -playOneGame = function - // The board is represented as a list of 13 numbers. - // Position 6 is the player's home; 13 is the computer's home. - globals.board = [3]*14; board[13] = 0; board[6] = 0 - // Also keep a list of the moves in the current game - globals.gameMoves = [] - print; print - while true - // Player's turn - printBoard - pos = getPlayerMove - gameMoves.push pos - if moveStones(board, pos, 6) then - if gameOver then break - printBoard - pos = getPlayerMove("Again") - gameMoves.push pos - moveStones board, pos, 6 - end if - if gameOver then break - // Computer's turn - printBoard; print "My move is ", "" - pos = getComputerMove - gameMoves.push pos - if moveStones(board, pos, 13) then - if gameOver then break - printBoard; print "...followed by ", "" - pos = getComputerMove - gameMoves.push pos - moveStones board, pos, 13 - end if - if gameOver then break - end while - printBoard - print; print "GAME OVER" - delta = board[6] - board[13] - if delta < 0 then - print "I win by " + (-delta) + " points" - return - end if - if delta == 0 then print "Drawn game" else print "You win by " + delta + " points" - if gameMoves.len > 8 then gameMoves = gameMoves[:8] - if badGames.indexOf(gameMoves) == null then badGames.push gameMoves -end function - -// Main loop -while true - playOneGame - print; print -end while diff --git a/00_Alternate_Languages/04_Awari/README.md b/00_Alternate_Languages/04_Awari/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/04_Awari/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/04_Awari/awari.bas b/00_Alternate_Languages/04_Awari/awari.bas deleted file mode 100644 index 78c204e35..000000000 --- a/00_Alternate_Languages/04_Awari/awari.bas +++ /dev/null @@ -1,70 +0,0 @@ -5 PRINT TAB(34);"AWARI" -7 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -10 DATA 0 -15 DIM B(13),G(13),F(50):READ N -20 PRINT:PRINT:E=0 -25 FOR I=0 TO 12:B(I)=3:NEXT I -30 C=0:F(N)=0:B(13)=0:B(6)=0 -35 GOSUB 500 -40 PRINT "YOUR MOVE";:GOSUB 110 -45 IF E=0 THEN 80 -50 IF M=H THEN GOSUB 100 -55 IF E=0 THEN 80 -60 PRINT "MY MOVE IS ";:GOSUB 800 -65 IF E=0 THEN 80 -70 IF M=H THEN PRINT ",";:GOSUB 800 -75 IF E>0 THEN 35 -80 PRINT:PRINT"GAME OVER" -85 D=B(6)-B(13):IF D<0 THEN PRINT "I WIN BY";-D;"POINTS":GOTO 20 -90 N=N+1:IF D=0 THEN PRINT "DRAWN GAME":GOTO 20 -95 PRINT "YOU WIN BY";D;"POINTS":GOTO 20 -100 PRINT "AGAIN"; -110 INPUT M:IF M<7 THEN IF M>0 THEN M=M-1:GOTO 130 -120 PRINT "ILLEGAL MOVE":GOTO 100 -130 IF B(M)=0 THEN 120 -140 H=6:GOSUB 200 -150 GOTO 500 -200 K=M:GOSUB 600 -205 E=0:IF K>6 THEN K=K-7 -210 C=C+1:IF C<9 THEN F(N)=F(N)*6+K -215 FOR I=0 TO 5:IF B(I)<>0 THEN 230 -220 NEXT I -225 RETURN -230 FOR I=7 TO 12:IF B(I)<>0 THEN E=1:RETURN -235 GOTO 220 -500 PRINT:PRINT" "; -505 FOR I=12 TO 7 STEP -1:GOSUB 580 -510 NEXT I -515 PRINT:I=13:GOSUB 580 -520 PRINT " ";:PRINT B(6):PRINT " "; -525 FOR I=0 TO 5:GOSUB 580 -530 NEXT I -535 PRINT:PRINT:RETURN -580 IF B(I)<10 THEN PRINT " "; -585 PRINT B(I);:RETURN -600 P=B(M):B(M)=0 -605 FOR P=P TO 1 STEP -1:M=M+1:IF M>13 THEN M=M-14 -610 B(M)=B(M)+1:NEXT P -615 IF B(M)=1 THEN IF M<>6 THEN IF M<>13 THEN IF B(12-M)<>0 THEN 625 -620 RETURN -625 B(H)=B(H)+B(12-M)+1:B(M)=0:B(12-M)=0:RETURN -800 D=-99:H=13 -805 FOR I=0 TO 13:G(I)=B(I):NEXT I -810 FOR J=7 TO 12:IF B(J)=0 THEN 885 -815 Q=0:M=J:GOSUB 600 -820 FOR I=0 TO 5:IF B(I)=0 THEN 845 -825 L=B(I)+I:R=0 -830 IF L>13 THEN L=L-14:R=1:GOTO 830 -835 IF B(L)=0 THEN IF L<>6 THEN IF L<>13 THEN R=B(12-L)+R -840 IF R>Q THEN Q=R -845 NEXT I -850 Q=B(13)-B(6)-Q:IF C>8 THEN 875 -855 K=J:IF K>6 THEN K=K-7 -860 FOR I=0 TO N-1:IF F(N)*6+K=INT(F(I)/6^(7-C)+.1) THEN Q=Q-2 -870 NEXT I -875 FOR I=0 TO 13:B(I)=G(I):NEXT I -880 IF Q>=D THEN A=J:D=Q -885 NEXT J -890 M=A:PRINT CHR$(42+M);:GOTO 200 -900 FOR I=0 TO N-1:PRINT B(I):NEXT I -999 END diff --git a/00_Alternate_Languages/04_Awari/elm/.gitignore b/00_Alternate_Languages/04_Awari/elm/.gitignore deleted file mode 100644 index c9488866a..000000000 --- a/00_Alternate_Languages/04_Awari/elm/.gitignore +++ /dev/null @@ -1,208 +0,0 @@ - -# Created by https://www.toptal.com/developers/gitignore/api/macos,visualstudiocode,elm -# Edit at https://www.toptal.com/developers/gitignore?templates=macos,visualstudiocode,elm - -### Elm ### -# elm-package generated files -elm-stuff -# elm-repl generated files -repl-temp-* - -### macOS ### -# General -.DS_Store -.AppleDouble -.LSOverride - -# Icon must end with two \r -Icon - - -# Thumbnails -._* - -# Files that might appear in the root of a volume -.DocumentRevisions-V100 -.fseventsd -.Spotlight-V100 -.TemporaryItems -.Trashes -.VolumeIcon.icns -.com.apple.timemachine.donotpresent - -# Directories potentially created on remote AFP share -.AppleDB -.AppleDesktop -Network Trash Folder -Temporary Items -.apdisk - -### 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 - -# End of https://www.toptal.com/developers/gitignore/api/macos,visualstudiocode,elm - -# Created by https://www.toptal.com/developers/gitignore/api/node -# Edit at https://www.toptal.com/developers/gitignore?templates=node - -### Node ### -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* -.pnpm-debug.log* - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage -*.lcov - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# Snowpack dependency directory (https://snowpack.dev/) -web_modules/ - -# TypeScript cache -*.tsbuildinfo - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Optional stylelint cache -.stylelintcache - -# Microbundle cache -.rpt2_cache/ -.rts2_cache_cjs/ -.rts2_cache_es/ -.rts2_cache_umd/ - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variable files -.env -.env.development.local -.env.test.local -.env.production.local -.env.local - -# parcel-bundler cache (https://parceljs.org/) -.cache -.parcel-cache - -# Next.js build output -.next -out - -# Nuxt.js build / generate output -.nuxt -dist - -# Gatsby files -.cache/ -# Comment in the public line in if your project uses Gatsby and not Next.js -# https://nextjs.org/blog/next-9-1#public-directory-support -# public - -# vuepress build output -.vuepress/dist - -# vuepress v2.x temp and cache directory -.temp - -# Docusaurus cache and generated files -.docusaurus - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -# TernJS port file -.tern-port - -# Stores VSCode versions used for testing VSCode extensions -.vscode-test - -# yarn v2 -.yarn/cache -.yarn/unplugged -.yarn/build-state.yml -.yarn/install-state.gz -.pnp.* - -### Node Patch ### -# Serverless Webpack directories -.webpack/ - -# Optional stylelint cache - -# SvelteKit build / generate output -.svelte-kit - -# End of https://www.toptal.com/developers/gitignore/api/node - -app.js diff --git a/00_Alternate_Languages/04_Awari/elm/README.md b/00_Alternate_Languages/04_Awari/elm/README.md deleted file mode 100644 index 356bf48dc..000000000 --- a/00_Alternate_Languages/04_Awari/elm/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# Awari - -This is an Elm implementation of the `Basic Compouter Games` Game Awari. - -## Build App - -- install elm - -```bash -yarn -yarn build -``` diff --git a/00_Alternate_Languages/04_Awari/elm/docs/index.html b/00_Alternate_Languages/04_Awari/elm/docs/index.html deleted file mode 100644 index 63fde5daf..000000000 --- a/00_Alternate_Languages/04_Awari/elm/docs/index.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - -
- - - - - \ No newline at end of file diff --git a/00_Alternate_Languages/04_Awari/elm/elm.json b/00_Alternate_Languages/04_Awari/elm/elm.json deleted file mode 100644 index dea3450db..000000000 --- a/00_Alternate_Languages/04_Awari/elm/elm.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "type": "application", - "source-directories": [ - "src" - ], - "elm-version": "0.19.1", - "dependencies": { - "direct": { - "elm/browser": "1.0.2", - "elm/core": "1.0.5", - "elm/html": "1.0.0" - }, - "indirect": { - "elm/json": "1.1.3", - "elm/time": "1.0.0", - "elm/url": "1.0.0", - "elm/virtual-dom": "1.0.2" - } - }, - "test-dependencies": { - "direct": {}, - "indirect": {} - } -} diff --git a/00_Alternate_Languages/04_Awari/elm/package.json b/00_Alternate_Languages/04_Awari/elm/package.json deleted file mode 100644 index 0954dc1cd..000000000 --- a/00_Alternate_Languages/04_Awari/elm/package.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "04_Awari", - "version": "1.0.0", - "main": "index.js", - "license": "MIT", - "scripts": { - "live": "elm-live src/Main.elm --proxy-prefix=/api --proxy-host=http://localhost:8080/api --open --start-page=resources/index.html -- --output=app.js --debug", - "build": "elm make src/Main.elm --optimize --output docs/app.js && cp -R resources/ docs/" - }, - "devDependencies": { - "elm-live": "^4.0.2" - } -} diff --git a/00_Alternate_Languages/04_Awari/elm/resources/index.html b/00_Alternate_Languages/04_Awari/elm/resources/index.html deleted file mode 100644 index 63fde5daf..000000000 --- a/00_Alternate_Languages/04_Awari/elm/resources/index.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - -
- - - - - \ No newline at end of file diff --git a/00_Alternate_Languages/04_Awari/elm/src/Main.elm b/00_Alternate_Languages/04_Awari/elm/src/Main.elm deleted file mode 100644 index 281f2747b..000000000 --- a/00_Alternate_Languages/04_Awari/elm/src/Main.elm +++ /dev/null @@ -1,424 +0,0 @@ -module Main exposing (main) - -import Array exposing (Array, repeat) -import Browser -import Html exposing (..) -import Html.Attributes exposing (style) -import Html.Events exposing (onClick) - - - --- Main - - -main : Program () Model Msg -main = - Browser.element - { init = init - , view = view - , update = update - , subscriptions = \_ -> Sub.none - } - - - --- Model - - -type alias Model = - { board : Array Int - , playerOnesTurn : Bool - , gameFinished : Bool - } - - -init : () -> ( Model, Cmd Msg ) -init _ = - ( { board = initArray 0 36 (repeat boardLength 0), playerOnesTurn = False, gameFinished = False }, Cmd.none ) - - - --- Messages - - -type Msg - = BoardClicked Int - | Reset - - - --- Update - - -update : Msg -> Model -> ( Model, Cmd Msg ) -update msg model = - case msg of - BoardClicked index -> - if indexIsOnPit index || index < rightPitIndex && model.playerOnesTurn || index > rightPitIndex && not model.playerOnesTurn then - ( model, Cmd.none ) - - else - let - lastStoneInPitIndex = - lastStonePitPosition index model.board - - boardAfterStonesSet = - changesOnBoardAfterStonesSet model.playerOnesTurn lastStoneInPitIndex (boardClicked index model.board) - - nextPlayer = - determineNextPlayer lastStoneInPitIndex model.playerOnesTurn boardAfterStonesSet - in - ( { model | board = boardAfterStonesSet, playerOnesTurn = nextPlayer, gameFinished = calculateGameFinished boardAfterStonesSet }, Cmd.none ) - - Reset -> - init () - - - --- Constants - - -boardLength : Int -boardLength = - 14 - - -leftPitIndex : Int -leftPitIndex = - 0 - - -rightPitIndex : Int -rightPitIndex = - 7 - - - --- View - - -view : Model -> Html Msg -view model = - div [ style "margin" "4rem" ] - [ h1 [] [ text "Awari" ] - , viewDescription - , getPlayerTurnText False model.playerOnesTurn - , viewBoard model - , viewWinnerIfGameFinished model - , getPlayerTurnText True model.playerOnesTurn - , div - [ style "display" "flex" - , style "justify-content" "center" - ] - [ button [ onClick Reset, style "max-width" "10rem", style "margin" "0", style "display" "inline-block" ] [ text "Restart" ] ] - ] - - -getPlayerTurnText : Bool -> Bool -> Html msg -getPlayerTurnText playerOne playerOnesTurn = - if playerOne && playerOnesTurn || not playerOnesTurn && not playerOne then - div [ style "height" "2rem", style "margin" "1rem 0", style "font-size" "1.5rem" ] - [ text - ("It's your turn Player " - ++ (if playerOnesTurn then - " 2 " - - else - " 1 " - ) - ) - ] - - else - div [ style "height" "2rem", style "margin" "1rem", style "font-size" "1.5rem" ] [] - - -viewWinnerIfGameFinished : Model -> Html msg -viewWinnerIfGameFinished model = - if not model.gameFinished then - div [] [] - - else - div [] [ text ("Winner is" ++ winnerPlayer model) ] - - -winnerPlayer : Model -> String -winnerPlayer model = - if getLeftPitValue model.board > getRightPitValue model.board then - "Player 1" - - else if getLeftPitValue model.board < getRightPitValue model.board then - "Player 2" - - else - "None" - - -viewBoard : Model -> Html Msg -viewBoard model = - let - boardGenerator = - boardCard model.playerOnesTurn - in - div boardSyle - (Array.toList <| - Array.indexedMap boardGenerator model.board - ) - - -boardSyle : List (Attribute msg) -boardSyle = - [ style "display" "flex" - , style "gap" "1rem" - , style "display" "grid" - , style "grid-template-columns" "repeat(8, 1fr)" - , style "align-items" "center" - , style "grid-template-areas" """ - 'a b c d e f g h' - 'a n m l k j i h' - """ - ] - - -boardCard : Bool -> Int -> Int -> Html Msg -boardCard playerOnesTurn index element = - div (boardCardStyle playerOnesTurn index) [ text (String.fromInt element) ] - - -boardCardStyle : Bool -> Int -> List (Attribute Msg) -boardCardStyle playerOnesTurn index = - if not playerOnesTurn && index < rightPitIndex || playerOnesTurn && index >= rightPitIndex then - [ onClick (BoardClicked index) - , style "grid-area" (areaFromIndex index) - , style "cursor" "pointer" - , style "background" "#36454F" - , style "border-radius" "6px" - , style "text-align" "center" - , style "padding" "0.5rem" - ] - - else - [ style "grid-area" (areaFromIndex index) - , style "background" "black" - , style "border-radius" "6px" - , style "text-align" "center" - , style "padding" "0.5rem" - ] - - -viewDescription : Html msg -viewDescription = - details [] - [ summary [] [ text "How the game works" ] - , p [] [ text """ - Awari is an ancient African game played with seven sticks and thirty-six stones or beans laid out as shown above. The board is divided into six compartments or pits on each side. In addition, there are two special home pits at the ends. - - A move is made by taking all the beans from any (non-empty) pit on your own side. Starting from the pit to the right of this one, these beans are ‘sown’ one in each pit working around the board anticlockwise. - - A turn consists of one or two moves. If the last bean of your move is sown in your own home you may take a second move. - - If the last bean sown in a move lands in an empty pit, provided that the opposite pit is not empty, all the beans in the opposite pit, together with the last bean sown are ‘captured’ and moved to the player’s home. - - When either side is empty, the game is finished. The player with the most beans in his home has won. - """ ] - ] - - - --- Functions - - -checkIfPlayerCanNotDoMove : Bool -> Array Int -> Bool -checkIfPlayerCanNotDoMove playerOnesTurn board = - if playerOnesTurn then - Array.foldr (+) 0 (Array.slice (rightPitIndex + 1) boardLength board) == 0 - - else - Array.foldr (+) 0 (Array.slice (leftPitIndex + 1) rightPitIndex board) == 0 - - -determineNextPlayer : Int -> Bool -> Array Int -> Bool -determineNextPlayer index playerOnesTurn board = - if checkIfPlayerCanNotDoMove (not playerOnesTurn) board then - playerOnesTurn - - else if indexIsOnPit index then - playerOnesTurn - - else - not playerOnesTurn - - -indexIsOnPit : Int -> Bool -indexIsOnPit index = - index == leftPitIndex || index == rightPitIndex - - -calculateGameFinished : Array Int -> Bool -calculateGameFinished board = - Array.foldr (+) 0 board - getLeftPitValue board - getRightPitValue board == 0 - - -getLeftPitValue : Array Int -> Int -getLeftPitValue board = - getPitValue leftPitIndex board - - -getRightPitValue : Array Int -> Int -getRightPitValue board = - getPitValue rightPitIndex board - - -getPitValue : Int -> Array Int -> Int -getPitValue index board = - Maybe.withDefault 0 (Array.get index board) - - -lastStonePitPosition : Int -> Array Int -> Int -lastStonePitPosition index board = - calcLastStonePosition index board (Maybe.withDefault 0 (Array.get index board)) - - -calcLastStonePosition : Int -> Array Int -> Int -> Int -calcLastStonePosition index board stones = - if stones == 0 then - index - - else - calcLastStonePosition (incrementRotatingIndex index board) board (stones - 1) - - -changesOnBoardAfterStonesSet : Bool -> Int -> Array Int -> Array Int -changesOnBoardAfterStonesSet playerOne lastStonesIndex board = - if Maybe.withDefault 0 (Array.get lastStonesIndex board) == 1 then - if indexIsOnPit lastStonesIndex then - board - - else - let - sumStones = - Maybe.withDefault 0 (Array.get (boardLength - lastStonesIndex) board) + 1 - - currentPit = - if playerOne then - getRightPitValue board - - else - getLeftPitValue board - - baordWithIndexZero = - Array.set lastStonesIndex 0 board - - baordWithOppositeZero = - Array.set (boardLength - lastStonesIndex) 0 baordWithIndexZero - - boardWithPitSum = - if playerOne then - Array.set rightPitIndex (sumStones + currentPit) baordWithOppositeZero - - else - Array.set leftPitIndex (sumStones + currentPit) baordWithOppositeZero - in - boardWithPitSum - - else - board - - -initArray : Int -> Int -> Array Int -> Array Int -initArray index stones array = - if stones == 0 then - array - - else if indexIsOnPit index then - initArray (index + 1) stones array - - else - initArray (index + 1) (stones - 3) (Array.set index 3 array) - - -boardClicked : Int -> Array Int -> Array Int -boardClicked index board = - if indexIsOnPit index then - board - - else - let - stonesLeft = - Maybe.withDefault 0 (Array.get index board) - - startBoard = - Array.set index 0 board - in - placeStones (incrementRotatingIndex index startBoard) stonesLeft startBoard - - -incrementRotatingIndex : Int -> Array Int -> Int -incrementRotatingIndex currentIndex board = - if 0 == currentIndex then - Array.length board - 1 - - else - currentIndex - 1 - - -placeStones : Int -> Int -> Array Int -> Array Int -placeStones index stonesLeft board = - if stonesLeft == 0 then - board - - else - let - oldStones = - Maybe.withDefault 0 (Array.get index board) - in - placeStones (incrementRotatingIndex index board) (stonesLeft - 1) (Array.set index (oldStones + 1) board) - - -areaFromIndex : Int -> String -areaFromIndex index = - case index of - 0 -> - "a" - - 1 -> - "b" - - 2 -> - "c" - - 3 -> - "d" - - 4 -> - "e" - - 5 -> - "f" - - 6 -> - "g" - - 7 -> - "h" - - 8 -> - "i" - - 9 -> - "j" - - 10 -> - "k" - - 11 -> - "l" - - 12 -> - "m" - - 13 -> - "n" - - i -> - String.fromInt i diff --git a/00_Alternate_Languages/05_Bagels/MiniScript/README.md b/00_Alternate_Languages/05_Bagels/MiniScript/README.md deleted file mode 100644 index 743d5160b..000000000 --- a/00_Alternate_Languages/05_Bagels/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript bagels.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "bagels" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/05_Bagels/MiniScript/bagels.ms b/00_Alternate_Languages/05_Bagels/MiniScript/bagels.ms deleted file mode 100644 index 93b33b010..000000000 --- a/00_Alternate_Languages/05_Bagels/MiniScript/bagels.ms +++ /dev/null @@ -1,83 +0,0 @@ -print " "*33 + "BAGELS" -print " "*15 + "Creative Computing Morristown, New Jersey"; print; print -// *** BAGELS Number Guessing Game -// *** Original source unknown but suspected to be -// *** Lawrence Hall of Science, U.C. Berkely - -print; print; print -inp = input("Would you like the rules (yes or no)? ") -if not inp or inp[0].lower != "n" then - print; print "I am thinking of a three-digit number. Try to guess" - print "my number and I will give you clues as follows:" - print " PICO - one digit correct but in the wrong position" - print " FERMI - one digit correct and in the right position" - print " BAGELS - no digits correct" -end if - -pickNumber = function - // pick three unique random digits - while true - actual = [floor(10*rnd), floor(10*rnd), floor(10*rnd)] - if actual[0] != actual[1] and actual[0] != actual[2] and actual[1] != actual[2] then break - end while - //print "DEBUG: actual=" + actual - print; print "O.K. I have a number in mind." - return actual -end function - -getGuess = function(guessNum) - isNotDigit = function(c); return c < "0" or c > "9"; end function - while true - inp = input("Guess #" + guessNum + "? ") - if inp.len != 3 then - print "Try guessing a three-digit number." - else if inp[0] == inp[1] or inp[0] == inp[2] or inp[1] == inp[2] then - print "Oh, I forgot to tell you that the number I have in mind" - print "has no two digits the same." - else if isNotDigit(inp[0]) or isNotDigit(inp[1]) or isNotDigit(inp[2]) then - print "What?" - else - return [inp[0].val, inp[1].val, inp[2].val] - end if - end while -end function - -doOneGame = function - actual = pickNumber - for guessNum in range(1, 20) - guess = getGuess(guessNum) - picos = 0; fermis = 0 - for i in [0,1,2] - if guess[i] == actual[i] then - fermis += 1 - else if actual.indexOf(guess[i]) != null then - picos += 1 - end if - end for - if fermis == 3 then - print "YOU GOT IT!!!" - globals.score += 1 - return - else if picos or fermis then - print "PICO " * picos + "FERMI " * fermis - else - print "BAGELS" - end if - end for - print "Oh well." - print "That's twenty guesses. My number was " + actual.join("") -end function - -// main loop -score = 0 -while true - doOneGame - print - inp = input("Play again (yes or no)? ") - if not inp or inp[0].upper != "Y" then break -end while -if score then - print; print "A " + score + " point BAGELS buff!!" -end if -print "Hope you had fun. Bye." - diff --git a/00_Alternate_Languages/05_Bagels/README.md b/00_Alternate_Languages/05_Bagels/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/05_Bagels/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/05_Bagels/bagels.bas b/00_Alternate_Languages/05_Bagels/bagels.bas deleted file mode 100644 index d16c20c3c..000000000 --- a/00_Alternate_Languages/05_Bagels/bagels.bas +++ /dev/null @@ -1,81 +0,0 @@ -5 PRINT TAB(33);"BAGELS" -10 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY":PRINT:PRINT -15 REM *** BAGLES NUMBER GUESSING GAME -20 REM *** ORIGINAL SOURCE UNKNOWN BUT SUSPECTED TO BE -25 REM *** LAWRENCE HALL OF SCIENCE, U.C. BERKELY -30 DIM A1(3),A(3),B(3) -40 Y=0:T=255 -50 PRINT:PRINT:PRINT -70 INPUT "WOULD YOU LIKE THE RULES (YES OR NO)";A$ -90 IF LEFT$(A$,1)="N" THEN 150 -100 PRINT:PRINT "I AM THINKING OF A THREE-DIGIT NUMBER. TRY TO GUESS" -110 PRINT "MY NUMBER AND I WILL GIVE YOU CLUES AS FOLLOWS:" -120 PRINT " PICO - ONE DIGIT CORRECT BUT IN THE WRONG POSITION" -130 PRINT " FERMI - ONE DIGIT CORRECT AND IN THE RIGHT POSITION" -140 PRINT " BAGELS - NO DIGITS CORRECT" -150 FOR I=1 TO 3 -160 A(I)=INT(10*RND(1)) -165 IF I-1=0 THEN 200 -170 FOR J=1 TO I-1 -180 IF A(I)=A(J) THEN 160 -190 NEXT J -200 NEXT I -210 PRINT:PRINT "O.K. I HAVE A NUMBER IN MIND." -220 FOR I=1 TO 20 -230 PRINT "GUESS #";I, -240 INPUT A$ -245 IF LEN(A$)<>3 THEN 630 -250 FOR Z=1 TO 3:A1(Z)=ASC(MID$(A$,Z,1)):NEXT Z -260 FOR J=1 TO 3 -270 IF A1(J)<48 THEN 300 -280 IF A1(J)>57 THEN 300 -285 B(J)=A1(J)-48 -290 NEXT J -295 GOTO 320 -300 PRINT "WHAT?" -310 GOTO 230 -320 IF B(1)=B(2) THEN 650 -330 IF B(2)=B(3) THEN 650 -340 IF B(3)=B(1) THEN 650 -350 C=0:D=0 -360 FOR J=1 TO 2 -370 IF A(J)<>B(J+1) THEN 390 -380 C=C+1 -390 IF A(J+1)<>B(J) THEN 410 -400 C=C+1 -410 NEXT J -420 IF A(1)<>B(3) THEN 440 -430 C=C+1 -440 IF A(3)<>B(1) THEN 460 -450 C=C+1 -460 FOR J=1 TO 3 -470 IF A(J)<>B(J) THEN 490 -480 D=D+1 -490 NEXT J -500 IF D=3 THEN 680 -505 IF C=0 THEN 545 -520 FOR J=1 TO C -530 PRINT "PICO "; -540 NEXT J -545 IF D=0 THEN 580 -550 FOR J=1 TO D -560 PRINT "FERMI "; -570 NEXT J -580 IF C+D<>0 THEN 600 -590 PRINT "BAGELS"; -600 PRINT -605 NEXT I -610 PRINT "OH WELL." -615 PRINT "THAT'S TWENTY GUESSES. MY NUMBER WAS";100*A(1)+10*A(2)+A(3) -620 GOTO 700 -630 PRINT "TRY GUESSING A THREE-DIGIT NUMBER.":GOTO 230 -650 PRINT "OH, I FORGOT TO TELL YOU THAT THE NUMBER I HAVE IN MIND" -660 PRINT "HAS NO TWO DIGITS THE SAME.":GOTO 230 -680 PRINT "YOU GOT IT!!!":PRINT -690 Y=Y+1 -700 INPUT "PLAY AGAIN (YES OR NO)";A$ -720 IF LEFT$(A$,1)="Y" THEN 150 -730 IF Y=0 THEN 750 -740 PRINT:PRINT "A";Y;"POINT BAGELS BUFF!!" -750 PRINT "HOPE YOU HAD FUN. BYE." -999 END diff --git a/00_Alternate_Languages/05_Bagels/go/main.go b/00_Alternate_Languages/05_Bagels/go/main.go deleted file mode 100644 index b0d2b106c..000000000 --- a/00_Alternate_Languages/05_Bagels/go/main.go +++ /dev/null @@ -1,166 +0,0 @@ -package main - -import ( - "bufio" - "fmt" - "math/rand" - "os" - "strconv" - "strings" - "time" -) - -const MAXGUESSES int = 20 - -func printWelcome() { - fmt.Println("\n Bagels") - fmt.Println("Creative Computing Morristown, New Jersey") - fmt.Println() -} -func printRules() { - fmt.Println() - fmt.Println("I am thinking of a three-digit number. Try to guess") - fmt.Println("my number and I will give you clues as follows:") - fmt.Println(" PICO - One digit correct but in the wrong position") - fmt.Println(" FERMI - One digit correct and in the right position") - fmt.Println(" BAGELS - No digits correct") -} - -func getNumber() []string { - numbers := []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"} - rand.Shuffle(len(numbers), func(i, j int) { numbers[i], numbers[j] = numbers[j], numbers[i] }) - - return numbers[:3] -} - -func getValidGuess(guessNumber int) string { - var guess string - scanner := bufio.NewScanner(os.Stdin) - valid := false - for !valid { - fmt.Printf("Guess # %d?\n", guessNumber) - scanner.Scan() - guess = strings.TrimSpace(scanner.Text()) - - // guess must be 3 characters - if len(guess) == 3 { - // and should be numeric - _, err := strconv.Atoi(guess) - if err != nil { - fmt.Println("What?") - } else { - // and the numbers should be unique - if (guess[0:1] != guess[1:2]) && (guess[0:1] != guess[2:3]) && (guess[1:2] != guess[2:3]) { - valid = true - } else { - fmt.Println("Oh, I forgot to tell you that the number I have in mind") - fmt.Println("has no two digits the same.") - } - } - } else { - fmt.Println("Try guessing a three-digit number.") - } - } - - return guess -} - -func buildResultString(num []string, guess string) string { - result := "" - - // correct digits in wrong place - for i := 0; i < 2; i++ { - if num[i] == guess[i+1:i+2] { - result += "PICO " - } - if num[i+1] == guess[i:i+1] { - result += "PICO " - } - } - if num[0] == guess[2:3] { - result += "PICO " - } - if num[2] == guess[0:1] { - result += "PICO " - } - - // correct digits in right place - for i := 0; i < 3; i++ { - if num[i] == guess[i:i+1] { - result += "FERMI " - } - } - - // nothing right? - if result == "" { - result = "BAGELS" - } - - return result -} - -func main() { - rand.Seed(time.Now().UnixNano()) - scanner := bufio.NewScanner(os.Stdin) - - printWelcome() - - fmt.Println("Would you like the rules (Yes or No)? ") - scanner.Scan() - response := scanner.Text() - if len(response) > 0 { - if strings.ToUpper(response[0:1]) != "N" { - printRules() - } - } else { - printRules() - } - - gamesWon := 0 - stillRunning := true - - for stillRunning { - num := getNumber() - numStr := strings.Join(num, "") - guesses := 1 - - fmt.Println("\nO.K. I have a number in mind.") - guessing := true - for guessing { - guess := getValidGuess(guesses) - - if guess == numStr { - fmt.Println("You got it!!") - gamesWon++ - guessing = false - } else { - fmt.Println(buildResultString(num, guess)) - guesses++ - if guesses > MAXGUESSES { - fmt.Println("Oh well") - fmt.Printf("That's %d guesses. My number was %s\n", MAXGUESSES, numStr) - guessing = false - } - } - } - - validRespone := false - for !validRespone { - fmt.Println("Play again (Yes or No)?") - scanner.Scan() - response := scanner.Text() - if len(response) > 0 { - validRespone = true - if strings.ToUpper(response[0:1]) != "Y" { - stillRunning = false - } - } - } - } - - if gamesWon > 0 { - fmt.Printf("\nA %d point Bagels buff!!\n", gamesWon) - } - - fmt.Println("Hope you had fun. Bye") -} diff --git a/00_Alternate_Languages/05_Bagels/nim/bagels.nim b/00_Alternate_Languages/05_Bagels/nim/bagels.nim deleted file mode 100644 index f302b375d..000000000 --- a/00_Alternate_Languages/05_Bagels/nim/bagels.nim +++ /dev/null @@ -1,97 +0,0 @@ -import std/[random,strutils] - -# BAGLES NUMBER GUESSING GAME -# ORIGINAL SOURCE UNKNOWN BUT SUSPECTED TO BE -# LAWRENCE HALL OF SCIENCE, U.C. BERKELY - -var - a, b: array[1..3, int] - wincount: int = 0 - prompt: string - stillplaying: bool = true - -randomize() # Seed the random number generator - -# Seed 3 unique random numbers; indicate if they're all unique -proc genSeed(): bool = - for i in 1..3: - a[i] = rand(0..9) - if (a[1] == a[2]) or (a[2] == a[3]) or (a[3] == a[1]): - return false - return true - -# Primary game logic -proc playGame() = - var youwin, unique: bool = false - # We want 3 unique random numbers: loop until we get them! - while unique == false: - unique = genSeed() - echo "O.K. I HAVE A NUMBER IN MIND." - for i in 1..20: - var c, d: int = 0 - echo "GUESS #", i - prompt = readLine(stdin).normalize() - if (prompt.len() != 3): - echo "TRY GUESSING A THREE-DIGIT NUMBER." - continue - for z in 1..3: - b[z] = prompt.substr(z-1, z-1).parseInt() # Convert string digits to array ints - if (b[1] == b[2]) or (b[2] == b[3]) or (b[3] == b[1]): - echo "OH, I FORGOT TO TELL YOU THAT THE NUMBER I HAVE IN MIND" - echo "HAS NO TWO DIGITS THE SAME." - # Figure out the PICOs - if (a[1] == b[2]): c += 1 - if (a[1] == b[3]): c += 1 - if (a[2] == b[1]): c += 1 - if (a[2] == b[3]): c += 1 - if (a[3] == b[1]): c += 1 - if (a[3] == b[2]): c += 1 - # Determine FERMIs - for j in 1..3: - if (a[j] == b[j]): d += 1 - # Reveal clues - if (d != 3): - if (c != 0): - for j in 1..c: - echo "PICO" - if (d != 0): - for j in 1..d: - echo "FERMI" - if (c == 0) and (d == 0): - echo "BAGELS" - # If we have 3 FERMIs, we win! - else: - echo "YOU GOT IT!!!" - echo "" - wincount += 1 - youwin = true - break - # Only invoke if we've tried 20 guesses without winning - if not youwin: - echo "OH WELL." - echo "THAT'S TWENTY GUESSES. MY NUMBER WAS ", a[1], a[2], a[3] - -# main program -echo spaces(33), "BAGELS" -echo spaces(15), "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -echo "\n\n" -echo "WOULD YOU LIKE THE RULES (YES OR NO)" -prompt = readLine(stdin).normalize() -if prompt.substr(0, 0) == "y": - echo "I AM THINKING OF A THREE-DIGIT NUMBER. TRY TO GUESS" - echo "MY NUMBER AND I WILL GIVE YOU CLUES AS FOLLOWS:" - echo " PICO - ONE DIGIT CORRECT BUT IN THE WRONG POSITION" - echo " FERMI - ONE DIGIT CORRECT AND IN THE RIGHT POSITION" - echo " BAGELS - NO DIGITS CORRECT" - echo "" -while(stillplaying == true): - playGame() - echo "PLAY AGAIN (YES OR NO)" - prompt = readLine(stdin).normalize() - if prompt.substr(0, 0) != "y": - stillplaying = false -if wincount > 0: - echo "" - echo "A ", wincount, " POINT BAGELS BUFF!!" -echo "" -echo "HOPE YOU HAD FUN. BYE." diff --git a/00_Alternate_Languages/06_Banner/MiniScript/README.md b/00_Alternate_Languages/06_Banner/MiniScript/README.md deleted file mode 100644 index 25a241af9..000000000 --- a/00_Alternate_Languages/06_Banner/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript banner.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "banner" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/06_Banner/MiniScript/banner.ms b/00_Alternate_Languages/06_Banner/MiniScript/banner.ms deleted file mode 100644 index d5d57e187..000000000 --- a/00_Alternate_Languages/06_Banner/MiniScript/banner.ms +++ /dev/null @@ -1,89 +0,0 @@ -blockWidth = input("Horizontal? ").val -if blockWidth <= 1 then blockWidth = 3 - -blockHeight = input("Vertical? ").val -if blockHeight <= 1 then blockHeight = 5 - -inp = input("Centered? ").upper -centered = inp and inp[0] > "P" - -printChar = input("Character (type 'all' if you want character being printed)? ") - -statement = input("Statement: ").upper - -//input("Set page") // <-- opportunity to set your pin-feed printer before proceeding! - -// Define the character data. For each character, we have 7 numbers -// which are the 9-bit binary representation of each row, plus one. -data = {} -data[" "] = [0,0,0,0,0,0,0] -data["!"] = [1,1,1,384,1,1,1] -data["?"] = [5,3,2,354,18,11,5] -data["."] = [1,1,129,449,129,1,1] -data["*"] = [69,41,17,512,17,41,69] -data["="] = [41,41,41,41,41,41,41] -data["0"] = [57,69,131,258,131,69,57] -data["1"] = [0,0,261,259,512,257,257] -data["2"] = [261,387,322,290,274,267,261] -data["3"] = [66,130,258,274,266,150,100] -data["4"] = [33,49,41,37,35,512,33] -data["5"] = [160,274,274,274,274,274,226] -data["6"] = [194,291,293,297,305,289,193] -data["7"] = [258,130,66,34,18,10,8] -data["8"] = [69,171,274,274,274,171,69] -data["9"] = [263,138,74,42,26,10,7] -data["A"] = [505,37,35,34,35,37,505] -data["B"] = [512,274,274,274,274,274,239] -data["C"] = [125,131,258,258,258,131,69] -data["D"] = [512,258,258,258,258,131,125] -data["E"] = [512,274,274,274,274,258,258] -data["F"] = [512,18,18,18,18,2,2] -data["G"] = [125,131,258,258,290,163,101] -data["H"] = [512,17,17,17,17,17,512] -data["I"] = [258,258,258,512,258,258,258] -data["J"] = [65,129,257,257,257,129,128] -data["K"] = [512,17,17,41,69,131,258] -data["L"] = [512,257,257,257,257,257,257] -data["M"] = [512,7,13,25,13,7,512] -data["N"] = [512,7,9,17,33,193,512] -data["O"] = [125,131,258,258,258,131,125] -data["P"] = [512,18,18,18,18,18,15] -data["Q"] = [125,131,258,258,322,131,381] -data["R"] = [512,18,18,50,82,146,271] -data["S"] = [69,139,274,274,274,163,69] -data["T"] = [2,2,2,512,2,2,2] -data["U"] = [128,129,257,257,257,129,128] -data["V"] = [64,65,129,257,129,65,64] -data["W"] = [256,257,129,65,129,257,256] -data["X"] = [388,69,41,17,41,69,388] -data["Y"] = [8,9,17,481,17,9,8] -data["Z"] = [386,322,290,274,266,262,260] - -for c in statement - if not data.hasIndex(c) then continue - - // Print character c in giant sideways banner-style! - for datum in data[c] - if datum then datum -= 1 // remove spurious +1 - if printChar.upper != "ALL" then c = printChar - - for lineRepeat in range(blockWidth-1) - if centered then print " " * (34 - 4.5*blockHeight), "" - - for bitPos in range(9,0) - if bitAnd(datum, 2^bitPos) then charToPrint=c else charToPrint=" " - print charToPrint * blockHeight, "" - end for // next bitPos - - print - wait 0.01 // put in a small pause so it's not too fast to see! - end for // next lineRepeat (repeating line according to entered Y value) - - end for // next datum (row of this character) - - // Add a little space after each character - for i in range(1, 2 * blockWidth) - print - wait 0.01 - end for -end for // next character in the message diff --git a/00_Alternate_Languages/06_Banner/README.md b/00_Alternate_Languages/06_Banner/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/06_Banner/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/06_Banner/banner.bas b/00_Alternate_Languages/06_Banner/banner.bas deleted file mode 100644 index 3eb50c451..000000000 --- a/00_Alternate_Languages/06_Banner/banner.bas +++ /dev/null @@ -1,94 +0,0 @@ -10 INPUT "HORIZONTAL";X -20 INPUT "VERTICAL";Y -21 INPUT "CENTERED";L$ -22 G1=0:IF L$>"P" THEN G1=1 -23 INPUT "CHARACTER (TYPE 'ALL' IF YOU WANT CHARACTER BEING PRINTED)";M$ -29 PRINT "STATEMENT"; -30 INPUT A$ -35 INPUT "SET PAGE";O$ -40 A=ASC(LEFT$(A$,1)) -50 REM -60 REM -70 FOR T=1 TO LEN(A$) -80 P$=MID$(A$,T,1) -90 FOR O=1 TO 50 -95 READ S$,S(1),S(2),S(3),S(4),S(5),S(6),S(7) -96 IF P$=" " THEN 812 -100 IF P$=S$ THEN 200 -120 NEXT O -200 RESTORE -201 X$=M$ -202 IF M$="ALL" THEN X$=S$ -205 FOR U=1 TO 7 -210 FOR K=8 TO 0 STEP -1 -230 IF 2^K= 6 then break - end while -end function - -// Do the center jump; return US or THEM who gets the ball. -centerJump = function - print "Center Jump" - if rnd < 0.6 then - print opponent + " controls the tap." - return THEM - else - print "Dartmouth controls the tap." - return US - end if -end function - -inputShot = function - while true - globals.shotType = input("Your shot (0-4): ") - if shotType == "0" then - inputDefense "Your new defensive alignment is? " - continue - end if - globals.shotType = shotType.val - if 1 <= shotType <= 4 then return - end while -end function - -endFirstHalf = function - print " ***** End of first half *****"; print - print "Score: Dartmouth: " + score[US] + " " + opponent + ": " + score[THEM] - print; print - globals.inControl = centerJump -end function - -checkGameOver = function - print - if score[0] != score[1] then - print " ***** END OF GAME *****" - print "Final score: Dartmouth: " + score[US] + " " + opponent + ": " + score[THEM] - print - return true - else - print " ***** End of Second Half *****" - print "Score at end of regulation time:" - print " Dartmouth: " + score[US] + " " + opponent + ": " + score[THEM] - print - print "Begin two minute overtime period" - return false - end if -end function - -scoreBasket = function(who = null) - if who == null then who = inControl - score[who] += 2 - printScore -end function - -printScore = function - print "Score: " + score[1] + " to " + score[0] - print "Time: " + timer -end function - -// Logic for a Dartmouth jump shot. Return true to continue as Dartmouth, -// false to pass the ball to the opponent. -dartmouthJumpShot = function - if rnd <= 0.341 * defense / 8 then - print "Shot is good." - scoreBasket - return false - end if - - if rnd < 0.682 * defense / 8 then - print "Shot is off target." - if defense/6 * rnd > 0.45 then - print "Rebound to " + opponent - return false - end if - print "Dartmouth controls the rebound." - if rnd <= 0.4 then - globals.shotType = 3 + (rnd > 0.5) - return true - end if - if defense == 6 and rnd < 0.6 then - print "Pass stolen by " + opponent + ", easy layup." - scoreBasket THEM - return true - end if - print "Ball passed back to you." - return true - end if - - if rnd < 0.782 * defense/8 then - print "Shot is blocked. Ball controlled by ", "" - if rnd > 0.5 then - print opponent + "." - return false - else - print "Dartmouth." - return true - end if - end if - - if rnd > 0.843 * defense/8 then - print "Charging foul. Dartmouth loses ball." - else - print "Shooter is fouled. Two shots." - doFoulShots US - end if - return false -end function - -// Logic for an opponent jump shot. Return true to continue as opponent, -// false to pass the ball to Dartmouth. -opponentJumpShot = function - if rnd <= 0.35 * defense / 8 then - print "Shot is good." - scoreBasket - return false - end if - - if 8 / defense * rnd <= 0.75 then - print "Shot is off rim." - return opponentMissed - end if - - if 8 / defense * rnd <= 0.9 then - print "Player fouled. Two shots." - doFoulShots THEM - return false - end if - print "Offensive foul. Dartmouth's ball." - return false -end function - -// Do a Dartmouth set shot or lay-up. Return true to continue as Dartmouth, -// false to pass the ball to the opponent. -dartmouthSetOrLay = function - if 7 / defense * rnd <= 0.4 then - print "Shot is good. Two points." - scoreBasket - else if 7 / defense * rnd <= 0.7 then - print "Shot is off the rim." - if rnd < 0.667 then - print opponent + " controls the rebound." - return false - end if - print "Dartmouth controls the rebound." - if rnd < 0.4 then return true - print "Ball passed back to you." - return true - else if 7 / defense * rnd < 0.875 then - print "Shooter fouled. Two shots." - doFoulShots US - else if 7 / defense * rnd < 0.925 then - print "Shot blocked. " + opponent + "'s ball." - else - print "Charging foul. Dartmouth loses the ball." - end if - return false -end function - -// Do an opponent set shot or lay-up. Return true to continue as opponent, -// false to pass the ball to Dartmouth. -opponentSetOrLay = function - if 7 / defense * rnd <= 0.413 then - print "Shot is missed." - return opponentMissed - else - print "Shot is good." - scoreBasket - return false - end if -end function - -// Handle opponent missing a shot -- return true to continue as opponent, -// false to pass the ball to Dartmouth. -opponentMissed = function - if defense / 6 * rnd <= 0.5 then - print "Dartmouth controls the rebound." - return false - else - print opponent + " controls the rebound." - if defense == 6 and rnd <= 0.75 then - print "Ball stolen. Easy lay up for Dartmouth." - scoreBasket US - return true - end if - if rnd <= 0.5 then - print "Pass back to " + opponent + " guard." - return true - end if - globals.shotType = 4 - (rnd > 0.5) - return true - end if -end function - -playOneSide = function - print - while true - globals.timer += 1 - if timer == 50 then return endFirstHalf - if time == 92 then - print " *** Two minutes left in the game ***"; print - end if - if shotType == 1 or shotType == 2 then - print "Jump Shot" - if inControl == US then - if dartmouthJumpShot then continue else break - else - if opponentJumpShot then continue else break - end if - else // (if shot type >= 3) - if shotType > 3 then print "Set shot." else print "Lay up." - if inControl == US then - if dartmouthSetOrLay then continue else break - else - if opponentSetOrLay then continue else break - end if - end if - end while - globals.inControl = 1 - globals.inControl -end function - -doFoulShots = function(who) - if rnd > 0.49 then - if rnd > 0.75 then - print "Both shots missed." - else - print "Shooter makes one shot and misses one." - score[who] += 1 - end if - else - print "Shooter makes both shots." - score[who] += 2 - end if - printScore -end function - -opponentPlay = function - print - while true - globals.timer += 1 - if timer == 50 then return endFirstHalf - if time == 92 then - print " *** Two minutes left in the game ***"; print - end if - if shotType == 1 or shotType == 2 then - print "Jump Shot" - if opponentJumpShot then continue else break - else // (if shot type >= 3) - if shotType > 3 then print "Set shot." else print "Lay up." - if opponentSetOrLay then continue else break - end if - end while - globals.inControl = US -end function - -// Constants -THEM = 0 -US = 1 - -// Main program -inputDefense "Your starting defense will be? " -print -opponent = input("Choose your opponent? ") -score = [0,0] // score for each team (US and THEM) -gameOver = false -inControl = centerJump -timer = 0 -while not gameOver - print - if inControl == US then - inputShot - playOneSide - else - shotType = ceil(10 / 4 * rnd + 1) - playOneSide - end if - if timer >= 100 then - if checkGameOver then break - timer = 93 - dartmouthHasBall = centerJump - end if -end while diff --git a/00_Alternate_Languages/07_Basketball/README.md b/00_Alternate_Languages/07_Basketball/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/07_Basketball/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/07_Basketball/basketball.bas b/00_Alternate_Languages/07_Basketball/basketball.bas deleted file mode 100644 index 4a00875b0..000000000 --- a/00_Alternate_Languages/07_Basketball/basketball.bas +++ /dev/null @@ -1,196 +0,0 @@ -5 PRINT TAB(31);"BASKETBALL" -7 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -8 PRINT:PRINT:PRINT -10 PRINT "THIS IS DARTMOUTH COLLEGE BASKETBALL. YOU WILL BE DARTMOUTH" -20 PRINT " CAPTAIN AND PLAYMAKER. CALL SHOTS AS FOLLOWS: 1. LONG" -30 PRINT " (30 FT.) JUMP SHOT; 2. SHORT (15 FT.) JUMP SHOT; 3. LAY" -40 PRINT " UP; 4. SET SHOT." -60 PRINT "BOTH TEAMS WILL USE THE SAME DEFENSE. CALL DEFENSE AS" -70 PRINT "FOLLOWS: 6. PRESS; 6.5 MAN-TO MAN; 7. ZONE; 7.5 NONE." -72 PRINT "TO CHANGE DEFENSE, JUST TYPE 0 AS YOUR NEXT SHOT." -76 INPUT "YOUR STARTING DEFENSE WILL BE";D:IF D<6 THEN 2010 -79 PRINT -80 INPUT "CHOOSE YOUR OPPONENT";O$ -370 PRINT "CENTER JUMP" -390 IF RND(1)> 3/5 THEN 420 -400 PRINT O$;" CONTROLS THE TAP." -410 GOTO 3000 -420 PRINT "DARTMOUTH CONTROLS THE TAP." -425 PRINT -430 INPUT "YOUR SHOT";Z -440 P=0 -445 IF Z<>INT(Z) THEN 455 -446 IF Z<0 OR Z>4 THEN 455 -447 GOTO 460 -455 PRINT "INCORRECT ANSWER. RETYPE IT. ";:GOTO 430 -460 IF RND(1)<.5 THEN 1000 -480 IF T<100 THEN 1000 -490 PRINT -491 IF S(1)<>S(0) THEN 510 -492 PRINT:PRINT " ***** END OF SECOND HALF *****":PRINT -493 PRINT "SCORE AT END OF REGULATION TIME:" -494 PRINT " DARTMOUTH:";S(1);" ";O$;":";S(0) -495 PRINT -496 PRINT "BEGIN TWO MINUTE OVERTIME PERIOD" -499 T=93 -500 GOTO 370 -510 PRINT " ***** END OF GAME *****" -515 PRINT "FINAL SCORE: DARTMOUTH:";S(1);" ";O$;":";S(0) -520 STOP -600 PRINT -610 PRINT " *** TWO MINUTES LEFT IN THE GAME ***" -620 PRINT -630 RETURN -1000 ON Z GOTO 1040,1040 -1030 GOTO 1300 -1040 T=T+1 -1041 IF T=50 THEN 8000 -1042 IF T=92 THEN 1046 -1043 GOTO 1050 -1046 GOSUB 600 -1050 PRINT "JUMP SHOT" -1060 IF RND(1)>.341*D/8 THEN 1090 -1070 PRINT "SHOT IS GOOD." -1075 GOSUB 7000 -1085 GOTO 3000 -1090 IF RND(1)>.682*D/8 THEN 1200 -1100 PRINT "SHOT IS OFF TARGET." -1105 IF D/6*RND(1)>.45 THEN 1130 -1110 PRINT "DARTMOUTH CONTROLS THE REBOUND." -1120 GOTO 1145 -1130 PRINT "REBOUND TO ";O$ -1140 GOTO 3000 -1145 IF RND(1)>.4 THEN 1158 -1150 GOTO 1300 -1158 IF D=6 THEN 5100 -1160 PRINT "BALL PASSED BACK TO YOU. "; -1170 GOTO 430 -1180 IF RND(1)>.9 THEN 1190 -1185 PRINT "PLAYER FOULED, TWO SHOTS." -1187 GOSUB 4000 -1188 GOTO 3000 -1190 PRINT "BALL STOLEN. ";O$;"'S BALL." -1195 GOTO 3000 -1200 IF RND(1)>.782*D/8 THEN 1250 -1210 PRINT "SHOT IS BLOCKED. BALL CONTROLLED BY "; -1230 IF RND(1)>.5 THEN 1242 -1235 PRINT "DARTMOUTH." -1240 GOTO 430 -1242 PRINT O$;"." -1245 GOTO 3000 -1250 IF RND(1)>.843*D/8 THEN 1270 -1255 PRINT "SHOOTER IS FOULED. TWO SHOTS." -1260 GOSUB 4000 -1265 GOTO 3000 -1270 PRINT "CHARGING FOUL. DARTMOUTH LOSES BALL." -1280 GOTO 3000 -1300 T=T+1 -1301 IF T=50 THEN 8000 -1302 IF T=92 THEN 1304 -1303 GOTO 1305 -1304 GOSUB 600 -1305 IF Z=0 THEN 2010 -1310 IF Z>3 THEN 1700 -1320 PRINT "LAY UP." -1330 IF 7/D*RND(1)>.4 THEN 1360 -1340 PRINT "SHOT IS GOOD. TWO POINTS." -1345 GOSUB 7000 -1355 GOTO 3000 -1360 IF 7/D*RND(1)>.7 THEN 1500 -1370 PRINT "SHOT IS OFF THE RIM." -1380 IF RND(1)>2/3 THEN 1415 -1390 PRINT O$;" CONTROLS THE REBOUND." -1400 GOTO 3000 -1415 PRINT "DARTMOUTH CONTROLS THE REBOUND." -1420 IF RND(1)>.4 THEN 1440 -1430 GOTO 1300 -1440 PRINT "BALL PASSED BACK TO YOU."; -1450 GOTO 430 -1500 IF 7/D*RND(1)>.875 THEN 1600 -1510 PRINT "SHOOTER FOULED. TWO SHOTS." -1520 GOSUB 4000 -1530 GOTO 3000 -1600 IF 7/D*RND(1)>.925 THEN 1630 -1610 PRINT "SHOT BLOCKED. ";O$;"'S BALL." -1620 GOTO 3000 -1630 PRINT "CHARGING FOUL. DARTMOUTH LOSES THE BALL." -1640 GOTO 3000 -1700 PRINT "SET SHOT." -1710 GOTO 1330 -2010 INPUT "YOUR NEW DEFENSIVE ALLIGNMENT IS";D -2030 IF D<6 THEN 2010 -2040 GOTO 425 -3000 P=1 -3005 T=T+1 -3008 IF T=50 THEN 8000 -3012 GOTO 3018 -3015 GOSUB 600 -3018 PRINT -3020 Z1=10/4*RND(1)+1 -3030 IF Z1>2 THEN 3500 -3040 PRINT "JUMP SHOT." -3050 IF 8/D*RND(1)>.35 THEN 3100 -3060 PRINT "SHOT IS GOOD." -3080 GOSUB 6000 -3090 GOTO 425 -3100 IF 8/D*RND(1)>.75 THEN 3200 -3105 PRINT "SHOT IS OFF RIM." -3110 IF D/6*RND(1)>.5 THEN 3150 -3120 PRINT "DARTMOUTH CONTROLS THE REBOUND." -3130 GOTO 425 -3150 PRINT O$;" CONTROLS THE REBOUND." -3160 IF D=6 THEN 5000 -3165 IF RND(1)>.5 THEN 3175 -3168 PRINT "PASS BACK TO ";O$;" GUARD." -3170 GOTO 3000 -3175 GOTO 3500 -3200 IF 8/D*RND(1)>.9 THEN 3310 -3210 PRINT "PLAYER FOULED. TWO SHOTS." -3220 GOSUB 4000 -3230 GOTO 425 -3310 PRINT "OFFENSIVE FOUL. DARTMOUTH'S BALL." -3320 GOTO 425 -3500 IF Z1>3 THEN 3800 -3510 PRINT "LAY UP." -3520 IF 7/D*RND(1)>.413 THEN 3600 -3530 PRINT "SHOT IS GOOD." -3540 GOSUB 6000 -3550 GOTO 425 -3600 PRINT "SHOT IS MISSED." -3610 GOTO 3110 -3800 PRINT "SET SHOT." -3810 GOTO 3520 -4000 REM FOUL SHOOTING -4010 IF RND(1)>.49 THEN 4050 -4020 PRINT "SHOOTER MAKES BOTH SHOTS." -4030 S(1-P)=S(1-P)+2 -4040 GOSUB 6010 -4041 RETURN -4050 IF RND(1)>.75 THEN 4100 -4060 PRINT "SHOOTER MAKES ONE SHOT AND MISSES ONE." -4070 S(1-P)=S(1-P)+1 -4080 GOTO 4040 -4100 PRINT "BOTH SHOTS MISSED." -4110 GOTO 4040 -5000 IF RND(1)>.75 THEN 5010 -5005 GOTO 3165 -5010 PRINT "BALL STOLEN. EASY LAY UP FOR DARTMOUTH." -5015 GOSUB 7000 -5030 GOTO 3000 -5100 IF RND(1)>.6 THEN 5120 -5110 GOTO 1160 -5120 PRINT "PASS STOLEN BY ";O$;" EASY LAYUP." -5130 GOSUB 6000 -5140 GOTO 425 -6000 S(0)=S(0)+2 -6010 PRINT "SCORE: ";S(1);"TO";S(0) -6020 RETURN -7000 S(1)=S(1)+2 -7010 GOSUB 6010 -7020 RETURN -8000 PRINT:PRINT " ***** END OF FIRST HALF *****":PRINT -8010 PRINT "SCORE: DARTMOUTH:";S(1);" ";O$;":";S(0) -8015 PRINT -8016 PRINT -8020 GOTO 370 -9999 END diff --git a/00_Alternate_Languages/08_Batnum/MiniScript/README.md b/00_Alternate_Languages/08_Batnum/MiniScript/README.md deleted file mode 100644 index b33a3f84d..000000000 --- a/00_Alternate_Languages/08_Batnum/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript batnum.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "batnum" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/08_Batnum/MiniScript/batnum.ms b/00_Alternate_Languages/08_Batnum/MiniScript/batnum.ms deleted file mode 100644 index d1019717b..000000000 --- a/00_Alternate_Languages/08_Batnum/MiniScript/batnum.ms +++ /dev/null @@ -1,109 +0,0 @@ -print " "*33 + "Batnum" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print -print "This program is a 'Battle of Numbers' game, where the" -print "computer is your opponent." -print -print "The game starts with an assumed pile of objects. You" -print "and your opponent alternately remove objects from the pile." -print "Winning is defined in advance as taking the last object or" -print "not. You can also specify some other beginning conditions." -print "Don't use zero, however, in playing the game." -print "Enter a negative number for new pile size to stop playing." -print - -options = {} -getOptions = function - while true - options.pileSize = input("Enter pile size? ").val - if options.pileSize != 0 and options.pileSize == floor(options.pileSize) then break - end while - if options.pileSize < 0 then return - - while true - winOption = input("Enter win option - 1 to take last, 2 to avoid last: ") - if winOption == "1" or winOption == "2" then break - end while - options.takeLast = (winOption == "1") - - while true - minMax = input("Enter min and max? ").replace(",", " ").split - if minMax.len < 2 then continue - options.minTake = minMax[0].val - options.maxTake = minMax[-1].val - if options.minTake >= 1 and options.minTake < options.maxTake then break - end while - - while true - startOpt = input("Enter start option - 1 computer first, 2 you first: ") - if startOpt == "1" or startOpt == "2" then break - end while - options.computerFirst = (startOpt == "1") -end function - -computerTurn = function - // Random computer play (not in original program): - take = options.minTake + floor(rnd * (options.maxTake - options.minTake)) - - // Proper (smart) computer play - q = pile - if not options.takeLast then q -= 1 - take = q % (options.minTake + options.maxTake) - if take < options.minTake then take = options.minTake - if take > options.maxTake then take = options.maxTake - - if take >= pile then - if options.takeLast then - print "Computer takes " + pile + " and wins." - else - print "Computer takes " + pile + " and loses." - end if - globals.gameOver = true - else - globals.pile -= take - print "Computer takes " + take + " and leaves " + pile - end if -end function - -playerTurn = function - while true - print; take = input("Your move? ").val - if take == 0 then - print "I told you not to use zero! Computer wins by forfeit." - globals.gameOver = true - return - end if - if options.minTake <= take <= options.maxTake and take <= pile then break - print "Illegal move, reenter it" - end while - if take >= pile then - if options.takeLast then - print "Congratulations, you win." - else - print "Tough luck, you lose." - end if - globals.gameOver = true - else - globals.pile -= take - //print "You take " + take + ", leaving " + pile // (not in original program) - end if -end function - -while true - getOptions - if options.pileSize < 0 then break - pile = options.pileSize - gameOver = false - - print; print - - if options.computerFirst then computerTurn - while not gameOver - playerTurn - if gameOver then break - computerTurn - end while - - for i in range(1,10); print; end for -end while -print "OK, bye!" \ No newline at end of file diff --git a/00_Alternate_Languages/08_Batnum/README.md b/00_Alternate_Languages/08_Batnum/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/08_Batnum/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/08_Batnum/batnum.bas b/00_Alternate_Languages/08_Batnum/batnum.bas deleted file mode 100644 index 40ec86161..000000000 --- a/00_Alternate_Languages/08_Batnum/batnum.bas +++ /dev/null @@ -1,90 +0,0 @@ -10 PRINT TAB(33);"BATNUM" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT:PRINT:PRINT -110 PRINT "THIS PROGRAM IS A 'BATTLE OF NUMBERS' GAME, WHERE THE" -120 PRINT "COMPUTER IS YOUR OPPONENT." -130 PRINT -140 PRINT "THE GAME STARTS WITH AN ASSUMED PILE OF OBJECTS. YOU" -150 PRINT "AND YOUR OPPONENT ALTERNATELY REMOVE OBJECTS FROM THE PILE." -160 PRINT "WINNING IS DEFINED IN ADVANCE AS TAKING THE LAST OBJECT OR" -170 PRINT "NOT. YOU CAN ALSO SPECIFY SOME OTHER BEGINNING CONDITIONS." -180 PRINT "DON'T USE ZERO, HOWEVER, IN PLAYING THE GAME." -190 PRINT "ENTER A NEGATIVE NUMBER FOR NEW PILE SIZE TO STOP PLAYING." -200 PRINT -210 GOTO 330 -220 FOR I=1 TO 10 -230 PRINT -240 NEXT I -330 INPUT "ENTER PILE SIZE";N -350 IF N>=1 THEN 370 -360 GOTO 330 -370 IF N<>INT(N) THEN 220 -380 IF N<1 THEN 220 -390 INPUT "ENTER WIN OPTION - 1 TO TAKE LAST, 2 TO AVOID LAST: ";M -410 IF M=1 THEN 430 -420 IF M<>2 THEN 390 -430 INPUT "ENTER MIN AND MAX ";A,B -450 IF A>B THEN 430 -460 IF A<1 THEN 430 -470 IF A<>INT(A) THEN 430 -480 IF B<>INT(B) THEN 430 -490 INPUT "ENTER START OPTION - 1 COMPUTER FIRST, 2 YOU FIRST ";S -500 PRINT:PRINT -510 IF S=1 THEN 530 -520 IF S<>2 THEN 490 -530 C=A+B -540 IF S=2 THEN 570 -550 GOSUB 600 -560 IF W=1 THEN 220 -570 GOSUB 810 -580 IF W=1 THEN 220 -590 GOTO 550 -600 Q=N -610 IF M=1 THEN 630 -620 Q=Q-1 -630 IF M=1 THEN 680 -640 IF N>A THEN 720 -650 W=1 -660 PRINT "COMPUTER TAKES";N;"AND LOSES." -670 RETURN -680 IF N>B THEN 720 -690 W=1 -700 PRINT "COMPUTER TAKES";N;"AND WINS." -710 RETURN -720 P=Q-C*INT(Q/C) -730 IF P>=A THEN 750 -740 P=A -750 IF P<=B THEN 770 -760 P=B -770 N=N-P -780 PRINT "COMPUTER TAKES";P;"AND LEAVES";N -790 W=0 -800 RETURN -810 PRINT:PRINT "YOUR MOVE "; -820 INPUT P -830 IF P<>0 THEN 870 -840 PRINT "I TOLD YOU NOT TO USE ZERO! COMPUTER WINS BY FORFEIT." -850 W=1 -860 RETURN -870 IF P<>INT(P) THEN 920 -880 IF P>=A THEN 910 -890 IF P=N THEN 960 -900 GOTO 920 -910 IF P<=B THEN 940 -920 PRINT "ILLEGAL MOVE, REENTER IT "; -930 GOTO 820 -940 N=N-P -950 IF N<>0 THEN 1030 -960 IF M=1 THEN 1000 -970 PRINT "TOUGH LUCK, YOU LOSE." -980 W=1 -990 RETURN -1000 PRINT "CONGRATULATIONS, YOU WIN." -1010 W=1 -1020 RETURN -1030 IF N>=0 THEN 1060 -1040 N=N+P -1050 GOTO 920 -1060 W=0 -1070 RETURN -1080 END diff --git a/00_Alternate_Languages/08_Batnum/go/main.go b/00_Alternate_Languages/08_Batnum/go/main.go deleted file mode 100644 index 103347995..000000000 --- a/00_Alternate_Languages/08_Batnum/go/main.go +++ /dev/null @@ -1,248 +0,0 @@ -package main - -import ( - "bufio" - "fmt" - "os" - "strconv" - "strings" -) - -type StartOption int8 - -const ( - StartUndefined StartOption = iota - ComputerFirst - PlayerFirst -) - -type WinOption int8 - -const ( - WinUndefined WinOption = iota - TakeLast - AvoidLast -) - -type GameOptions struct { - pileSize int - winOption WinOption - startOption StartOption - minSelect int - maxSelect int -} - -func NewOptions() *GameOptions { - g := GameOptions{} - - g.pileSize = getPileSize() - if g.pileSize < 0 { - return &g - } - - g.winOption = getWinOption() - g.minSelect, g.maxSelect = getMinMax() - g.startOption = getStartOption() - - return &g -} - -func getPileSize() int { - ps := 0 - var err error - scanner := bufio.NewScanner(os.Stdin) - - for { - fmt.Println("Enter Pile Size ") - scanner.Scan() - ps, err = strconv.Atoi(scanner.Text()) - if err == nil { - break - } - } - return ps -} - -func getWinOption() WinOption { - scanner := bufio.NewScanner(os.Stdin) - - for { - fmt.Println("ENTER WIN OPTION - 1 TO TAKE LAST, 2 TO AVOID LAST:") - scanner.Scan() - w, err := strconv.Atoi(scanner.Text()) - if err == nil && (w == 1 || w == 2) { - return WinOption(w) - } - } -} - -func getStartOption() StartOption { - scanner := bufio.NewScanner(os.Stdin) - - for { - fmt.Println("ENTER START OPTION - 1 COMPUTER FIRST, 2 YOU FIRST ") - scanner.Scan() - s, err := strconv.Atoi(scanner.Text()) - if err == nil && (s == 1 || s == 2) { - return StartOption(s) - } - } -} - -func getMinMax() (int, int) { - minSelect := 0 - maxSelect := 0 - var minErr error - var maxErr error - scanner := bufio.NewScanner(os.Stdin) - - for { - fmt.Println("ENTER MIN AND MAX ") - scanner.Scan() - enteredValues := scanner.Text() - vals := strings.Split(enteredValues, " ") - minSelect, minErr = strconv.Atoi(vals[0]) - maxSelect, maxErr = strconv.Atoi(vals[1]) - if (minErr == nil) && (maxErr == nil) && (minSelect > 0) && (maxSelect > 0) && (maxSelect > minSelect) { - return minSelect, maxSelect - } - } -} - -// This handles the player's turn - asking the player how many objects -// to take and doing some basic validation around that input. Then it -// checks for any win conditions. -// Returns a boolean indicating whether the game is over and the new pile_size. -func playerMove(pile, min, max int, win WinOption) (bool, int) { - scanner := bufio.NewScanner(os.Stdin) - done := false - for !done { - fmt.Println("YOUR MOVE") - scanner.Scan() - m, err := strconv.Atoi(scanner.Text()) - if err != nil { - continue - } - - if m == 0 { - fmt.Println("I TOLD YOU NOT TO USE ZERO! COMPUTER WINS BY FORFEIT.") - return true, pile - } - - if m > max || m < min { - fmt.Println("ILLEGAL MOVE, REENTER IT") - continue - } - - pile -= m - done = true - - if pile <= 0 { - if win == AvoidLast { - fmt.Println("TOUGH LUCK, YOU LOSE.") - } else { - fmt.Println("CONGRATULATIONS, YOU WIN.") - } - return true, pile - } - } - return false, pile -} - -// This handles the logic to determine how many objects the computer -// will select on its turn. -func computerPick(pile, min, max int, win WinOption) int { - var q int - if win == AvoidLast { - q = pile - 1 - } else { - q = pile - } - c := min + max - - pick := q - (c * int(q/c)) - - if pick < min { - pick = min - } else if pick > max { - pick = max - } - - return pick -} - -// This handles the computer's turn - first checking for the various -// win/lose conditions and then calculating how many objects -// the computer will take. -// Returns a boolean indicating whether the game is over and the new pile_size. -func computerMove(pile, min, max int, win WinOption) (bool, int) { - // first check for end-game conditions - if win == TakeLast && pile <= max { - fmt.Printf("COMPUTER TAKES %d AND WINS\n", pile) - return true, pile - } - - if win == AvoidLast && pile <= min { - fmt.Printf("COMPUTER TAKES %d AND LOSES\n", pile) - return true, pile - } - - // otherwise determine the computer's selection - selection := computerPick(pile, min, max, win) - pile -= selection - fmt.Printf("COMPUTER TAKES %d AND LEAVES %d\n", selection, pile) - return false, pile -} - -// This is the main game loop - repeating each turn until one -// of the win/lose conditions is met. -func play(pile, min, max int, start StartOption, win WinOption) { - gameOver := false - playersTurn := (start == PlayerFirst) - - for !gameOver { - if playersTurn { - gameOver, pile = playerMove(pile, min, max, win) - playersTurn = false - if gameOver { - return - } - } - - if !playersTurn { - gameOver, pile = computerMove(pile, min, max, win) - playersTurn = true - } - } -} - -// Print out the introduction and rules of the game -func printIntro() { - fmt.Printf("%33s%s\n", " ", "BATNUM") - fmt.Printf("%15s%s\n", " ", "CREATIVE COMPUTING MORRISSTOWN, NEW JERSEY") - fmt.Printf("\n\n\n") - fmt.Println("THIS PROGRAM IS A 'BATTLE OF NUMBERS' GAME, WHERE THE") - fmt.Println("COMPUTER IS YOUR OPPONENT.") - fmt.Println() - fmt.Println("THE GAME STARTS WITH AN ASSUMED PILE OF OBJECTS. YOU") - fmt.Println("AND YOUR OPPONENT ALTERNATELY REMOVE OBJECTS FROM THE PILE.") - fmt.Println("WINNING IS DEFINED IN ADVANCE AS TAKING THE LAST OBJECT OR") - fmt.Println("NOT. YOU CAN ALSO SPECIFY SOME OTHER BEGINNING CONDITIONS.") - fmt.Println("DON'T USE ZERO, HOWEVER, IN PLAYING THE GAME.") - fmt.Println("ENTER A NEGATIVE NUMBER FOR NEW PILE SIZE TO STOP PLAYING.") - fmt.Println() -} - -func main() { - for { - printIntro() - - g := NewOptions() - - if g.pileSize < 0 { - return - } - - play(g.pileSize, g.minSelect, g.maxSelect, g.startOption, g.winOption) - } -} diff --git a/00_Alternate_Languages/09_Battle/MiniScript/README.md b/00_Alternate_Languages/09_Battle/MiniScript/README.md deleted file mode 100644 index 07cd98272..000000000 --- a/00_Alternate_Languages/09_Battle/MiniScript/README.md +++ /dev/null @@ -1,21 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -NOTE: One feature has been added to the original game. At the "??" prompt, instead of entering coordinates, you can enter "?" (a question mark) to reprint the fleet disposition code. - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript battle.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "battle" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/09_Battle/MiniScript/battle.ms b/00_Alternate_Languages/09_Battle/MiniScript/battle.ms deleted file mode 100644 index e082b25b5..000000000 --- a/00_Alternate_Languages/09_Battle/MiniScript/battle.ms +++ /dev/null @@ -1,157 +0,0 @@ -print " "*33 + "Battle" -print " "*15 + "Creative Computing Morristown, New Jersey" -// -- BATTLE WRITTEN BY RAY WESTERGARD 10/70 -// COPYRIGHT 1971 BY THE REGENTS OF THE UNIV. OF CALIF. -// PRODUCED AT THE LAWRENCE HALL OF SCIENCE, BERKELEY -// Converted to MiniScript by Joe Strout, July 2023. - -import "listUtil" - -setup = function - // prepare the shield with the bad guys' ships - globals.field = list.init2d(6,6, 0) // matrix of enemy ships -- 0th row/column unused - for shipType in [1,2,3] - for ship in [1,2] - while not addShip(shipType, ship) - // keep trying until we successfully add it! - end while - end for - end for - - // prepare another matrix to keep track of where we have hit - globals.hits = list.init2d(6,6, 0) - - // and some some info per ship (ID) and ship type - globals.shipHitsLeft = [null, 2, 2, 3, 3, 4, 4] // hits left till each ship is sunk - globals.sunkPerType = [0] * 3 // counts how many of each type were sunk - - // finally, keep track of hits and splashes - globals.splashCount = 0 - globals.hitCount = 0 -end function - -// Try to add the given ship to field. -// Return true on success, false on failure. -addShip = function(shipType, shipNum) - size = 5 - shipType - x = floor(rnd * 6) - y = floor(rnd * 6) - direction = floor(rnd * 4) - if direction == 0 then - dx = 1; dy = 0 - else if direction == 1 then - dx = 1; dy = 1 - else if direction == 2 then - dx = 0; dy = 1 - else - dx = -1; dy = 1 - end if - // First make sure our placement doesn't go out of bounds - if not (0 <= x + dx * size <= 5) then return false - if not (0 <= y + dy * size <= 5) then return false - // Then, make sure it's not blocked by another ship - for i in range(0, size-1) - px = x + dx * i // (point under consideration) - py = y + dy * i - // make sure where we want to place the ship is still empty - if field[px][py] then return false - // if placing a ship diagonally, don't allow it to cross - // another ship on the other diagonal - if i > 0 and dx and dy then - adjacent1 = field[px-dx][py] - adjacent2 = field[px][py-dy] - if adjacent1 and adjacent1 == adjacent2 then return false - end if - end for - // Looks like it's all clear, so fill it in! - id = 9 - 2 * shipType - shipNum; - for i in range(0, size-1) - field[x + dx * i][y + dy * i] = id - end for - return true -end function - -// Print the "encoded" fleet disposition. This is just the regular field, -// but rotated and flipped. -printField = function - print - print "The following code of the bad guys' fleet disposition" - print "has been captured but not decoded:" - print - for i in range(0,5) - for j in range(0,5) - print field[5-j][i], " " - end for - print - end for -end function - -doOneTurn = function - while true - xy = input("??").replace(",", " ") - if xy == "?" then; printField; continue; end if // (not in original game) - x = xy[0].val; y = xy[-1].val - if xy.len < 2 or x != floor(x) or x < 1 or x > 6 or y != floor(y) or y < 1 or y > 6 then - print "Invalid input. Try again." - continue - end if - break - end while - row = x - 1 // (minus one since our matrix is 0-based instead of 1-based) - col = y - 1 - shipId = field[row][col] - if shipId == 0 then - // fall through to 'end if' below - else if shipHitsLeft[shipId] == 0 then - print "There used to be a ship at that point, but you sank it." - else if hits[row][col] then - print "You already put a hole in ship number " + shipId + " at that point." - else - hits[row][col] = shipId - print "A direct hit on ship number " + shipId - globals.hitCount += 1 - shipHitsLeft[shipId] -= 1 - if shipHitsLeft[shipId] == 0 then - shipType = floor((shipId-1) / 2) // get ship type, 0-2 - sunkPerType[shipType] += 1 - print "And you sunk it. Hurray for the good guys." - print "So far, the bad guys have lost" - print sunkPerType[0] + " destroyer(s), " + sunkPerType[1] + - " cruiser(s), and " + sunkPerType[2] + " aircraft carrier(s)." - print "Your current splash/hit ratio is " + (splashCount / hitCount) - end if - return - end if - print "Splash! Try again." - globals.splashCount += 1 -end function - -playOneGame = function - setup - printField - print - print "De-code it and use it if you can" - print "but keep the de-coding method a secret." - print - print "START GAME" - - while true - doOneTurn - if sunkPerType.sum == 6 then break - end while - - print - print "You have totally wiped out the bad guys' fleet" - print "with a final splash/hit ratio of " + (splashCount / hitCount) - if splashCount == 0 then - print "Congratulations -- a direct hit every time." - end if -end function - -// Main loop -while true - playOneGame - print - print "****************************" - print -end while diff --git a/00_Alternate_Languages/09_Battle/README.md b/00_Alternate_Languages/09_Battle/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/09_Battle/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/09_Battle/battle.bas b/00_Alternate_Languages/09_Battle/battle.bas deleted file mode 100644 index 6f85f5672..000000000 --- a/00_Alternate_Languages/09_Battle/battle.bas +++ /dev/null @@ -1,196 +0,0 @@ -5 PRINT TAB(33);"BATTLE" -7 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -10 REM -- BATTLE WRITTEN BY RAY WESTERGARD 10/70 -20 REM COPYRIGHT 1971 BY THE REGENTS OF THE UNIV. OF CALIF. -30 REM PRODUCED AT THE LAWRENCE HALL OF SCIENCE, BERKELEY -40 DIM F(6,6),H(6,6),A(4),B(4),C(6),L(3) -50 FOR X=1 TO 6 -51 FOR Y=1 TO 6 -52 F(X,Y)=0 -53 NEXT Y -54 NEXT X -60 FOR I=1 TO 3 -70 N=4-I -80 FOR J=1 TO 2 -90 A=INT(6*RND(1)+1) -100 B=INT(6*RND(1)+1) -110 D=INT(4*RND(1)+1) -120 IF F(A,B)>0 THEN 90 -130 M=0 -140 ON D GOTO 150,340,550,740 -150 B(1)=B -160 B(2)=7:B(3)=7 -170 FOR K=1 TO N -180 IF M>1 THEN 240 -190 IF B(K)=6 THEN 230 -200 IF F(A,B(K)+1)>0 THEN 230 -210 B(K+1)=B(K)+1 -220 GOTO 280 -230 M=2 -240 IF B(1)0 THEN 90 -270 B(K+1)=Z-1 -280 NEXT K -290 F(A,B)=9-2*I-J -300 FOR K=1 TO N -310 F(A,B(K+1))=F(A,B) -320 NEXT K -330 GOTO 990 -340 A(1)=A -350 B(1)=B -360 A(2)=0:A(3)=0:B(2)=0:B(3)=0 -370 FOR K=1 TO N -380 IF M>1 THEN 460 -390 IF A(K)=1 OR B(K)=1 THEN 450 -400 IF F(A(K)-1,B(K)-1)>0 THEN 450 -410 IF F(A(K)-1,B(K))>0 AND F(A(K)-1,B(K))=F(A(K),B(K)-1) THEN 450 -420 A(K+1)=A(K)-1 -430 B(K+1)=B(K)-1 -440 GOTO 530 -450 M=2 -460 IF A(1)>A(2) AND A(1)>A(3) THEN Z1=A(1) -462 IF A(2)>A(1) AND A(2)>A(3) THEN Z1=A(2) -464 IF A(3)>A(1) AND A(3)>A(2) THEN Z1=A(3) -470 IF B(1)>B(2) AND B(1)>B(3) THEN Z2=B(1) -474 IF B(2)>B(1) AND B(2)>B(3) THEN Z2=B(2) -476 IF B(3)>B(1) AND B(3)>B(2) THEN Z2=B(3) -480 IF Z1=6 OR Z2=6 THEN 90 -490 IF F(Z1+1,Z2+1)>0 THEN 90 -500 IF F(Z1,Z2+1)>0 AND F(Z1,Z2+1)=F(Z1+1,Z2) THEN 90 -510 A(K+1)=Z1+1 -520 B(K+1)=Z2+1 -530 NEXT K -540 GOTO 950 -550 A(1)=A -560 A(2)=7:A(3)=7 -570 FOR K=1 TO N -580 IF M>1 THEN 640 -590 IF A(K)=6 THEN 630 -600 IF F(A(K)+1,B)>0 THEN 630 -610 A(K+1)=A(K)+1 -620 GOTO 680 -630 M=2 -640 IF A(1)0 THEN 90 -670 A(K+1)=Z-1 -680 NEXT K -690 F(A,B)=9-2*I-J -700 FOR K=1 TO N -710 F(A(K+1),B)=F(A,B) -720 NEXT K -730 GOTO 990 -740 A(1)=A -750 B(1)=B -760 A(2)=7:A(3)=7 -770 B(2)=0:B(3)=0 -780 FOR K=1 TO N -790 IF M>1 THEN 870 -800 IF A(K)=6 OR B(K)=1 THEN 860 -810 IF F(A(K)+1,B(K)-1)>0 THEN 860 -820 IF F(A(K)+1,B(K))>0 AND F(A(K)+1,B(K))=F(A(K),B(K)-1) THEN 860 -830 A(K+1)=A(K)+1 -840 B(K+1)=B(K)-1 -850 GOTO 940 -860 M=2 -870 IF A(1)B(2) AND B(1)>B(3) THEN Z2=B(1) -882 IF B(2)>B(1) AND B(2)>B(3) THEN Z2=B(2) -884 IF B(3)>B(1) AND B(3)>B(2) THEN Z2=B(3) -890 IF Z1=1 OR Z2=6 THEN 90 -900 IF F(Z1-1,Z2+1)>0 THEN 90 -910 IF F(Z1,Z2+1)>0 AND F(Z1,Z2+1)=F(Z1-1,Z2) THEN 90 -920 A(K+1)=Z1-1 -930 B(K+1)=Z2+1 -940 NEXT K -950 F(A,B)=9-2*I-J -960 FOR K=1 TO N -970 F(A(K+1),B(K+1))=F(A,B) -980 NEXT K -990 NEXT J -1000 NEXT I -1010 PRINT -1020 PRINT "THE FOLLOWING CODE OF THE BAD GUYS' FLEET DISPOSITION" -1030 PRINT "HAS BEEN CAPTURED BUT NOT DECODED:" -1040 PRINT -1050 FOR I=1 TO 6 -1051 FOR J=1 TO 6 -1052 H(I,J)=F(J,I) -1053 NEXT J -1054 NEXT I -1060 FOR I=1 TO 6 -1061 FOR J=1 TO 6 -1062 PRINT H(I,J); -1063 NEXT J -1064 PRINT -1065 NEXT I -1070 PRINT -1080 PRINT "DE-CODE IT AND USE IT IF YOU CAN" -1090 PRINT "BUT KEEP THE DE-CODING METHOD A SECRET." -1100 PRINT -1110 FOR I=1 TO 6 -1111 FOR J=1 TO 6 -1112 H(I,J)=0 -1113 NEXT J -1114 NEXT I -1120 FOR I=1 TO 3 -1121 L(I)=0 -1122 NEXT I -1130 C(1)=2:C(2)=2 -1140 C(3)=1:C(4)=1 -1150 C(5)=0:C(6)=0 -1160 S=0:H=0 -1170 PRINT "START GAME" -1180 INPUT X,Y -1190 IF X<1 OR X>6 OR INT(X)<>ABS(X) THEN 1210 -1200 IF Y>0 AND Y<7 AND INT(Y)=ABS(Y) THEN 1230 -1210 PRINT "INVALID INPUT. TRY AGAIN." -1220 GOTO 1180 -1230 R=7-Y -1240 C=X -1250 IF F(R,C)>0 THEN 1290 -1260 S=S+1 -1270 PRINT "SPLASH! TRY AGAIN." -1280 GOTO 1180 -1290 IF C(F(R,C))<4 THEN 1340 -1300 PRINT "THERE USED TO BE A SHIP AT THAT POINT, BUT YOU SUNK IT." -1310 PRINT "SPLASH! TRY AGAIN." -1320 S=S+1 -1330 GOTO 1180 -1340 IF H(R,C)>0 THEN 1420 -1350 H=H+1 -1360 H(R,C)=F(R,C) -1370 PRINT "A DIRECT HIT ON SHIP NUMBER";F(R,C) -1380 C(F(R,C))=C(F(R,C))+1 -1390 IF C(F(R,C))>=4 THEN 1470 -1400 PRINT "TRY AGAIN." -1410 GOTO 1180 -1420 PRINT "YOU ALREADY PUT A HOLE IN SHIP NUMBER";F(R,C); -1430 PRINT "AT THAT POINT." -1440 PRINT "SPLASH! TRY AGAIN." -1450 S=S+1 -1460 GOTO 1180 -1470 L((INT(F(R,C)-1)/2)+1)=L((INT(F(R,C)-1)/2)+1)+1 -1480 PRINT "AND YOU SUNK IT. HURRAH FOR THE GOOD GUYS." -1490 PRINT "SO FAR, THE BAD GUYS HAVE LOST" -1500 PRINT L(1);"DESTROYER(S),";L(2);"CRUISER(S), AND"; -1510 PRINT L(3);"AIRCRAFT CARRIER(S)." -1520 PRINT "YOUR CURRENT SPLASH/HIT RATIO IS";S/H -1530 IF (L(1)+L(2)+L(3))<6 THEN 1180 -1540 PRINT -1550 PRINT "YOU HAVE TOTALLY WIPED OUT THE BAD GUYS' FLEET" -1560 PRINT "WITH A FINAL SPLASH/HIT RATIO OF";S/H -1570 IF S/H>0 THEN 1590 -1580 PRINT "CONGRATULATIONS -- A DIRECT HIT EVERY TIME." -1590 PRINT -1600 PRINT "****************************" -1610 PRINT -1620 GOTO 50 -1630 END diff --git a/00_Alternate_Languages/09_Battle/go/main.go b/00_Alternate_Languages/09_Battle/go/main.go deleted file mode 100644 index c0f911f41..000000000 --- a/00_Alternate_Languages/09_Battle/go/main.go +++ /dev/null @@ -1,266 +0,0 @@ -package main - -import ( - "bufio" - "fmt" - "math/rand" - "os" - "strconv" - "strings" - "time" -) - -const ( - SEA_WIDTH = 6 - DESTROYER_LENGTH = 2 - CRUISER_LENGTH = 3 - CARRIER_LENGTH = 4 -) - -type Point [2]int -type Vector Point -type Sea [][]int - -func NewSea() Sea { - s := make(Sea, 6) - for r := 0; r < SEA_WIDTH; r++ { - c := make([]int, 6) - s[r] = c - } - - return s -} - -func getRandomVector() Vector { - v := Vector{} - - for { - v[0] = rand.Intn(3) - 1 - v[1] = rand.Intn(3) - 1 - - if !(v[0] == 0 && v[1] == 0) { - break - } - } - return v -} - -func addVector(p Point, v Vector) Point { - newPoint := Point{} - - newPoint[0] = p[0] + v[0] - newPoint[1] = p[1] + v[1] - - return newPoint -} - -func isWithinSea(p Point, s Sea) bool { - return (1 <= p[0] && p[0] <= len(s)) && (1 <= p[1] && p[1] <= len(s)) -} - -func valueAt(p Point, s Sea) int { - return s[p[1]-1][p[0]-1] -} - -func reportInputError() { - fmt.Printf("INVALID. SPECIFY TWO NUMBERS FROM 1 TO %d, SEPARATED BY A COMMA.\n", SEA_WIDTH) -} - -func getNextTarget(s Sea) Point { - scanner := bufio.NewScanner(os.Stdin) - - for { - fmt.Println("\n?") - scanner.Scan() - - vals := strings.Split(scanner.Text(), ",") - - if len(vals) != 2 { - reportInputError() - continue - } - - x, xErr := strconv.Atoi(strings.TrimSpace(vals[0])) - y, yErr := strconv.Atoi(strings.TrimSpace(vals[1])) - - if (len(vals) != 2) || (xErr != nil) || (yErr != nil) { - reportInputError() - continue - } - - p := Point{} - p[0] = x - p[1] = y - if isWithinSea(p, s) { - return p - } - } -} - -func setValueAt(value int, p Point, s Sea) { - s[p[1]-1][p[0]-1] = value -} - -func hasShip(s Sea, code int) bool { - hasShip := false - for r := 0; r < SEA_WIDTH; r++ { - for c := 0; c < SEA_WIDTH; c++ { - if s[r][c] == code { - hasShip = true - break - } - } - } - return hasShip -} - -func countSunk(s Sea, codes []int) int { - sunk := 0 - - for _, c := range codes { - if !hasShip(s, c) { - sunk += 1 - } - } - - return sunk -} - -func placeShip(s Sea, size, code int) { - for { - start := Point{} - start[0] = rand.Intn(SEA_WIDTH) + 1 - start[1] = rand.Intn(SEA_WIDTH) + 1 - vector := getRandomVector() - - point := start - points := []Point{} - - for i := 0; i < size; i++ { - point = addVector(point, vector) - points = append(points, point) - } - - clearPosition := true - for _, p := range points { - if !isWithinSea(p, s) { - clearPosition = false - break - } - if valueAt(p, s) > 0 { - clearPosition = false - break - } - } - if !clearPosition { - continue - } - - for _, p := range points { - setValueAt(code, p, s) - } - break - } -} - -func setupShips(s Sea) { - placeShip(s, DESTROYER_LENGTH, 1) - placeShip(s, DESTROYER_LENGTH, 2) - placeShip(s, CRUISER_LENGTH, 3) - placeShip(s, CRUISER_LENGTH, 4) - placeShip(s, CARRIER_LENGTH, 5) - placeShip(s, CARRIER_LENGTH, 6) -} - -func printIntro() { - fmt.Println(" BATTLE") - fmt.Println("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") - fmt.Println() - fmt.Println("THE FOLLOWING CODE OF THE BAD GUYS' FLEET DISPOSITION") - fmt.Println("HAS BEEN CAPTURED BUT NOT DECODED: ") - fmt.Println() -} - -func printInstructions() { - fmt.Println() - fmt.Println() - fmt.Println("DE-CODE IT AND USE IT IF YOU CAN") - fmt.Println("BUT KEEP THE DE-CODING METHOD A SECRET.") - fmt.Println() - fmt.Println("START GAME") -} - -func printEncodedSea(s Sea) { - for x := 0; x < SEA_WIDTH; x++ { - fmt.Println() - for y := SEA_WIDTH - 1; y > -1; y-- { - fmt.Printf(" %d", s[y][x]) - } - } - fmt.Println() -} - -func wipeout(s Sea) bool { - for c := 1; c <= 7; c++ { - if hasShip(s, c) { - return false - } - } - return true -} - -func main() { - rand.Seed(time.Now().UnixNano()) - - s := NewSea() - - setupShips(s) - - printIntro() - - printEncodedSea(s) - - printInstructions() - - splashes := 0 - hits := 0 - - for { - target := getNextTarget(s) - targetValue := valueAt(target, s) - - if targetValue < 0 { - fmt.Printf("YOU ALREADY PUT A HOLE IN SHIP NUMBER %d AT THAT POINT.\n", targetValue) - } - - if targetValue <= 0 { - fmt.Println("SPLASH! TRY AGAIN.") - splashes += 1 - continue - } - - fmt.Printf("A DIRECT HIT ON SHIP NUMBER %d\n", targetValue) - hits += 1 - setValueAt(targetValue*-1, target, s) - - if !hasShip(s, targetValue) { - fmt.Println("AND YOU SUNK IT. HURRAH FOR THE GOOD GUYS.") - fmt.Println("SO FAR, THE BAD GUYS HAVE LOST") - fmt.Printf("%d DESTROYER(S), %d CRUISER(S), AND %d AIRCRAFT CARRIER(S).\n", countSunk(s, []int{1, 2}), countSunk(s, []int{3, 4}), countSunk(s, []int{5, 6})) - } - - if !wipeout(s) { - fmt.Printf("YOUR CURRENT SPLASH/HIT RATIO IS %2f\n", float32(splashes)/float32(hits)) - continue - } - - fmt.Printf("YOU HAVE TOTALLY WIPED OUT THE BAD GUYS' FLEET WITH A FINAL SPLASH/HIT RATIO OF %2f\n", float32(splashes)/float32(hits)) - - if splashes == 0 { - fmt.Println("CONGRATULATIONS -- A DIRECT HIT EVERY TIME.") - } - - fmt.Println("\n****************************") - break - } -} diff --git a/00_Alternate_Languages/10_Blackjack/MiniScript/README.md b/00_Alternate_Languages/10_Blackjack/MiniScript/README.md deleted file mode 100644 index 2f68bb794..000000000 --- a/00_Alternate_Languages/10_Blackjack/MiniScript/README.md +++ /dev/null @@ -1,21 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript blackjack.ms -``` -But note that the current release (1.2.1) of command-line MiniScript does not properly flush the output buffer when line breaks are suppressed, as this program does when prompting for your next action after a Hit. So, method 2 (below) is recommended for now. - -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "blackjack" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/10_Blackjack/MiniScript/blackjack.ms b/00_Alternate_Languages/10_Blackjack/MiniScript/blackjack.ms deleted file mode 100644 index f6d7959b7..000000000 --- a/00_Alternate_Languages/10_Blackjack/MiniScript/blackjack.ms +++ /dev/null @@ -1,285 +0,0 @@ -import "listUtil" -print " "*31 + "Black Jack" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print - -fna = function(q); return q - 11*(q >= 22); end function -hands = [[]]*15 // hands(i,j) is the jth card in hand i (P) -handValue = [0]*15 // total value of each hand (Q) -deck = [] // the deck being dealt from (C) -playerMoney = [0]*8 // total $ for each player (T) -roundWinnings = [0]*7 // total $ won/lost this hand for each player (S) -betPerHand = [0]*15 // bet for each hand (B) - -cardNames = " A 2 3 4 5 6 7 8 9 10 J Q K".split - -reshuffle = function - print "Reshuffling" - globals.deck = range(1,13)*4 - deck.shuffle -end function - -// Function to draw a card from the deck (reshuffling if needed) -getCard = function - if not deck then reshuffle - return deck.pop -end function - -// Function to get a name for the given card, preceded by "a" or "an" -a = function(cardNum) - article = "a" + "n" * (cardNum == 1 or cardNum == 8) - return article + " " + cardNames[cardNum] -end function - -// Function to evaluate the given hand. Total is usually put into -// handValue(handNum). Totals have the following meaning: -// 2-10...Hard 2-10 -// 11-21...Soft 11-21 -// 22-32...Hard 11-21 -// 33+ or -1...Busted -evalHand = function(handNum) - result = 0 - for card in hands[handNum] - result = addCardToTotal(result, card) - end for - return result -end function - -// Function to add a card into a total hand value. -addCardToTotal = function(total, card) - if total < 0 then return total // (already busted) - x1 = card; if x1 > 10 then x1 = 10 - q1 = total + x1 - if total < 11 then - if card == 1 then return total + 11 // (ace) - return q1 + 11 * (q1 >= 11) - end if - total = q1 + (total <= 21 and q1 > 21) - if total >= 33 then total = -1 - return total -end function - -// Print one of those totals as it should appear to the user. -displayTotal = function(total) - return total - 11 * (total >= 22) -end function - -// Get a yes/no response from the user -getYesNo = function(prompt) - while true - inp = input(prompt).upper - if inp and (inp[0] == "Y" or inp[0] == "N") then return inp[0] - end while -end function - -// Get a number, within a given range, from the user -getNumber = function(prompt, minVal=0, maxVal=500) - while true - result = input(prompt).val - if result == floor(result) and minVal <= result <= maxVal then return result - print "Please enter a number from " + minVal + " to " + maxVal - end while -end function - -// Get one of a list of one-letter (uppercase) options. -getOption = function(prompt, options) - while true - result = input(prompt).upper - if result and options.indexOf(result[0]) != null then return result[0] - print "Type " + options[:-1].join(", ") + " or " + options[-1] + " please" - end while -end function - -getBets = function - print "Bets:" - for i in range(0, numPlayers-1) - betPerHand[i] = getNumber("# " + (i+1) + "? ", 1, 500) - end for -end function - -playOneRound = function - globals.roundWinnings = [0] * numPlayers - if deck.len < (numPlayers+1) * 2 then reshuffle - getBets - print "PLAYER ", "" - for i in range(0, numPlayers-1) - print i+1, " " - hands[i] = [] - end for - print "DEALER" - hands[numPlayers] = [] - for row in [1,2] - print " ", "" - for i in range(0, numPlayers) - hands[i].push getCard - if row == 1 or i < numPlayers then - print " " + (cardNames[hands[i][-1]] + " ")[:2], " " - end if - end for - print - end for - dealerCard0 = hands[numPlayers][0] - dealerCard1 = hands[numPlayers][1] - // Test for insurance - if dealerCard0 == 1 and getYesNo("Any insurance? ") == "Y" then - print "Insurance Bets" - for i in range(0, numPlayers-1) - insurance = getNumber("# " + (i+1) + "? ", 0, betPerHand[i]/2) - roundWinnings[i] = insurance * (3 * (dealerCard1 >= 10) - 1) - end for - end if - // Test for dealer blackjack - if (dealerCard0==1 and dealerCard1 > 9) or - (dealerCard0 > 9 and dealerCard1==1) then - print; print "Dealer has " + a(dealerCard1) + " in the hole for Blackjack" - for i in range(0, numPlayers) - handValue[i] = evalHand(i) - end for - else - // no dealer blackjack - if dealerCard0 == 1 or dealerCard0 >= 10 then - print; print "No dealer Blackjack." - end if - // now play the hands - for i in range(0, numPlayers-1) - playHand i - end for - handValue[numPlayers] = evalHand(numPlayers) // (evaluate dealer hand) - // Test for playing the dealer's hand... we only do so if - // there are any player hands with cards left. - anyLeft = false - for i in range(0, numPlayers-1) - if hands[i] or hands[i+8] then anyLeft = true - end for - if not anyLeft then - print "Dealer had " + a(hands[numPlayers][1]) + " concealed." - else - // Play dealer's hand. - dispTotal = displayTotal(handValue[numPlayers]) - print "Dealer has " + a(hands[numPlayers][1]) + " concealed" + - " for a total of " + dispTotal + "." - while handValue[numPlayers] > 0 and dispTotal <= 16 - card = getCard - if hands[numPlayers].len == 2 then print "Draws ", "" - print cardNames[card], " " - hands[numPlayers].push card - handValue[numPlayers] = evalHand(numPlayers) - dispTotal = displayTotal(handValue[numPlayers]) - end while - if hands[numPlayers].len > 2 then - if handValue[numPlayers] < 0 then print " ---Busted" else print " ---Total is " + dispTotal - end if - print - end if - end if - tallyResults -end function - -playHand = function(handNum, prompt=null, allowSplit=true) - if not prompt then prompt = "Player " + (handNum % 8 + 1) - while hands[handNum] - options = ["H", "S", "D"] + ["/"] * allowSplit - choice = getOption(prompt + "? ", options) - if choice == "S" then // player wants to stand - handValue[handNum] = evalHand(handNum) - if handValue[handNum] == 21 and hands[handNum].len == 2 then - print "Blackjack" - roundWinnings[handNum] += 1.5 * betPerHand[handNum] - betPerHand[handNum] = 0 - discardHand handNum - else - print "Total is " + displayTotal(handValue[handNum]) - end if - break - else if choice == "D" or choice == "H" then // hit or double down - handValue[handNum] = evalHand(handNum) - if choice == "D" then betPerHand[handNum] *= 2 - card = getCard - print "Received " + a(card), " " - hands[handNum].push card - handValue[handNum] = evalHand(handNum) - if handValue[handNum] < 0 then - print "...Busted" - discardHand handNum - roundWinnings[handNum] = -betPerHand[handNum] - betPerHand[handNum] = 0 - end if - prompt = "Hit" - if choice == "D" then; print; break; end if - else if choice == "/" then // split - card1 = hands[handNum][0]; if card1 > 10 then card1 = 10 - card2 = hands[handNum][1]; if card2 > 10 then card2 = 10 - if card1 != card2 then - print "Splitting not allowed." - continue - end if - hand2 = handNum + 8 - hands[hand2] = [hands[handNum].pop] - betPerHand[hand2] = betPerHand[handNum] - card = getCard - print "First hand receives " + a(card) - hands[handNum].push card - card = getCard - print "Second hand receives " + a(card) - hands[hand2].push card - if card1 != 1 then - // Now play the two hands - playHand handNum, "Hand 1", false - playHand hand2, "Hand 2", false - end if - break - end if - allowSplit = false - end while -end function - -discardHand = function(handNum) - hands[handNum] = [] - handValue[handNum] = 0 -end function - -tallyResults = function - dealerTotal = displayTotal(evalHand(numPlayers)) - for i in range(0, numPlayers-1) - playerHandATotal = displayTotal(evalHand(i)) - playerHandBTotal = displayTotal(evalHand(i+8)) - // calculate roundWinnings[i], which is the $ won/lost for player i - roundWinnings[i] = roundWinnings[i] + betPerHand[i]*sign(playerHandATotal - dealerTotal) + betPerHand[i+8]*sign(playerHandBTotal - dealerTotal) - betPerHand[i+8] = 0 - s = "Player " + (i+1) + " " - s += ["loses", "pushes", "wins"][sign(roundWinnings[i])+1] - if roundWinnings[i] != 0 then s += " " + abs(roundWinnings[i]) - playerMoney[i] += roundWinnings[i] - playerMoney[numPlayers] -= roundWinnings[i] - s = (s + " "*25)[:25] + "Total = " + playerMoney[i] - print s - discardHand i - discardHand i+8 - end for - print "Dealer's total = " + playerMoney[numPlayers] - print -end function - -// Main program starts here - -if getYesNo("Do you want instructions? ") == "Y" then - print "This is the game of 21. As many as 7 players may play the" - print "game. On each deal, bets will be asked for, and the" - print "players' bets should be typed in. The cards will then be" - print "dealt, and each player in turn plays his hand. The" - print "first response should be either 'D', indicating that the" - print "player is doubling down, 'S', indicating that he is" - print "standing, 'H', indicating he wants another card, or '/'," - print "indicating that he wants to split his cards. After the" - print "initial response, all further responses should be 'S' or" - print "'H', unless the cards were split, in which case doubling" - print "down is again permitted. In order to collect for" - print "blackjack, the initial response should be 'S'." - print -end if -numPlayers = getNumber("Number of players? ", 1, 7) -print -// main loop! -while true - playOneRound -end while diff --git a/00_Alternate_Languages/10_Blackjack/README.md b/00_Alternate_Languages/10_Blackjack/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/10_Blackjack/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/10_Blackjack/blackjack.bas b/00_Alternate_Languages/10_Blackjack/blackjack.bas deleted file mode 100644 index 121c6502c..000000000 --- a/00_Alternate_Languages/10_Blackjack/blackjack.bas +++ /dev/null @@ -1,321 +0,0 @@ -2 PRINT TAB(31);"BLACK JACK" -4 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -6 PRINT:PRINT:PRINT -10 DEF FNA(Q)=Q+11*(Q>=22) -20 DIM P(15,12),Q(15),C(52),D(52),T(8),S(7),B(15) -30 DIM R(15) -40 REM--P(I,J) IS THE JTH CARD IN HAND I, Q(I) IS TOTAL OF HAND I -50 REM--C IS THE DECK BEING DEALT FROM, D IS THE DISCARD PILE, -60 REM--T(I) IS THE TOTAL FOR PLAYER I, S(I) IS THE TOTAL THIS HAND FOR -70 REM--PLAYER I, B(I) IS TH BET FOR HAND I -80 REM--R(I) IS THE LENGTH OF P(I,*) -90 GOTO 1500 -100 REM--SUBROUTINE TO GET A CARD. RESULT IS PUT IN X. -110 IF C<51 THEN 230 -120 PRINT "RESHUFFLING" -130 FOR D=D TO 1 STEP -1 -140 C=C-1 -150 C(C)=D(D) -160 NEXT D -170 FOR C1=52 TO C STEP -1 -180 C2=INT(RND(1)*(C1-C+1))+C -190 C3=C(C2) -200 C(C2)=C(C1) -210 C(C1)=C3 -220 NEXT C1 -230 X=C(C) -240 C=C+1 -250 RETURN -300 REM--SUBROUTINE TO EVALUATE HAND I. TOTAL IS PUT INTO -310 REM--Q(I). TOTALS HAVE THE FOLLOWING MEANING: -320 REM-- 2-10...HARD 2-10 -330 REM-- 11-21...SOFT 11-21 -340 REM-- 22-32...HARD 11-21 -350 REM-- 33+....BUSTED -360 Q=0 -370 FOR Q2=1 TO R(I) -380 X=P(I,Q2) -390 GOSUB 500 -400 NEXT Q2 -410 Q(I)=Q -420 RETURN -500 REM--SUBROUTINE TO ADD CARD X TO TOTAL Q. -510 X1=X: IF X1>10 THEN X1=10: REM SAME AS X1=10 MIN X -520 Q1=Q+X1 -530 IF Q>=11 THEN 590 -540 IF X>1 THEN 570 -550 Q=Q+11 -560 RETURN -570 Q=Q1-11*(Q1>=11) -580 RETURN -590 Q=Q1-(Q<=21 AND Q1>21) -600 IF Q<33 THEN 620 -610 Q=-1 -620 RETURN -700 REM--CARD PRINTING SUBROUTINE -710 REM D$ DEFINED ELSEWHERE -720 PRINT MID$(D$,3*X-2,3); -730 PRINT " "; -740 RETURN -750 REM--ALTERNATIVE PRINTING ROUTINE -760 PRINT " ";MID$(D$,3*X-1,2); -770 PRINT " "; -780 RETURN -800 REM--SUBROUTINE TO PLAY OUT A HAND. -810 REM--NO SPLITTING OR BLACKJACKS ALLOWED -820 H1=5 -830 GOSUB 1410 -840 H1=3 -850 ON H GOTO 950,930 -860 GOSUB 100 -870 B(I)=B(I)*2 -880 PRINT "RECEIVED A"; -890 GOSUB 700 -900 GOSUB 1100 -910 IF Q>0 THEN GOSUB 1300 -920 RETURN -930 GOSUB 1320 -940 RETURN -950 GOSUB 100 -960 PRINT "RECEIVED A"; -970 GOSUB 700 -980 GOSUB 1100 -990 IF Q<0 THEN 940 -1000 PRINT "HIT"; -1010 GOTO 830 -1100 REM--SUBROUTINE TO ADD A CARD TO ROW I -1110 R(I)=R(I)+1 -1120 P(I,R(I))=X -1130 Q=Q(I) -1140 GOSUB 500 -1150 Q(I)=Q -1160 IF Q>=0 THEN 1190 -1170 PRINT "...BUSTED" -1180 GOSUB 1200 -1190 RETURN -1200 REM--SUBROUTINE TO DISCARD ROW I -1210 IF R(I)<>0 THEN 1230 -1220 RETURN -1230 D=D+1 -1240 D(D)=P(I,R(I)) -1250 R(I)=R(I)-1 -1260 GOTO 1210 -1300 REM--PRINTS TOTAL OF HAND I -1310 PRINT -1320 AA=Q(I): GOSUB 3400 -1325 PRINT "TOTAL IS";AA -1330 RETURN -1400 REM--SUBROUTINE TO READ REPLY -1410 REM I$ DEFINED ELSEWHERE -1420 INPUT H$: H$=LEFT$(H$,1) -1430 FOR H=1 TO H1 STEP 2 -1440 IF H$=MID$(I$,H,1) THEN 1480 -1450 NEXT H -1460 PRINT "TYPE ";MID$(I$,1,H1-1);" OR ";MID$(I$,H1,2);" PLEASE"; -1470 GOTO 1420 -1480 H=(H+1)/2 -1490 RETURN -1500 REM--PROGRAM STARTS HERE -1510 REM--INITIALIZE -1520 D$="N A 2 3 4 5 6 7N 8 9 10 J Q K" -1530 I$="H,S,D,/," -1540 FOR I=1 TO 13 -1550 FOR J=4*I-3 TO 4*I -1560 D(J)=I -1570 NEXT J -1580 NEXT I -1590 D=52 -1600 C=53 -1610 PRINT "DO YOU WANT INSTRUCTIONS"; -1620 INPUT H$ -1630 IF LEFT$(H$,1)="N" OR LEFT$(H$,1)="n" THEN 1760 -1640 PRINT "THIS IS THE GAME OF 21. AS MANY AS 7 PLAYERS MAY PLAY THE" -1650 PRINT "GAME. ON EACH DEAL, BETS WILL BE ASKED FOR, AND THE" -1660 PRINT "PLAYERS' BETS SHOULD BE TYPED IN. THE CARDS WILL THEN BE" -1670 PRINT "DEALT, AND EACH PLAYER IN TURN PLAYS HIS HAND. THE" -1680 PRINT "FIRST RESPONSE SHOULD BE EITHER 'D', INDICATING THAT THE" -1690 PRINT "PLAYER IS DOUBLING DOWN, 'S', INDICATING THAT HE IS" -1700 PRINT "STANDING, 'H', INDICATING HE WANTS ANOTHER CARD, OR '/'," -1710 PRINT "INDICATING THAT HE WANTS TO SPLIT HIS CARDS. AFTER THE" -1720 PRINT "INITIAL RESPONSE, ALL FURTHER RESPONSES SHOULD BE 'S' OR" -1730 PRINT "'H', UNLESS THE CARDS WERE SPLIT, IN WHICH CASE DOUBLING" -1740 PRINT "DOWN IS AGAIN PERMITTED. IN ORDER TO COLLECT FOR" -1750 PRINT "BLACKJACK, THE INITIAL RESPONSE SHOULD BE 'S'." -1760 PRINT "NUMBER OF PLAYERS"; -1770 INPUT N -1775 PRINT -1780 IF N<1 OR N>7 OR N>INT(N) THEN 1760 -1790 FOR I=1 TO 8: T(I)=0: NEXT I -1800 D1=N+1 -1810 IF 2*D1+C>=52 THEN GOSUB 120 -1820 IF C=2 THEN C=C-1 -1830 FOR I=1 TO N: Z(I)=0: NEXT I -1840 FOR I=1 TO 15: B(I)=0: NEXT I -1850 FOR I=1 TO 15: Q(I)=0: NEXT I -1860 FOR I=1 TO 7: S(I)=0: NEXT I -1870 FOR I=1 TO 15: R(I)=0: NEXT I -1880 PRINT "BETS:" -1890 FOR I=1 TO N: PRINT "#";I;: INPUT Z(I): NEXT I -1900 FOR I=1 TO N -1910 IF Z(I)<=0 OR Z(I)>500 THEN 1880 -1920 B(I)=Z(I) -1930 NEXT I -1940 PRINT "PLAYER"; -1950 FOR I=1 TO N -1960 PRINT I;" "; -1970 NEXT I -1980 PRINT "DEALER" -1990 FOR J=1 TO 2 -2000 PRINT TAB(5); -2010 FOR I=1 TO D1 -2020 GOSUB 100 -2030 P(I,J)=X -2040 IF J=1 OR I<=N THEN GOSUB 750 -2050 NEXT I -2060 PRINT -2070 NEXT J -2080 FOR I=1 TO D1 -2090 R(I)=2 -2100 NEXT I -2110 REM--TEST FOR INSURANCE -2120 IF P(D1,1)>1 THEN 2240 -2130 PRINT "ANY INSURANCE"; -2140 INPUT H$ -2150 IF LEFT$(H$,1)<>"Y" THEN 2240 -2160 PRINT "INSURANCE BETS" -2170 FOR I=1 TO N: PRINT "#";I;: INPUT Z(I): NEXT I -2180 FOR I=1 TO N -2190 IF Z(I)<0 OR Z(I)>B(I)/2 THEN 2160 -2200 NEXT I -2210 FOR I=1 TO N -2220 S(I)=Z(I)*(3*(-(P(D1,2)>=10))-1) -2230 NEXT I -2240 REM--TEST FOR DEALER BLACKJACK -2250 L1=1: L2=1 -2252 IF P(D1,1)=1 AND P(D1,2)>9 THEN L1=0: L2=0 -2253 IF P(D1,2)=1 AND P(D1,1)>9 THEN L1=0: L2=0 -2254 IF L1<>0 OR L2<>0 THEN 2320 -2260 PRINT:PRINT "DEALER HAS A";MID$(D$,3*P(D1,2)-2,3);" IN THE HOLE "; -2270 PRINT "FOR BLACKJACK" -2280 FOR I=1 TO D1 -2290 GOSUB 300 -2300 NEXT I -2310 GOTO 3140 -2320 REM--NO DEALER BLACKJACK -2330 IF P(D1,1)>1 AND P(D1,1)<10 THEN 2350 -2340 PRINT:PRINT "NO DEALER BLACKJACK." -2350 REM--NOW PLAY THE HANDS -2360 FOR I=1 TO N -2370 PRINT "PLAYER";I; -2380 H1=7 -2390 GOSUB 1410 -2400 ON H GOTO 2550,2410,2510,2600 -2410 REM--PLAYER WANTS TO STAND -2420 GOSUB 300 -2430 IF Q(I)<>21 THEN 2490 -2440 PRINT "BLACKJACK" -2450 S(I)=S(I)+1.5*B(I) -2460 B(I)=0 -2470 GOSUB 1200 -2480 GOTO 2900 -2490 GOSUB 1320 -2500 GOTO 2900 -2510 REM--PLAYER WANTS TO DOUBLE DOWN -2520 GOSUB 300 -2530 GOSUB 860 -2540 GOTO 2900 -2550 REM--PLAYER WANTS TO BE HIT -2560 GOSUB 300 -2570 H1=3 -2580 GOSUB 950 -2590 GOTO 2900 -2600 REM--PLAYER WANTS TO SPLIT -2610 L1=P(I,1): IF P(I,1)>10 THEN L1=10 -2612 L2=P(I,2): IF P(I,2)>10 THEN L2=10 -2614 IF L1=L2 THEN 2640 -2620 PRINT "SPLITTING NOT ALLOWED." -2630 GOTO 2370 -2640 REM--PLAY OUT SPLIT -2650 I1=I+D1 -2660 R(I1)=2 -2670 P(I1,1)=P(I,2) -2680 B(I+D1)=B(I) -2690 GOSUB 100 -2700 PRINT "FIRST HAND RECEIVES A"; -2710 GOSUB 700 -2720 P(I,2)=X -2730 GOSUB 300 -2740 PRINT -2750 GOSUB 100 -2760 PRINT "SECOND HAND RECEIVES A"; -2770 I=I1 -2780 GOSUB 700 -2790 P(I,2)=X -2800 GOSUB 300 -2810 PRINT -2820 I=I1-D1 -2830 IF P(I,1)=1 THEN 2900 -2840 REM--NOW PLAY THE TWO HANDS -2850 PRINT "HAND";1-(I>D1); -2860 GOSUB 800 -2870 I=I+D1 -2880 IF I=I1 THEN 2850 -2890 I=I1-D1 -2900 NEXT I -2910 GOSUB 300 -2920 REM--TEST FOR PLAYING DEALER'S HAND -2930 FOR I=1 TO N -2940 IF R(I)>0 OR R(I+D1)>0 THEN 3010 -2950 NEXT I -2960 PRINT "DEALER HAD A"; -2970 X=P(D1,2) -2980 GOSUB 700 -2990 PRINT " CONCEALED." -3000 GOTO 3140 -3010 PRINT "DEALER HAS A";MID$(D$,3*P(D1,2)-2,3);" CONCEALED "; -3020 I=D1 -3030 AA=Q(I): GOSUB 3400 -3035 PRINT "FOR A TOTAL OF";AA -3040 IF AA>16 THEN 3130 -3050 PRINT "DRAWS"; -3060 GOSUB 100 -3070 GOSUB 750 -3080 GOSUB 1100 -3090 AA=Q: GOSUB 3400 -3095 IF Q>0 AND AA<17 THEN 3060 -3100 Q(I)=Q-(Q<0)/2 -3110 IF Q<0 THEN 3140 -3120 AA=Q: GOSUB 3400 -3125 PRINT "---TOTAL IS";AA -3130 PRINT -3140 REM--TALLY THE RESULT -3150 REM -3160 Z$="LOSES PUSHES WINS " -3165 PRINT -3170 FOR I=1 TO N -3180 AA=Q(I): GOSUB 3400 -3182 AB=Q(I+D1): GOSUB 3410 -3184 AC=Q(D1): GOSUB 3420 -3186 S(I)=S(I)+B(I)*SGN(AA-AC)+B(I+D1)*SGN(AB-AC) -3188 B(I+D1)=0 -3200 PRINT "PLAYER";I; -3210 PRINT MID$(Z$,SGN(S(I))*6+7,6);" "; -3220 IF S(I)<>0 THEN 3250 -3230 PRINT " "; -3240 GOTO 3260 -3250 PRINT ABS(S(I)); -3260 T(I)=T(I)+S(I) -3270 PRINT "TOTAL=";T(I) -3280 GOSUB 1200 -3290 T(D1)=T(D1)-S(I) -3300 I=I+D1 -3310 GOSUB 1200 -3320 I=I-D1 -3330 NEXT I -3340 PRINT "DEALER'S TOTAL=";T(D1) -3345 PRINT -3350 GOSUB 1200 -3360 GOTO 1810 -3400 AA=AA+11*(AA>=22): RETURN -3410 AB=AB+11*(AB>=22): RETURN -3420 AC=AC+11*(AC>=22): RETURN diff --git a/00_Alternate_Languages/11_Bombardment/MiniScript/README.md b/00_Alternate_Languages/11_Bombardment/MiniScript/README.md deleted file mode 100644 index 4a399a7bd..000000000 --- a/00_Alternate_Languages/11_Bombardment/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript bombardment.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "bombardment" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/11_Bombardment/MiniScript/bombardment.ms b/00_Alternate_Languages/11_Bombardment/MiniScript/bombardment.ms deleted file mode 100644 index a6f75009b..000000000 --- a/00_Alternate_Languages/11_Bombardment/MiniScript/bombardment.ms +++ /dev/null @@ -1,101 +0,0 @@ -print " "*33 + "Bombardment" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print -print "You are on a battlefield with 4 platoons and you" -print "have 25 outposts available where they may be placed." -print "You can only place one platoon at any one outpost." -print "The computer does the same with its four platoons." -print -print "The object of the game is to fire missiles at the" -print "outposts of the computer. It will do the same to you." -print "The one who destroys all four of the enemy's platoons" -print "first is the winner." -print -print "Good luck... and tell us where you want the bodies sent!" -print -input "(Press Return.)" // (so user can read the above) -print -print "Tear off matrix and use it to check off the numbers." -for i in range(1,5); print; end for -memory = [] // records computer's guesses -for row in range(1,5) - for i in range(row*5-4, row*5) - print (" " + i)[-6:], "" - end for - print -end for -print - -// Define a helper function to pick a random position (1-25) -// that is not already in the given list. -pickOutpost = function(excludingThese) - while true - pick = floor(rnd * 25) + 1 - if excludingThese.indexOf(pick) == null then return pick - end while -end function - -// Choose the computer's four positions. -computerOutposts = [] -for i in range(1,4) - computerOutposts.push pickOutpost(computerOutposts) -end for - -playerOutposts = [] -while playerOutposts.len != 4 - inp = input("What are your four positions? ") - inp = inp.replace(", ", " ").replace(",", " ") - inp = inp.split - for pos in inp - pos = pos.val - playerOutposts.push pos - if pos < 1 or pos > 25 then playerOutposts=[] - end for -end while - -// Main loop. -while true - // player's attack - pos = input("Where do you wish to fire your missile? ").val - if computerOutposts.indexOf(pos) == null then - print "Ha, ha you missed. My turn now:" - else - print "You got one of my outposts!" - computerOutposts.remove computerOutposts.indexOf(pos) - left = computerOutposts.len - if left == 3 then - print "One down, three to go." - else if left == 2 then - print "Two down, two to go." - else if left == 3 then - print "Three down, one to go." - else - print "You got me, I'm going fast. ButI'll get you when" - print "My transisto&s recup%ra*e!" - break - end if - end if - - // computer's attack - pos = pickOutpost(memory) - memory.push pos - if playerOutposts.indexOf(pos) == null then - print "I missed you, you dirty rat. I picked " + pos + ". Your turn:" - else - playerOutposts.remove playerOutposts.indexOf(pos) - left = playerOutposts.len - if left == 0 then - print "You're dead. Your last outpost was at " + pos + ". Ha, ha, ha." - print "Better luck next time." - break - end if - print "I got you. It won't be long now. Post " + pos + " was hit." - if left == 3 then - print "You have only three outposts left." - else if left == 2 then - print "You have only two outposts left." - else if left == 1 then - print "You have only one outpost left." - end if - end if -end while diff --git a/00_Alternate_Languages/11_Bombardment/README.md b/00_Alternate_Languages/11_Bombardment/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/11_Bombardment/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/11_Bombardment/bombardment.bas b/00_Alternate_Languages/11_Bombardment/bombardment.bas deleted file mode 100644 index 0c2950ce4..000000000 --- a/00_Alternate_Languages/11_Bombardment/bombardment.bas +++ /dev/null @@ -1,93 +0,0 @@ -10 PRINT TAB(33);"BOMBARDMENT" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT:PRINT:PRINT -100 PRINT "YOU ARE ON A BATTLEFIELD WITH 4 PLATOONS AND YOU" -110 PRINT "HAVE 25 OUTPOSTS AVAILABLE WHERE THEY MAY BE PLACED." -120 PRINT "YOU CAN ONLY PLACE ONE PLATOON AT ANY ONE OUTPOST." -130 PRINT "THE COMPUTER DOES THE SAME WITH ITS FOUR PLATOONS." -135 PRINT -140 PRINT "THE OBJECT OF THE GAME IS TO FIRE MISSLES AT THE" -150 PRINT "OUTPOSTS OF THE COMPUTER. IT WILL DO THE SAME TO YOU." -160 PRINT "THE ONE WHO DESTROYS ALL FOUR OF THE ENEMY'S PLATOONS" -170 PRINT "FIRST IS THE WINNER." -180 PRINT -190 PRINT "GOOD LUCK... AND TELL US WHERE YOU WANT THE BODIES SENT!" -200 PRINT -210 PRINT "TEAR OFF MATRIX AND USE IT TO CHECK OFF THE NUMBERS." -220 FOR R=1 TO 5: PRINT: NEXT R -260 DIM M(100) -270 FOR R=1 TO 5 -280 I=(R-1)*5+1 -290 PRINT I,I+1,I+2,I+3,I+4 -300 NEXT R -350 FOR R=1 TO 10: PRINT: NEXT R -380 C=INT(RND(1)*25)+1 -390 D=INT(RND(1)*25)+1 -400 E=INT(RND(1)*25)+1 -410 F=INT(RND(1)*25)+1 -420 IF C=D THEN 390 -430 IF C=E THEN 400 -440 IF C=F THEN 410 -450 IF D=E THEN 400 -460 IF D=F THEN 410 -470 IF E=F THEN 410 -480 PRINT "WHAT ARE YOUR FOUR POSITIONS"; -490 INPUT G,H,K,L -495 PRINT -500 PRINT "WHERE DO YOU WISH TO FIRE YOUR MISSLE"; -510 INPUT Y -520 IF Y=C THEN 710 -530 IF Y=D THEN 710 -540 IF Y=E THEN 710 -550 IF Y=F THEN 710 -560 GOTO 630 -570 M=INT(RND(1)*25)+1 -575 GOTO 1160 -580 IF X=G THEN 920 -590 IF X=H THEN 920 -600 IF X=L THEN 920 -610 IF X=K THEN 920 -620 GOTO 670 -630 PRINT "HA, HA YOU MISSED. MY TURN NOW:" -640 PRINT: PRINT: GOTO 570 -670 PRINT "I MISSED YOU, YOU DIRTY RAT. I PICKED";M". YOUR TURN:" -680 PRINT: PRINT: GOTO 500 -710 Q=Q+1 -720 IF Q=4 THEN 890 -730 PRINT "YOU GOT ONE OF MY OUTPOSTS!" -740 IF Q=1 THEN 770 -750 IF Q=2 THEN 810 -760 IF Q=3 THEN 850 -770 PRINT "ONE DOWN, THREE TO GO." -780 PRINT: PRINT: GOTO 570 -810 PRINT "TWO DOWN, TWO TO GO." -820 PRINT: PRINT: GOTO 570 -850 PRINT "THREE DOWN, ONE TO GO." -860 PRINT: PRINT: GOTO 570 -890 PRINT "YOU GOT ME, I'M GOING FAST. BUT I'LL GET YOU WHEN" -900 PRINT "MY TRANSISTO&S RECUP%RA*E!" -910 GOTO 1235 -920 Z=Z+1 -930 IF Z=4 THEN 1110 -940 PRINT "I GOT YOU. IT WON'T BE LONG NOW. POST";X;"WAS HIT." -950 IF Z=1 THEN 990 -960 IF Z=2 THEN 1030 -970 IF Z=3 THEN 1070 -990 PRINT "YOU HAVE ONLY THREE OUTPOSTS LEFT." -1000 PRINT: PRINT: GOTO 500 -1030 PRINT "YOU HAVE ONLY TWO OUTPOSTS LEFT." -1040 PRINT: PRINT: GOTO 500 -1070 PRINT "YOU HAVE ONLY ONE OUTPOST LEFT." -1080 PRINT: PRINT: GOTO 500 -1110 PRINT "YOU'RE DEAD. YOUR LAST OUTPOST WAS AT";X;". HA, HA, HA." -1120 PRINT "BETTER LUCK NEXT TIME." -1150 GOTO 1235 -1160 P=P+1 -1170 N=P-1 -1180 FOR T=1 TO N -1190 IF M=M(T) THEN 570 -1200 NEXT T -1210 X=M -1220 M(P)=M -1230 GOTO 580 -1235 END diff --git a/00_Alternate_Languages/11_Bombardment/go/main.go b/00_Alternate_Languages/11_Bombardment/go/main.go deleted file mode 100644 index e69ff3ea7..000000000 --- a/00_Alternate_Languages/11_Bombardment/go/main.go +++ /dev/null @@ -1,181 +0,0 @@ -package main - -import ( - "bufio" - "fmt" - "math/rand" - "os" - "strconv" - "strings" - "time" -) - -// Messages correspond to outposts remaining (3, 2, 1, 0) -var PLAYER_PROGRESS_MESSAGES = []string{ - "YOU GOT ME, I'M GOING FAST. BUT I'LL GET YOU WHEN\nMY TRANSISTO&S RECUP%RA*E!", - "THREE DOWN, ONE TO GO.\n\n", - "TWO DOWN, TWO TO GO.\n\n", - "ONE DOWN, THREE TO GO.\n\n", -} - -var ENEMY_PROGRESS_MESSAGES = []string{ - "YOU'RE DEAD. YOUR LAST OUTPOST WAS AT %d. HA, HA, HA.\nBETTER LUCK NEXT TIME.", - "YOU HAVE ONLY ONE OUTPOST LEFT.\n\n", - "YOU HAVE ONLY TWO OUTPOSTS LEFT.\n\n", - "YOU HAVE ONLY THREE OUTPOSTS LEFT.\n\n", -} - -func displayField() { - for r := 0; r < 5; r++ { - initial := r*5 + 1 - for c := 0; c < 5; c++ { - //x := strconv.Itoa(initial + c) - fmt.Printf("\t%d", initial+c) - } - fmt.Println() - } - fmt.Print("\n\n\n\n\n\n\n\n\n") -} - -func printIntro() { - fmt.Println(" BOMBARDMENT") - fmt.Println(" CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") - fmt.Println() - fmt.Println() - fmt.Println("YOU ARE ON A BATTLEFIELD WITH 4 PLATOONS AND YOU") - fmt.Println("HAVE 25 OUTPOSTS AVAILABLE WHERE THEY MAY BE PLACED.") - fmt.Println("YOU CAN ONLY PLACE ONE PLATOON AT ANY ONE OUTPOST.") - fmt.Println("THE COMPUTER DOES THE SAME WITH ITS FOUR PLATOONS.") - fmt.Println() - fmt.Println("THE OBJECT OF THE GAME IS TO FIRE MISSLES AT THE") - fmt.Println("OUTPOSTS OF THE COMPUTER. IT WILL DO THE SAME TO YOU.") - fmt.Println("THE ONE WHO DESTROYS ALL FOUR OF THE ENEMY'S PLATOONS") - fmt.Println("FIRST IS THE WINNER.") - fmt.Println() - fmt.Println("GOOD LUCK... AND TELL US WHERE YOU WANT THE BODIES SENT!") - fmt.Println() - fmt.Println("TEAR OFF MATRIX AND USE IT TO CHECK OFF THE NUMBERS.") - fmt.Print("\n\n\n\n") -} - -func positionList() []int { - positions := make([]int, 25) - for i := 0; i < 25; i++ { - positions[i] = i + 1 - } - return positions -} - -// Randomly choose 4 'positions' out of a range of 1 to 25 -func generateEnemyPositions() []int { - positions := positionList() - rand.Shuffle(len(positions), func(i, j int) { positions[i], positions[j] = positions[j], positions[i] }) - return positions[:4] -} - -func isValidPosition(p int) bool { - return p >= 1 && p <= 25 -} - -func promptForPlayerPositions() []int { - scanner := bufio.NewScanner(os.Stdin) - var positions []int - - for { - fmt.Println("\nWHAT ARE YOUR FOUR POSITIONS (1-25)?") - scanner.Scan() - rawPositions := strings.Split(scanner.Text(), " ") - - if len(rawPositions) != 4 { - fmt.Println("PLEASE ENTER FOUR UNIQUE POSITIONS") - goto there - } - - for _, p := range rawPositions { - pos, err := strconv.Atoi(p) - if (err != nil) || !isValidPosition(pos) { - fmt.Println("ALL POSITIONS MUST RANGE (1-25)") - goto there - } - positions = append(positions, pos) - } - if len(positions) == 4 { - return positions - } - - there: - } -} - -func promptPlayerForTarget() int { - scanner := bufio.NewScanner(os.Stdin) - - for { - fmt.Println("\nWHERE DO YOU WISH TO FIRE YOUR MISSILE?") - scanner.Scan() - target, err := strconv.Atoi(scanner.Text()) - - if (err != nil) || !isValidPosition(target) { - fmt.Println("POSITIONS MUST RANGE (1-25)") - continue - } - return target - } -} - -func generateAttackSequence() []int { - positions := positionList() - rand.Shuffle(len(positions), func(i, j int) { positions[i], positions[j] = positions[j], positions[i] }) - return positions -} - -// Performs attack procedure returning True if we are to continue. -func attack(target int, positions *[]int, hitMsg, missMsg string, progressMsg []string) bool { - for i := 0; i < len(*positions); i++ { - if target == (*positions)[i] { - fmt.Print(hitMsg) - - // remove the target just hit - (*positions)[i] = (*positions)[len((*positions))-1] - (*positions)[len((*positions))-1] = 0 - (*positions) = (*positions)[:len((*positions))-1] - - if len((*positions)) != 0 { - fmt.Print(progressMsg[len((*positions))]) - } else { - fmt.Printf(progressMsg[len((*positions))], target) - } - return len((*positions)) > 0 - } - } - fmt.Print(missMsg) - return len((*positions)) > 0 -} - -func main() { - rand.Seed(time.Now().UnixNano()) - - printIntro() - displayField() - - enemyPositions := generateEnemyPositions() - enemyAttacks := generateAttackSequence() - enemyAttackCounter := 0 - - playerPositions := promptForPlayerPositions() - - for { - // player attacks - if !attack(promptPlayerForTarget(), &enemyPositions, "YOU GOT ONE OF MY OUTPOSTS!\n\n", "HA, HA YOU MISSED. MY TURN NOW:\n\n", PLAYER_PROGRESS_MESSAGES) { - break - } - // computer attacks - hitMsg := fmt.Sprintf("I GOT YOU. IT WON'T BE LONG NOW. POST %d WAS HIT.\n", enemyAttacks[enemyAttackCounter]) - missMsg := fmt.Sprintf("I MISSED YOU, YOU DIRTY RAT. I PICKED %d. YOUR TURN:\n\n", enemyAttacks[enemyAttackCounter]) - if !attack(enemyAttacks[enemyAttackCounter], &playerPositions, hitMsg, missMsg, ENEMY_PROGRESS_MESSAGES) { - break - } - enemyAttackCounter += 1 - } - -} diff --git a/00_Alternate_Languages/12_Bombs_Away/MiniScript/README.md b/00_Alternate_Languages/12_Bombs_Away/MiniScript/README.md deleted file mode 100644 index 22bcc0b1a..000000000 --- a/00_Alternate_Languages/12_Bombs_Away/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript bombsaway.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "bombsaway" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/12_Bombs_Away/MiniScript/bombsaway.ms b/00_Alternate_Languages/12_Bombs_Away/MiniScript/bombsaway.ms deleted file mode 100644 index ea06ea48d..000000000 --- a/00_Alternate_Languages/12_Bombs_Away/MiniScript/bombsaway.ms +++ /dev/null @@ -1,112 +0,0 @@ - -getNum = function(prompt, maxVal=5) - while true - num = floor(input(prompt + "? ").val) - if num > 0 and num <= maxVal then return num - print "Try again..." - end while -end function - -showReturn = function - print "You made it through tremendous flak!!" -end function - -showShotDown = function - print "* * * * boom * * * *" - print "You have been shot down....." - print "Dearly beloved, we are gathered here today to pay our" - print "last tribute..." -end function - -showSuccess = function - print "Direct hit!!!! " + floor(100*rnd) + " killed." - print "Mission successful." -end function - -// Function to calculate the mission result for all nations except Japan. -doNonJapanResult = function - print - d = input("How many missions have you flown? ").val - while d >= 160 - print "Missions, not miles..." - print "150 missions is high even for old-timers." - d = input("Now then, how many missions have you flown? ").val - end while - print - if d >= 100 then print "That's pushing the odds!" - if d < 25 then print "Fresh out of training, eh?" - print - if d >= 160 * rnd then - showSuccess - else - print "Missed target by " + floor(2+30*rnd) + " miles!" - print "Now you're really in for it !!"; print - r = getNum("Does the enemy have guns(1), missiles(2), or both(3)") - print - if r != 2 then - s = input("What's the percent hit rate of enemy gunners (10 to 50)? ").val - if s<10 then - print "You lie, but you'll pay..." - showShotDown - return - end if - end if - print - print - if r > 1 then t = 35 else t = 0 - if s + t > 100 * rnd then - showShotDown - else - showReturn - end if - end if -end function - -s = 0 // hit rate of enemy gunners -r = 0 // whether enemy has guns(1), missiles(2), or both(3) - -// Main Loop -while true - print "You are a pilot in a World War II bomber." - a = getNum("What side -- Italy(1), Allies(2), Japan(3), Germany(4)", 4) - - if a == 1 then // Italy - b = getNum("Your target -- Albania(1), Greece(2), North Africa(3)") - print - print ["Should be easy -- you're flying a nazi-made plane.", - "Be careful!!!", "You're going for the oil, eh?"][b-1] - doNonJapanResult - - else if a == 2 then // Allies - g = getNum("Aircraft -- Liberator(1), B-29(2), B-17(3), Lancaster(4)", 4) - print ["You've got 2 tons of bombs flying for Ploesti.", - "You're dumping the A-bomb on Hiroshima.", - "You're chasing the Aismark in the North Sea.", - "You're busting a German heavy water plant in the Ruhr."][g-1] - doNonJapanResult - - else if a == 3 then // Japan (different logic than all others) - print "You're flying a kamikaze mission over the USS Lexington." - isFirst = input("Your first kamikaze mission(y or n)? ").lower - if isFirst and isFirst[0] == "n" then - s = 0 - showReturn - else - print - if rnd > 0.65 then showSuccess else showShotDown - end if - - else // Germany - m = getNum("A nazi, eh? Oh well. Are you going for Russia(1)," + - char(13) + "England(2), or France(3)") - print ["You're nearing Stalingrad.", - "Nearing London. Be careful, they've got radar.", - "Nearing Versailles. Duck soup. They're nearly defenseless."][m-1] - doNonJapanResult - end if - - print; print; print; another = input("Another mission (y or n)? ").lower - if not another or another[0] != "y" then - print "Chicken !!!" ; print ; break - end if -end while diff --git a/00_Alternate_Languages/12_Bombs_Away/README.md b/00_Alternate_Languages/12_Bombs_Away/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/12_Bombs_Away/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/12_Bombs_Away/bombsaway.bas b/00_Alternate_Languages/12_Bombs_Away/bombsaway.bas deleted file mode 100644 index bbf61c8a3..000000000 --- a/00_Alternate_Languages/12_Bombs_Away/bombsaway.bas +++ /dev/null @@ -1,65 +0,0 @@ -8 PRINT "YOU ARE A PILOT IN A WORLD WAR II BOMBER." -10 INPUT "WHAT SIDE -- ITALY(1), ALLIES(2), JAPAN(3), GERMANY(4)";A -20 IF A>0 AND A<5 THEN 25 -22 PRINT "TRY AGAIN..." : GOTO 10 -25 ON A GOTO 30, 110, 200, 220 -30 INPUT "YOUR TARGET -- ALBANIA(1), GREECE(2), NORTH AFRICA(3)";B -40 IF B>0 AND B<4 THEN 45 -42 PRINT "TRY AGAIN..." : GOTO 30 -45 PRINT : ON B GOTO 50, 80,90 -50 PRINT "SHOULD BE EASY -- YOU'RE FLYING A NAZI-MADE PLANE." -60 GOTO 280 -80 PRINT "BE CAREFUL!!!" : GOTO 280 -90 PRINT "YOU'RE GOING FOR THE OIL, EH?" : GOTO 280 -110 INPUT "AIRCRAFT -- LIBERATOR(1), B-29(2), B-17(3), LANCASTER(4)";G -120 IF G>0 AND G<5 THEN 125 -122 PRINT "TRY AGAIN..." : GOTO 110 -125 PRINT : ON G GOTO 130, 150, 170, 190 -130 PRINT "YOU'VE GOT 2 TONS OF BOMBS FLYING FOR PLOESTI." : GOTO 280 -150 PRINT "YOU'RE DUMPING THE A-BOMB ON HIROSHIMA." : GOTO 280 -170 PRINT "YOU'RE CHASING THE BISMARK IN THE NORTH SEA." : GOTO 280 -190 PRINT "YOU'RE BUSTING A GERMAN HEAVY WATER PLANT IN THE RUHR." -195 GOTO 280 -200 PRINT "YOU'RE FLYING A KAMIKAZE MISSION OVER THE USS LEXINGTON." -205 INPUT "YOUR FIRST KAMIKAZE MISSION(Y OR N)";F$ -207 IF F$="N" THEN S=0 : GOTO 358 -210 PRINT : IF RND(1)>.65 THEN 325 -215 GOTO 380 -220 PRINT "A NAZI, EH? OH WELL. ARE YOU GOING FOR RUSSIA(1)," -230 INPUT "ENGLAND(2), OR FRANCE(3)";M : IF M>0 AND M<4 THEN 235 -232 PRINT "TRY AGAIN..." : GOTO 220 -235 PRINT : ON M GOTO 250, 260, 270 -250 PRINT "YOU'RE NEARING STALINGRAD." : GOTO 280 -260 PRINT "NEARING LONDON. BE CAREFUL, THEY'VE GOT RADAR." : GOTO 280 -270 PRINT "NEARING VERSAILLES. DUCK SOUP. THEY'RE NEARLY DEFENSELESS." -280 PRINT -285 INPUT "HOW MANY MISSIONS HAVE YOU FLOWN";D -290 IF D<160 THEN 300 -292 PRINT "MISSIONS, NOT MILES..." -295 PRINT "150 MISSIONS IS HIGH EVEN FOR OLD-TIMERS." -297 PRINT "NOW THEN, "; : GOTO 285 -300 PRINT:IF D<100 THEN 310 -305 PRINT "THAT'S PUSHING THE ODDS!" : GOTO 320 -310 IF D<25 THEN PRINT "FRESH OUT OF TRAINING, EH?" -320 PRINT : IF D<160*RND(1) THEN 330 -325 PRINT "DIRECT HIT!!!! "INT(100*RND(1))"KILLED." -327 PRINT "MISSION SUCCESSFUL." : GOTO 390 -330 PRINT "MISSED TARGET BY"INT(2+30*RND(1))"MILES!" -335 PRINT "NOW YOU'RE REALLY IN FOR IT !!" : PRINT -340 INPUT "DOES THE ENEMY HAVE GUNS(1), MISSILES(2), OR BOTH(3)";R -345 IF R>0 AND R<4 THEN 350 -347 PRINT "TRY AGAIN..." : GOTO 340 -350 PRINT : T=0 : IF R=2 THEN 360 -355 INPUT "WHAT'S THE PERCENT HIT RATE OF ENEMY GUNNERS (10 TO 50)";S -357 IF S<10 THEN PRINT "YOU LIE, BUT YOU'LL PAY...": GOTO 380 -358 PRINT -360 PRINT : IF R>1 THEN T=35 -365 IF S+T>100*RND(1) THEN 380 -370 PRINT "YOU MADE IT THROUGH TREMENDOUS FLAK!!" : GOTO 390 -380 PRINT "* * * * BOOM * * * *" -384 PRINT "YOU HAVE BEEN SHOT DOWN....." -386 PRINT "DEARLY BELOVED, WE ARE GATHERED HERE TODAY TO PAY OUR" -387 PRINT "LAST TRIBUTE..." -390 PRINT:PRINT:PRINT:INPUT "ANOTHER MISSION (Y OR N)";U$ -395 IF U$="Y" THEN 8 -400 PRINT "CHICKEN !!!" : PRINT : END diff --git a/00_Alternate_Languages/12_Bombs_Away/go/main.go b/00_Alternate_Languages/12_Bombs_Away/go/main.go deleted file mode 100644 index 616f44515..000000000 --- a/00_Alternate_Languages/12_Bombs_Away/go/main.go +++ /dev/null @@ -1,188 +0,0 @@ -package main - -import ( - "bufio" - "fmt" - "math/rand" - "os" - "strconv" - "strings" - "time" -) - -type Choice struct { - idx string - msg string -} - -func playerSurvived() { - fmt.Println("YOU MADE IT THROUGH TREMENDOUS FLAK!!") -} - -func playerDeath() { - fmt.Println("* * * * BOOM * * * *") - fmt.Println("YOU HAVE BEEN SHOT DOWN.....") - fmt.Println("DEARLY BELOVED, WE ARE GATHERED HERE TODAY TO PAY OUR") - fmt.Println("LAST TRIBUTE...") -} - -func missionSuccess() { - fmt.Printf("DIRECT HIT!!!! %d KILLED.\n", int(100*rand.Int())) - fmt.Println("MISSION SUCCESSFUL.") -} - -// 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 -func deathWithChance(probability float64) bool { - return probability > rand.Float64() -} - -func startNonKamikaziAttack() { - numMissions := getIntInput("HOW MANY MISSIONS HAVE YOU FLOWN? ") - - for numMissions > 160 { - fmt.Println("MISSIONS, NOT MILES...") - fmt.Println("150 MISSIONS IS HIGH EVEN FOR OLD-TIMERS") - numMissions = getIntInput("HOW MANY MISSIONS HAVE YOU FLOWN? ") - } - - if numMissions > 100 { - fmt.Println("THAT'S PUSHING THE ODDS!") - } - - if numMissions < 25 { - fmt.Println("FRESH OUT OF TRAINING, EH?") - } - - fmt.Println() - - if float32(numMissions) > (160 * rand.Float32()) { - missionSuccess() - } else { - missionFailure() - } -} - -func missionFailure() { - fmt.Printf("MISSED TARGET BY %d MILES!\n", int(2+30*rand.Float32())) - fmt.Println("NOW YOU'RE REALLY IN FOR IT !!") - fmt.Println() - - enemyWeapons := getInputFromList("DOES THE ENEMY HAVE GUNS(1), MISSILES(2), OR BOTH(3)? ", []Choice{{idx: "1", msg: "GUNS"}, {idx: "2", msg: "MISSILES"}, {idx: "3", msg: "BOTH"}}) - - // 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 - enemyGunnerAccuracy := 0.0 - if enemyWeapons.idx != "2" { - enemyGunnerAccuracy = float64(getIntInput("WHAT'S THE PERCENT HIT RATE OF ENEMY GUNNERS (10 TO 50)? ")) - if enemyGunnerAccuracy < 10.0 { - fmt.Println("YOU LIE, BUT YOU'LL PAY...") - playerDeath() - } - } - - missileThreatWeighting := 35.0 - if enemyWeapons.idx == "1" { - missileThreatWeighting = 0 - } - - death := deathWithChance((enemyGunnerAccuracy + missileThreatWeighting) / 100) - - if death { - playerDeath() - } else { - playerSurvived() - } -} - -func playItaly() { - targets := []Choice{{idx: "1", msg: "SHOULD BE EASY -- YOU'RE FLYING A NAZI-MADE PLANE."}, {idx: "2", msg: "BE CAREFUL!!!"}, {idx: "3", msg: "YOU'RE GOING FOR THE OIL, EH?"}} - target := getInputFromList("YOUR TARGET -- ALBANIA(1), GREECE(2), NORTH AFRICA(3)", targets) - fmt.Println(target.msg) - startNonKamikaziAttack() -} - -func playAllies() { - aircraftMessages := []Choice{{idx: "1", msg: "YOU'VE GOT 2 TONS OF BOMBS FLYING FOR PLOESTI."}, {idx: "2", msg: "YOU'RE DUMPING THE A-BOMB ON HIROSHIMA."}, {idx: "3", msg: "YOU'RE CHASING THE BISMARK IN THE NORTH SEA."}, {idx: "4", msg: "YOU'RE BUSTING A GERMAN HEAVY WATER PLANT IN THE RUHR."}} - aircraft := getInputFromList("AIRCRAFT -- LIBERATOR(1), B-29(2), B-17(3), LANCASTER(4): ", aircraftMessages) - fmt.Println(aircraft.msg) - startNonKamikaziAttack() -} - -func playJapan() { - acknowledgeMessage := []Choice{{idx: "Y", msg: "Y"}, {idx: "N", msg: "N"}} - firstMission := getInputFromList("YOU'RE FLYING A KAMIKAZE MISSION OVER THE USS LEXINGTON.\nYOUR FIRST KAMIKAZE MISSION? (Y OR N): ", acknowledgeMessage) - if firstMission.msg == "N" { - playerDeath() - } - if rand.Float64() > 0.65 { - missionSuccess() - } else { - playerDeath() - } -} - -func playGermany() { - targets := []Choice{{idx: "1", msg: "YOU'RE NEARING STALINGRAD."}, {idx: "2", msg: "NEARING LONDON. BE CAREFUL, THEY'VE GOT RADAR."}, {idx: "3", msg: "NEARING VERSAILLES. DUCK SOUP. THEY'RE NEARLY DEFENSELESS."}} - target := getInputFromList("A NAZI, EH? OH WELL. ARE YOU GOING FOR RUSSIA(1),\nENGLAND(2), OR FRANCE(3)? ", targets) - fmt.Println(target.msg) - startNonKamikaziAttack() -} - -func playGame() { - fmt.Println("YOU ARE A PILOT IN A WORLD WAR II BOMBER.") - side := getInputFromList("WHAT SIDE -- ITALY(1), ALLIES(2), JAPAN(3), GERMANY(4): ", []Choice{{idx: "1", msg: "ITALY"}, {idx: "2", msg: "ALLIES"}, {idx: "3", msg: "JAPAN"}, {idx: "4", msg: "GERMANY"}}) - switch side.idx { - case "1": - playItaly() - case "2": - playAllies() - case "3": - playJapan() - case "4": - playGermany() - } -} - -func main() { - rand.Seed(time.Now().UnixNano()) - - for { - playGame() - if getInputFromList("ANOTHER MISSION (Y OR N):", []Choice{{idx: "Y", msg: "Y"}, {idx: "N", msg: "N"}}).msg == "N" { - break - } - } -} - -func getInputFromList(prompt string, choices []Choice) Choice { - scanner := bufio.NewScanner(os.Stdin) - for { - fmt.Println(prompt) - scanner.Scan() - choice := scanner.Text() - for _, c := range choices { - if strings.EqualFold(strings.ToUpper(choice), strings.ToUpper(c.idx)) { - return c - } - } - fmt.Println("TRY AGAIN...") - } -} - -func getIntInput(prompt string) int { - scanner := bufio.NewScanner(os.Stdin) - for { - fmt.Println(prompt) - scanner.Scan() - choice, err := strconv.Atoi(scanner.Text()) - if err != nil { - fmt.Println("TRY AGAIN...") - continue - } else { - return choice - } - } -} diff --git a/00_Alternate_Languages/13_Bounce/MiniScript/README.md b/00_Alternate_Languages/13_Bounce/MiniScript/README.md deleted file mode 100644 index e7e8f23a7..000000000 --- a/00_Alternate_Languages/13_Bounce/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript bounce.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "bounce" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/13_Bounce/MiniScript/bounce.ms b/00_Alternate_Languages/13_Bounce/MiniScript/bounce.ms deleted file mode 100644 index 64174be62..000000000 --- a/00_Alternate_Languages/13_Bounce/MiniScript/bounce.ms +++ /dev/null @@ -1,55 +0,0 @@ -print " "*33 + "Bounce" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print -t = [0]*21 -print "This simulation lets you specify the initial velocity" -print "of a ball thrown straight up, and the coefficient of" -print "elasticity of the ball. Please use a decimal fraction" -print "coefficiency (less than 1)." -print -print "You also specify the time increment to be used in" -print "'strobing' the ball's flight (try .1 initially)." -print - -addToLine = function(line, tabPos, textToAdd) - return line + " " * (floor(tabPos) - line.len) + textToAdd -end function - -while true - s2 = input("Time increment (sec)? ").val - print - v = input("Velocity (fps)? ").val - print - c = input("Coefficient? ").val - print - print "feet" - print - s1 = floor(70/(v/(16*s2))) - for i in range(1, s1) - t[i]=v*c^(i-1)/16 - end for - for h in range(floor(-16*(v/32)^2+v^2/32+.5), 0, -0.5) - line = "" - if floor(h)==h then line = str(h) - l=0 - for i in range(1, s1) - for time in range(0, t[i], s2) - l=l+s2 - if abs(h-(.5*(-32)*time^2+v*c^(i-1)*time))<=.25 then - line = addToLine(line, l/s2, "0") - end if - end for - time = t[i+1]/2 - if -16*time^2+v*c^(i-1)*time < h then break - end for - print line - end for - print " " + "." * floor((l+1)/s2+1) - line = " 0" - for i in range(1, l+.9995) - line = addToLine(line, i/s2, i) - end for - print line - print " " * floor((l+1)/(2*s2)-2) + "seconds" - print -end while diff --git a/00_Alternate_Languages/13_Bounce/README.md b/00_Alternate_Languages/13_Bounce/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/13_Bounce/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/13_Bounce/bounce.bas b/00_Alternate_Languages/13_Bounce/bounce.bas deleted file mode 100644 index 7dd04509a..000000000 --- a/00_Alternate_Languages/13_Bounce/bounce.bas +++ /dev/null @@ -1,53 +0,0 @@ -10 PRINT TAB(33);"BOUNCE" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT:PRINT:PRINT -90 DIM T(20) -100 PRINT "THIS SIMULATION LETS YOU SPECIFY THE INITIAL VELOCITY" -110 PRINT "OF A BALL THROWN STRAIGHT UP, AND THE COEFFICIENT OF" -120 PRINT "ELASTICITY OF THE BALL. PLEASE USE A DECIMAL FRACTION" -130 PRINT "COEFFICIENCY (LESS THAN 1)." -131 PRINT -132 PRINT "YOU ALSO SPECIFY THE TIME INCREMENT TO BE USED IN" -133 PRINT "'STROBING' THE BALL'S FLIGHT (TRY .1 INITIALLY)." -134 PRINT -135 INPUT "TIME INCREMENT (SEC)";S2 -140 PRINT -150 INPUT "VELOCITY (FPS)";V -160 PRINT -170 INPUT "COEFFICIENT";C -180 PRINT -182 PRINT "FEET" -184 PRINT -186 S1=INT(70/(V/(16*S2))) -190 FOR I=1 TO S1 -200 T(I)=V*C^(I-1)/16 -210 NEXT I -220 FOR H=INT(-16*(V/32)^2+V^2/32+.5) TO 0 STEP -.5 -221 IF INT(H)<>H THEN 225 -222 PRINT H; -225 L=0 -230 FOR I=1 TO S1 -240 FOR T=0 TO T(I) STEP S2 -245 L=L+S2 -250 IF ABS(H-(.5*(-32)*T^2+V*C^(I-1)*T))>.25 THEN 270 -260 PRINT TAB(L/S2);"0"; -270 NEXT T -275 T=T(I+1)/2 -276 IF -16*T^2+V*C^(I-1)*T 0 then - print "Error!!!" // (i.e., didn't clear all the pins in 2 balls) - globals.status = 1 - end if -end function - -rollOneBall = function - print "Type roll to get the ball going." - input // (response ignored) - for i in range(1, 20) - // Generate a random number from 0-99, then take this mod 15. - // This gives us a slightly higher chance of hitting a non-existent - // pin than one of the actual 10. - x = floor(rnd*100) - if x % 15 < 10 then pinDown[x % 15] = 1 - end for - printPinDiagram -end function - -doOneFrame = function - globals.pinDown = [0]*10 - globals.ball = 0 - rollOneBall - printAnalysis - hitOnBall0 = pinDown.sum - scores[frame][player][ball] = hitOnBall0 - - globals.ball = 1 - if hitOnBall0 < 10 then - print "Roll your 2nd ball" - print - rollOneBall - printAnalysis hitOnBall0 - end if - // Note: scoring in this program is not like real bowling. - // It just stores the number of pins down at the end of each ball, - // and a status code (1, 2, or 3). - scores[frame][player][ball] = pinDown.sum - scores[frame][player][2] = status -end function - -pad = function(n, width=3) - return (" "*width + n)[-width:] -end function - -printFinalScores = function - print "FRAMES" - for i in range(1,10) - print pad(i), "" - end for - print - for player in range(0, numPlayers-1) - for i in range(0, 2) - for frame in range(0, 9) - print pad(scores[frame][player][i]), "" - end for - print - end for - print - end for -end function - -playOneGame = function - for f in range(0, 9) - globals.frame = f - for p in range(0, numPlayers-1) - globals.player = p - doOneFrame - end for - end for - print - printFinalScores -end function - -// Main program -print "Welcome to the alley" -print "Bring your friends" -print "Okay let's first get acquainted" -print -ans = input("The instructions (Y/N)? ").upper -if not ans or ans[0] != "N" then printInstructions -while true - numPlayers = input("First of all...How many are playing? ").val - if 0 < numPlayers < 5 then break - print "Please enter a number from 1 to 4." -end while -print -print "Very good..." -while true - playOneGame - print - ans = input("Do you want another game? ").upper - if not ans or ans[0] != "Y" then break -end while diff --git a/00_Alternate_Languages/14_Bowling/README.md b/00_Alternate_Languages/14_Bowling/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/14_Bowling/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/14_Bowling/bowling.bas b/00_Alternate_Languages/14_Bowling/bowling.bas deleted file mode 100644 index a6732580e..000000000 --- a/00_Alternate_Languages/14_Bowling/bowling.bas +++ /dev/null @@ -1,101 +0,0 @@ -10 PRINT TAB(34);"BOWL" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT:PRINT:PRINT -270 DIM C(15),A(100,6) -360 PRINT "WELCOME TO THE ALLEY" -450 PRINT "BRING YOUR FRIENDS" -540 PRINT "OKAY LET'S FIRST GET ACQUAINTED" -630 PRINT "" -720 PRINT "THE INSTRUCTIONS (Y/N)" -810 INPUT Z$ -900 IF Z$="Y" THEN 990 -960 IF Z$="N" THEN 1530 -990 PRINT "THE GAME OF BOWLING TAKES MIND AND SKILL.DURING THE GAME" -1080 PRINT "THE COMPUTER WILL KEEP SCORE.YOU MAY COMPETE WITH" -1170 PRINT "OTHER PLAYERS[UP TO FOUR].YOU WILL BE PLAYING TEN FRAMES" -1260 PRINT "ON THE PIN DIAGRAM 'O' MEANS THE PIN IS DOWN...'+' MEANS THE" -1350 PRINT "PIN IS STANDING.AFTER THE GAME THE COMPUTER WILL SHOW YOUR" -1440 PRINT "SCORES ." -1530 PRINT "FIRST OF ALL...HOW MANY ARE PLAYING"; -1620 INPUT R -1710 PRINT -1800 PRINT "VERY GOOD..." -1890 FOR I=1 TO 100: FOR J=1 TO 6: A(I,J)=0: NEXT J: NEXT I -1980 F=1 -2070 FOR P=1 TO R -2160 M=0 -2250 B=1 -2340 M=0: Q=0 -2430 FOR I=1 TO 15: C(I)=0: NEXT I -2520 REM ARK BALL GENERATOR USING MOD '15' SYSTEM -2610 PRINT "TYPE ROLL TO GET THE BALL GOING." -2700 INPUT N$ -2790 K=0: D=0 -2880 FOR I=1 TO 20 -2970 X=INT(RND(1)*100) -3060 FOR J=1 TO 10 -3150 IF X<15*J THEN 3330 -3240 NEXT J -3330 C(15*J-X)=1 -3420 NEXT I -3510 REM ARK PIN DIAGRAM -3600 PRINT "PLAYER:"P;"FRAME:";F"BALL:"B -3690 FOR I=0 TO 3 -3780 PRINT -3870 FOR J=1 TO 4-I -3960 K=K+1 -4050 IF C(K)=1 THEN 4320 -4140 PRINT TAB(I);"+ "; -4230 GOTO 4410 -4320 PRINT TAB(I);"O "; -4410 NEXT J -4500 NEXT I -4590 PRINT "" -4680 REM ARK ROLL ANALYSIS -4770 FOR I=1 TO 10 -4860 D=D+C(I) -4950 NEXT I -5040 IF D-M <> 0 THEN 5220 -5130 PRINT "GUTTER!!" -5220 IF B<>1 OR D<>10 THEN 5490 -5310 PRINT "STRIKE!!!!!" -5400 Q=3 -5490 IF B<>2 OR D<>10 THEN 5760 -5580 PRINT "SPARE!!!!" -5670 Q=2 -5760 IF B<>2 OR D>=10 THEN 6030 -5850 PRINT "ERROR!!!" -5940 Q=1 -6030 IF B<>1 OR D>=10 THEN 6210 -6120 PRINT "ROLL YOUR 2ND BALL" -6210 REM ARK STORAGE OF THE SCORES -6300 PRINT -6390 A(F*P,B)=D -6480 IF B=2 THEN 7020 -6570 B=2 -6660 M=D -6750 IF Q=3 THEN 6210 -6840 A(F*P,B)=D-M -6930 IF Q=0 THEN 2520 -7020 A(F*P,3)=Q -7110 NEXT P -7200 F=F+1 -7290 IF F<11 THEN 2070 -7295 PRINT "FRAMES" -7380 FOR I=1 TO 10 -7470 PRINT I; -7560 NEXT I -7650 PRINT -7740 FOR P=1 TO R -7830 FOR I=1 TO 3 -7920 FOR J=1 TO 10 -8010 PRINT A(J*P,I); -8100 NEXT J -8105 PRINT -8190 NEXT I -8280 PRINT -8370 NEXT P -8460 PRINT "DO YOU WANT ANOTHER GAME" -8550 INPUT A$ -8640 IF LEFT$(A$,1)="Y" THEN 2610 -8730 END diff --git a/00_Alternate_Languages/15_Boxing/MiniScript/README.md b/00_Alternate_Languages/15_Boxing/MiniScript/README.md deleted file mode 100644 index 9c0ae8fc2..000000000 --- a/00_Alternate_Languages/15_Boxing/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript boxing.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "boxing" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/15_Boxing/MiniScript/boxing.ms b/00_Alternate_Languages/15_Boxing/MiniScript/boxing.ms deleted file mode 100644 index 948a3bdde..000000000 --- a/00_Alternate_Languages/15_Boxing/MiniScript/boxing.ms +++ /dev/null @@ -1,174 +0,0 @@ -print " "*33 + "Boxing" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print -print "Boxing Olympic Style (3 Rounds -- 2 out of 3 Wins)" - -playerWins = 0 -opponentWins = 0 -print -opponentName = input("What is your opponent's name? ") -playerName = input("Input your man's name? ") -print "Different punches are: (1) full swing; (2) hook; (3) uppercut; (4) jab." -playerBest = input("What is your man's best? ").val -playerWeakness = input("What is his vulnerability? " ).val -while true - opponentBest = floor(4 * rnd + 1) - opponentWeakness = floor(4 * rnd + 1) - if opponentBest != opponentWeakness then break -end while -print opponentName + "'s advantage is " + opponentBest + " and vulnerability is secret." -print - -playerConnects = function - print "He connects!" - if playerPoints > 35 then - print opponentName + " is knocked cold and " + playerName + " is the winner and champ!" - globals.done = true - return - end if - globals.playerPoints += 15 -end function - -doPlayerPunch = function - p = input(playerName + "'s punch? ").val - if p == playerBest then globals.playerPoints += 2 - if p == 1 then // Full Swing - print playerName + " swings and ", "" - if opponentWeakness == 4 then // (probably a bug in original code) - playerConnects - else - x3 = floor(30 * rnd+1) - if x3 < 10 then - playerConnects - else - print "he misses " - if playerPoints != 1 then - print - print - end if - end if - end if - else if p == 2 then // Hook - print playerName + " gives the hook... ", "" - if opponentWeakness == 2 then - globals.playerPoints += 7 - else - h1 = floor(2 * rnd + 1) - if h1 == 1 then - print "But it's blocked!!!!!!!!!!!!!" - else - print "Connects..." - globals.playerPoints += 7 - end if - end if - else if p == 3 then // Uppercut - print playerName + " tries an uppercut ", "" - if opponentWeakness == 3 or floor(100 * rnd + 1) < 51 then - print "and he connects!" - globals.playerPoints += 4 - else - print "and it's blocked (lucky block!)" - end if - else // Jab - print playerName + " jabs at " + opponentName + "'s head ", "" - if opponentWeakness != 4 and floor(8 * rnd + 1) >= 4 then - print "It's blocked." - else - globals.playerPoints += 3 - end if - end if -end function - -playerKnockedOut = function - print playerName + " is knocked cold and " + opponentName + " is the winner and champ!" - globals.done = true -end function - -doOpponentPunch = function - j7 = floor(4 * rnd + 1) - if j7 == playerBest then globals.opponentPoints += 2 - if j7 == 1 then // Full swing - print opponentName + " takes a full swing and ", "" - if playerWeakness == 1 or floor(60 * rnd + 1) < 30 then - print "POW!!!!! He hits him right in the face!" - if opponentPoints > 35 then - playerKnockedOut - else - globals.opponentPoints += 15 - end if - else - print "it's blocked!" - end if - end if - if j7 == 2 then // Hook - print opponentName + " gets " + playerName + " in the jaw (ouch!)" - globals.playerPoints += 7 - print "....and again!" - globals.playerPoints += 5 - if opponentPoints > 35 then - playerKnockedOut - return - end if - print - // continue below as if an Uppercut (probably a bug in the original code) - end if - if j7 == 2 or j7 == 3 then // Uppercut, or Hook - print playerName + " is attacked by an uppercut (oh,oh)..." - if playerWeakness == 3 or floor(200*rnd+1) <= 75 then - print "and " + opponentName + " connects..." - globals.opponentPoints += 8 - else - print " blocks and hits " + opponentName + " with a hook." - globals.playerPoints += 5 - end if - end if - if j7 == 4 then // Jab - print opponentName + " jabs and ", "" - if playerWeakness == 4 or floor(7 * rnd + 1) > 4 then - print "blood spills !!!" - globals.opponentPoints += 5 - else - print "It's blocked!" - end if - end if -end function - -playOneRound = function - globals.playerPoints = 0 - globals.opponentPoints = 0 - print "Round " + round + " begins..." - for r1 in range(1, 7) - i = floor(10 * rnd + 1) - if i <= 5 then - doPlayerPunch - else - doOpponentPunch - end if - if done then return - end for // next R1 (sub-round) - if playerPoints > opponentPoints then - print; print playerName + " wins round " + round - globals.playerWins += 1 - else - print; print opponentName + " wins round " + round - globals.opponentWins += 1 - end if -end function - -done = false -for round in range(1,3) - playOneRound - if done then break - if opponentWins >= 2 then - print opponentName + " wins (nice going, " + opponentName + ")." - break - else if playerWins >= 2 then - print playerName + " amazingly wins!!" - break - end if -end for // next round - -print -print -print "and now goodbye from the Olympic arena." -print diff --git a/00_Alternate_Languages/15_Boxing/README.md b/00_Alternate_Languages/15_Boxing/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/15_Boxing/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/15_Boxing/boxing.bas b/00_Alternate_Languages/15_Boxing/boxing.bas deleted file mode 100644 index f6d0d7277..000000000 --- a/00_Alternate_Languages/15_Boxing/boxing.bas +++ /dev/null @@ -1,142 +0,0 @@ -1 PRINT TAB(33);"BOXING" -2 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -3 PRINT:PRINT:PRINT -4 PRINT "BOXING OLYMPIC STYLE (3 ROUNDS -- 2 OUT OF 3 WINS)" -5 J=0 -6 L=0 -8 PRINT -10 PRINT "WHAT IS YOUR OPPONENT'S NAME"; -20 INPUT J$ -30 PRINT "INPUT YOUR MAN'S NAME"; -40 INPUT L$ -50 PRINT "DIFFERENT PUNCHES ARE: (1) FULL SWING; (2) HOOK; (3) UPPERCUT; (4) JAB." -60 PRINT "WHAT IS YOUR MANS BEST"; -64 INPUT B -70 PRINT "WHAT IS HIS VULNERABILITY"; -80 INPUT D -90 B1=INT(4*RND(1)+1) -100 D1=INT(4*RND(1)+1) -110 IF B1=D1 THEN 90 -120 PRINT J$;"'S ADVANTAGE IS";B1;"AND VULNERABILITY IS SECRET.":PRINT -130 FOR R=1 TO 3 -140 IF J>= 2 THEN 1040 -150 IF L>=2 THEN 1060 -160 X=0 -170 Y=0 -180 PRINT "ROUND";R;"BEGINS..." -185 FOR R1= 1 TO 7 -190 I=INT(10*RND(1)+1) -200 IF I>5 THEN 600 -210 PRINT L$;"'S PUNCH"; -220 INPUT P -221 IF P=B THEN 225 -222 GOTO 230 -225 X=X+2 -230 IF P=1 THEN 340 -240 IF P=2 THEN 450 -250 IF P=3 THEN 520 -270 PRINT L$;" JABS AT ";J$"'S HEAD "; -271 IF D1=4 THEN 290 -275 C=INT(8*RND(1)+1) -280 IF C<4 THEN 310 -290 X=X+3 -300 GOTO 950 -310 PRINT "IT'S BLOCKED." -330 GOTO 950 -340 PRINT L$ " SWINGS AND "; -341 IF D1=4 THEN 410 -345 X3=INT(30*RND(1)+1) -350 IF X3<10 THEN 410 -360 PRINT "HE MISSES "; -370 PRINT -375 IF X=1 THEN 950 -380 PRINT -390 PRINT -400 GOTO 300 -410 PRINT "HE CONNECTS!" -420 IF X>35 THEN 980 -425 X=X+15 -440 GOTO 300 -450 PRINT L$;" GIVES THE HOOK... "; -455 IF D1=2 THEN 480 -460 H1=INT(2*RND(1)+1) -470 IF H1=1 THEN 500 -475 PRINT "CONNECTS..." -480 X=X+7 -490 GOTO 300 -500 PRINT "BUT IT'S BLOCKED!!!!!!!!!!!!!" -510 GOTO 300 -520 PRINT L$ " TRIES AN UPPERCUT "; -530 IF D1=3 THEN 570 -540 D5=INT(100*RND(1)+1) -550 IF D5<51 THEN 570 -560 PRINT "AND IT'S BLOCKED (LUCKY BLOCK!)" -565 GOTO 300 -570 PRINT "AND HE CONNECTS!" -580 X=X+4 -590 GOTO 300 -600 J7=INT(4*RND(1)+1) -601 IF J7 =B1 THEN 605 -602 GOTO 610 -605 Y=Y+2 -610 IF J7=1 THEN 720 -620 IF J7=2 THEN 810 -630 IF J7 =3 THEN 860 -640 PRINT J$;" JABS AND "; -645 IF D=4 THEN 700 -650 Z4=INT(7*RND(1)+1) -655 IF Z4>4 THEN 690 -660 PRINT "IT'S BLOCKED!" -670 GOTO 300 -690 PRINT " BLOOD SPILLS !!!" -700 Y=Y+5 -710 GOTO 300 -720 PRINT J$" TAKES A FULL SWING AND"; -730 IF D=1 THEN 770 -740 R6=INT(60*RND(1)+1) -745 IF R6 <30 THEN 770 -750 PRINT " IT'S BLOCKED!" -760 GOTO 300 -770 PRINT " POW!!!!! HE HITS HIM RIGHT IN THE FACE!" -780 IF Y>35 THEN 1010 -790 Y=Y+15 -800 GOTO 300 -810 PRINT J$;" GETS ";L$;" IN THE JAW (OUCH!)" -820 Y=Y+7 -830 PRINT "....AND AGAIN!" -835 Y=Y+5 -840 IF Y>35 THEN 1010 -850 PRINT -860 PRINT L$;" IS ATTACKED BY AN UPPERCUT (OH,OH)..." -865 IF D=3 THEN 890 -870 Q4=INT(200*RND(1)+1) -880 IF Q4>75 THEN 920 -890 PRINT "AND ";J$;" CONNECTS..." -900 Y=Y+8 -910 GOTO 300 -920 PRINT " BLOCKS AND HITS ";J$;" WITH A HOOK." -930 X=X+5 -940 GOTO 300 -950 NEXT R1 -951 IF X>Y THEN 955 -952 PRINT:PRINT J$" WINS ROUND" R -953 J=J+1 -954 GOTO 960 -955 PRINT:PRINT L$" WINS ROUND"R -956 L=L+1 -960 NEXT R -961 IF J>= 2 THEN 1040 -962 IF L>=2 THEN 1060 -980 PRINT J$ " IS KNOCKED COLD AND " L$" IS THE WINNER AND CHAMP!"; -1000 GOTO 1080 -1010 PRINT L$ " IS KNOCKED COLD AND " J$" IS THE WINNER AND CHAMP!"; -1030 GOTO 1000 -1040 PRINT J$ " WINS (NICE GOING," J$;")." -1050 GOTO 1000 -1060 PRINT L$ " AMAZINGLY WINS!!" -1070 GOTO 1000 -1080 PRINT -1085 PRINT -1090 PRINT "AND NOW GOODBYE FROM THE OLYMPIC ARENA." -1100 PRINT -1110 END diff --git a/00_Alternate_Languages/16_Bug/MiniScript/README.md b/00_Alternate_Languages/16_Bug/MiniScript/README.md deleted file mode 100644 index 554d5e529..000000000 --- a/00_Alternate_Languages/16_Bug/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript bug.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "bug" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/16_Bug/MiniScript/bug.ms b/00_Alternate_Languages/16_Bug/MiniScript/bug.ms deleted file mode 100644 index 29349b2a2..000000000 --- a/00_Alternate_Languages/16_Bug/MiniScript/bug.ms +++ /dev/null @@ -1,192 +0,0 @@ -print " "*34 + "Bug" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print -print "The game Bug" -print "I hope you enjoy this game." -print -ans = input("Do you want instructions? ").lower -if not ans or ans[0] != "n" then - 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 "Ihe numbers stand for parts as follows:" - print "Number Part Number of part needed" - print "1 body 1" - print "2 neck 1" - print "3 head 1" - print "4 feelers 2" - print "5 tail 1" - print "6 legs 6" - print - input "(Press Return.)" // (wait before starting the game) - print -end if - -// define a class to represent a bug (with all its body parts) -Bug = {} -Bug.body = false -Bug.neck = false -Bug.head = false -Bug.feelers = 0 -Bug.tail = false -Bug.legs = 0 -Bug.feelerLetter = "F" -Bug.pronoun = "I" - -// add a method to determine if the bug is complete -Bug.complete = function - return self.tail and self.feelers >= 2 and self.legs >= 6 -end function - -// add a method to draw the bug using print -Bug.draw = function - if self.feelers then - for row in range(1,4) - print " "*10 + (self.feelerLetter + " ") * self.feelers - end for - end if - if self.head then - print " HHHHHHH" - print " H H" - print " H O O H" - print " H H" - print " H V H" - print " HHHHHHH" - end if - if self.neck then - print " N N" - print " N N" - end if - if self.body then - print " BBBBBBBBBBBB" - print " B B" - print " B B" - if self.tail then print "TTTTTB B" - print " BBBBBBBBBBBB" - end if - if self.legs then - for row in [1,2] - print " "*5 + "L " * self.legs - end for - end if -end function - -// add a method to add a part, if possible; return true if bug changed -Bug.addPart = function(partNum) - if partNum == 1 then - print "1=Body" - if self.body then - print self.pronoun + " do not need a body." - else - print self.pronoun + " now have a body." - self.body = true - return true - end if - else if partNum == 2 then - print "2=neck" - if self.neck then - print self.pronoun + " do not need a neck." - else if not self.body then - print self.pronoun + " do not have a body." - else - print self.pronoun + " now have a neck." - self.neck = true - return true - end if - else if partNum == 3 then - print "3=head" - if self.head then - print self.pronoun + " have a head." - else if not self.neck then - print self.pronoun + " do not have a neck." - else - print self.pronoun + " needed a head." - self.head = true - return true - end if - else if partNum == 4 then - print "4=feelers" - if self.feelers >= 2 then - print self.pronoun + " have two feelers already." - else if not self.head then - print self.pronoun + " do not have a head." - else - if self.pronoun == "You" then - print "I now give you a feeler." - else - print "I get a feeler." - end if - self.feelers += 1 - return true - end if - else if partNum == 5 then - print "5=tail" - if self.tail then - print self.pronoun + " already have a tail." - else if not self.body then - print self.pronoun + " do not have a body." - else - if self.pronoun == "You" then - print "I now give you a tail." - else - print "I now have a tail." - end if - self.tail = true - return true - end if - else if partNum == 6 then - print "6=legs" - if self.legs >= 6 then - print self.pronoun + " have 6 feet." - else if not self.body then - print self.pronoun + " do not have a body." - else - self.legs += 1 - print self.pronoun + " now have " + self.legs + " leg" + "s"*(self.legs>1) + "." - return true - end if - end if - return 0 -end function - - -// ...then, instantiate a bug for You (human player) and Me (computer) -you = new Bug -you.feelerLetter = "A" // (don't ask me why) -you.pronoun = "You" -me = new Bug - -// Main loop -while not you.complete and not me.complete - anyChange = false - die = floor(6 * rnd + 1) - print; print "You rolled a " + die - if you.addPart(die) then anyChange = true - wait 2 - die = floor(6 * rnd + 1) - print; print "I rolled a " + die - if me.addPart(die) then anyChange = true - if you.complete then print "Your bug is finished." - if me.complete then print "My bug is finished." - if anyChange then - ans = input("Do you want the pictures? ").lower - if not ans or ans[0] != "n" then - print "*****Your Bug*****" - print; print - you.draw - wait 2 - print - print "*****My Bug*****" - print; print - me.draw - wait 2 - end if - end if -end while -print "I hope you enjoyed the game, play it again soon!!" - diff --git a/00_Alternate_Languages/16_Bug/README.md b/00_Alternate_Languages/16_Bug/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/16_Bug/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/16_Bug/bug.bas b/00_Alternate_Languages/16_Bug/bug.bas deleted file mode 100644 index ec129998b..000000000 --- a/00_Alternate_Languages/16_Bug/bug.bas +++ /dev/null @@ -1,256 +0,0 @@ -10 PRINT TAB(34);"BUG" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT:PRINT:PRINT -40 REM -50 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 -60 PRINT "THE GAME BUG" -70 PRINT "I HOPE YOU ENJOY THIS GAME." -80 PRINT -90 PRINT "DO YOU WANT INSTRUCTIONS"; -100 INPUT Z$ -110 IF Z$="NO" THEN 300 -120 PRINT "THE OBJECT OF BUG IS TO FINISH YOUR BUG BEFORE I FINISH" -130 PRINT "MINE. EACH NUMBER STANDS FOR A PART OF THE BUG BODY." -140 PRINT "I WILL ROLL THE DIE FOR YOU, TELL YOU WHAT I ROLLED FOR YOU" -150 PRINT "WHAT THE NUMBER STANDS FOR, AND IF YOU CAN GET THE PART." -160 PRINT "IF YOU CAN GET THE PART I WILL GIVE IT TO YOU." -170 PRINT "THE SAME WILL HAPPEN ON MY TURN." -180 PRINT "IF THERE IS A CHANGE IN EITHER BUG I WILL GIVE YOU THE" -190 PRINT "OPTION OF SEEING THE PICTURES OF THE BUGS." -200 PRINT "THE NUMBERS STAND FOR PARTS AS FOLLOWS:" -210 PRINT "NUMBER","PART","NUMBER OF PART NEEDED" -220 PRINT "1","BODY","1" -230 PRINT "2","NECK","1" -240 PRINT "3","HEAD","1" -250 PRINT "4","FEELERS","2" -260 PRINT "5","TAIL","1" -270 PRINT "6","LEGS","6" -280 PRINT -290 PRINT -300 IF Y>0 THEN 2480 -310 Z=INT(6*RND(1)+1) -320 C=1 -330 PRINT "YOU ROLLED A";Z -340 ON Z GOTO 350,430,540,650,760,870 -350 PRINT "1=BODY" -360 IF B=1 THEN 410 -370 PRINT "YOU NOW HAVE A BODY." -380 B=1 -390 C=0 -400 GOTO 970 -410 PRINT "YOU DO NOT NEED A BODY." -420 GOTO 970 -430 PRINT "2=NECK" -440 IF N=1 THEN 500 -450 IF B=0 THEN 520 -460 PRINT "YOU NOW HAVE A NECK." -470 N=1 -480 C=0 -490 GOTO 970 -500 PRINT "YOU DO NOT NEED A NECK." -510 GOTO 970 -520 PRINT "YOU DO NOT HAVE A BODY." -530 GOTO 970 -540 PRINT "3=HEAD" -550 IF N=0 THEN 610 -560 IF H=1 THEN 630 -570 PRINT "YOU NEEDED A HEAD." -580 H=1 -590 C=0 -600 GOTO 970 -610 PRINT "YOU DO NOT HAVE A NECK." -620 GOTO 970 -630 PRINT "YOU HAVE A HEAD." -640 GOTO 970 -650 PRINT "4=FEELERS" -660 IF H=0 THEN 740 -670 IF A=2 THEN 720 -680 PRINT "I NOW GIVE YOU A FEELER." -690 A=A+1 -700 C=0 -710 GOTO 970 -720 PRINT "YOU HAVE TWO FEELERS ALREADY." -730 GOTO 970 -740 PRINT "YOU DO NOT HAVE A HEAD." -750 GOTO 970 -760 PRINT "5=TAIL" -770 IF B=0 THEN 830 -780 IF T=1 THEN 850 -790 PRINT "I NOW GIVE YOU A TAIL." -800 T=T+1 -810 C=0 -820 GOTO 970 -830 PRINT "YOU DO NOT HAVE A BODY." -840 GOTO 970 -850 PRINT "YOU ALREADY HAVE A TAIL." -860 GOTO 970 -870 PRINT "6=LEG" -880 IF L=6 THEN 940 -890 IF B=0 THEN 960 -900 L=L+1 -910 C=0 -920 PRINT "YOU NOW HAVE";L;"LEGS." -930 GOTO 970 -940 PRINT "YOU HAVE 6 FEET ALREADY." -950 GOTO 970 -960 PRINT "YOU DO NOT HAVE A BODY." -970 X=INT(6*RND(1)+1) -971 PRINT -975 FOR DELAY=1 TO 2000:NEXT DELAY -980 PRINT "I ROLLED A";X -990 ON X GOTO 1000,1080,1190,1300,1410,1520 -1000 PRINT "1=BODY" -1010 IF P=1 THEN 1060 -1020 PRINT "I NOW HAVE A BODY." -1030 C=0 -1040 P=1 -1050 GOTO 1630 -1060 PRINT "I DO NOT NEED A BODY." -1070 GOTO 1630 -1080 PRINT "2=NECK" -1090 IF Q=1 THEN 1150 -1100 IF P=0 THEN 1170 -1110 PRINT "I NOW HAVE A NECK." -1120 Q=1 -1130 C=0 -1140 GOTO 1630 -1150 PRINT "I DO NOT NEED A NECK." -1160 GOTO 1630 -1170 PRINT "I DO NOT HAVE A BODY." -1180 GOTO 1630 -1190 PRINT "3=HEAD" -1200 IF Q=0 THEN 1260 -1210 IF R=1 THEN 1280 -1220 PRINT "I NEEDED A HEAD." -1230 R=1 -1240 C=0 -1250 GOTO 1630 -1260 PRINT "I DO NOT HAVE A NECK." -1270 GOTO 1630 -1280 PRINT "I DO NOT NEED A HEAD." -1290 GOTO 1630 -1300 PRINT "4=FEELERS" -1310 IF R=0 THEN 1390 -1320 IF S=2 THEN 1370 -1330 PRINT "I GET A FEELER." -1340 S=S+1 -1350 C=0 -1360 GOTO 1630 -1370 PRINT "I HAVE 2 FEELERS ALREADY." -1380 GOTO 1630 -1390 PRINT "I DO NOT HAVE A HEAD." -1400 GOTO 1630 -1410 PRINT "5=TAIL" -1420 IF P=0 THEN 1480 -1430 IF U=1 THEN 1500 -1440 PRINT "I NOW HAVE A TAIL." -1450 U=1 -1460 C=0 -1470 GOTO 1630 -1480 PRINT "I DO NOT HAVE A BODY." -1490 GOTO 1630 -1500 PRINT "I DO NOT NEED A TAIL." -1510 GOTO 1630 -1520 PRINT "6=LEGS" -1530 IF V=6 THEN 1590 -1540 IF P=0 THEN 1610 -1550 V=V+1 -1560 C=0 -1570 PRINT "I NOW HAVE";V;"LEGS." -1580 GOTO 1630 -1590 PRINT,"I HAVE 6 FEET." -1600 GOTO 1630 -1610 PRINT "I DO NOT HAVE A BODY." -1620 GOTO 1630 -1630 IF A=2 AND T=1 AND L=6 THEN 1650 -1640 GOTO 1670 -1650 PRINT "YOUR BUG IS FINISHED." -1660 Y=Y+1 -1670 IF S=2 AND P=1 AND V=6 THEN 1690 -1680 GOTO 1710 -1690 PRINT "MY BUG IS FINISHED." -1700 Y=Y+2 -1710 IF C=1 THEN 300 -1720 PRINT "DO YOU WANT THE PICTURES"; -1730 INPUT Z$ -1740 IF Z$="NO" THEN 300 -1750 PRINT "*****YOUR BUG*****" -1760 PRINT -1770 PRINT -1780 IF A=0 THEN 1860 -1790 FOR Z=1 TO 4 -1800 FOR X=1 TO A -1810 PRINT TAB(10); -1820 PRINT "A "; -1830 NEXT X -1840 PRINT -1850 NEXT Z -1860 IF H=0 THEN 1880 -1870 GOSUB 2470 -1880 IF N=0 THEN 1920 -1890 FOR Z=1 TO 2 -1900 PRINT " N N" -1910 NEXT Z -1920 IF B=0 THEN 2000 -1930 PRINT " BBBBBBBBBBBB" -1940 FOR Z=1 TO 2 -1950 PRINT " B B" -1960 NEXT Z -1970 IF T<>1 THEN 1990 -1980 PRINT "TTTTTB B" -1990 PRINT " BBBBBBBBBBBB" -2000 IF L=0 THEN 2080 -2010 FOR Z=1 TO 2 -2020 PRINT TAB(5); -2030 FOR X=1 TO L -2040 PRINT " L"; -2050 NEXT X -2060 PRINT -2070 NEXT Z -2080 FOR Z=1 TO 4 -2090 PRINT -2100 NEXT Z -2110 PRINT "*****MY BUG*****" -2120 PRINT -2130 PRINT -2140 PRINT -2150 IF S=0 THEN 2230 -2160 FOR Z=1 TO 4 -2170 PRINT TAB(10); -2180 FOR X=1 TO S -2190 PRINT "F "; -2200 NEXT X -2210 PRINT -2220 NEXT Z -2230 IF R<>1 THEN 2250 -2240 GOSUB 2470 -2250 IF Q=0 THEN 2280 -2260 PRINT " N N" -2270 PRINT " N N" -2280 IF P=0 THEN 2360 -2290 PRINT " BBBBBBBBBBBB" -2300 FOR Z=1 TO 2 -2310 PRINT " B B" -2320 NEXT Z -2330 IF U<>1 THEN 2350 -2340 PRINT "TTTTTB B" -2350 PRINT " BBBBBBBBBBBB" -2360 IF V=0 THEN 2450 -2370 FOR Z=1 TO 2 -2380 PRINT TAB(5); -2390 FOR X=1 TO V -2400 PRINT " L"; -2410 NEXT X -2420 PRINT -2430 NEXT Z -2450 IF Y<>0 THEN 2540 -2460 GOTO 300 -2470 PRINT " HHHHHHH" -2480 PRINT " H H" -2490 PRINT " H O O H" -2500 PRINT " H H" -2510 PRINT " H V H" -2520 PRINT " HHHHHHH" -2530 RETURN -2540 PRINT "I HOPE YOU ENJOYED THE GAME, PLAY IT AGAIN SOON!!" -2550 END diff --git a/00_Alternate_Languages/17_Bullfight/MiniScript/README.md b/00_Alternate_Languages/17_Bullfight/MiniScript/README.md deleted file mode 100644 index 2290e6e12..000000000 --- a/00_Alternate_Languages/17_Bullfight/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript bull.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "bull" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/17_Bullfight/MiniScript/bull.ms b/00_Alternate_Languages/17_Bullfight/MiniScript/bull.ms deleted file mode 100644 index 1259d651f..000000000 --- a/00_Alternate_Languages/17_Bullfight/MiniScript/bull.ms +++ /dev/null @@ -1,188 +0,0 @@ -print " "*34 + "Bull" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print - -getYesNo = function(prompt) - while true - ans = input(prompt + "? ").lower - if ans and (ans[0] == "y" or ans[0] == "n") then return ans[0] - print "Incorrect answer - - please type 'yes' or 'no'." - end while -end function - -if getYesNo("Do you want instructions") == "y" then - 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; input "(Press return.)" -end if -print; print -bravery = 1 -outcome = 1 -qualities = [null, "superb", "good", "fair", "poor", "awful"] - -// Select a bull (level 1-5, lower numbers are tougher) -bullLevel = floor(rnd*5+1) -print "You have drawn a " + qualities[bullLevel] + " bull." -if bullLevel > 4 then print "You're lucky." -if bullLevel < 2 then print "Good luck. You'll need it." -print - -// Simulate one of the preliminary types of bullfighters -// (picodores or toreadores). Return their effect, 0.1 - 0.5. -simPreliminary = function(fighterType) - effect = 0.1 - temp = 3 / bullLevel * rnd - if temp < 0.87 then effect = 0.2 - if temp < 0.63 then effect = 0.3 - if temp < 0.5 then effect = 0.4 - if temp < 0.37 then effect = 0.5 - t = floor(10 * effect + 0.2) // (get quality in range 1 - 5) - print "The " + fighterType + " did a " + qualities[t] + " job." - if t == 5 then - if fighterType == "picadores" then - print floor(rnd*2+1) + " of the horses of the picadores killed." - end if - print floor(rnd*2+1) + " of the " + fighterType + " killed." - else if t == 4 then - if rnd > 0.5 then - print "One of the " + fighterType + " killed." - else - print "No " + fighterType + " were killed." - end if - end if - print - return effect -end function - -picaEffect = simPreliminary("picadores") -toreEffect = simPreliminary("toreadores") - -getGored = function - while not done - if rnd > 0.5 then - print "You are dead." - globals.bravery = 1.5 - globals.done = true - else - print "You are still alive."; print - if getYesNo("Do you run from the ring") == "y" then - print "Coward" - globals.bravery = 0 - globals.done = true - else - print "You are brave. Stupid, but brave." - if rnd > 0.5 then - globals.bravery = 2 - break - else - print "You are gored again!" - end if - end if - end if - end while -end function - -pass = 0 -courage = 1 // cumulative effect of cape choices -bravery = 1 // set mainly by outcomes after getting gored -victory = false // true if we kill the bull -done = false - -while not done - pass += 1 - print - print "Pass number " + pass - if pass < 3 then - print "The bull is charging at you! You are the matador--" - tryKill = (getYesNo("do you want to kill the bull") == "y") - else - tryKill = (getYesNo("Here comes the bull. Try for a kill") == "y") - end if - if tryKill then - print; print "It is the moment of truth."; print - h = input("How do you try to kill the bull? " ).val - if h != 4 and h != 5 then - print "You panicked. The bull gored you." - getGored - break - end if - k = (6-bullLevel) * 10 * rnd / ((picaEffect + toreEffect) * 5 * pass) - if h == 4 then - victory = (k <= 0.8) - else - victory = (k <= 0.2) - end if - if victory then - print "You killed the bull!" - else - print "The bull has gored you!" - getGored - end if - done = true - else - if pass < 3 then - capeMove = input("What move do you make with the cape? ").val - else - capeMove = input("Cape move? ").val - end if - while capeMove < 0 or capeMove > 2 or capeMove != floor(capeMove) - print "Don't panic, you idiot! Put down a correct number" - capeMove = input.val - end while - m = [3, 2, 0.5][capeMove] - courage += m - f = (6-bullLevel+m/10)*rnd / ((picaEffect+toreEffect+pass/10)*5) - if f >= 0.51 then - print "The bull has gored you!" - getGored - end if - end if -end while - -// Final outcome -if bravery == 0 then - 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 - fnd = (4.5+courage/6-(picaEffect+toreEffect)*2.5+4*bravery+2*(victory+1)-pass^2/120-bullLevel) - fnc = function; return fnd * rnd; end function - if bravery == 2 then - print "The crowd cheers wildly!" - else if victory then - print "The crowd cheers!"; print - end if - print "The crowd awards you" - if fnc < 2.4 then - print "nothing at all." - else if fnc < 4.9 then - print "one ear of the bull." - else if fnc < 7.4 then - print "Both ears of the bull!" - print "Ole!" - else - print "Ole! You are 'Muy Hombre!"" Ole! Ole!" - end if -end if -print -print "Adios"; print; print; print - - - diff --git a/00_Alternate_Languages/17_Bullfight/README.md b/00_Alternate_Languages/17_Bullfight/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/17_Bullfight/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/17_Bullfight/bullfight.bas b/00_Alternate_Languages/17_Bullfight/bullfight.bas deleted file mode 100644 index 32b04b891..000000000 --- a/00_Alternate_Languages/17_Bullfight/bullfight.bas +++ /dev/null @@ -1,193 +0,0 @@ -10 PRINT TAB(34);"BULL" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 DEF FNA(K)=INT(RND(1)*2+1) -200 PRINT:PRINT:PRINT -202 L=1 -205 PRINT "DO YOU WANT INSTRUCTIONS"; -206 INPUT Z$ -207 IF Z$="NO" THEN 400 -210 PRINT "HELLO, ALL YOU BLOODLOVERS AND AFICIONADOS." -220 PRINT "HERE IS YOUR BIG CHANCE TO KILL A BULL." -230 PRINT -240 PRINT "ON EACH PASS OF THE BULL, YOU MAY TRY" -250 PRINT "0 - VERONICA (DANGEROUS INSIDE MOVE OF THE CAPE)" -260 PRINT "1 - LESS DANGEROUS OUTSIDE MOVE OF THE CAPE" -270 PRINT "2 - ORDINARY SWIRL OF THE CAPE." -280 PRINT -290 PRINT "INSTEAD OF THE ABOVE, YOU MAY TRY TO KILL THE BULL" -300 PRINT "ON ANY TURN: 4 (OVER THE HORNS), 5 (IN THE CHEST)." -310 PRINT "BUT IF I WERE YOU," -320 PRINT "I WOULDN'T TRY IT BEFORE THE SEVENTH PASS." -330 PRINT -340 PRINT "THE CROWD WILL DETERMINE WHAT AWARD YOU DESERVE" -350 PRINT "(POSTHUMOUSLY IF NECESSARY)." -360 PRINT "THE BRAVER YOU ARE, THE BETTER THE AWARD YOU RECEIVE." -370 PRINT -380 PRINT "THE BETTER THE JOB THE PICADORES AND TOREADORES DO," -390 PRINT "THE BETTER YOUR CHANCES ARE." -400 PRINT -410 PRINT -420 D(5)=1 -430 D(4)=1 -450 DIM L$(5) -455 A=INT(RND(1)*5+1) -460 FOR I=1 TO 5 -463 READ L$(I) -467 NEXT I -470 DATA "SUPERB","GOOD","FAIR","POOR","AWFUL" -490 PRINT "YOU HAVE DRAWN A ";L$(A);" BULL." -500 IF A>4 THEN 530 -510 IF A<2 THEN 550 -520 GOTO 570 -530 PRINT "YOU'RE LUCKY." -540 GOTO 570 -550 PRINT "GOOD LUCK. YOU'LL NEED IT." -560 PRINT -570 PRINT -590 A$="PICADO" -595 B$="RES" -600 GOSUB 1610 -610 D(1)=C -630 A$="TOREAD" -635 B$="ORES" -640 GOSUB 1610 -650 D(2)=C -660 PRINT -670 PRINT -680 IF Z=1 THEN 1310 -690 D(3)=D(3)+1 -700 PRINT "PASS NUMBER";D(3) -710 IF D(3)<3 THEN 760 -720 PRINT "HERE COMES THE BULL. TRY FOR A KILL"; -730 GOSUB 1930 -735 IF Z1=1 THEN 1130 -740 PRINT "CAPE MOVE"; -750 GOTO 800 -760 PRINT "THE BULL IS CHARGING AT YOU! YOU ARE THE MATADOR--" -770 PRINT "DO YOU WANT TO KILL THE BULL"; -780 GOSUB 1930 -785 IF Z1=1 THEN 1130 -790 PRINT "WHAT MOVE DO YOU MAKE WITH THE CAPE"; -800 INPUT E -810 IF E<>INT(ABS(E)) THEN 830 -820 IF E<3 THEN 850 -830 PRINT "DON'T PANIC, YOU IDIOT! PUT DOWN A CORRECT NUMBER" -840 GOTO 800 -850 REM -860 IF E=0 THEN 920 -870 IF E=1 THEN 900 -880 M=.5 -890 GOTO 930 -900 M=2 -910 GOTO 930 -920 M=3 -930 L=L+M -940 F=(6-A+M/10)*RND(1)/((D(1)+D(2)+D(3)/10)*5) -950 IF F<.51 THEN 660 -960 PRINT "THE BULL HAS GORED YOU!" -970 ON FNA(0) GOTO 980,1010 -980 PRINT "YOU ARE DEAD." -990 D(4)=1.5 -1000 GOTO 1310 -1010 PRINT "YOU ARE STILL ALIVE.":PRINT -1020 PRINT "DO YOU RUN FROM THE RING"; -1030 GOSUB 1930 -1035 IF Z1=2 THEN 1070 -1040 PRINT "COWARD" -1050 D(4)=0 -1060 GOTO 1310 -1070 PRINT "YOU ARE BRAVE. STUPID, BUT BRAVE." -1080 ON FNA(0) GOTO 1090,1110 -1090 D(4)=2 -1100 GOTO 660 -1110 PRINT "YOU ARE GORED AGAIN!" -1120 GOTO 970 -1130 REM -1140 Z=1 -1150 PRINT:PRINT "IT IS THE MOMENT OF TRUTH.":PRINT -1155 PRINT "HOW DO YOU TRY TO KILL THE BULL"; -1160 INPUT H -1170 IF H=4 THEN 1230 -1180 IF H=5 THEN 1230 -1190 PRINT "YOU PANICKED. THE BULL GORED YOU." -1220 GOTO 970 -1230 K=(6-A)*10*RND(1)/((D(1)+D(2))*5*D(3)) -1240 IF H=4 THEN 1290 -1250 IF K>.2 THEN 960 -1260 PRINT "YOU KILLED THE BULL!" -1270 D(5)=2 -1280 GOTO 1320 -1290 IF K>.8 THEN 960 -1300 GOTO 1260 -1310 PRINT -1320 PRINT -1330 PRINT -1340 IF D(4)<>0 THEN 1390 -1350 PRINT "THE CROWD BOOS FOR TEN MINUTES. IF YOU EVER DARE TO SHOW" -1360 PRINT "YOUR FACE IN A RING AGAIN, THEY SWEAR THEY WILL KILL YOU--" -1370 PRINT "UNLESS THE BULL DOES FIRST." -1380 GOTO 1580 -1390 DEF FNC(Q)=FND(Q)*RND(1) -1395 DEF FND(Q)=(4.5+L/6-(D(1)+D(2))*2.5+4*D(4)+2*D(5)-D(3)^2/120-A) -1400 IF D(4)<>2 THEN 1430 -1410 PRINT "THE CROWD CHEERS WILDLY!" -1420 GOTO 1450 -1430 IF D(5)<>2 THEN 1450 -1440 PRINT "THE CROWD CHEERS!":PRINT -1450 PRINT "THE CROWD AWARDS YOU" -1460 IF FNC(Q)<2.4 THEN 1570 -1470 IF FNC(Q)<4.9 THEN 1550 -1480 IF FNC(Q)<7.4 THEN 1520 -1500 PRINT "OLE! YOU ARE 'MUY HOMBRE'!! OLE! OLE!" -1510 GOTO 1580 -1520 PRINT "BOTH EARS OF THE BULL!" -1530 PRINT "OLE!" -1540 GOTO 1580 -1550 PRINT "ONE EAR OF THE BULL." -1560 GOTO 1580 -1570 PRINT "NOTHING AT ALL." -1580 PRINT -1590 PRINT "ADIOS":PRINT:PRINT:PRINT -1600 GOTO 2030 -1610 B=3/A*RND(1) -1620 IF B<.37 THEN 1740 -1630 IF B<.5 THEN 1720 -1640 IF B<.63 THEN 1700 -1650 IF B<.87 THEN 1680 -1660 C=.1 -1670 GOTO 1750 -1680 C=.2 -1690 GOTO 1750 -1700 C=.3 -1710 GOTO 1750 -1720 C=.4 -1730 GOTO 1750 -1740 C=.5 -1750 T=INT(10*C+.2) -1760 PRINT "THE ";A$;B$;" DID A ";L$(T);" JOB." -1770 IF 4>T THEN 1900 -1780 IF 5=T THEN 1870 -1790 ON FNA(K) GOTO 1830,1850 -1800 IF A$="TOREAD" THEN 1820 -1810 PRINT "ONE OF THE HORSES OF THE ";A$;B$;" WAS KILLED." -1820 ON FNA(K) GOTO 1830,1850 -1830 PRINT "ONE OF THE ";A$;B$;" WAS KILLED." -1840 GOTO 1900 -1850 PRINT "NO ";A$;B$;" WERE KILLED." -1860 GOTO 1900 -1870 IF A$="TOREAD" THEN 1890 -1880 PRINT FNA(K);"OF THE HORSES OF THE ";A$;B$;" KILLED." -1890 PRINT FNA(K);"OF THE ";A$;B$;" KILLED." -1900 PRINT -1910 RETURN -1920 REM -1930 INPUT A$ -1940 IF A$="YES" THEN 1990 -1950 IF A$="NO" THEN 2010 -1970 PRINT "INCORRECT ANSWER - - PLEASE TYPE 'YES' OR 'NO'." -1980 GOTO 1930 -1990 Z1=1 -2000 GOTO 2020 -2010 Z1=2 -2020 RETURN -2030 END diff --git a/00_Alternate_Languages/18_Bullseye/MiniScript/README.md b/00_Alternate_Languages/18_Bullseye/MiniScript/README.md deleted file mode 100644 index 73a1c749a..000000000 --- a/00_Alternate_Languages/18_Bullseye/MiniScript/README.md +++ /dev/null @@ -1,22 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -0. Try-It! Page: -Go to https://miniscript.org/tryit/, clear the sample code from the code editor, and paste in the contents of bullseye.ms. Then click the "Run Script" button. Program output (and input) will appear in the green-on-black terminal display to the right of or below the code editor. - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript bullseye.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "bullseye" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/18_Bullseye/MiniScript/bullseye.ms b/00_Alternate_Languages/18_Bullseye/MiniScript/bullseye.ms deleted file mode 100644 index 10dc95cac..000000000 --- a/00_Alternate_Languages/18_Bullseye/MiniScript/bullseye.ms +++ /dev/null @@ -1,59 +0,0 @@ -print " "*32 + "Bullseye" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print - -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 description probable score" -print " 1 fast overarm bullseye or complete miss" -print " 2 controlled overarm 10, 20 or 30 points" -print " 3 underarm anything";print -names = [] -n = input("How many players? ").val; print -for i in range(0, n-1) - names.push input("Name of player #" + (i+1) + "? ") -end for -scores = [0] * n - -round = 0 -while true - round += 1; print; print "round " + round; print "---------" - for i in range(0, n-1) - while true - print; t = input(names[i] + "'s throw? ").val - if 1 <= t <= 3 then break - print "Input 1, 2, or 3!" - end while - if t == 1 then - p1=.65; p2=.55; p3=.5; p4=.5 - else if t == 2 then - p1=.99; p2=.77; p3=.43; p4=.01 - else - p1=.95; p2=.75; p3=.45; p4=.05 - end if - u = rnd - if u>=p1 then - print "Bullseye!! 40 points!"; b=40 - else if u>=p2 then - print "30-point zone!"; b=30 - else if u>=p3 then - print "20-point zone"; b=20 - else if u>=p4 then - print "Whew! 10 points."; b=10 - else - print "Missed the target! too bad."; b=0 - end if - scores[i] += b; print "Total score = " + scores[i] - end for - winners = [] - for i in range(0, n-1) - if scores[i] >= 200 then winners.push i - end for - if winners then break -end while - -print; print "We have a winner!!"; print -for i in winners; print names[i] + " scored " + scores[i] + " points."; end for -print; print "Thanks for the game." - diff --git a/00_Alternate_Languages/18_Bullseye/README.md b/00_Alternate_Languages/18_Bullseye/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/18_Bullseye/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/18_Bullseye/bullseye.bas b/00_Alternate_Languages/18_Bullseye/bullseye.bas deleted file mode 100644 index eec7cf069..000000000 --- a/00_Alternate_Languages/18_Bullseye/bullseye.bas +++ /dev/null @@ -1,37 +0,0 @@ -5 PRINT TAB(32);"BULLSEYE" -10 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -20 PRINT:PRINT:PRINT -30 PRINT "IN THIS GAME, UP TO 20 PLAYERS THROW DARTS AT A TARGET" -40 PRINT "WITH 10, 20, 30, AND 40 POINT ZONES. THE OBJECTIVE IS" -50 PRINT "TO GET 200 POINTS.": PRINT -60 PRINT "THROW",TAB(20);"DESCRIPTION";TAB(45);"PROBABLE SCORE" -70 PRINT" 1";TAB(20);"FAST OVERARM";TAB(45);"BULLSEYE OR COMPLETE MISS" -80 PRINT" 2";TAB(20);"CONTROLLED OVERARM";TAB(45);"10, 20 OR 30 POINTS" -90 PRINT" 3";TAB(20);"UNDERARM";TAB(45);"ANYTHING":PRINT -100 DIM A$(20),S(20),W(10): M=0: R=0: FOR I=1 TO 20: S(I)=0: NEXT I -110 INPUT "HOW MANY PLAYERS";N: PRINT -120 FOR I=1 TO N -130 PRINT "NAME OF PLAYER #";I;:INPUT A$(I) -140 NEXT I -150 R=R+1: PRINT: PRINT "ROUND";R:PRINT "---------" -160 FOR I=1 TO N -170 PRINT: PRINT A$(I)"'S THROW";: INPUT T -180 IF T<1 OR T>3 THEN PRINT "INPUT 1, 2, OR 3!": GOTO 170 -190 ON T GOTO 200, 210, 200 -200 P1=.65: P2=.55: P3=.5: P4=.5: GOTO 230 -210 P1=.99: P2=.77: P3=.43: P4=.01: GOTO 230 -220 P1=.95: P2=.75: P3=.45: P4=.05 -230 U=RND(1) -240 IF U>=P1 THEN PRINT "BULLSEYE!! 40 POINTS!":B=40: GOTO 290 -250 IF U>=P2 THEN PRINT "30-POINT ZONE!":B=30: GOTO 290 -260 IF U>=P3 THEN PRINT "20-POINT ZONE":B=20: GOTO 290 -270 IF U>=P4 THEN PRINT "WHEW! 10 POINTS.":B=10: GOTO 290 -280 PRINT "MISSED THE TARGET! TOO BAD.": B=0 -290 S(I)=S(I)+B: PRINT "TOTAL SCORE =";S(I): NEXT I -300 FOR I=1 TO N -310 IF S(I)>=200 THEN M=M+1: W(M)=I -320 NEXT I -330 IF M=0 THEN 150 -340 PRINT: PRINT "WE HAVE A WINNER!!": PRINT -350 FOR I=1 TO M: PRINT A$(W(I));" SCORED";S(W(I));"POINTS.": NEXT I -360 PRINT: PRINT "THANKS FOR THE GAME.": END diff --git a/00_Alternate_Languages/19_Bunny/MiniScript/README.md b/00_Alternate_Languages/19_Bunny/MiniScript/README.md deleted file mode 100644 index 90a054330..000000000 --- a/00_Alternate_Languages/19_Bunny/MiniScript/README.md +++ /dev/null @@ -1,22 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -0. Try-It! Page: -Go to https://miniscript.org/tryit/, clear the sample code from the code editor, and paste in the contents of bunny.ms. Then click the "Run Script" button. Program output (and input) will appear in the green-on-black terminal display to the right of or below the code editor. - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript bunny.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "bunny" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/19_Bunny/MiniScript/bunny.ms b/00_Alternate_Languages/19_Bunny/MiniScript/bunny.ms deleted file mode 100644 index 176e1e6cf..000000000 --- a/00_Alternate_Languages/19_Bunny/MiniScript/bunny.ms +++ /dev/null @@ -1,43 +0,0 @@ -print " "*33 + "Bunny" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print - -data = [] -data += [1,2,-1,0,2,45,50,-1,0,5,43,52,-1,0,7,41,52,-1] -data += [1,9,37,50,-1,2,11,36,50,-1,3,13,34,49,-1,4,14,32,48,-1] -data += [5,15,31,47,-1,6,16,30,45,-1,7,17,29,44,-1,8,19,28,43,-1] -data += [9,20,27,41,-1,10,21,26,40,-1,11,22,25,38,-1,12,22,24,36,-1] -data += [13,34,-1,14,33,-1,15,31,-1,17,29,-1,18,27,-1] -data += [19,26,-1,16,28,-1,13,30,-1,11,31,-1,10,32,-1] -data += [8,33,-1,7,34,-1,6,13,16,34,-1,5,12,16,35,-1] -data += [4,12,16,35,-1,3,12,15,35,-1,2,35,-1,1,35,-1] -data += [2,34,-1,3,34,-1,4,33,-1,6,33,-1,10,32,34,34,-1] -data += [14,17,19,25,28,31,35,35,-1,15,19,23,30,36,36,-1] -data += [14,18,21,21,24,30,37,37,-1,13,18,23,29,33,38,-1] -data += [12,29,31,33,-1,11,13,17,17,19,19,22,22,24,31,-1] -data += [10,11,17,18,22,22,24,24,29,29,-1] -data += [22,23,26,29,-1,27,29,-1,28,29,-1,4096] - -string.pad = function(w) - return self + " " * (w - self.len) -end function - -for i in range(5); print; end for - -line = "" -while true - x = data.pull - if x > 128 then break - if x >= 0 then - line = line.pad(x) - y = data.pull - for i in range(x, y) - line += "BUNNY"[i % 5] - end for - else - print line - line = "" - wait 0.1 // optional delay to make printing more visible - end if -end while - diff --git a/00_Alternate_Languages/19_Bunny/README.md b/00_Alternate_Languages/19_Bunny/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/19_Bunny/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/19_Bunny/bunny.bas b/00_Alternate_Languages/19_Bunny/bunny.bas deleted file mode 100644 index 1d37fb4a1..000000000 --- a/00_Alternate_Languages/19_Bunny/bunny.bas +++ /dev/null @@ -1,40 +0,0 @@ -10 PRINT TAB(33);"BUNNY" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT: PRINT: PRINT -100 REM "BUNNY" FROM AHL'S 'BASIC COMPUTER GAMES' -110 REM -120 FOR I=0 TO 4: READ B(I): NEXT I -130 GOSUB 260 -140 L=64: REM ASCII LETTER CODE... -150 REM -160 PRINT -170 READ X: IF X<0 THEN 160 -175 IF X>128 THEN 240 -180 PRINT TAB(X);: READ Y -190 FOR I=X TO Y: J=I-5*INT(I/5) -200 PRINT CHR$(L+B(J)); -210 NEXT I -220 GOTO 170 -230 REM -240 GOSUB 260: GOTO 450 -250 REM -260 FOR I=1 TO 6: PRINT CHR$(10);: NEXT I -270 RETURN -280 REM -290 DATA 2,21,14,14,25 -300 DATA 1,2,-1,0,2,45,50,-1,0,5,43,52,-1,0,7,41,52,-1 -310 DATA 1,9,37,50,-1,2,11,36,50,-1,3,13,34,49,-1,4,14,32,48,-1 -320 DATA 5,15,31,47,-1,6,16,30,45,-1,7,17,29,44,-1,8,19,28,43,-1 -330 DATA 9,20,27,41,-1,10,21,26,40,-1,11,22,25,38,-1,12,22,24,36,-1 -340 DATA 13,34,-1,14,33,-1,15,31,-1,17,29,-1,18,27,-1 -350 DATA 19,26,-1,16,28,-1,13,30,-1,11,31,-1,10,32,-1 -360 DATA 8,33,-1,7,34,-1,6,13,16,34,-1,5,12,16,35,-1 -370 DATA 4,12,16,35,-1,3,12,15,35,-1,2,35,-1,1,35,-1 -380 DATA 2,34,-1,3,34,-1,4,33,-1,6,33,-1,10,32,34,34,-1 -390 DATA 14,17,19,25,28,31,35,35,-1,15,19,23,30,36,36,-1 -400 DATA 14,18,21,21,24,30,37,37,-1,13,18,23,29,33,38,-1 -410 DATA 12,29,31,33,-1,11,13,17,17,19,19,22,22,24,31,-1 -420 DATA 10,11,17,18,22,22,24,24,29,29,-1 -430 DATA 22,23,26,29,-1,27,29,-1,28,29,-1,4096 -440 REM -450 END diff --git a/00_Alternate_Languages/20_Buzzword/MiniScript/README.md b/00_Alternate_Languages/20_Buzzword/MiniScript/README.md deleted file mode 100644 index 90a054330..000000000 --- a/00_Alternate_Languages/20_Buzzword/MiniScript/README.md +++ /dev/null @@ -1,22 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -0. Try-It! Page: -Go to https://miniscript.org/tryit/, clear the sample code from the code editor, and paste in the contents of bunny.ms. Then click the "Run Script" button. Program output (and input) will appear in the green-on-black terminal display to the right of or below the code editor. - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript bunny.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "bunny" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/20_Buzzword/MiniScript/buzzword.ms b/00_Alternate_Languages/20_Buzzword/MiniScript/buzzword.ms deleted file mode 100644 index 26a377755..000000000 --- a/00_Alternate_Languages/20_Buzzword/MiniScript/buzzword.ms +++ /dev/null @@ -1,38 +0,0 @@ -print " "*26 + "Buzzword Generator" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print - -print "This program prints highly acceptable phrases in" -print "'educator-speak' that you can work into reports" -print "and speeches. Whenever a question mark is printed," -print "type a 'y' for another phrase or 'n' to quit." - -words1 = ["ability","basal","behavioral","child-centered", - "differentiated","discovery","flexible","heterogeneous", - "homogeneous","manipulative","modular","tavistock", - "individualized"] - -words2 = ["learning", "evaluative","objective", - "cognitive","enrichment","scheduling","humanistic", - "integrated","non-graded","training","vertical age", - "motivational","creative"] - -words3 = ["grouping","modification", - "accountability","process","core curriculum","algorithm", - "performance","reinforcement","open classroom","resource", - "structure","facility","environment"] - -list.any = function - return self[self.len * rnd] -end function - -print; print; print "Here's the first phrase:" - -while true - print [words1.any, words2.any, words3.any].join - print - yn = input("?").lower - if yn != "y" then break -end while - -print "Come back when you need help with another report!" diff --git a/00_Alternate_Languages/20_Buzzword/README.md b/00_Alternate_Languages/20_Buzzword/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/20_Buzzword/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/20_Buzzword/buzzword.bas b/00_Alternate_Languages/20_Buzzword/buzzword.bas deleted file mode 100644 index 7c751a703..000000000 --- a/00_Alternate_Languages/20_Buzzword/buzzword.bas +++ /dev/null @@ -1,26 +0,0 @@ -10 PRINT TAB(26);"BUZZWORD GENERATOR" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT:PRINT:PRINT -40 PRINT "THIS PROGRAM PRINTS HIGHLY ACCEPTABLE PHRASES IN" -50 PRINT "'EDUCATOR-SPEAK' THAT YOU CAN WORK INTO REPORTS" -60 PRINT "AND SPEECHES. WHENEVER A QUESTION MARK IS PRINTED," -70 PRINT "TYPE A 'Y' FOR ANOTHER PHRASE OR 'N' TO QUIT." -80 PRINT:PRINT:PRINT "HERE'S THE FIRST PHRASE:" -90 DIM A$(40) -100 FOR I=1 TO 39 : READ A$(I) : NEXT I -110 PRINT A$(INT(13*RND(1)+1));" "; -120 PRINT A$(INT(13*RND(1)+14));" "; -130 PRINT A$(INT(13*RND(1)+27)) : PRINT -150 INPUT Y$ : IF Y$="Y" THEN 110 -160 GOTO 999 -200 DATA "ABILITY","BASAL","BEHAVIORAL","CHILD-CENTERED" -210 DATA "DIFFERENTIATED","DISCOVERY","FLEXIBLE","HETEROGENEOUS" -220 DATA "HOMOGENEOUS","MANIPULATIVE","MODULAR","TAVISTOCK" -230 DATA "INDIVIDUALIZED","LEARNING","EVALUATIVE","OBJECTIVE" -240 DATA "COGNITIVE","ENRICHMENT","SCHEDULING","HUMANISTIC" -250 DATA "INTEGRATED","NON-GRADED","TRAINING","VERTICAL AGE" -260 DATA "MOTIVATIONAL","CREATIVE","GROUPING","MODIFICATION" -270 DATA "ACCOUNTABILITY","PROCESS","CORE CURRICULUM","ALGORITHM" -280 DATA "PERFORMANCE","REINFORCEMENT","OPEN CLASSROOM","RESOURCE" -290 DATA "STRUCTURE","FACILITY","ENVIRONMENT" -999 PRINT "COME BACK WHEN YOU NEED HELP WITH ANOTHER REPORT!":END diff --git a/00_Alternate_Languages/20_Buzzword/go/main.go b/00_Alternate_Languages/20_Buzzword/go/main.go deleted file mode 100644 index fdab9afa7..000000000 --- a/00_Alternate_Languages/20_Buzzword/go/main.go +++ /dev/null @@ -1,91 +0,0 @@ -package main - -import ( - "bufio" - "fmt" - "math/rand" - "os" - "strings" - "time" -) - -func main() { - rand.Seed(time.Now().UnixNano()) - words := [][]string{ - { - "Ability", - "Basal", - "Behavioral", - "Child-centered", - "Differentiated", - "Discovery", - "Flexible", - "Heterogeneous", - "Homogenous", - "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", - }, - } - - scanner := bufio.NewScanner(os.Stdin) - - // Display intro text - fmt.Println("\n Buzzword Generator") - fmt.Println("Creative Computing Morristown, New Jersey") - fmt.Println("\n\n") - fmt.Println("This program prints highly acceptable phrases in") - fmt.Println("'educator-speak' that you can work into reports") - fmt.Println("and speeches. Whenever a question mark is printed,") - fmt.Println("type a 'Y' for another phrase or 'N' to quit.") - fmt.Println("\n\nHere's the first phrase:") - - for { - phrase := "" - for _, section := range words { - if len(phrase) > 0 { - phrase += " " - } - phrase += section[rand.Intn(len(section))] - } - fmt.Println(phrase) - fmt.Println() - - // continue? - fmt.Println("?") - scanner.Scan() - if strings.ToUpper(scanner.Text())[0:1] != "Y" { - break - } - } - fmt.Println("Come back when you need help with another report!") -} diff --git a/00_Alternate_Languages/20_Buzzword/nim/buzzword.nim b/00_Alternate_Languages/20_Buzzword/nim/buzzword.nim deleted file mode 100644 index dfba31c9d..000000000 --- a/00_Alternate_Languages/20_Buzzword/nim/buzzword.nim +++ /dev/null @@ -1,34 +0,0 @@ -import std/[random,strutils] - -randomize() - -const - words1 = ["ABILITY","BASAL","BEHAVIORAL","CHILD-CENTERED","DIFFERENTIATED","DISCOVERY","FLEXIBLE", - "HETEROGENEOUS","HOMOGENEOUS","MANIPULATIVE","MODULAR","TAVISTOCK","INDIVIDUALIZED"] - words2 = ["LEARNING","EVALUATIVE","OBJECTIVE","COGNITIVE","ENRICHMENT","SCHEDULING","HUMANISTIC", - "INTEGRATED","NON-GRADED","TRAINING","VERTICAL AGE","MOTIVATIONAL","CREATIVE"] - words3 = ["GROUPING","MODIFICATION","ACCOUNTABILITY","PROCESS","CORE CURRICULUM","ALGORITHM", "PERFORMANCE", - "REINFORCEMENT","OPEN CLASSROOM","RESOURCE","STRUCTURE","FACILITY","ENVIRONMENT"] - -var - stillplaying: bool = true - prompt: string - -echo spaces(26), "BUZZWORD GENERATOR" -echo spaces(15), "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -echo "\n" -echo "THIS PROGRAM PRINTS HIGHLY ACCEPTABLE PHRASES IN" -echo "'EDUCATOR-SPEAK' THAT YOU CAN WORK INTO REPORTS" -echo "AND SPEECHES. AFTER EACH PHRASE, HIT 'ENTER' FOR" -echo "ANOTHER PHRASE, OR TYPE 'N' TO QUIT." -echo "\n" -echo "HERE'S THE FIRST PHRASE..." - -while stillplaying: - echo "" - echo words1[rand(0..12)], " ", words2[rand(0..12)], " ", words3[rand(0..12)] - prompt = readLine(stdin).normalize() - if prompt.substr(0, 0) == "n": - stillplaying = false - -echo "COME BACK WHEN YOU NEED HELP WITH ANOTHER REPORT!" diff --git a/00_Alternate_Languages/21_Calendar/MiniScript/README.md b/00_Alternate_Languages/21_Calendar/MiniScript/README.md deleted file mode 100644 index fea2264e6..000000000 --- a/00_Alternate_Languages/21_Calendar/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript calendar.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "calendar" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/21_Calendar/MiniScript/calendar.ms b/00_Alternate_Languages/21_Calendar/MiniScript/calendar.ms deleted file mode 100644 index 27691bdb9..000000000 --- a/00_Alternate_Languages/21_Calendar/MiniScript/calendar.ms +++ /dev/null @@ -1,89 +0,0 @@ -import "stringUtil" - -print " "*32 + "Calendar" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print - -startingDOW = 0 -leapYear = false - -// Note: while the original program required changes to the code to configure -// it for the current year, in this port we choose to ask the user. -// Here's the function to do that. -getParameters = function - days = "sunday monday tuesday wednesday thursday friday saturday".split - globals.startingDOW = 999 - while startingDOW == 999 - ans = input("What is the first day of the week of the year? ").lower - if not ans then continue - for i in days.indexes - if days[i].startsWith(ans) then - globals.startingDOW = -i - break - end if - end for - end while - - while true - ans = input("Is it a leap year? ").lower - if ans and (ans[0] == "y" or ans[0] == "n") then break - end while - globals.leapYear = (ans[0] == "y") - - while true - ans = input("Pause after each month? ").lower - if ans and (ans[0] == "y" or ans[0] == "n") then break - end while - globals.pause = (ans[0] == "y") -end function - -getParameters -monthNames = [ - " JANUARY ", - " FEBRUARY", - " MARCH ", - " APRIL ", - " MAY ", - " JUNE ", - " JULY ", - " AUGUST ", - "SEPTEMBER", - " OCTOBER ", - " NOVEMBER", - " DECEMBER", - ] -monthDays = [31, 28 + leapYear, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] - -// Function to print one month calendar. -// month: numeric month number, 0-based (0-11) -printMonth = function(month) - daysSoFar = monthDays[:month].sum - daysLeft = monthDays[month:].sum - print "** " + str(daysSoFar).pad(4) + "*"*18 + " " + monthNames[month] + - " " + "*"*18 + " " + str(daysLeft).pad(4) + "**" - print - print " S M T W T F S" - print - print "*" * 61 - // calculate the day of the week, from 0=Sunday to 6=Saturday - dow = (daysSoFar - startingDOW) % 7 - print " " * 5 + " " * (8*dow), "" - for i in range(1, monthDays[month]) - print str(i).pad(8), "" - dow += 1 - if dow == 7 then - dow = 0 - print - if i == monthDays[month] then break - print; print " " * 5, "" - end if - end for - print -end function - -// Main loop. -for month in range(0, 11) - printMonth month - print - if month < 11 and pause then input -end for diff --git a/00_Alternate_Languages/21_Calendar/README.md b/00_Alternate_Languages/21_Calendar/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/21_Calendar/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/21_Calendar/calendar.bas b/00_Alternate_Languages/21_Calendar/calendar.bas deleted file mode 100644 index 8a7703f9a..000000000 --- a/00_Alternate_Languages/21_Calendar/calendar.bas +++ /dev/null @@ -1,58 +0,0 @@ -10 PRINT TAB(32);"CALENDAR" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT:PRINT:PRINT -100 REM VALUES FOR 1979 - SEE NOTES -110 DIM M(12) -120 FOR I=1 TO 6: PRINT CHR$(10);: NEXT I -130 D=-1: REM 1979 STARTS ON MONDAY (0=SUN, -1=MON, -2=TUES...) -140 S=0 -150 REM READ DAYS OF EACH MONTH -160 FOR N=0 TO 12: READ M(N): NEXT N -170 REM -180 FOR N=1 TO 12 -190 PRINT: PRINT: S=S+M(N-1) -200 PRINT "**";S;TAB(7); -210 FOR I=1 TO 18: PRINT "*";: NEXT I -220 ON N GOTO 230,240,250,260,270,280,290,300,310,320,330,340 -230 PRINT " JANUARY ";: GOTO 350 -240 PRINT " FEBRUARY";: GOTO 350 -250 PRINT " MARCH ";: GOTO 350 -260 PRINT " APRIL ";: GOTO 350 -270 PRINT " MAY ";: GOTO 350 -280 PRINT " JUNE ";: GOTO 350 -290 PRINT " JULY ";: GOTO 350 -300 PRINT " AUGUST ";: GOTO 350 -310 PRINT "SEPTEMBER";: GOTO 350 -320 PRINT " OCTOBER ";: GOTO 350 -330 PRINT " NOVEMBER";: GOTO 350 -340 PRINT " DECEMBER"; -350 FOR I=1 TO 18: PRINT "*";: NEXT I -360 PRINT 365-S;"**"; -370 REM 366-S; ON LEAP YEARS -380 PRINT CHR$(10): PRINT " S M T W"; -390 PRINT " T F S" -400 PRINT -410 FOR I=1 TO 59: PRINT "*";: NEXT I -420 REM -430 FOR W=1 TO 6 -440 PRINT CHR$(10) -450 PRINT TAB(4) -460 REM -470 FOR G=1 TO 7 -480 D=D+1 -490 D2=D-S -500 IF D2>M(N) THEN 580 -510 IF D2>0 THEN PRINT D2; -520 PRINT TAB(4+8*G); -530 NEXT G -540 REM -550 IF D2=M(N) THEN 590 -560 NEXT W -570 REM -580 D=D-G -590 NEXT N -600 REM -610 FOR I=1 TO 6: PRINT CHR$(10);: NEXT I -620 DATA 0,31,28,31,30,31,30,31,31,30,31,30,31 -630 REM 0,31,29, ..., ON LEAP YEARS -640 END diff --git a/00_Alternate_Languages/22_Change/MiniScript/README.md b/00_Alternate_Languages/22_Change/MiniScript/README.md deleted file mode 100644 index 5708156d8..000000000 --- a/00_Alternate_Languages/22_Change/MiniScript/README.md +++ /dev/null @@ -1,22 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -0. Try-It! Page: -Go to https://miniscript.org/tryit/, clear the sample code from the code editor, and paste in the contents of change.ms. Then click the "Run Script" button. Program output (and input) will appear in the green-on-black terminal display to the right of or below the code editor. - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript change.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "change" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/22_Change/MiniScript/change.ms b/00_Alternate_Languages/22_Change/MiniScript/change.ms deleted file mode 100644 index 675a179aa..000000000 --- a/00_Alternate_Languages/22_Change/MiniScript/change.ms +++ /dev/null @@ -1,57 +0,0 @@ -print " "*33 + "Change" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print - -print "I, your friendly microcomputer, will determine" -print "the correct change for items costing up to $100." -print; print -while true - itemCost = input("Cost of item? ").val - if itemCost == 0 then break - payment = input("Amount of payment? ").val - change = payment - itemCost - if change < 0 then - print "Sorry, you have short-changed me $" + (itemCost - payment) - continue - else if change == 0 then - print "Correct amount, thank you." - continue - end if - - print "Your change, $" + change - - dollars = floor(change/10) - if dollars then print dollars + " ten dollar bill(s)" - change -= dollars * 10 - - fivers = floor(change/5) - if fivers then print fivers + " five dollar bill(s)" - change -= fivers * 5 - - ones = floor(change) - if ones then print ones + " one dollar bill(s)" - change -= ones - - change *= 100 // (now working in cents) - - halfs = floor(change / 50) - if halfs then print halfs + " one half dollar(s)" - change -= halfs * 50 - - quarters = floor(change / 25) - if quarters then print quarters + " quarter(s)" - change -= quarters * 25 - - dimes = floor(change / 10) - if dimes then print dimes + " dime(s)" - change -= dimes * 10 - - nickels = floor(change / 5) - if nickels then print nickels + " nickel(s)" - change -= nickels * 5 - - pennies = round(change) - if pennies then print pennies + " penny(s)" - print "Thank you, come again." - print; print -end while \ No newline at end of file diff --git a/00_Alternate_Languages/22_Change/README.md b/00_Alternate_Languages/22_Change/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/22_Change/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/22_Change/change.bas b/00_Alternate_Languages/22_Change/change.bas deleted file mode 100644 index ac84db06f..000000000 --- a/00_Alternate_Languages/22_Change/change.bas +++ /dev/null @@ -1,51 +0,0 @@ -2 PRINT TAB(33);"CHANGE" -4 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -5 PRINT:PRINT:PRINT -6 PRINT "I, YOUR FRIENDLY MICROCOMPUTER, WILL DETERMINE" -8 PRINT "THE CORRECT CHANGE FOR ITEMS COSTING UP TO $100." -9 PRINT:PRINT -10 PRINT "COST OF ITEM";:INPUT A:PRINT "AMOUNT OF PAYMENT";:INPUT P -20 C=P-A:M=C:IF C<>0 THEN 90 -25 PRINT "CORRECT AMOUNT, THANK YOU." -30 GOTO 400 -90 IF C>0 THEN 120 -95 PRINT "SORRY, YOU HAVE SHORT-CHANGED ME $";A-P -100 GOTO 10 -120 PRINT "YOUR CHANGE, $";C -130 D=INT(C/10) -140 IF D=0 THEN 155 -150 PRINT D;"TEN DOLLAR BILL(S)" -155 C=M-(D*10) -160 E=INT(C/5) -170 IF E=0 THEN 185 -180 PRINT E;"FIVE DOLLARS BILL(S)" -185 C=M-(D*10+E*5) -190 F=INT(C) -200 IF F=0 THEN 215 -210 PRINT F;"ONE DOLLAR BILL(S)" -215 C=M-(D*10+E*5+F) -220 C=C*100 -225 N=C -230 G=INT(C/50) -240 IF G=0 THEN 255 -250 PRINT G;"ONE HALF DOLLAR(S)" -255 C=N-(G*50) -260 H=INT(C/25) -270 IF H=0 THEN 285 -280 PRINT H;"QUARTER(S)" -285 C=N-(G*50+H*25) -290 I=INT(C/10) -300 IF I=0 THEN 315 -310 PRINT I;"DIME(S)" -315 C=N-(G*50+H*25+I*10) -320 J=INT(C/5) -330 IF J=0 THEN 345 -340 PRINT J;"NICKEL(S)" -345 C=N-(G*50+H*25+I*10+J*5) -350 K=INT(C+.5) -360 IF K=0 THEN 380 -370 PRINT K;"PENNY(S)" -380 PRINT "THANK YOU, COME AGAIN." -390 PRINT:PRINT -400 GOTO 10 -410 END diff --git a/00_Alternate_Languages/22_Change/go/main.go b/00_Alternate_Languages/22_Change/go/main.go deleted file mode 100644 index fabe4d4bb..000000000 --- a/00_Alternate_Languages/22_Change/go/main.go +++ /dev/null @@ -1,115 +0,0 @@ -package main - -import ( - "bufio" - "fmt" - "math" - "os" - "strconv" -) - -func printWelcome() { - fmt.Println(" CHANGE") - fmt.Println("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") - fmt.Println() - fmt.Println() - fmt.Println() - fmt.Println("I, YOUR FRIENDLY MICROCOMPUTER, WILL DETERMINE") - fmt.Println("THE CORRECT CHANGE FOR ITEMS COSTING UP TO $100.") - fmt.Println() -} - -func computeChange(cost, payment float64) { - change := int(math.Round((payment - cost) * 100)) - - if change == 0 { - fmt.Println("\nCORRECT AMOUNT, THANK YOU.") - return - } - - if change < 0 { - fmt.Printf("\nSORRY, YOU HAVE SHORT-CHANGED ME $%0.2f\n", float64(change)/-100.0) - print() - return - } - - fmt.Printf("\nYOUR CHANGE, $%0.2f:\n", float64(change)/100.0) - - d := change / 1000 - if d > 0 { - fmt.Printf(" %d TEN DOLLAR BILL(S)\n", d) - change -= d * 1000 - } - - d = change / 500 - if d > 0 { - fmt.Printf(" %d FIVE DOLLAR BILL(S)\n", d) - change -= d * 500 - } - - d = change / 100 - if d > 0 { - fmt.Printf(" %d ONE DOLLAR BILL(S)\n", d) - change -= d * 100 - } - - d = change / 50 - if d > 0 { - fmt.Println(" 1 HALF DOLLAR") - change -= d * 50 - } - - d = change / 25 - if d > 0 { - fmt.Printf(" %d QUARTER(S)\n", d) - change -= d * 25 - } - - d = change / 10 - if d > 0 { - fmt.Printf(" %d DIME(S)\n", d) - change -= d * 10 - } - - d = change / 5 - if d > 0 { - fmt.Printf(" %d NICKEL(S)\n", d) - change -= d * 5 - } - - if change > 0 { - fmt.Printf(" %d PENNY(S)\n", change) - } -} - -func main() { - scanner := bufio.NewScanner(os.Stdin) - - printWelcome() - - var cost, payment float64 - var err error - for { - fmt.Println("COST OF ITEM?") - scanner.Scan() - cost, err = strconv.ParseFloat(scanner.Text(), 64) - if err != nil || cost < 0.0 { - fmt.Println("INVALID INPUT. TRY AGAIN.") - continue - } - break - } - for { - fmt.Println("\nAMOUNT OF PAYMENT?") - scanner.Scan() - payment, err = strconv.ParseFloat(scanner.Text(), 64) - if err != nil { - fmt.Println("INVALID INPUT. TRY AGAIN.") - continue - } - break - } - - computeChange(cost, payment) - fmt.Println() -} diff --git a/00_Alternate_Languages/23_Checkers/MiniScript/README.md b/00_Alternate_Languages/23_Checkers/MiniScript/README.md deleted file mode 100644 index 9cb5fd6ee..000000000 --- a/00_Alternate_Languages/23_Checkers/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript checkers.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "checkers" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/23_Checkers/MiniScript/checkers.ms b/00_Alternate_Languages/23_Checkers/MiniScript/checkers.ms deleted file mode 100644 index dc7527128..000000000 --- a/00_Alternate_Languages/23_Checkers/MiniScript/checkers.ms +++ /dev/null @@ -1,243 +0,0 @@ -print " "*32 + "Checkers" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print - -print "This is the game of Checkers. The computer is X," -print "and you are O. The computer will move first." -print "Squares are referred to by a coordinate system." -print "(0,0) is the lower left corner" -print "(0,7) is the upper left corner" -print "(7,0) is the lower right corner" -print "(7,7) is the upper right corner" -print "The computer will type '+TO' when you have another" -print "jump. Type two negative numbers if you cannot jump." -print; print; print - -input "(Press Return.)"; print // (give player a chance to read) - -// The board. Pieces are represented by numeric values: -// - 0 = empty square -// - -1,-2 = computer (X) (-1 for regular piece, -2 for king) -// - 1,2 = human (O) (1 for regular piece, 2 for king) -// Board is indexed by [x][y], so we have to initialize it sideways: -board = [ - [ 1, 0, 1, 0, 0, 0, -1, 0], - [ 0, 1, 0, 0, 0, -1, 0, -1], - [ 1, 0, 1, 0, 0, 0, -1, 0], - [ 0, 1, 0, 0, 0, -1, 0, -1], - [ 1, 0, 1, 0, 0, 0, -1, 0], - [ 0, 1, 0, 0, 0, -1, 0, -1], - [ 1, 0, 1, 0, 0, 0, -1, 0], - [ 0, 1, 0, 0, 0, -1, 0, -1]] - -// Function to print the board -printBoard = function - for y in range(7, 0) - for x in range(0, 7) - // We print by indexing with the board entry (-2 to 2) into a list - // of possible representations. Remember that in MiniScript, a - // negative index counts from the end. - print [". ", "O ", "O*", "X*", "X "][board[x][y]], " " - end for - print; print - end for -end function - -// Function to get x,y coordinates from the player. -// This is written to allow the two numbers to be -// separated by any combination of ',' and ' '. -// Returns input as [x,y]. -inputPosition = function(prompt, requiredPieceSign, allowCancel=false) - while true - ans = input(prompt + "? ").replace(",", " ").split - if ans.len < 2 then - print "Enter two coordinates, for example: 4 0" - continue - end if - x = val(ans[0]) - y = val(ans[-1]) - if x < 0 and y < 0 and allowCancel then - return [x, y] - else if x < 0 or x > 7 or y < 0 or y > 7 then - print "Coordinates must be in the range 0-7" - else if x%2 != y%2 then - print "Invalid coordinates (both must be odd, or both even)" - else if sign(board[x][y]) != requiredPieceSign then - print "Invalid coordinates" - else - return [x, y] - end if - end while -end function - -// Evaluate a potential (computer) move. -evalMove = function(fromX, fromY, toX, toY) - score = 0 - - // +2 if it promotes this piece - if toY == 0 and board[fromX][fromY] == -1 then score += 2 - - // +5 if it jumps an opponent's piece - if abs(fromY-toY) == 2 then score += 5 - - // -2 if the piece is moving away from the top boundary - if fromY == 7 then score -= 2 - - // +1 for putting the piece against a vertical boundary - if toX == 0 or toX == 7 then score += 1 - - // check neighboring pieces of the target position - for c in [-1, 1] - if toX+c < 0 or toX+c > 7 or toY-1 < 0 then continue - // +1 for each adjacent friendly piece - if board[toX+c][toY-1] < 0 then score += 1 - - // -1 for each opponent piece that could now jump this one - if toX-c >= 0 and toX-c <= 7 and toY+1 <= 7 and board[toX+c][toY-1] > 0 and ( - board[toX-c][toY+1] == 0 or (toX-c == fromX and toY+1 == fromY)) then score -= 2 - end for - return score -end function - -// Consider a possible (computer) move, including whether it's even valid. -// Return it or the previous best, whichever is better. -consider = function(fromX, fromY, toX, toY, previousBest) - - // make sure it's within the bounds of the board - if toX < 0 or toX > 7 or toY < 0 or toY > 7 then return previousBest - - // if it's an opponent's piece, consider jumping it instead - dx = toX - fromX - if board[toX][toY] > 0 and abs(dx) == 1 then - dy = toY - fromY - return consider(fromX, fromY, fromX + dx*2, fromY + dy*2, previousBest) - end if - - // if it's a jump, make sure it's over an opponent piece - if abs(dx) == 2 then - midX = (fromX + toX)/2; midY = (fromY + toY)/2 - if board[midX][midY] < 1 then return previousBest - end if - - // make sure the destination is empty - if board[toX][toY] then return previousBest - - // all checks passed; score it, and return whichever is better - rating = evalMove(fromX, fromY, toX, toY) - if not previousBest or rating > previousBest.rating then - newBest = {} - newBest.fromX = fromX; newBest.fromY = fromY - newBest.toX = toX; newBest.toY = toY - newBest.rating = rating - return newBest - else - return previousBest - end if -end function - -// Do the computer's turn -doComputerTurn = function - // For each square on the board containing one of my pieces, consider - // possible moves and keep the best one so far. Start with a step - // size of 1 (ordinary move), but if we jump, then keep jumping. - stepSize = 1 - while true - bestMove = null - for x in range(0, 7) - for y in range(0, 7) - if board[x][y] >= 0 then continue // not my piece - move = {} - move.fromPos = [x,y] - - // Consider forward moves; if it's a king, also consider backward moves - for dx in [-stepSize, stepSize] - move.toPos = [dx, -stepSize] - bestMove = consider(x, y, x+dx, y-stepSize, bestMove) - if board[x][y] == -2 then bestMove = consider(x, y, x+dx, y+stepSize, bestMove) - end for - end for - end for - - if not bestMove then - // No valid move -- if step size is still 1, this means we - // couldn't find ANY move on our turn, and we have lost. - // Otherwise, we're done. - if stepSize == 1 then - globals.gameOver = true - globals.winner = 1 - end if - break - end if - - // Do the move, and stop if we did not jump. - if stepSize == 1 then - print "From " + bestMove.fromX + " " + bestMove.fromY, "" - end if - print " to " + bestMove.toX + " " + bestMove.toY, "" - - movePiece bestMove.fromX, bestMove.fromY, bestMove.toX, bestMove.toY - if abs(bestMove.toX - bestMove.fromX) == 1 then break - stepSize = 2 - end while - print -end function - -// Move one piece (including captures and crowning -movePiece = function(fromX, fromY, toX, toY) - piece = board[fromX][fromY] - board[toX][toY] = piece - board[fromX][fromY] = 0 - // capture piece jumped over - if abs(toX - fromX) == 2 then - board[(fromX+toX)/2][(fromY+toY)/2] = 0 - end if - // crown (make into a king) a piece that reaches the back row - if (toY == 7 and piece > 0) or (toY == 0 and piece < 0) then - board[toX][toY] = 2 * sign(piece) - end if -end function - -// Handle the player's move. -doPlayerTurn = function - fromPos = inputPosition("From", 1, true) - fromX = fromPos[0]; fromY = fromPos[1] - if fromX < 0 then - // Player concedes the game. - globals.gameOver = true - globals.winner = -1 - return - end if - while true - toPos = inputPosition("To", 0) - toX = toPos[0]; toY = toPos[1] - dist = abs(toX - fromX) - if dist <= 2 and abs(toY - fromY) == dist then break - end while - while true - // Make the move, and continue as long as we have a jump - movePiece fromX, fromY, toX, toY - if dist != 2 then break - - // Prompt for another move, allowing a cancel (negative input). - fromX = toX; fromY = toX - toPos = inputPosition("+To", 0, true) - if toPos[0] < 0 or toPos[1] < 0 then break - toX = toPos[0]; toY = toPos[1] - end while - // If piece has reached the end of the board, crown this piece - if toY == 7 then board[toX][toY] = 2 -end function - -// Main loop. -gameOver = false -while not gameOver - doComputerTurn - if gameOver then break - printBoard - doPlayerTurn - if gameOver then break - printBoard -end while - -print -if winner > 0 then print "You win." else print "I win." diff --git a/00_Alternate_Languages/23_Checkers/README.md b/00_Alternate_Languages/23_Checkers/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/23_Checkers/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/23_Checkers/checkers.annotated.bas b/00_Alternate_Languages/23_Checkers/checkers.annotated.bas deleted file mode 100644 index 78e2e2d96..000000000 --- a/00_Alternate_Languages/23_Checkers/checkers.annotated.bas +++ /dev/null @@ -1,315 +0,0 @@ - # Annotated version of CHECKERS.BAS, modified to improve readability. - # - # I've made the following changes: - # - # 1. Added many comments and blank lines. - # 2. Separated each statement into its own line. - # 3. Indented loops, conditionals and subroutines. - # 4. Turned *SOME* conditionals and loops into - # structured-BASIC-style if/endif and loop/endloop blocks. - # 5. Switched to using '#' to delimit comments. - # 6. Subroutines now begin with "Sub_Start" - # 7. All non-string text has been converted to lower-case - # 8. All line numbers that are not jump destinations have been removed. - # - # This has helped me make sense of the code. I hope it will also help you. - # - - # Print the banner - print tab(32);"CHECKERS" - print tab(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" - print - print - print - print "THIS IS THE GAME OF CHECKERS. THE COMPUTER IS X," - print "AND YOU ARE O. THE COMPUTER WILL MOVE FIRST." - print "SQUARES ARE REFERRED TO BY A COORDINATE SYSTEM." - print "(0,0) IS THE LOWER LEFT CORNER" - print "(0,7) IS THE UPPER LEFT CORNER" - print "(7,0) IS THE LOWER RIGHT CORNER" - print "(7,7) IS THE UPPER RIGHT CORNER" - print "THE COMPUTER WILL TYPE '+TO' WHEN YOU HAVE ANOTHER" - print "JUMP. TYPE TWO NEGATIVE NUMBERS IF YOU CANNOT JUMP." - print - print - print - - # Declare the "globals": - - # The current move: (rating, current x, current y, new x, new y) - # 'rating' represents how good the move is; higher is better. - dim r(4) - r(0)=-99 # Start with minimum score - - # The board. Pieces are represented by numeric values: - # - # - 0 = empty square - # - -1,-2 = X (-1 for regular piece, -2 for king) - # - 1,2 = O (1 for regular piece, 2 for king) - # - # This program's player ("me") plays X. - dim s(7,7) - - g=-1 # constant holding -1 - - # Initialize the board. Data is 2 length-wise strips repeated. - data 1,0,1,0,0,0,-1,0,0,1,0,0,0,-1,0,-1,15 - for x=0 to 7 - for y=0 to 7 - read j - if j=15 then 180 - s(x,y)=j - goto 200 -180 restore - read s(x,y) -200 next y,x - -230 # Start of game loop. First, my turn. - - # For each square on the board, search for one of my pieces - # and if it can make the best move so far, store that move in 'r' - for x=0 to 7 - for y=0 to 7 - - # Skip if this is empty or an opponent's piece - if s(x,y) > -1 then 350 - - # If this is one of my ordinary pieces, analyze possible - # forward moves. - if s(x,y) = -1 then - for a=-1 to 1 step 2 - b=g - gosub 650 - next a - endif - - # If this is one of my kings, analyze possible forward - # and backward moves. - if s(x,y) = -2 then - for a=-1 to 1 step 2 - for b=-1 to 1 step 2 - gosub 650 - next b,a - endif - -350 next y,x - goto 1140 # Skip the subs - - - # Analyze a move from (x,y) to (x+a, y+b) and schedule it if it's - # the best candidate so far. -650 Sub_Start - u=x+a - v=y+b - - # Done if it's off the board - if u<0 or u>7 or v<0 or v>7 then 870 - - # Consider the destination if it's empty - if s(u,v) = 0 then - gosub 910 - goto 870 - endif - - # If it's got an opponent's piece, jump it instead - if s(u,v) > 0 - - # Restore u and v, then return if it's off the board - u=u+a - v=v+b - if u<0 or v<0 or u>7 or v>7 then 870 - - # Otherwise, consider u,v - if s(u,v)=0 then gosub 910 - endif -870 return - - # Evaluate jumping (x,y) to (u,v). - # - # Computes a score for the proposed move and if it's higher - # than the best-so-far move, uses that instead by storing it - # and its score in array 'r'. -910 Sub_Start - - # q is the score; it starts at 0 - - # +2 if it promotes this piece - if v=0 and s(x,y)=-1 then q=q+2 - - # +5 if it takes an opponent's piece - if abs(y-v)=2 then q=q+5 - - # -2 if the piece is moving away from the top boundary - if y=7 then q=q-2 - - # +1 for putting the piece against a vertical boundary - if u=0 or u=7 then q=q+1 - - for c=-1 to 1 step 2 - if u+c < 0 or u+c > 7 or v+g < 0 then 1080 - - # +1 for each adjacent friendly piece - if s(u+c, v+g) < 0 then - q=q+1 - goto 1080 - endif - - # Prevent out-of-bounds testing - if u-c < 0 or u-c > 7 or v-g > 7 then 1080 - - # -2 for each opponent piece that can now take this piece here - if s(u+c,v+g) > 0 and(s(u-c,v-g)=0 or(u-c=x and v-g=y))then q=q-2 -1080 next c - - # Use this move if it's better than the previous best - if q>r(0) then - r(0)=q - r(1)=x - r(2)=y - r(3)=u - r(4)=v - endif - - q=0 # reset the score - return - -1140 if r(0)=-99 then 1880 # Game is lost if no move could be found. - - # Print the computer's move. (Note: chr$(30) is an ASCII RS - # (record separator) code; probably no longer relevant.) - print chr$(30)"FROM"r(1);r(2)"TO"r(3);r(4); - r(0)=-99 - - # Make the computer's move. If the piece finds its way to the - # end of the board, crown it. -1240 if r(4)=0 then - s(r(3),r(4))=-2 - goto 1420 - endif - s(r(3),r(4))=s(r(1),r(2)) - s(r(1),r(2))=0 - - # If the piece has jumped 2 squares, it means the computer has - # taken an opponents' piece. - if abs(r(1)-r(3)) == 2 then - s((r(1)+r(3))/2,(r(2)+r(4))/2)=0 # Delete the opponent's piece - - # See if we can jump again. Evaluate all possible moves. - x=r(3) - y=r(4) - for a=-2 to 2 step 4 - if s(x,y)=-1 then - b=-2 - gosub 1370 - endif - if s(x,y)=-2 then - for b=-2 to 2 step 4 - gosub 1370 - next b - endif - next a - - # If we've found a move, go back and make that one as well - if r(0) <> -99 then - print "TO" r(3); r(4); - r(0)=-99 - goto 1240 - endif - - goto 1420 # Skip the sub - - # If (u,v) is in the bounds, evaluate it as a move using - # the sub at 910 -1370 Sub_Start - u=x+a - v=y+b - if u<0 or u>7 or v<0 or v>7 then 1400 - if s(u,v)=0 and s(x+a/2,y+b/2)>0 then gosub 910 -1400 return - -1420 endif - - # Now, print the board - print - print - print - for y=7 to 0 step-1 - for x=0 to 7 - i=5*x - print tab(i); - if s(x,y)=0 then print"."; - if s(x,y)=1 then print"O"; - if s(x,y)=-1 then print"X"; - if s(x,y)=-2 then print"X*"; - if s(x,y)=2 then print"O*"; - next x - print" " - print - next y - print - - # Check if either player is out of pieces. If so, announce the - # winner. - for l=0 to 7 - for m=0 to 7 - if s(l,m)=1 or s(l,m)=2 then z=1 - if s(l,m)=-1 or s(l,m)=-2 then t=1 - next m - next l - if z<>1 then 1885 - if t<>1 then 1880 - - # Prompt the player for their move. - z=0 - t=0 -1590 input "FROM";e,h - x=e - y=h - if s(x,y)<=0 then 1590 -1670 input "TO";a,b - x=a - y=b - if s(x,y)=0 and abs(a-e)<=2 and abs(a-e)=abs(b-h)then 1700 - print chr$(7)chr$(11); # bell, vertical tab; invalid move - goto 1670 - -1700 i=46 # Not used; probably a bug -1750 loop - # Make the move and stop unless it might be a jump. - s(a,b) = s(e,h) - s(e,h) = 0 - if abs(e-a) <> 2 then break - - # Remove the piece jumped over - s((e+a)/2,(h+b)/2) = 0 - - # Prompt for another move; -1 means player can't, so I've won. - # Keep prompting until there's a valid move or the player gives - # up. -1802 input "+TO";a1,b1 - if a1 < 0 then break - if s(a1,b1) <> 0 or abs(a1-a) <>2 or abs(b1-b) <> 2 then 1802 - - # Update the move variables to correspond to the next jump - e=a - h=b - a=a1 - b=b1 - - i=i+15 # Not used; probably a bug - endloop - - # If the player has reached the end of the board, crown this piece -1810 if b=7 then s(a,b)=2 - - # And play the next turn. - goto 230 - - # Endgame: -1880 print - print "YOU WIN." - end - -1885 print - print "I WIN." - end diff --git a/00_Alternate_Languages/23_Checkers/checkers.bas b/00_Alternate_Languages/23_Checkers/checkers.bas deleted file mode 100644 index 634c24866..000000000 --- a/00_Alternate_Languages/23_Checkers/checkers.bas +++ /dev/null @@ -1,82 +0,0 @@ -5 PRINT TAB(32);"CHECKERS" -10 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -15 PRINT:PRINT:PRINT -20 PRINT "THIS IS THE GAME OF CHECKERS. THE COMPUTER IS X," -25 PRINT "AND YOU ARE O. THE COMPUTER WILL MOVE FIRST." -30 PRINT "SQUARES ARE REFERRED TO BY A COORDINATE SYSTEM." -35 PRINT "(0,0) IS THE LOWER LEFT CORNER" -40 PRINT "(0,7) IS THE UPPER LEFT CORNER" -45 PRINT "(7,0) IS THE LOWER RIGHT CORNER" -50 PRINT "(7,7) IS THE UPPER RIGHT CORNER" -55 PRINT "THE COMPUTER WILL TYPE '+TO' WHEN YOU HAVE ANOTHER" -60 PRINT "JUMP. TYPE TWO NEGATIVE NUMBERS IF YOU CANNOT JUMP." -65 PRINT:PRINT:PRINT -80 DIM R(4),S(7,7):G=-1:R(0)=-99 -90 DATA 1,0,1,0,0,0,-1,0,0,1,0,0,0,-1,0,-1,15 -120 FOR X=0 TO 7:FOR Y=0 TO 7:READ J:IF J=15 THEN 180 -160 S(X,Y)=J:GOTO 200 -180 RESTORE:READ S(X,Y) -200 NEXT Y,X -230 FOR X=0 TO 7:FOR Y=0 TO 7:IF S(X,Y)>-1 THEN 350 -310 IF S(X,Y)=-1 THEN FOR A=-1 TO 1 STEP 2:B=G:GOSUB 650:NEXT A -330 IF S(X,Y)=-2 THEN FOR A=-1 TO 1 STEP 2:FOR B=-1 TO 1 STEP 2:GOSUB 650:NEXT B,A -350 NEXT Y,X:GOTO 1140 -650 U=X+A:V=Y+B:IF U<0 OR U>7 OR V<0 OR V>7 THEN 870 -740 IF S(U,V)=0 THEN GOSUB 910:GOTO 870 -770 IF S(U,V)<0 THEN 870 -790 U=U+A:V=V+B:IF U<0 OR V<0 OR U>7 OR V>7 THEN 870 -850 IF S(U,V)=0 THEN GOSUB 910 -870 RETURN -910 IF V=0 AND S(X,Y)=-1 THEN Q=Q+2 -920 IF ABS(Y-V)=2 THEN Q=Q+5 -960 IF Y=7 THEN Q=Q-2 -980 IF U=0 OR U=7 THEN Q=Q+1 -1030 FOR C=-1 TO 1 STEP 2:IF U+C<0 OR U+C>7 OR V+G<0 THEN 1080 -1035 IF S(U+C,V+G)<0 THEN Q=Q+1:GOTO 1080 -1040 IF U-C<0 OR U-C>7 OR V-G>7 THEN 1080 -1045 IF S(U+C,V+G)>0 AND(S(U-C,V-G)=0 OR(U-C=X AND V-G=Y))THEN Q=Q-2 -1080 NEXT C:IF Q>R(0)THEN R(0)=Q:R(1)=X:R(2)=Y:R(3)=U:R(4)=V -1100 Q=0:RETURN -1140 IF R(0)=-99 THEN 1880 -1230 PRINT CHR$(30)"FROM"R(1);R(2)"TO"R(3);R(4);:R(0)=-99 -1240 IF R(4)=0 THEN S(R(3),R(4))=-2:GOTO 1420 -1250 S(R(3),R(4))=S(R(1),R(2)) -1310 S(R(1),R(2))=0:IF ABS(R(1)-R(3))<>2 THEN 1420 -1330 S((R(1)+R(3))/2,(R(2)+R(4))/2)=0 -1340 X=R(3):Y=R(4):IF S(X,Y)=-1 THEN B=-2:FOR A=-2 TO 2 STEP 4:GOSUB 1370 -1350 IF S(X,Y)=-2 THEN FOR A=-2 TO 2 STEP 4:FOR B=-2 TO 2 STEP 4:GOSUB 1370:NEXT B -1360 NEXT A:IF R(0)<>-99 THEN PRINT"TO"R(3);R(4);:R(0)=-99:GOTO 1240 -1365 GOTO 1420 -1370 U=X+A:V=Y+B:IF U<0 OR U>7 OR V<0 OR V>7 THEN 1400 -1380 IF S(U,V)=0 AND S(X+A/2,Y+B/2)>0 THEN GOSUB 910 -1400 RETURN -1420 PRINT:PRINT:PRINT:FOR Y=7 TO 0 STEP-1:FOR X=0 TO 7:I=5*X:PRINT TAB(I); -1430 IF S(X,Y)=0 THEN PRINT"."; -1470 IF S(X,Y)=1 THEN PRINT"O"; -1490 IF S(X,Y)=-1 THEN PRINT"X"; -1510 IF S(X,Y)=-2 THEN PRINT"X*"; -1530 IF S(X,Y)=2 THEN PRINT"O*"; -1550 NEXT X:PRINT" ":PRINT:NEXT Y:PRINT -1552 FOR L=0 TO 7 -1554 FOR M=0 TO 7 -1556 IF S(L,M)=1 OR S(L,M)=2 THEN Z=1 -1558 IF S(L,M)=-1 OR S(L,M)=-2 THEN T=1 -1560 NEXT M -1562 NEXT L -1564 IF Z<>1 THEN 1885 -1566 IF T<>1 THEN 1880 -1570 Z=0: T=0 -1590 INPUT "FROM";E,H:X=E:Y=H:IF S(X,Y)<=0 THEN 1590 -1670 INPUT "TO";A,B:X=A:Y=B -1680 IF S(X,Y)=0 AND ABS(A-E)<=2 AND ABS(A-E)=ABS(B-H)THEN 1700 -1690 PRINT CHR$(7)CHR$(11);:GOTO 1670 -1700 I=46 -1750 S(A,B)=S(E,H):S(E,H)=0:IF ABS(E-A)<>2 THEN 1810 -1800 S((E+A)/2,(H+B)/2)=0 -1802 INPUT "+TO";A1,B1:IF A1<0 THEN 1810 -1804 IF S(A1,B1)<>0 OR ABS(A1-A)<>2 OR ABS(B1-B)<>2 THEN 1802 -1806 E=A:H=B:A=A1:B=B1:I=I+15:GOTO 1750 -1810 IF B=7 THEN S(A,B)=2 -1830 GOTO 230 -1880 PRINT: PRINT "YOU WIN.": END -1885 PRINT: PRINT "I WIN.": END diff --git a/00_Alternate_Languages/24_Chemist/MiniScript/README.md b/00_Alternate_Languages/24_Chemist/MiniScript/README.md deleted file mode 100644 index 82983edc2..000000000 --- a/00_Alternate_Languages/24_Chemist/MiniScript/README.md +++ /dev/null @@ -1,22 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -0. Try-It! Page: -Go to https://miniscript.org/tryit/, clear the sample code from the code editor, and paste in the contents of chemist.ms. Then click the "Run Script" button. Program output (and input) will appear in the green-on-black terminal display to the right of or below the code editor. - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript chemist.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "chemist" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/24_Chemist/MiniScript/chemist.ms b/00_Alternate_Languages/24_Chemist/MiniScript/chemist.ms deleted file mode 100644 index 712792ce9..000000000 --- a/00_Alternate_Languages/24_Chemist/MiniScript/chemist.ms +++ /dev/null @@ -1,30 +0,0 @@ -print " "*33 + "Chemist" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print -print "The fictitious chemical kryptocyanic acid can only be" -print "diluted by the ratio of 7 parts water to 3 parts acid." -print "If any other ratio is attempted, the acid becomes unstable" -print "and soon explodes. Given the amount of acid, you must" -print "decide how much water to add for dilution. If you miss" -print "you face the consequences." - -deaths = 0 -while deaths < 9 - acid = floor(rnd * 50) - water = 7 * acid/3 - response = input(acid +" liters of kryptocyanic acid. How much water? ").val - diff = abs(water - response) - if diff > water/20 then - print " SIZZLE! You have just been desalinated into a blob" - print " of quivering protoplasm!" - deaths += 1 - if deaths < 9 then - print " However, you may try again with another life." - end if - else - print " Good job! You may breathe now, but don't inhale the fumes!" - print - end if -end while -print " Your 9 lives are used, but you will be long remembered for" -print " your contributions to the field of comic book chemistry." diff --git a/00_Alternate_Languages/24_Chemist/README.md b/00_Alternate_Languages/24_Chemist/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/24_Chemist/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/24_Chemist/chemist.bas b/00_Alternate_Languages/24_Chemist/chemist.bas deleted file mode 100644 index 8b673c27e..000000000 --- a/00_Alternate_Languages/24_Chemist/chemist.bas +++ /dev/null @@ -1,27 +0,0 @@ -3 PRINT TAB(33);"CHEMIST" -6 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -8 PRINT:PRINT:PRINT -10 PRINT "THE FICTITIOUS CHEMICAL KRYPTOCYANIC ACID CAN ONLY BE" -20 PRINT "DILUTED BY THE RATIO OF 7 PARTS WATER TO 3 PARTS ACID." -30 PRINT "IF ANY OTHER RATIO IS ATTEMPTED, THE ACID BECOMES UNSTABLE" -40 PRINT "AND SOON EXPLODES. GIVEN THE AMOUNT OF ACID, YOU MUST" -50 PRINT "DECIDE WHO MUCH WATER TO ADD FOR DILUTION. IF YOU MISS" -60 PRINT "YOU FACE THE CONSEQUENCES." -100 A=INT(RND(1)*50) -110 W=7*A/3 -120 PRINT A;"LITERS OF KRYPTOCYANIC ACID. HOW MUCH WATER"; -130 INPUT R -140 D=ABS(W-R) -150 IF D>W/20 THEN 200 -160 PRINT " GOOD JOB! YOU MAY BREATHE NOW, BUT DON'T INHALE THE FUMES!" -170 PRINT -180 GOTO 100 -200 PRINT " SIZZLE! YOU HAVE JUST BEEN DESALINATED INTO A BLOB" -210 PRINT " OF QUIVERING PROTOPLASM!" -220 T=T+1 -230 IF T=9 THEN 260 -240 PRINT " HOWEVER, YOU MAY TRY AGAIN WITH ANOTHER LIFE." -250 GOTO 100 -260 PRINT " YOUR 9 LIVES ARE USED, BUT YOU WILL BE LONG REMEMBERED FOR" -270 PRINT " YOUR CONTRIBUTIONS TO THE FIELD OF COMIC BOOK CHEMISTRY." -280 END diff --git a/00_Alternate_Languages/25_Chief/C/chief.c b/00_Alternate_Languages/25_Chief/C/chief.c deleted file mode 100644 index 83cdd8cf9..000000000 --- a/00_Alternate_Languages/25_Chief/C/chief.c +++ /dev/null @@ -1,92 +0,0 @@ -#include -#include -#include -#include - -//check if windows or linux for the clear screen -#ifdef _WIN32 -#define CLEAR "cls" -#else -#define CLEAR "clear" -#endif - -void show_solution(float guess); -float guess_number(float number); -void game(); - -float guess_number(float number){ - float guess; - guess = ((((number - 4) * 5) / 8) * 5 - 3); - return guess; -} - -void game(){ - float number,guess; - char answer[4]; - printf("Think a number\n"); - printf("Then add to it 3 and divide it by 5\n"); - printf("Now multiply by 8, divide by 5 and then add 5\n"); - printf("Finally substract 1\n"); - printf("What is the number you got?(if you got decimals put them ex: 23.6): "); - scanf("%f",&number); - guess = guess_number(number); - printf("The number you thought was %f am I right(Yes or No)?\n",guess); - scanf("%s",answer); - for(int i = 0; i < strlen(answer); i++){ - answer[i] = tolower(answer[i]); - } - if(strcmp(answer,"yes") == 0){ - printf("\nHuh, I Knew I was unbeatable"); - printf("And here is how i did it:\n"); - show_solution(guess); - } - else if (strcmp(answer,"no") == 0){ - printf("HUH!! what was you original number?: "); - scanf("%f",&number); - if(number == guess){ - printf("Huh, I Knew I was unbeatable"); - printf("And here is how i did it:\n"); - show_solution(guess); - } - else{ - printf("If I got it wrong I guess you are smarter than me"); - } - } - else{ - system(CLEAR); - printf("I don't understand what you said\n"); - printf("Please answer with Yes or No\n"); - game(); - } - -} - -void show_solution(float guess){ - printf("%f plus 3 is %f\n",guess,guess + 3); - printf("%f divided by 5 is %f\n",guess + 3,(guess + 3) / 5); - printf("%f multiplied by 8 is %f\n",(guess + 3) / 5,(guess + 3) / 5 * 8); - printf("%f divided by 5 is %f\n",(guess + 3) / 5 * 8,(guess + 3) / 5 * 8 / 5); - printf("%f plus 5 is %f\n",(guess + 3) / 5 * 8 / 5,(guess + 3) / 5 * 8 / 5 + 5); - printf("%f minus 1 is %f\n",(guess + 3) / 5 * 8 / 5 + 5,(guess + 3) / 5 * 8 / 5 + 5 - 1); -} - -void main(){ - char answer[4]; - printf("I am CHIEF NUMBERS FREEK, The GREAT INDIAN MATH GOD.\n"); - printf("Are you ready to take the test you called me out for(Yes or No)? "); - scanf("%s",answer); - for(int i = 0; i < strlen(answer); i++){ - answer[i] = tolower(answer[i]); - } - if(strcmp(answer,"yes") == 0){ - game(); - }else if (strcmp(answer,"no") == 0){ - printf("You are a coward, I will not play with you.%d %s\n",strcmp(answer,"yes"),answer); - } - else{ - system(CLEAR); - printf("I don't understand what you said\n"); - printf("Please answer with Yes or No\n"); - main(); - } -} \ No newline at end of file diff --git a/00_Alternate_Languages/25_Chief/MiniScript/README.md b/00_Alternate_Languages/25_Chief/MiniScript/README.md deleted file mode 100644 index fa28aa67b..000000000 --- a/00_Alternate_Languages/25_Chief/MiniScript/README.md +++ /dev/null @@ -1,24 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -NOTE: I have added `wait` statements before and while printing the lightning bolt, without which it appears too quickly to be properly dramatic. - -Ways to play: - -0. Try-It! Page: -Go to https://miniscript.org/tryit/, clear the sample code from the code editor, and paste in the contents of chief.ms. Then click the "Run Script" button. Program output (and input) will appear in the green-on-black terminal display to the right of or below the code editor. - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript chief.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "chief" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/25_Chief/MiniScript/chief.ms b/00_Alternate_Languages/25_Chief/MiniScript/chief.ms deleted file mode 100644 index 272e6699e..000000000 --- a/00_Alternate_Languages/25_Chief/MiniScript/chief.ms +++ /dev/null @@ -1,50 +0,0 @@ -print " "*30 + "Chief" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print -print "I am chief Numbers Freek, the great Indian math god." -yn = input("Are you ready to take the test you called me out for? ").lower -if not yn or yn[0] != "y" then - print "Shut up, pale face with wise tongue." -end if -print " Take a number and add 3. Divide this number by 5 and" -print "multiply by 8. Divide by 5 and add the same. Subtract 1." -b = input(" What do you have? ").val -c = (b+1-5)*5/8*5-3 -yn = input("I bet your number was " + c + ". Am I right? ").lower -if yn and yn[0] == "y" then - print "Bye!!!" -else - k = input("What was your original number? ").val - 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?" - print "Now watch." - print k + " plus 3 equals " + f +". This divided by 5 equals " + g + ";" - print "this times 8 equals " + h + ". If we divide by 5 and add 5," - print "we get " + i + ", which, minus 1, equals " + j + "." - yn = input("Now do you believe me? ").lower - if yn and yn[0] == "y" then - print "Bye!!!" - else - print "You have made me mad!!!" - print "There must be a great lightning bolt!" - print; print; wait 2 - for x in range(30, 22) - print " "*x + "x x"; wait 0.1 - end for - print " "*21 + "x xxx"; wait 0.1 - print " "*20 + "x x"; wait 0.1 - print " "*19 + "xx x"; wait 0.1 - for y in range(20, 13) - print " "*y + "x x"; wait 0.1 - end for - print " "*12 + "xx"; wait 0.1 - print " "*11 + "x"; wait 0.1 - print " "*10 + "*"; wait 0.1 - print; print"#########################"; print - print "I hope you believe me now, for your sake!!" - end if -end if diff --git a/00_Alternate_Languages/25_Chief/README.md b/00_Alternate_Languages/25_Chief/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/25_Chief/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/25_Chief/chief.bas b/00_Alternate_Languages/25_Chief/chief.bas deleted file mode 100644 index d3157e735..000000000 --- a/00_Alternate_Languages/25_Chief/chief.bas +++ /dev/null @@ -1,51 +0,0 @@ -2 PRINT TAB(30) "CHIEF" -4 PRINT TAB(15) "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -6 PRINT:PRINT:PRINT -10 PRINT "I AM CHIEF NUMBERS FREEK, THE GREAT INDIAN MATH GOD." -20 PRINT "ARE YOU READY TO TAKE THE TEST YOU CALLED ME OUT FOR"; -30 INPUT A$ -40 IF A$="YES" THEN 60 -50 PRINT "SHUT UP, PALE FACE WITH WISE TONGUE." -60 PRINT " TAKE A NUMBER AND ADD 3. DIVIDE THIS NUMBER BY 5 AND" -70 PRINT "MULTIPLY BY 8. DIVIDE BY 5 AND ADD THE SAME. SUBTRACT 1." -80 PRINT " WHAT DO YOU HAVE"; -90 INPUT B -100 LET C = (B+1-5)*5/8*5-3 -110 PRINT "I BET YOUR NUMBER WAS" C". AM I RIGHT"; -120 INPUT D$ -130 IF D$="YES" THEN 500 -140 PRINT "WHAT WAS YOUR ORIGINAL NUMBER"; -150 INPUT K -155 LET F=K+3 -160 LET G=F/5 -170 LET H=G*8 -180 LET I=H/5+5 -190 LET J=I-1 -200 PRINT "SO YOU THINK YOU'RE SO SMART, EH?" -210 PRINT "NOW WATCH." -230 PRINT K"PLUS 3 EQUALS"F". THIS DIVIDED BY 5 EQUALS"G";" -240 PRINT "THIS TIMES 8 EQUALS"H". IF WE DIVIDE BY 5 AND ADD 5," -250 PRINT "WE GET"I", WHICH, MINUS 1, EQUALS"J"." -260 PRINT "NOW DO YOU BELIEVE ME"; -270 INPUT Z$ -290 IF Z$="YES" THEN 500 -295 PRINT "YOU HAVE MADE ME MAD!!!" -300 PRINT "THERE MUST BE A GREAT LIGHTNING BOLT!" -310 PRINT:PRINT -330 FOR X=30 TO 22 STEP -1 -340 PRINT TAB(X) "X X" -350 NEXT X -360 PRINT TAB(21) "X XXX" -370 PRINT TAB(20) "X X" -380 PRINT TAB(19) "XX X" -390 FOR Y=20 TO 13 STEP -1 -400 PRINT TAB(Y) "X X" -410 NEXT Y -420 PRINT TAB(12) "XX" -430 PRINT TAB(11) "X" -440 PRINT TAB(10) "*" -450 PRINT:PRINT"#########################":PRINT -470 PRINT "I HOPE YOU BELIEVE ME NOW, FOR YOUR SAKE!!" -480 GOTO 520 -500 PRINT "BYE!!!" -520 END diff --git a/00_Alternate_Languages/25_Chief/go/main.go b/00_Alternate_Languages/25_Chief/go/main.go deleted file mode 100644 index 19d3e97cb..000000000 --- a/00_Alternate_Languages/25_Chief/go/main.go +++ /dev/null @@ -1,116 +0,0 @@ -package main - -import ( - "bufio" - "fmt" - "os" - "strconv" - "strings" -) - -func printLightning() { - fmt.Println("************************************") - n := 24 - for n > 16 { - var b strings.Builder - b.Grow(n + 3) - for i := 0; i < n; i++ { - b.WriteString(" ") - } - b.WriteString("x x") - fmt.Println(b.String()) - n-- - } - fmt.Println(" x xxx") - fmt.Println(" x x") - fmt.Println(" xx xx") - n-- - for n > 8 { - var b strings.Builder - b.Grow(n + 3) - for i := 0; i < n; i++ { - b.WriteString(" ") - } - b.WriteString("x x") - fmt.Println(b.String()) - n-- - } - fmt.Println(" xx") - fmt.Println(" x") - fmt.Println("************************************") -} - -func printSolution(n float64) { - fmt.Printf("\n%f plus 3 gives %f. This divided by 5 equals %f\n", n, n+3, (n+3)/5) - fmt.Printf("This times 8 gives %f. If we divide 5 and add 5.\n", ((n+3)/5)*8) - fmt.Printf("We get %f, which, minus 1 equals %f\n", (((n+3)/5)*8)/5+5, ((((n+3)/5)*8)/5+5)-1) -} - -func play() { - fmt.Println("\nTake a Number and ADD 3. Now, Divide this number by 5 and") - fmt.Println("multiply by 8. Now, Divide by 5 and add the same. Subtract 1") - - youHave := getFloat("\nWhat do you have?") - compGuess := (((youHave-4)*5)/8)*5 - 3 - if getYesNo(fmt.Sprintf("\nI bet your number was %f was I right(Yes or No)? ", compGuess)) { - fmt.Println("\nHuh, I knew I was unbeatable") - fmt.Println("And here is how i did it") - printSolution(compGuess) - } else { - originalNumber := getFloat("\nHUH!! what was you original number? ") - if originalNumber == compGuess { - fmt.Println("\nThat was my guess, AHA i was right") - fmt.Println("Shamed to accept defeat i guess, don't worry you can master mathematics too") - fmt.Println("Here is how i did it") - printSolution(compGuess) - } else { - fmt.Println("\nSo you think you're so smart, EH?") - fmt.Println("Now, Watch") - printSolution(originalNumber) - - if getYesNo("\nNow do you believe me? ") { - print("\nOk, Lets play again sometime bye!!!!") - } else { - fmt.Println("\nYOU HAVE MADE ME VERY MAD!!!!!") - fmt.Println("BY THE WRATH OF THE MATHEMATICS AND THE RAGE OF THE GODS") - fmt.Println("THERE SHALL BE LIGHTNING!!!!!!!") - printLightning() - fmt.Println("\nI Hope you believe me now, for your own sake") - } - } - } -} - -func getFloat(prompt string) float64 { - scanner := bufio.NewScanner(os.Stdin) - - for { - fmt.Println(prompt) - scanner.Scan() - val, err := strconv.ParseFloat(scanner.Text(), 64) - if err != nil { - fmt.Println("INVALID INPUT, TRY AGAIN") - continue - } - return val - } -} - -func getYesNo(prompt string) bool { - scanner := bufio.NewScanner(os.Stdin) - fmt.Println(prompt) - scanner.Scan() - - return (strings.ToUpper(scanner.Text())[0:1] == "Y") - -} - -func main() { - fmt.Println("I am CHIEF NUMBERS FREEK, The GREAT INDIAN MATH GOD.") - - if getYesNo("\nAre you ready to take the test you called me out for(Yes or No)? ") { - play() - } else { - fmt.Println("Ok, Nevermind. Let me go back to my great slumber, Bye") - } -} diff --git a/00_Alternate_Languages/26_Chomp/MiniScript/README.md b/00_Alternate_Languages/26_Chomp/MiniScript/README.md deleted file mode 100644 index 2fce3ec72..000000000 --- a/00_Alternate_Languages/26_Chomp/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript chomp.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "chomp" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/26_Chomp/MiniScript/chomp.ms b/00_Alternate_Languages/26_Chomp/MiniScript/chomp.ms deleted file mode 100644 index 01b12f815..000000000 --- a/00_Alternate_Languages/26_Chomp/MiniScript/chomp.ms +++ /dev/null @@ -1,102 +0,0 @@ -print " "*33 + "Chomp" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print -// *** THE GAME OF CHOMP *** COPYRIGHT PCC 1973 *** - -initBoard = function(rows, columns) - globals.rows = rows - globals.columns = columns - globals.board = [[null]] // indexed as [row][column], 1-based - for i in range(1, rows) - board.push ["."] + ["*"] * columns - end for - board[1][1] = "P" -end function - -printBoard = function - print - print " "*7 + "1 2 3 4 5 6 7 8 9" - for i in range(1, rows) - print i + " "*6 + board[i][1:].join - end for - print -end function - -introduction = function - print - print "This is the game of chomp (Scientific American, Jan 1973)" - r = input("Do you want the rules (1=yes, 0=no!)? ").val - if r == 0 then return - print "Chomp is for 1 or more players (humans only)." - print - print "Here's how a board looks (this one is 5 by 7):" - initBoard 5, 7 - printBoard - print - print "The board is a big cookie - R rows high and C columns" - print "wide. You input R and C at the start. In the upper left" - print "corner of the cookie is a poison square (P). The one who" - print "chomps the poison square loses. To take a chomp, type the" - print "row and column of one of the squares on the cookie." - print "All of the squares below and to the right of that square" - print "(including that square, too) disappear -- chomp!!" - print "No fair chomping squares that have already been chomped," - print "or that are outside the original dimensions of the cookie." - print -end function - -setup = function - print - globals.numPlayers = input("How many players? ").val - rows = input("How many rows? ").val - while rows > 9 - rows = input("Too many rows (9 is maximum). Now, how many rows? ").val - end while - columns = input("How many columns? ").val - while rows > 9 - columns = input("Too many columns (9 is maximum). Now, how many columns? ").val - end while - print - initBoard rows, columns -end function - -doOneTurn = function(player) - printBoard - print "Player " + player - while true - inp = input("Coordinates of chomp (row,column)? ") - inp = inp.replace(",", " ").split - if inp.len < 2 then continue - r = inp[0].val - c = inp[-1].val - if 1 <= r <= rows and 1 <= c <= columns and board[r][c] != " " then break - print "No fair. You're trying to chomp on empty space!" - end while - if board[r][c] == "P" then - print "You lose, player " + player - globals.gameOver = true - else - - end if - for row in range(r, rows) - for col in range(c, columns) - board[row][col] = " " - end for - end for -end function - -// Main program -introduction -while true - setup - gameOver = false - player = 0 - while not gameOver - player += 1 - if player > numPlayers then player = 1 - doOneTurn player - end while - print - r = input("Again (1=yes, 0=no!)? ").val - if r != 1 then break -end while diff --git a/00_Alternate_Languages/26_Chomp/README.md b/00_Alternate_Languages/26_Chomp/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/26_Chomp/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/26_Chomp/chomp.bas b/00_Alternate_Languages/26_Chomp/chomp.bas deleted file mode 100644 index 2ca7a51f0..000000000 --- a/00_Alternate_Languages/26_Chomp/chomp.bas +++ /dev/null @@ -1,104 +0,0 @@ -10 PRINT TAB(33);"CHOMP" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT:PRINT:PRINT -40 DIM A(10,10) -100 REM *** THE GAME OF CHOMP *** COPYRIGHT PCC 1973 *** -110 PRINT -120 PRINT "THIS IS THE GAME OF CHOMP (SCIENTIFIC AMERICAN, JAN 1973)" -130 PRINT "DO YOU WANT THE RULES (1=YES, 0=NO!)"; -140 INPUT R -150 IF R=0 THEN 340 -160 F=1 -170 R=5 -180 C=7 -190 PRINT "CHOMP IS FOR 1 OR MORE PLAYERS (HUMANS ONLY)." -200 PRINT -210 PRINT "HERE'S HOW A BOARD LOOKS (THIS ONE IS 5 BY 7):" -220 GOSUB 540 -230 PRINT -240 PRINT "THE BOARD IS A BIG COOKIE - R ROWS HIGH AND C COLUMNS" -250 PRINT "WIDE. YOU INPUT R AND C AT THE START. IN THE UPPER LEFT" -260 PRINT "CORNER OF THE COOKIE IS A POISON SQUARE (P). THE ONE WHO" -270 PRINT "CHOMPS THE POISON SQUARE LOSES. TO TAKE A CHOMP, TYPE THE" -280 PRINT "ROW AND COLUMN OF ONE OF THE SQUARES ON THE COOKIE." -290 PRINT "ALL OF THE SQUARES BELOW AND TO THE RIGHT OF THAT SQUARE" -300 PRINT "(INCLUDING THAT SQUARE, TOO) DISAPPEAR -- CHOMP!!" -310 PRINT "NO FAIR CHOMPING SQUARES THAT HAVE ALREADY BEEN CHOMPED," -320 PRINT "OR THAT ARE OUTSIDE THE ORIGINAL DIMENSIONS OF THE COOKIE." -330 PRINT -340 PRINT "HERE WE GO..." -350 REM -360 F=0 -370 FOR I=1 TO 10 -372 FOR J=1 TO 10 -375 A(I,J)=0 -377 NEXT J -379 NEXT I -380 PRINT -390 PRINT "HOW MANY PLAYERS"; -400 INPUT P -410 I1=0 -420 PRINT "HOW MANY ROWS"; -430 INPUT R -440 IF R <= 9 THEN 470 -450 PRINT "TOO MANY ROWS (9 IS MAXIMUM). NOW, "; -460 GOTO 420 -470 PRINT "HOW MANY COLUMNS"; -480 INPUT C -490 IF C <= 9 THEN 530 -500 PRINT "TOO MANY COLUMNS (9 IS MAXIMUM). NOW, "; -510 GOTO 470 -530 PRINT -540 FOR I=1 TO R -550 FOR J=1 TO C -560 A(I,J)=1 -570 NEXT J -580 NEXT I -590 A(1,1)=-1 -600 REM PRINT THE BOARD -610 PRINT -620 PRINT TAB(7);"1 2 3 4 5 6 7 8 9" -630 FOR I=1 TO R -640 PRINT I;TAB(7); -650 FOR J=1 TO C -660 IF A(I,J)=-1 THEN 700 -670 IF A(I,J)=0 THEN 720 -680 PRINT "* "; -690 GOTO 710 -700 PRINT "P "; -710 NEXT J -720 PRINT -730 NEXT I -740 PRINT -750 IF F=0 THEN 770 -760 RETURN -770 REM GET CHOMPS FOR EACH PLAYER IN TURN -780 LET I1=I1+1 -790 LET P1=I1-INT(I1/P)*P -800 IF P1 <> 0 THEN 820 -810 P1=P -820 PRINT "PLAYER";P1 -830 PRINT "COORDINATES OF CHOMP (ROW,COLUMN)"; -840 INPUT R1,C1 -850 IF R1<1 THEN 920 -860 IF R1>R THEN 920 -870 IF C1<1 THEN 920 -880 IF C1>C THEN 920 -890 IF A(R1,C1)=0 THEN 920 -900 IF A(R1,C1)=-1 THEN 1010 -910 GOTO 940 -920 PRINT "NO FAIR. YOU'RE TRYING TO CHOMP ON EMPTY SPACE!" -930 GOTO 820 -940 FOR I=R1 TO R -950 FOR J=C1 TO C -960 A(I,J)=0 -970 NEXT J -980 NEXT I -990 GOTO 610 -1000 REM END OF GAME DETECTED IN LINE 900 -1010 PRINT "YOU LOSE, PLAYER";P1 -1020 PRINT -1030 PRINT "AGAIN (1=YES, 0=NO!)"; -1040 INPUT R -1050 IF R=1 THEN 340 -1060 END diff --git a/00_Alternate_Languages/27_Civil_War/MiniScript/README.md b/00_Alternate_Languages/27_Civil_War/MiniScript/README.md deleted file mode 100644 index ad8e06ed8..000000000 --- a/00_Alternate_Languages/27_Civil_War/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript civilwar.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "civilwar" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/27_Civil_War/MiniScript/civilwar.ms b/00_Alternate_Languages/27_Civil_War/MiniScript/civilwar.ms deleted file mode 100644 index 30b1ce829..000000000 --- a/00_Alternate_Languages/27_Civil_War/MiniScript/civilwar.ms +++ /dev/null @@ -1,437 +0,0 @@ -print " "*26 + "Civil War" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print -// ORIGINAL GAME DESIGN: CRAM, GOODIE, HIBBARD LEXINGTON H.S. -// MODIFICATIONS: G. PAUL, R. HESS (TIES), 1973 -// Conversion to MiniScript: J. Strout, 2023 - -sides = ["Confederate", "Union"] - -getYesNo = function(prompt) - while true - yn = input(prompt + "? ").lower - if yn and yn[0] == "y" then return "YES" - if yn and yn[0] == "n" then return "NO" - print "Yes or no -- " - end while -end function - -instructions = function - print; print; print; print - print "This is a civil war simulation." - print "To play type a response when the computer asks." - print "Remember that all factors are interrelated and that your" - print "responses could change history. Facts and figures used are" - print "based on the actual occurrence. Most battles tend to result" - print "as they did in the civil war, but it all depends on you!!" - print - print "The object of the game is to win as many battles as "; - print "possible." - print - print "Your choices for defensive strategy are:" - print " (1) artillery attack" - print " (2) fortification against frontal attack" - print " (3) fortification against flanking maneuvers" - print " (4) falling back" - print " Your choices for offensive strategy are:" - print " (1) artillery attack" - print " (2) frontal attack" - print " (3) flanking maneuvers" - print " (4) encirclement" - print "You may surrender by typing a '5' for your strategy." -end function - -historicalBattles = [] -addBattle = function(name, men0, men1, cas0, cas1, offDef, desc) - battle = {} - battle.name = name - battle.men = [men0, men1] - battle.casualties = [cas0, cas1] - battle.offDef = offDef // 1=Confederate Defense, 2=both Offense, 3=Confederate Offense - battle.description = desc - historicalBattles.push battle -end function - -loadData = function - // Historical data - addBattle "Bull Run",18000,18500,1967,2708,1, [ -"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."] - - addBattle "Shiloh",40000.,44894.,10699,13047,3, [ -"April 6-7, 1862. The Confederate surprise attack at", -"Shiloh failed due to poor organization."] - - addBattle "Seven Days",95000.,115000.,20614,15849,3, [ -"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."] - - addBattle "Second Bull Run",54000.,63000.,10000,14000,2, [ -"Aug 29-30, 1862. The combined Confederate forces under Lee", -"and Jackson drove the Union forces back into washington."] - - addBattle "Antietam",40000.,50000.,10000,12000,3, [ -"Sept 17, 1862. The South failed to incorporate Maryland", -"into the Confederacy."] - - addBattle "Fredericksburg",75000.,120000.,5377,12653,1, [ -"Dec 13, 1862. The Confederacy under Lee successfully", -"repulsed an attack by the Union under Gen. Burnside."] - - addBattle "Murfreesboro",38000.,45000.,11000,12000,1, [ -"Dec 31, 1862. The South under Gen. Bragg won a close battle."] - - addBattle "Chancellorsville",32000,90000.,13000,17197,2, [ -"May 1-6, 1863. The South had a costly victory and lost", -"one of their outstanding generals, 'Stonewall' Jackson."] - - addBattle "Vicksburg",50000.,70000.,12000,19000,1, [ -"July 4, 1863. Vicksburg was a costly defeat for the South", -"because it gave the Union access to the Mississippi."] - - addBattle "Gettysburg",72500.,85000.,20000,23000,3, [ -"July 1-3, 1863. A Southern mistake by Gen. Lee at Gettysburg", -"cost them one of the most crucial battles of the war."] - - addBattle "Chickamauga",66000.,60000.,18000,16000,2, [ -"Sept. 15, 1863. Confusion in a forest near Chickamauga led", -"to a costly Southern victory."] - - addBattle "Chattanooga",37000.,60000.,36700.,5800,2, [ -"Nov. 25, 1863. After the South had sieged Gen. Rosencrans'", -"army for three months, Gen. Grant broke the siege."] - - addBattle "Spotsylvania",62000.,110000.,17723,18000,2, [ -"May 5, 1864. Grant's plan to keep Lee isolated began to", -"fail here, and continued at Cold Harbor and Petersburg."] - - addBattle "Atlanta",65000.,100000.,8500,3700,1, [ -"August, 1864. Sherman and three veteran armies converged", -"on Atlanta and dealt the death blow to the Confederacy."] - -end function - -setup = function - print; print; print - if getYesNo("Are there two generals present") == "YES" then - globals.numPlayers = 2 - else - globals.numPlayers = 1 - print; print "You are the Confederacy. Good luck!" - print - end if - print "Select a battle by typing a number from 1 to 14 on" - print "request. Type any other number to end the simulation." - print "But '0' brings back exact previous battle situation" - print "allowing you to replay it." - print - print "Note: a negative food$ entry causes the program to " - print "use the entries from the previous battle." - print - yn = getYesNo("After requesting a battle, do you wish battle descriptions") - globals.battleDesc = (yn == "YES") -end function - -// Game variables -- the 2-element arrays below represent the stats for -// player 0 (Confederacy) and 1 (Union) -D = [0,0] // money -F = [0,0] // food budget -H = [0,0] // salary budget -B = [0,0] // ammo budget -men = [0,0] // men at start of battle? (M1, M2) -menAdded = [0,0] // men added (M3, M4) -menAvail = [0,0] // men available (M5, M6) -P = [0,0] // casualties? -T = [0,0] // total losses? -resources = [0,0] // total resources (money) available to each side (R1, R2) -spending = [0,0] // total expenditures for each side (Q1, Q2) -morale = [0,0] // troop morale (O) -strategy = [0,0] // strategy choice (Y1, Y2) -inflation = [0,0] // inflation (I1, I2) - -R = 0 // previous battle -losses = 0 // Confederate losses -wins = 0 // Confederate wins -unresolved = 0 // battles where neither side clearly won - -printInColumns = function(a, b, c) - print (a + " "*20)[:20] + (b + " "*16)[:16] + c -end function - -pickBattle = function - print; print; print - globals.replay = false - while true - num = input("Which battle do you wish to simulate? ").val - if num == 0 and R > 0 then - num = R - globals.replay = true - end if - if 0 < num <= historicalBattles.len then break - end while - globals.bat = historicalBattles[num - 1] - if not replay then - men[0] = bat.men[0] - men[1] = bat.men[1] - - // inflation calc - inflation[0] = 10 + (losses - wins) * 2 - inflation[1] = 10 + (wins - losses) * 2 - - // money available - D[0] = 100 * floor((men[0]*(100-inflation[0])/2000) * (1+(resources[0]-spending[0])/(resources[0]+1))+0.5) - D[1] = 100 * floor(men[1]*(100-inflation[1])/2000 + 0.5) - if numPlayers == 2 then - D[1] = 100 * floor((men[1]*(100-inflation[1])/2000) * (1+(resources[1]-spending[1])/(resources[1]+1))+0.5) - end if - - // men available - menAvail[0] = floor(men[0]*(1 + (P[0]-T[0])/(menAdded[0]+1))) - menAvail[1] = floor(men[1]*(1 + (P[1]-T[1])/(menAdded[1]+1))) - globals.F1 = 5/6 * men[0] // ?!? - print; print; print; print; print -print "P:" + P + "; T:" + T + "; menAdded:" + menAdded -print "men[0]:" + men[0] + " ...F1:" + F1 - - print "This is the battle of " + bat.name - if battleDesc then - for line in bat.description - print line - end for - end if - else - print bat.name + " Instant Replay" - end if - print - printInColumns " ", "CONFEDERACY", " UNION" - printInColumns "MEN", " "+menAvail[0], " "+menAvail[1] - printInColumns "MONEY", "$ "+D[0], "$ "+D[1] - printInColumns "INFLATION", " "+(inflation[0]+15)+" %", " " +inflation[1]+" %" - // (Note: printout lies and shows confederate inflation 15% higher than actual) - print -end function - -getBudget = function(player) - print sides[player] + " General---How much do you wish to spend for" - getNum = function(prompt, allowNegative) - while true - n = input(prompt) - if not n then continue - if n[-1] == "k" then n = n[:-1] + "000" // (allow entries like "60k") - if n.val >= 0 or allowNegative then return n.val - print "Negative values are not allowed." - end while - end function - - while true - f = getNum(" - Food......? ", true) - if f < 0 then - if resources[player] == 0 then - print "No previous entries." - print "How much do you wish to spend for" - continue - end if - break // keep all previous entries - end if - F[player] = f - H[player] = getNum(" - Salaries..? ", false) - B[player] = getNum(" - Ammunition? ", false) - if F[player] + H[player] + B[player] <= D[player] then break - print "Think again! You have only $" + D[player] - end while -end function - -calcMorale = function(player) - m = ((2*F[player]^2 + H[player]^2) / F1^2 + 1) - print (" "*11 + sides[player])[-11:], " " - if m >= 10 then - print "morale is high" - else if m >= 5 then - print "morale is fair" - else - print "morale is poor" - end if - morale[player] = m -end function - -getStrategy = function(player) - if numPlayers == 1 then prompt = "Your strategy" else prompt = sides[player] + " strategy" - while true - strat = input(prompt + "? ").val - if 0 < strat < 6 then break - print "Strategy " + strat + " not allowed." - end while - strategy[player] = strat - if strat == 5 then - print "The " + ["Confederacy", "Union"][player] + " has surrendered." - globals.gameOver = true - end if -end function - -calcComputerStrategy = function - // Union strategy is computer chosen - print "Union strategy is ", "" - s0 = 0 - r = 100 * rnd - for i in range(0, 3) - s0 += unionStrats[i] - if r < s0 then - strategy[1] = i+1 - break - end if - end for - print strategy[1] -end function - -learnStrategy = function - // Learn present strategy, start forgetting old ones. - // - Present strategy of south gains 3*s, others lose s - // probability points, unless a strategy falls below 5%. - s = 3; s0 = 0 - for i in range(0,3) - if unionStrats[i] < 5 then continue - unionStrats[i] -= s - s0 += s - end for - unionStrats[strategy[1]-1] += s0 -end function - -doBattle = function - U = 0; U2 = 0 - // simulated losses -- North - C6 = (2 * bat.casualties[1]/5) * (1+1/(2*(abs(strategy[1]-strategy[0])+1))) - C6 = C6 * (1.28 + (5*men[1]/6) / (B[1]+1)) - C6 = floor(C6 * (1+1/morale[1]) + .5) - // - IF LOSS > MEN PRESENT, RESCALE LOSSES - E2 = 100/morale[1] // desertions (Union) - if floor(C6 + E2) >= menAvail[1] then - C6 = floor(13*menAvail[1]/20) - E2 = 7 * C6/13 - U2=1 // Union loss - end if - // simulated losses -- South - C5 = (2 * bat.casualties[0]/5) * (1+1/(2*(abs(strategy[1]-strategy[0])+1))) - print "step A:" + C5 - C5 = floor(C5 * (1+1/morale[0])*(1.28+F1/(B[0]+1))+.5) - print "step B:" + C5 - print "based on morale[0]:"+morale[0]+", F1:"+F1+", B[0]:"+B[0] - E=100/morale[0] - if C5+100/morale[0] >= men[0]*(1+(P1-T1)/(menAdded[0]+1)) then - C5 = floor(13*men[0]/20 * (1+(P1-T1)/(menAdded[0]+1))) - print "step C:" + C5 - print "men: " + men; print "menAdded: " + menAdded; print "P1,T1:" + P1 + "," + T1 - E=7*C5/13 // desertions (Confed) - U=1 // Confederate loss - end if - print - print; print; printInColumns "", "CONFEDERACY", "UNION" - if numPlayers == 1 then - C6 = floor(17 * bat.casualties[1] * bat.casualties[0] / (C5*20)) - E2 = 5 * morale[0] - end if - printInColumns "CASUALTIES", C5, C6 - printInColumns "DESERTIONS", floor(E), floor(E2) - print - if numPlayers == 2 then - print "Compared to the actual casualties at " + bat.name - print "Confederate: " + round(100*C5/bat.casualties[0]) + "% of the original" - print "Union: " + round(100*C6/bat.casualties[1]) + "% of the original" - print - // Who won? - print "U:"+U+ " U2:"+U2 - if (U == 1 and U2 != 1) or (U == U2 and C5+E > C6+E2) then - print "The Union wins " + bat.name - globals.losses += 1 - else if (U2 == 1 and U != 1) or (U == U2 and C5+E < C6+E2) then - print "The confederacy wins " + bat.name - globals.wins += 1 - else - print "Battle outcome unresolved" - globals.unresolved += 1 - end if - else - print "Your casualties were " + round(100*C5/bat.casualties[0]) + "% of" - print "the actual casualties at " + bat.name - print - if U == 1 or C5+E >= 17*bat.casualties[1]*bat.casualties[0]/(C5*20)+5*morale[0] then - print "You lose " + bat.name - if not replay then globals.losses += 1 - else - print "You win " + bat.name - if not replay then globals.wins += 1 - end if - end if - if not replay then - // Cumulative battle factors which alter historical - // resources availeble. (If a replay, don't update.) - T[0] += C5 + E - T[1] += C6 + E2 - P[0] += bat.casualties[0] - P[1] += bat.casualties[1] - spending[0] += F[0] + H[0] + B[0] - spending[1] += F[1] + H[1] + B[1] - resources[0] += men[0]*(100-inflation[0])/20 - resources[1] += men[1]*(100-inflation[1])/20 - menAdded[0] += men[0] - menAdded[1] += men[1] - - learnStrategy - end if - print "---------------" -end function - -// Main Program -loadData -unionStrats = [25, 25, 25, 25] -P1=0; P2=0; T1=0; T2=0 // cumulative stat thingies -print -if getYesNo("Do you want instructions") == "YES" then instructions -setup -gameOver = false -while not gameOver - pickBattle - if gameOver then break - for i in range(0, numPlayers-1) - getBudget i - end for - for i in range(0, numPlayers-1) - calcMorale i - end for - print "Confederate General---", "" - if bat.offDef == 3 then - print "you are on the offensive" - else if bat.offDef == 1 then - print "you are on the defensive" - else - print "both sides are on the offensive " - end if - print - getStrategy 0 - if numPlayers == 2 then getStrategy 1 else calcComputerStrategy - if gameOver then break - doBattle -end while - -// Finish off -print; print; print; print; print; print -print "The Confederacy has won " + wins + " battles and lost " + losses -if strategy[0] == 5 or (strategy[1] != 5 and losses > wins) then - print "The Union has won the war" -else - print "The Confederacy has won the war" -end if -print "For the " + (wins + losses + unresolved) + " battles fought (excluding reruns)" -print -printInColumns "", "Confederacy", "Union" -printInColumns "Historical Losses", round(P[0]), round(P[1]) -printInColumns "Simulated Losses", round(T[0]), round(T[1]) -print -printInColumns " % of Original", round(100*T[0]/P[0]), round(100*T[1]/P[1]) -if numPlayers == 1 then - print - print "Union intelligence suggsets that the South used " - print "strategies 1, 2, 3, 4 in the following percentages" - print unionStrats.join -end if diff --git a/00_Alternate_Languages/27_Civil_War/README.md b/00_Alternate_Languages/27_Civil_War/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/27_Civil_War/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/27_Civil_War/civilwar.bas b/00_Alternate_Languages/27_Civil_War/civilwar.bas deleted file mode 100644 index f8fe97018..000000000 --- a/00_Alternate_Languages/27_Civil_War/civilwar.bas +++ /dev/null @@ -1,395 +0,0 @@ -2 PRINT TAB(26) "CIVIL WAR" -4 PRINT TAB(15) "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -6 PRINT : PRINT : PRINT -20 REM ORIGINAL GAME DESIGN: CRAM, GOODIE, HIBBARD LEXINGTON H.S. -30 REM MODIFICATIONS: G. PAUL, R. HESS (TIES), 1973 -50 DIM S(4),C$(14),M1(14),M2(14),C1(14),C2(14),M(14) -60 REM UNION INFO ON LIKELY CONFEDERATE STRATEGY -70 S(1)=25 : S(2)=25 : S(3)=25 : S(4)=25 -82 REM READ HISTORICAL DATA. -84 FOR D=1 TO 14 -86 READ C$(D),M1(D),M2(D),C1(D),C2(D),M(D) -88 NEXT D -89 LET D=RND(-1) -90 PRINT -100 PRINT "DO YOU WANT INSTRUCTIONS"; -110 INPUT X$ -120 IF X$="YES" THEN 160 -130 IF X$="NO" THEN 370 -140 PRINT "YES OR NO -- "; -150 GOTO 110 -160 PRINT : PRINT : PRINT : PRINT -170 PRINT "THIS IS A CIVIL WAR SIMULATION." -180 PRINT "TO PLAY TYPE A RESPONSE WHEN THE COMPUTER ASKS." -190 PRINT "REMEMBER THAT ALL FACTORS ARE INTERRELATED AND THAT YOUR" -200 PRINT "RESPONSES COULD CHANGE HISTORY. FACTS AND FIGURES USED ARE" -210 PRINT "BASED ON THE ACTUAL OCCURRENCE. MOST BATTLES TEND TO RESULT" -220 PRINT "AS THEY DID IN THE CIVIL WAR, BUT IT ALL DEPENDS ON YOU!!" -230 PRINT -240 PRINT "THE OBJECT OF THE GAME IS TO WIN AS MANY BATTLES AS "; -245 PRINT "POSSIBLE." -250 PRINT -260 PRINT "YOUR CHOICES FOR DEFENSIVE STRATEGY ARE:" -270 PRINT " (1) ARTILLERY ATTACK" -280 PRINT " (2) FORTIFICATION AGAINST FRONTAL ATTACK" -290 PRINT " (3) FORTIFICATION AGAINST FLANKING MANEUVERS" -300 PRINT " (4) FALLING BACK" -310 PRINT " YOUR CHOICES FOR OFFENSIVE STRATEGY ARE:" -320 PRINT " (1) ARTILLERY ATTACK" -330 PRINT " (2) FRONTAL ATTACK" -340 PRINT " (3) FLANKING MANEUVERS" -350 PRINT " (4) ENCIRCLEMENT" -360 PRINT "YOU MAY SURRENDER BY TYPING A '5' FOR YOUR STRATEGY." -370 PRINT : PRINT : PRINT : PRINT "ARE THERE TWO GENERALS PRESENT "; -380 PRINT "(ANSWER YES OR NO)"; -390 INPUT B$ -400 IF B$="YES" THEN 430 -410 IF B$ <> "NO" THEN 380 -420 PRINT : PRINT "YOU ARE THE CONFEDERACY. GOOD LUCK!" -425 PRINT -430 LET D=1 -440 IF B$ <> "YES" THEN 460 -450 LET D=2 -460 PRINT "SELECT A BATTLE BY TYPING A NUMBER FROM 1 TO 14 ON" -470 PRINT "REQUEST. TYPE ANY OTHER NUMBER TO END THE SIMULATION." -480 PRINT "BUT '0' BRINGS BACK EXACT PREVIOUS BATTLE SITUATION" -490 PRINT "ALLOWING YOU TO REPLAY IT" -500 PRINT -510 PRINT "NOTE: A NEGATIVE FOOD$ ENTRY CAUSES THE PROGRAM TO " -520 PRINT "USE THE ENTRIES FROM THE PREVIOUS BATTLE" -530 PRINT -540 PRINT "AFTER REQUESTING A BATTLE, DO YOU WISH "; -550 PRINT "BATTLE DESCRIPTIONS "; -560 PRINT "(ANSWER YES OR NO)"; -570 INPUT X$ -580 IF X$="YES" THEN 600 -590 IF X$ <> "NO" THEN 560 -600 L=0:W=0:R1=0:Q1=0:M3=0:M4=0:P1=0:P2=0:T1=0:T2=0 -610 F(2)=0:H(2)=0:B(2)=0:R2=0:Q2=0:C6=0:F=0:W0=0:Y=0:Y2=0:U=0:U2=0 -620 PRINT : PRINT : PRINT -630 PRINT "WHICH BATTLE DO YOU WISH TO SIMULATE"; -640 INPUT A -650 IF A <> 0 THEN 660 -655 IF R <> 0 THEN 1140 -660 IF A <=0 THEN 2860 -665 IF A >= 15 THEN 2860 -670 LET C$=C$(A) -680 LET M1=M1(A) -690 LET M2=M2(A) -700 LET C1=C1(A) -710 LET C2=C2(A) -720 LET M=M(A) -960 LET U=0 -970 REM INFLATION CALC -980 LET I1=10+(L-W)*2 -990 LET I2=10+(W-L)*2 -1000 REM - MONEY AVAILABLE -1010 LET D(1)=100*INT((M1*(100-I1)/2000)*(1+(R1-Q1)/(R1+1))+.5) -1020 LET D(2)=100*INT(M2*(100-I2)/2000+.5) -1030 IF B$ <> "YES" THEN 1050 -1040 LET D(2)=100*INT((M2*(100-I2)/2000)*(1+(R2-Q2)/(R2+1))+.5) -1050 REM - MEN AVAILABLE -1060 LET M5=INT(M1*(1+(P1-T1)/(M3+1))) -1070 LET M6=INT(M2*(1+(P2-T2)/(M4+1))) -1080 LET F1=5*M1/6 -1090 PRINT : PRINT : PRINT : PRINT : PRINT -1100 PRINT "THIS IS THE BATTLE OF ";C$ -1110 IF X$="NO" THEN 1150 -1120 IF A>11 THEN 1130 -1125 ON A GOTO 3580,3620,3650,3690,3720,3750,3780,3800,3830,3860,3890 -1130 ON A-11 GOTO 3920,3950,3980 -1140 PRINT C$" INSTANT REPLAY" -1150 PRINT -1160 PRINT " ","CONFEDERACY"," UNION" -1170 PRINT "MEN"," "M5," "M6 -1180 PRINT "MONEY","$";D(1),"$";D(2) -1190 PRINT "INFLATION"," ";I1+15;"%"," ";I2;"%" -1195 PRINT -1200 REM - ONLY IN PRINTOUT IS CONFED INFLATION = I1+15% -1210 REM - IF TWO GENERALS, INPUT CONFED. FIRST -1220 FOR I=1 TO D -1230 IF B$ <> "YES" THEN 1260 -1240 IF I=2 THEN 1260 -1250 PRINT "CONFEDERATE GENERAL---"; -1260 PRINT "HOW MUCH DO YOU WISH TO SPEND FOR" -1270 PRINT " - FOOD......"; -1280 INPUT F -1290 IF F >= 0 THEN 1360 -1300 IF R1 <> 0 THEN 1330 -1310 PRINT "NO PREVIOUS ENTRIES" -1320 GOTO 1270 -1330 PRINT "ASSUME YOU WANT TO KEEP SAME ALLOCATIONS" -1340 PRINT -1350 GOTO 1510 -1360 LET F(I)=F -1370 PRINT " - SALARIES.."; -1380 INPUT H(I) -1390 LET N=1 -1400 IF H(I)<0 THEN 1490 -1410 PRINT " - AMMUNITION"; -1420 INPUT B(I) -1430 LET N=2 -1440 IF B(I)<0 THEN 1490 -1450 PRINT -1460 IF F(I)+H(I)+B(I) <= D(I) THEN 1510 -1470 PRINT "THINK AGAIN! YOU HAVE ONLY $"D(I) -1480 GOTO 1270 -1490 PRINT "NEGATIVE VALUES NOT ALLOWED." -1500 ON N GOTO 1370,1410 -1510 IF B$ <> "YES" THEN 1550 -1520 IF I=2 THEN 1550 -1530 PRINT "UNION GENERAL---"; -1540 NEXT I -1550 FOR Z=1 TO D -1560 IF B$ <> "YES" THEN 1620 -1570 ON Z GOTO 1580,1600 -1580 PRINT "CONFEDERATE "; -1590 GOTO 1620 -1600 PRINT " UNION "; -1610 REM - FIND MORALE -1620 LET O=((2*F(Z)^2+H(Z)^2)/F1^2+1) -1630 IF O<10 THEN 1660 -1640 PRINT "MORALE IS HIGH" -1650 GOTO 1700 -1660 IF O<5 THEN 1690 -1670 PRINT "MORALE IS FAIR" -1680 GOTO 1700 -1690 PRINT "MORALE IS POOR" -1700 IF B$ <> "YES" THEN 1760 -1710 LET O(Z)=O -1720 NEXT Z -1730 LET O2=O(2) -1740 LET O=O(1) -1750 PRINT "CONFEDERATE GENERAL---"; -1760 REM - ACTUAL OFF/DEF BATTLE SITUATION -1770 IF M <> 3 THEN 1800 -1780 PRINT "YOU ARE ON THE OFFENSIVE" -1790 GOTO 1840 -1800 IF M <> 1 THEN 1830 -1810 PRINT "YOU ARE ON THE DEFENSIVE" -1820 GOTO 1840 -1830 PRINT "BOTH SIDES ARE ON THE OFFENSIVE " -1840 PRINT -1850 REM - CHOOSE STRATEGIES -1860 IF B$ <> "YES" THEN 1910 -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 "; -2030 NEXT I -2040 LET Y2=Y -2050 LET Y=Y1 -2060 IF Y2=5 THEN 2020 -2070 REM : SIMULATED LOSSES-NORTH -2080 LET C6=(2*C2/5)*(1+1/(2*(ABS(Y2-Y)+1))) -2090 LET C6=C6*(1.28+(5*M2/6)/(B(2)+1)) -2100 LET C6=INT(C6*(1+1/O2)+.5) -2110 REM - IF LOSS > MEN PRESENT, RESCALE LOSSES -2120 LET E2=100/O2 -2130 IF INT(C6+E2) "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" -2350 PRINT -2360 REM - 1 WHO WON -2370 IF U <> 1 THEN 2380 -2375 IF U2=1 THEN 2460 -2380 IF U=1 THEN 2420 -2390 IF U2=1 THEN 2440 -2400 IF C5+E=C6+E2 THEN 2460 -2410 IF C5+E 0 THEN 3180 -3140 INPUT Y2 -3150 IF Y2 <=0 THEN 3160 -3155 IF Y2<5 THEN 3290 -3160 PRINT "ENTER 1 , 2 ,3 , OR 4 (USUALLY PREVIOUS UNION STRATEGY)" -3170 GOTO 3140 -3180 LET S0=0 -3190 LET R=100*RND(0) -3200 FOR I=1 TO 4 -3210 LET S0=S0+S(I) -3220 REM - IF ACTUAL STRATEGY INFO IS IN PROGRAM DATA STATEMENTS -3230 REM THEN R-100 IS EXTRA WEIGHT GIVEN TO THAT STATEGY. -3240 IF R 3 then - // Army attack - if x > a then continue - if x < a/3 then - print "You lost "+x+" men from your army." - a=floor(a-x) - else if x < 2*a/3 then - print "You lost " + floor(x/3) + " men, but I lost " + floor(2*d/3) - a=floor(a-x/3) - d=0 // (message above lied!) - else - print "You sunk one of my patrol boats, but I wiped out two" - print "of your air force bases and 3 army bases." - a=floor(a/3) - c=floor(c/3) - e=floor(2*e/3) - end if - else if y == 2 then - // Naval attack - if x > b then continue - if x < e/3 then - print "Your attack was stopped!" - b = floor(b-x) - else if x < 2*e/3 then - print "You destroyed " + floor(2*e/3) + "of my army." - e=floor(e/3) - else - print "You sunk one of my patrol boats, but I wiped out two" - print "of your air force bases and 3 army bases." - a=floor(a/3) - c=floor(c/3) - e=floor(2*e/3) - end if - else - // Air force attack - if x > c then continue - if x < c/3 then - print "Your attack was wiped out." - c = floor(c-x) - else if x < 2*c/3 then - print "We had a dogfight. You won - and finished your mission." - d=floor(2*d/3) - e=floor(e/3) - f=floor(f/3) - else - print "You wiped out one of my army patrols, but I destroyed" - print "two navy bases and bombed three army bases." - a=floor(a/4) - b=floor(b/3) - d=floor(2*d/3) - end if - end if - break -end while - -result = null // 1 you win, -1 you lose, 0 tie (treaty) -print -printInColumns3 "", "YOU", "ME" -printInColumns3 "army", a, d -printInColumns3 "navy", b, e -printInColumns3 "a. f.", c, f -print "What is your next move?" -print "army=1 navy=2 air force=3" -g = input.val -while true - t = input("How many men? ").val - if t < 0 then continue - if g <= 1 or g > 3 then - // Army attack - if t > a then continue - if t < d/2 then - print "I wiped out your attack!" - a = a-t - else - print "You destroyed my army!" - d=0 - end if - else if g == 2 then - // Naval attack - if t > b then continue - if t < e/2 then - print "I sunk two of your battleships, and my air force" - print "wiped out your ungaurded capitol." // (sic) - a = a/4 - b = b/2 - else - print "Your navy shot down three of my xiii planes," - print "and sunk three battleships." - f = 2*f/3 - e = (e/2) - end if - else - // Air Force attack - if t > c then continue - if t > f/2 then - print "My navy and air force in a combined attack left" - print "your country in shambles." - a = a/3 - b = b/3 - c = c/3 - else - print "One of your planes crashed into my house. I am dead." - print "My country fell apart." - result = 1 - end if - end if - break -end while - -if result == null then - print - print "From the results of both of your attacks," - result = 0 - if a+b+c > 3/2*(d+e+f) then result = 1 - if a+b+c < 2/3*(d+e+f) then result = -1 -end if - -if result == 0 then - print "the treaty of paris concluded that we take our" - print "respective countries and live in peace." -else if result == 1 then - print "You won, oh! shucks!!!!" -else - print "You lost-I conquered your country. It serves you" - print "right for playing this stupid game!!!" -end if diff --git a/00_Alternate_Languages/28_Combat/README.md b/00_Alternate_Languages/28_Combat/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/28_Combat/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/28_Combat/combat.bas b/00_Alternate_Languages/28_Combat/combat.bas deleted file mode 100644 index c5fdf9b3e..000000000 --- a/00_Alternate_Languages/28_Combat/combat.bas +++ /dev/null @@ -1,124 +0,0 @@ -1 PRINT TAB(33);"COMBAT" -2 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -3 PRINT: PRINT: PRINT -4 PRINT "I AM AT WAR WITH YOU.": PRINT "WE HAVE 72000 SOLDIERS APIECE." -5 PRINT:PRINT "DISTRIBUTE YOUR FORCES." -6 PRINT ,"ME"," YOU" -7 PRINT "ARMY",30000, -8 INPUT A -9 PRINT "NAVY",20000, -10 INPUT B -11 PRINT "A. F.",22000, -12 INPUT C -13 IF A+B+C>72000 THEN 5 -14 D=30000 -15 E=20000 -16 F=22000 -17 PRINT "YOU ATTACK FIRST. TYPE (1) FOR ARMY; (2) FOR NAVY;" -18 PRINT "AND (3) FOR AIR FORCE." -19 INPUT Y -20 PRINT "HOW MANY MEN" -21 INPUT X -22 IF X<0 THEN 20 -23 ON Y GOTO 100,200,300 -100 IF X>A THEN 20 -105 IF XB THEN 20 -210 IF XC THEN 20 -310 IF XA THEN 1030 -1610 IF TB THEN 1030 -1710 IF TC THEN 1030 -1810 IF T>F/2 THEN 1830 -1820 GOTO 1850 -1830 PRINT "MY NAVY AND AIR FORCE IN A COMBINED ATTACK LEFT" -1831 PRINT "YOUR COUNTRY IN SHAMBLES." -1835 A=A/3 -1837 B=B/3 -1840 C=C/3 -1845 GOTO 2000 -1850 PRINT "ONE OF YOUR PLANES CRASHED INTO MY HOUSE. I AM DEAD." -1851 PRINT "MY COUNTRY FELL APART." -1860 GOTO 2010 -2000 PRINT -2001 PRINT "FROM THE RESULTS OF BOTH OF YOUR ATTACKS," -2002 IF A+B+C>3/2*(D+E+F) THEN 2010 -2005 IF A+B+C<2/3*(D+E+F) THEN 2015 -2006 PRINT "THE TREATY OF PARIS CONCLUDED THAT WE TAKE OUR" -2007 PRINT "RESPECTIVE COUNTRIES AND LIVE IN PEACE." -2008 GOTO 2020 -2010 PRINT "YOU WON, OH! SHUCKS!!!!" -2012 GOTO 2020 -2015 PRINT "YOU LOST-I CONQUERED YOUR COUNTRY. IT SERVES YOU" -2016 PRINT "RIGHT FOR PLAYING THIS STUPID GAME!!!" -2020 END diff --git a/00_Alternate_Languages/29_Craps/MiniScript/README.md b/00_Alternate_Languages/29_Craps/MiniScript/README.md deleted file mode 100644 index e500f4c36..000000000 --- a/00_Alternate_Languages/29_Craps/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript craps.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "craps" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/29_Craps/MiniScript/craps.ms b/00_Alternate_Languages/29_Craps/MiniScript/craps.ms deleted file mode 100644 index 900ba5d43..000000000 --- a/00_Alternate_Languages/29_Craps/MiniScript/craps.ms +++ /dev/null @@ -1,87 +0,0 @@ -// Craps -// Ported from BASIC to MiniScript by Joe Strout (2023) - -print " "*33 + "CRAPS" -print " "*15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -print; print; print - -print "2,3,12 are losers; 4,5,6,8,9,10 are points; 7,11 are natural winners." -winnings = 0 - -rollDice = function - wait 0.5 // (a small delay makes the game more dramatic) - return ceil(rnd*6) + ceil(rnd*6) -end function - -doOneBet = function - while true - wager = input("Input the amount of your wager: ").val - if wager > 0 then break - end while - print "I will now throw the dice." - result = 0 // 1 if we win, 2 if win double, -1 if we lose - roll = rollDice - if roll == 7 or roll == 11 then - print roll + "- natural....a winner!!!!" - print roll + " pays even money, you win " + wager + " dollars" - result = 1 - else if roll == 2 then - print "2- snake eyes....you lose." - print "You lose " + wager + " dollars." - result = -1 - else if roll == 3 or roll == 12 then - print roll + " - craps...you lose." - print "You lose " + wager + " dollars." - result = -1 - else - point = roll - print point + " is the point. I will roll again" - while true - roll = rollDice - if roll == 7 then - print "7 - craps. You lose." - print "You lose $" + wager - result = -1 - break - else if roll == point then - print roll + "- a winner.........CONGRATS!!!!!!!!" - print roll + " at 2 to 1 odds pays you...let me see..." + - (2*wager) + " dollars" - result = 2 - break - else - print roll + " - no point. I will roll again" - end if - end while - end if - globals.winnings += wager * result -end function - -// Main loop. -while true - doOneBet - - while true - // Why you have to enter 5 to continue is anyone's guess, - // but that's what the original program did. - again = input(" If you want to play again print 5 if not print 2: ") - if again == "5" or again == "2" then break - end while - - if winnings < 0 then - print "You are now under $" + (-winnings) - else if winnings > 0 then - print "You are now ahead $" + winnings - else - print "You are now even at 0" - end if - if again != "5" then break -end while - -if winnings < 0 then - print "Too bad, you are in the hole. Come again." -else if winnings > 0 then - print "Congratulations---You came out a winner. Come again!" -else - print "Congrtulations---You came out even, not bad for an amateur" -end if diff --git a/00_Alternate_Languages/29_Craps/README.md b/00_Alternate_Languages/29_Craps/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/29_Craps/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/29_Craps/craps.bas b/00_Alternate_Languages/29_Craps/craps.bas deleted file mode 100644 index 3a387059f..000000000 --- a/00_Alternate_Languages/29_Craps/craps.bas +++ /dev/null @@ -1,82 +0,0 @@ -5 PRINT TAB(33);"CRAPS" -10 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -12 PRINT:PRINT:PRINT -15 LET R=0 -20 PRINT"2,3,12 ARE LOSERS; 4,5,6,8,9,10 ARE POINTS; 7,11 ARE NATURAL WINNERS." -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 -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 -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 -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 -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 -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 -320 PRINT " IF YOU WANT TO PLAY AGAIN PRINT 5 IF NOT PRINT 2"; -330 INPUT M -331 IF R<0 THEN 334 -332 IF R>0 THEN 336 -333 IF R=0 THEN 338 -334 PRINT "YOU ARE NOW UNDER $";-R -335 GOTO 340 -336 PRINT "YOU ARE NOW AHEAD $";R -337 GOTO 340 -338 PRINT "YOU ARE NOW EVEN AT 0" -340 IF M=5 THEN 27 -341 IF R<0 THEN 350 -342 IF R>0 THEN 353 -343 IF R=0 THEN 355 -350 PRINT"TOO BAD, YOU ARE IN THE HOLE. COME AGAIN." -351 GOTO 360 -353 PRINT"CONGRATULATIONS---YOU CAME OUT A WINNER. COME AGAIN!" -354 GOTO 360 -355 PRINT"CONGRATULATIONS---YOU CAME OUT EVEN, NOT BAD FOR AN AMATEUR" -360 END diff --git a/00_Alternate_Languages/29_Craps/distributions.bas b/00_Alternate_Languages/29_Craps/distributions.bas deleted file mode 100644 index a963b228a..000000000 --- a/00_Alternate_Languages/29_Craps/distributions.bas +++ /dev/null @@ -1,24 +0,0 @@ -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 diff --git a/00_Alternate_Languages/29_Craps/nim/craps.nim b/00_Alternate_Languages/29_Craps/nim/craps.nim deleted file mode 100644 index 770b6c0e1..000000000 --- a/00_Alternate_Languages/29_Craps/nim/craps.nim +++ /dev/null @@ -1,68 +0,0 @@ -import std/[random,strutils] - -var - wager, winnings, rollResult: int - stillplaying: bool = true - -randomize() # Seed the random number generator - -proc tryAgain(): bool = - echo "WANT TO PLAY AGAIN? (YES OR NO)" - var answer = readLine(stdin).normalize() - result = (answer == "y") or (answer == "yes") - -proc takePoint(point: int) = - var flag = true - while flag: - var pointRoll: int = (rand 1..6) + (rand 1..6) # roll dice, then add the sum - if pointRoll == 7: - echo pointRoll, "- CRAPS. YOU LOSE." - echo "YOU LOSE ", wager, " DOLLARS." - winnings -= wager - flag = false - if pointRoll == point: - echo point, "- A WINNER.........CONGRATS!!!!!!!!" - echo "AT 2 TO 1 ODDS PAYS YOU...LET ME SEE... ", 2*wager, " DOLLARS" - winnings += (2*wager) - flag = false - if flag: - echo pointRoll, " - NO POINT. I WILL ROLL AGAIN" - -echo spaces(33), "CRAPS" -echo spaces(15), "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -echo "\n" -echo "2,3,12 ARE LOSERS; 4,5,6,8,9,10 ARE POINTS; 7,11 ARE NATURAL WINNERS." -winnings = 0 - -# play the game -while stillplaying: - echo "" - echo "INPUT THE AMOUNT OF YOUR WAGER." - wager = readline(stdin).parseInt() - echo "I WILL NOW THROW THE DICE" - rollResult = (rand 1..6) + (rand 1..6) # roll dice, then add the sum - case rollResult: - of 7, 11: - echo rollResult, "- NATURAL....A WINNER!!!!" - echo rollResult, " PAYS EVEN MONEY, YOU WIN ", wager, " DOLLARS" - winnings += wager - of 2: - echo rollResult, "- SNAKE EYES....YOU LOSE." - echo "YOU LOSE ", wager, " DOLLARS." - winnings -= wager - of 3, 12: - echo rollResult, "- CRAPS...YOU LOSE." - echo "YOU LOSE ", wager, " DOLLARS." - winnings -= wager - else: - echo rollResult, " IS THE POINT. I WILL ROLL AGAIN" - takePoint(rollResult) - if winnings < 0: echo "YOU ARE NOW UNDER $", winnings - if winnings > 0: echo "YOU ARE NOW AHEAD $", winnings - if winnings == 0: echo "YOU ARE NOW EVEN AT 0" - stillplaying = tryAgain() - -# done playing -if winnings < 0: echo "TOO BAD, YOU ARE IN THE HOLE. COME AGAIN." -if winnings > 0: echo "CONGRATULATIONS---YOU CAME OUT A WINNER. COME AGAIN!" -if winnings == 0: echo "CONGRATULATIONS---YOU CAME OUT EVEN, NOT BAD FOR AN AMATEUR" diff --git a/00_Alternate_Languages/30_Cube/C/cube.c b/00_Alternate_Languages/30_Cube/C/cube.c deleted file mode 100644 index a42b3bca3..000000000 --- a/00_Alternate_Languages/30_Cube/C/cube.c +++ /dev/null @@ -1,142 +0,0 @@ -#include -#include -#include - -//check if windows or linux for the clear screen -#ifdef _WIN32 -#define CLEAR "cls" -#else -#define CLEAR "clear" -#endif - -typedef struct{ - int x; - int y; - int z; -}coords; - -void instuctions(){ - printf("\nThis is a game in which you will be playing against the\n"); - printf("random decisions of the computer. The field of play is a\n"); - printf("cube of side 3. Any of the 27 locations can be designated\n"); - printf("by inputing three numbers such as 2,3,1. At the start,\n"); - printf("you are automatically at location 1,1,1. The object of\n"); - printf("the game is to get to location 3,3,3. One minor detail:\n"); - printf("the computer will pick, at random, 5 locations at which\n"); - printf("it will plant land mines. If you hit one of these locations\n"); - printf("you lose. One other detail: You may move only one space\n"); - printf("in one direction each move. For example: From 1,1,2 you\n"); - printf("may move to 2,1,2 or 1,1,3. You may not change\n"); - printf("two of the numbers on the same move. If you make an illegal\n"); - printf("move, you lose and the computer takes the money you may\n"); - printf("have bet on that round.\n\n"); - printf("When stating the amount of a wager, printf only the number\n"); - printf("of dollars (example: 250) you are automatically started with\n"); - printf("500 dollars in your account.\n\n"); - printf("Good luck!\n"); -} - -void game(int money){ - coords player,playerold,mines[5]; - int wager,account = money; - char choice; - if(money == 0){ - printf("You have no money left. See ya next time.\n"); - exit(0); - } - player.x = 1; - player.y = 1; - player.z = 1; - - printf("You have $%d in your account.\n",account); - printf("How much do you want to wager? "); - scanf("%d",&wager); - while(wager > account){ - system(CLEAR); - printf("You do not have that much money in your account.\n"); - printf("How much do you want to wager? "); - scanf("%d",&wager); - } - srand(time(NULL)); - for(int i=0;i<5;i++){ - mines[i].x = rand()%3+1; - mines[i].y = rand()%3+1; - mines[i].z = rand()%3+1; - if(mines[i].x == 3 && mines[i].y == 3 && mines[i].z == 3){ - i--; - } - } - while(player.x != 3 || player.y != 3 || player.z != 3){ - printf("You are at location %d.%d.%d\n",player.x,player.y,player.z); - if(player.x == 1 && player.y == 1 && player.z == 1) - printf("Enter new location(use commas like 1,1,2 or else the program will break...): "); - else printf("Enter new location: "); - playerold.x = player.x; - playerold.y = player.y; - playerold.z = player.z; - scanf("%d,%d,%d",&player.x,&player.y,&player.z); - if(((player.x + player.y + player.z) > (playerold.x + playerold.y + playerold.z + 1)) || ((player.x + player.y + player.z) < (playerold.x + playerold.y + playerold.z -1))){ - system(CLEAR); - printf("Illegal move!\n"); - printf("You lose $%d.\n",wager); - game(account -= wager); - break; - } - if(player.x < 1 || player.x > 3 || player.y < 1 || player.y > 3 || player.z < 1 || player.z > 3){ - system(CLEAR); - printf("Illegal move. You lose!\n"); - game(account -= wager); - break; - } - for(int i=0;i<5;i++){ - if(player.x == mines[i].x && player.y == mines[i].y && player.z == mines[i].z){ - system(CLEAR); - printf("You hit a mine!\n"); - printf("You lose $%d.\n",wager); - game(account -= wager); - exit(0); - } - } - if(account == 0){ - system(CLEAR); - printf("You have no money left!\n"); - printf("Game over!\n"); - exit(0); - } - } - if(player.x == 3 && player.y == 3 && player.z == 3){ - system(CLEAR); - printf("You made it to the end. You win!\n"); - game(account += wager); - exit(0); - } -} - -void init(){ - int account = 500; - char choice; - - printf("Welcome to the game of Cube!\n"); - printf("wanna see the instructions? (y/n): "); - scanf("%c",&choice); - if(choice == 'y'){ - system(CLEAR); - instuctions(); - } - else if (choice == 'n'){ - system(CLEAR); - printf("Ok, let's play!\n"); - } - else{ - system(CLEAR); - printf("Invalid choice. Try again...\n"); - init(); - exit(0); - } - game(account); - exit(0); -} - -void main(){ - init(); -} \ No newline at end of file diff --git a/00_Alternate_Languages/30_Cube/MiniScript/README.md b/00_Alternate_Languages/30_Cube/MiniScript/README.md deleted file mode 100644 index 17eeb20b7..000000000 --- a/00_Alternate_Languages/30_Cube/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript cube.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "cube" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/30_Cube/MiniScript/cube.ms b/00_Alternate_Languages/30_Cube/MiniScript/cube.ms deleted file mode 100644 index 1639ce43f..000000000 --- a/00_Alternate_Languages/30_Cube/MiniScript/cube.ms +++ /dev/null @@ -1,100 +0,0 @@ -print " "*34 + "Bullseye" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print - -if input("Do you want to see the instructions? (yes--1,no--0) ").val then - print "This is a game in which you will be playing against the" - print "random decision of the computer. The field of play is a" - print "cube of size 3. Any of the locations can be designated" - print "by inputing three numbers such as 2,3,1. At the start," - print "you are automatically at location 1,1,1. The object of" - print "the game is to get to location 3,3,3. One minor detail:" - print "the computer will pick, at random, locations at which" - print "it will plant land mines. If you hit one of these locations" - print "you lose. One other detail: you may move only one space " - print "in one direction each move. For example: from 1,1,2 you" - print "may move to 2,1,2 or 1,1,3. You may not change" - print "two of the numbers on the same move. If you make an illegal" - print "move, you lose and the computer takes the money you may" - print "have bet on that round." - print - print - print "All yes or no questions will be answered by a 1 for yes" - print "or a 0 (zero) for no." - print - print "When stating the amount of a wager, print only the number" - print "of dollars (example: 250). You are automatically started with" - print "500 dollars in your account." - print - print "Good luck!" -end if - -money = 500 - -while money >= 0 - mineLocs = [] - // Note: unlike the original BASIC program, which doesn't actually pick random - // numbers unless you manually set X to a positive value before running the - // program, we do pick five random mine locations here. - // But like that program, we make no attempt to avoid 1,1,1 or 3,3,3, or to - // ensure that we have picked five DIFFERENT locations. - for i in range(1,5) - mineLocs.push [floor(3 * rnd + 1), floor(3 * rnd + 1), floor(3 * rnd + 1)] - end for - wager = 0 - if input("Want to make a wager? ").val then - wager = input("How much? ").val - while money < wager - wager = input("Tried to fool me; bet again? ").val - end while - end if - position = [1,1,1] - print - inp = input("It's your move: ") - won = 0 - while true - inp = inp.replace(",", " ").replace(" ", " ").split - newPos = [] - if inp.len == 3 then newPos = [inp[0].val, inp[1].val, inp[2].val] - legal = newPos.len == 3 - totalChange = 0 - for i in newPos.indexes - // The original game allowed you to walk outside the 1-3 range, - // thus safely avoiding all the mines. To disallow this exploit, - // uncomment the following line. - //if newPos[i] < 1 or newPos[i] > 3 then legal = false - totalChange += abs(newPos[i] - position[i]) - end for - if totalChange > 1 then legal = false - if not legal then - print; print "Illegal move. You lose." - won = -wager - break - end if - if newPos == [3,3,3] then - print "Congratulations!" - won = wager - break - else if mineLocs.indexOf(newPos) != null then - print "******BANG******" - print "You lose!" - print - print - won = -wager - break - end if - position = newPos - inp = input("Next move: ") - end while - if won != 0 then - globals.money += won - if money <= 0 then print "You bust." - end if - if wager then - print " You now have " + money + " dollars." - end if - if not input("Do you want to try again? ").val then break -end while -print "Tough luck!" -print -print "Goodbye." diff --git a/00_Alternate_Languages/30_Cube/README.md b/00_Alternate_Languages/30_Cube/README.md deleted file mode 100644 index d9f03b9d9..000000000 --- a/00_Alternate_Languages/30_Cube/README.md +++ /dev/null @@ -1,3 +0,0 @@ -#### 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 diff --git a/00_Alternate_Languages/30_Cube/cube.bas b/00_Alternate_Languages/30_Cube/cube.bas deleted file mode 100644 index b20198396..000000000 --- a/00_Alternate_Languages/30_Cube/cube.bas +++ /dev/null @@ -1,161 +0,0 @@ -10 PRINT TAB(34);"CUBE" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT : PRINT : PRINT -100 PRINT "DO YOU WANT TO SEE THE INSTRUCTIONS? (YES--1,NO--0)" -110 INPUT B7 -120 IF B7=0 THEN 370 -130 PRINT"THIS IS A GAME IN WHICH YOU WILL BE PLAYING AGAINST THE" -140 PRINT"RANDOM DECISION OF THE COMPUTER. THE FIELD OF PLAY IS A" -150 PRINT"CUBE OF SIDE 3. ANY OF THE 27 LOCATIONS CAN BE DESIGNATED" -160 PRINT"BY INPUTING THREE NUMBERS SUCH AS 2,3,1. AT THE START," -170 PRINT"YOU ARE AUTOMATICALLY AT LOCATION 1,1,1. THE OBJECT OF" -180 PRINT"THE GAME IS TO GET TO LOCATION 3,3,3. ONE MINOR DETAIL:" -190 PRINT"THE COMPUTER WILL PICK, AT RANDOM, 5 LOCATIONS AT WHICH" -200 PRINT"IT WILL PLANT LAND MINES. IF YOU HIT ONE OF THESE LOCATIONS" -210 PRINT"YOU LOSE. ONE OTHER DETAIL: YOU MAY MOVE ONLY ONE SPACE " -220 PRINT"IN ONE DIRECTION EACH MOVE. FOR EXAMPLE: FROM 1,1,2 YOU" -230 PRINT"MAY MOVE TO 2,1,2 OR 1,1,3. YOU MAY NOT CHANGE" -240 PRINT"TWO OF THE NUMBERS ON THE SAME MOVE. IF YOU MAKE AN ILLEGAL" -250 PRINT"MOVE, YOU LOSE AND THE COMPUTER TAKES THE MONEY YOU MAY" -260 PRINT"HAVE BET ON THAT ROUND." -270 PRINT -280 PRINT -290 PRINT"ALL YES OR NO QUESTIONS WILL BE ANSWERED BY A 1 FOR YES" -300 PRINT"OR A 0 (ZERO) FOR NO." -310 PRINT -320 PRINT"WHEN STATING THE AMOUNT OF A WAGER, PRINT ONLY THE NUMBER" -330 PRINT"OF DOLLARS (EXAMPLE: 250) YOU ARE AUTOMATICALLY STARTED WITH" -340 PRINT"500 DOLLARS IN YOUR ACCOUNT." -350 PRINT -360 PRINT "GOOD LUCK!" -370 LET A1=500 -380 LET A=INT(3*(RND(X))) -390 IF A<>0 THEN 410 -400 LET A=3 -410 LET B=INT(3*(RND(X))) -420 IF B<>0 THEN 440 -430 LET B=2 -440 LET C=INT(3*(RND(X))) -450 IF C<>0 THEN 470 -460 LET C=3 -470 LET D=INT(3*(RND(X))) -480 IF D<>0 THEN 500 -490 LET D=1 -500 LET E=INT(3*(RND(X))) -510 IF E<>0 THEN 530 -520 LET E=3 -530 LET F=INT(3*(RND(X))) -540 IF F<>0 THEN 560 -550 LET F=3 -560 LET G=INT(3*(RND(X))) -570 IF G<>0 THEN 590 -580 LET G=3 -590 LET H=INT(3*(RND(X))) -600 IF H<>0 THEN 620 -610 LET H=3 -620 LET I=INT(3*(RND(X))) -630 IF I<>0 THEN 650 -640 LET I=2 -650 LET J=INT(3*(RND(X))) -660 IF J<>0 THEN 680 -670 LET J=3 -680 LET K=INT(3*(RND(X))) -690 IF K<>0 THEN 710 -700 LET K=2 -710 LET L=INT(3*(RND(X))) -720 IF L<>0 THEN 740 -730 LET L=3 -740 LET M=INT(3*(RND(X))) -750 IF M<>0 THEN 770 -760 LET M=3 -770 LET N=INT(3*(RND(X))) -780 IF N<>0 THEN 800 -790 LET N=1 -800 LET O=INT (3*(RND(X))) -810 IF O <>0 THEN 830 -820 LET O=3 -830 PRINT "WANT TO MAKE A WAGER?" -840 INPUT Z -850 IF Z=0 THEN 880 -860 PRINT "HOW MUCH "; -870 INPUT Z1 -876 IF A1W+1 THEN 1030 -950 IF P=W+1 THEN 1000 -960 IF Q>X+1 THEN 1030 -970 IF Q=(X+1) THEN 1010 -980 IF R >(Y+1) THEN 1030 -990 GOTO 1050 -1000 IF Q>= X+1 THEN 1030 -1010 IF R>=Y+1 THEN 1030 -1020 GOTO 1050 -1030 PRINT:PRINT "ILLEGAL MOVE. YOU LOSE." -1040 GOTO 1440 -1050 LET W=P -1060 LET X=Q -1070 LET Y=R -1080 IF P=3 THEN 1100 -1090 GOTO 1130 -1100 IF Q=3 THEN 1120 -1110 GOTO 1130 -1120 IF R=3 THEN 1530 -1130 IF P=A THEN 1150 -1140 GOTO 1180 -1150 IF Q=B THEN 1170 -1160 GOTO 1180 -1170 IF R=C THEN 1400 -1180 IF P=D THEN 1200 -1190 GOTO 1230 -1200 IF Q=E THEN 1220 -1210 GOTO 1230 -1220 IF R=F THEN 1400 -1230 IF P=G THEN 1250 -1240 GOTO 1280 -1250 IF Q=H THEN 1270 -1260 GOTO 1280 -1270 IF R=I THEN 1400 -1280 IF P=J THEN 1300 -1290 GOTO 1330 -1300 IF Q=K THEN 1320 -1310 GOTO 1330 -1320 IF R=L THEN 1400 -1330 IF P=M THEN 1350 -1340 GOTO 1380 -1350 IF Q=N THEN 1370 -1360 GOTO 1380 -1370 IF R=O THEN 1400 -1380 PRINT "NEXT MOVE: "; -1390 GOTO 930 -1400 PRINT"******BANG******" -1410 PRINT "YOU LOSE!" -1420 PRINT -1430 PRINT -1440 IF Z=0 THEN 1580 -1450 PRINT -1460 LET Z2=A1-Z1 -1470 IF Z2>0 THEN 1500 -1480 PRINT "YOU BUST." -1490 GOTO 1610 -1500 PRINT " YOU NOW HAVE"; Z2; "DOLLARS." -1510 LET A1=Z2 -1520 GOTO 1580 -1522 PRINT"TRIED TO FOOL ME; BET AGAIN"; -1525 GOTO 870 -1530 PRINT"CONGRATULATIONS!" -1540 IF Z=0 THEN 1580 -1550 LET Z2=A1+Z1 -1560 PRINT "YOU NOW HAVE"; Z2;"DOLLARS." -1570 LET A1=Z2 -1580 PRINT"DO YOU WANT TO TRY AGAIN "; -1590 INPUT S -1600 IF S=1 THEN 380 -1610 PRINT "TOUGH LUCK!" -1620 PRINT -1630 PRINT "GOODBYE." -1640 END diff --git a/00_Alternate_Languages/31_Depth_Charge/MiniScript/README.md b/00_Alternate_Languages/31_Depth_Charge/MiniScript/README.md deleted file mode 100644 index 0c20ea36f..000000000 --- a/00_Alternate_Languages/31_Depth_Charge/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript depthcharge.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "depthcharge.ms" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/31_Depth_Charge/MiniScript/depthcharge.ms b/00_Alternate_Languages/31_Depth_Charge/MiniScript/depthcharge.ms deleted file mode 100644 index 3607cb805..000000000 --- a/00_Alternate_Languages/31_Depth_Charge/MiniScript/depthcharge.ms +++ /dev/null @@ -1,116 +0,0 @@ -// Depth Charge -// Originally by Dana Noftle (1978) -// Translated from BASIC to MiniScript by Ryushinaka and Joe Strout (2023) - -askYesNo = function(prompt) - while true - answer = input(prompt).lower[:1] - if answer == "y" or answer == "n" then return answer - end while -end function - -showWelcome = function - print - print " "*34 + "Depth Charge" - print " "*15 + "Creative Computing Morristown, New Jersey" - print -end function - -setup = function - while true - globals.size = input("Dimension of search area? ").val - if size > 0 then break - end while - - globals.numCharges = ceil(log(size,2)) - if numCharges == 0 then globals.numCharges = 1 // ensure we have at least 1 shot - - print "You are the captain of the destroyer USS Computer." - print "An enemy sub has been causing you trouble. Your" - print "mission is to destroy it. You have " + numCharges + " shots." - print "Specify depth charge explosion point with a" - print "trio of numbers -- the first two are the" - print "surface coordinates; the third is the depth." -end function - -showShotResult = function(shot,location) - result = "Sonar reports shot was " - if shot[1] > location[1] then - result = result + "north" - else if shot[1] < location[1] then - result = result + "south" - end if - - if shot[0] > location[0] then - result = result + "east" - else if shot[0] < location[0] then - result = result + "west" - end if - - if shot[1] != location[1] or shot[0] != location[0] then - result = result + " and " - end if - - if shot[2] > location[2] then - result = result + "too low." - else if shot[2] < location[2] then - result = result + "too high." - else - result = result + "depth OK." - end if - - print result -end function - -getShot = function - shotPos = [0,0,0] - while true - rawGuess = input("Enter coordinates: ").split(" ") - if rawGuess.len == 3 then - shotPos[0] = rawGuess[0].val - shotPos[1] = rawGuess[1].val - shotPos[2] = rawGuess[2].val - return shotPos - else - print "Please enter coordinates separated by spaces" - print "Example: 3 2 1" - end if - end while -end function - - -playGame = function - print "Good luck!" - print - - subPos = [floor(rnd*size), floor(rnd*size), floor(rnd*size)] - - // For debugging, you can give away the answer: - //print "(Sub is hidden at: " + subPos.join(" ") + ")" - - for c in range(1, numCharges) - print "Trial " + c - - shot = getShot - - if shot[0] == subPos[0] and shot[1] == subPos[1] and shot[2] == subPos[2] then - print "B O O M ! ! You found it in " + c + " tries!" - return - else - showShotResult(shot,subPos) - end if - end for - - print "You have been torpedoed! Abandon ship!" - print "The submarine was at " + subPos.join(" ") + "." -end function - -showWelcome -setup -while true - playGame - if askYesNo("Another game (Y or N): ") == "n" then - print "OK. Hope you enjoyed yourself." - break - end if -end while diff --git a/00_Alternate_Languages/31_Depth_Charge/README.md b/00_Alternate_Languages/31_Depth_Charge/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/31_Depth_Charge/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/31_Depth_Charge/depthcharge.bas b/00_Alternate_Languages/31_Depth_Charge/depthcharge.bas deleted file mode 100644 index 0b58467d8..000000000 --- a/00_Alternate_Languages/31_Depth_Charge/depthcharge.bas +++ /dev/null @@ -1,33 +0,0 @@ -2 PRINT TAB(30);"DEPTH CHARGE" -4 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -6 PRINT: PRINT: PRINT -20 INPUT "DIMENSION OF SEARCH AREA";G: PRINT -30 N=INT(LOG(G)/LOG(2))+1 -40 PRINT "YOU ARE THE CAPTAIN OF THE DESTROYER USS COMPUTER" -50 PRINT "AN ENEMY SUB HAS BEEN CAUSING YOU TROUBLE. YOUR" -60 PRINT "MISSION IS TO DESTROY IT. YOU HAVE";N;"SHOTS." -70 PRINT "SPECIFY DEPTH CHARGE EXPLOSION POINT WITH A" -80 PRINT "TRIO OF NUMBERS -- THE FIRST TWO ARE THE" -90 PRINT "SURFACE COORDINATES; THE THIRD IS THE DEPTH." -100 PRINT : PRINT "GOOD LUCK !": PRINT -110 A=INT(G*RND(1)) : B=INT(G*RND(1)) : C=INT(G*RND(1)) -120 FOR D=1 TO N : PRINT : PRINT "TRIAL #";D; : INPUT X,Y,Z -130 IF ABS(X-A)+ABS(Y-B)+ABS(Z-C)=0 THEN 300 -140 GOSUB 500 : PRINT : NEXT D -200 PRINT : PRINT "YOU HAVE BEEN TORPEDOED! ABANDON SHIP!" -210 PRINT "THE SUBMARINE WAS AT";A;",";B;",";C : GOTO 400 -300 PRINT : PRINT "B O O M ! ! YOU FOUND IT IN";D;"TRIES!" -400 PRINT : PRINT: INPUT "ANOTHER GAME (Y OR N)";A$ -410 IF A$="Y" THEN 100 -420 PRINT "OK. HOPE YOU ENJOYED YOURSELF." : GOTO 600 -500 PRINT "SONAR REPORTS SHOT WAS "; -510 IF Y>B THEN PRINT "NORTH"; -520 IF YA THEN PRINT "EAST"; -540 IF XB OR X<>A THEN PRINT " AND"; -560 IF Z>C THEN PRINT " TOO LOW." -570 IF Z location[1] { // y-direction - result += "north" - } else if shot[1] < location[1] { // y-direction - result += "south" - } - - if shot[0] > location[0] { // x-direction - result += "east" - } else if shot[0] < location[0] { // x-direction - result += "west" - } - - if shot[1] != location[1] || shot[0] != location[0] { - result += " and " - } - if shot[2] > location[2] { - result += "too low." - } else if shot[2] < location[2] { - result += "too high." - } else { - result += "depth OK." - } - - fmt.Println(result) -} - -func getShot() Position { - scanner := bufio.NewScanner(os.Stdin) - - for { - shotPos := NewPosition() - fmt.Println("Enter coordinates: ") - scanner.Scan() - rawGuess := strings.Split(scanner.Text(), " ") - if len(rawGuess) != 3 { - goto there - } - for i := 0; i < 3; i++ { - val, err := strconv.Atoi(rawGuess[i]) - if err != nil { - goto there - } - shotPos[i] = val - } - return shotPos - there: - fmt.Println("Please enter coordinates separated by spaces") - fmt.Println("Example: 3 2 1") - } -} - -func getRandomPosition(searchArea int) Position { - pos := NewPosition() - for i := 0; i < 3; i++ { - pos[i] = rand.Intn(searchArea) - } - return pos -} - -func playGame(searchArea, numCharges int) { - rand.Seed(time.Now().UTC().UnixNano()) - fmt.Println("\nYou are the captain of the destroyer USS Computer.") - fmt.Println("An enemy sub has been causing you trouble. Your") - fmt.Printf("mission is to destroy it. You have %d shots.\n", numCharges) - fmt.Println("Specify depth charge explosion point with a") - fmt.Println("trio of numbers -- the first two are the") - fmt.Println("surface coordinates; the third is the depth.") - fmt.Println("\nGood luck!") - fmt.Println() - - subPos := getRandomPosition(searchArea) - - for c := 0; c < numCharges; c++ { - fmt.Printf("\nTrial #%d\n", c+1) - - shot := getShot() - - if shot[0] == subPos[0] && shot[1] == subPos[1] && shot[2] == subPos[2] { - fmt.Printf("\nB O O M ! ! You found it in %d tries!\n", c+1) - askForNewGame() - } else { - showShotResult(shot, subPos) - } - } - - // out of depth charges - fmt.Println("\nYou have been torpedoed! Abandon ship!") - fmt.Printf("The submarine was at %d %d %d\n", subPos[0], subPos[1], subPos[2]) - askForNewGame() - -} - -func main() { - showWelcome() - - searchArea, numCharges := getNumCharges() - - playGame(searchArea, numCharges) -} diff --git a/00_Alternate_Languages/32_Diamond/MiniScript/README.md b/00_Alternate_Languages/32_Diamond/MiniScript/README.md deleted file mode 100644 index 3a8249a0d..000000000 --- a/00_Alternate_Languages/32_Diamond/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript diamond.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "diamond" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/32_Diamond/MiniScript/diamond.ms b/00_Alternate_Languages/32_Diamond/MiniScript/diamond.ms deleted file mode 100644 index 8166b570a..000000000 --- a/00_Alternate_Languages/32_Diamond/MiniScript/diamond.ms +++ /dev/null @@ -1,23 +0,0 @@ -// Diamond -// -// Ported from BASIC to MiniScript by Joe Strout - -print " "*33 + "DIAMOND" -print " "*15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -print; print; print -print "For a pretty diamond pattern," -maxw = input("type in an odd number between 5 and 21: ").val -s = "CC" + "!" * maxw -columns = floor(68/maxw) -for row in range(1, columns) - for w in range(1, maxw, 2) + range(maxw-2, 1, -2) - print " "*(maxw-w)/2, "" - for column in range(1, columns) - print s[:w], "" - if column < columns then print " "*(maxw-w), "" - end for - print - wait 0.01 - end for -end for - diff --git a/00_Alternate_Languages/32_Diamond/README.md b/00_Alternate_Languages/32_Diamond/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/32_Diamond/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/32_Diamond/diamond.bas b/00_Alternate_Languages/32_Diamond/diamond.bas deleted file mode 100644 index 5c9405802..000000000 --- a/00_Alternate_Languages/32_Diamond/diamond.bas +++ /dev/null @@ -1,27 +0,0 @@ -1 PRINT TAB(33);"DIAMOND" -2 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -3 PRINT:PRINT:PRINT -4 PRINT "FOR A PRETTY DIAMOND PATTERN," -5 INPUT "TYPE IN AN ODD NUMBER BETWEEN 5 AND 21";R:PRINT -6 Q=INT(60/R):A$="CC" -8 FOR L=1 TO Q -10 X=1:Y=R:Z=2 -20 FOR N=X TO Y STEP Z -25 PRINT TAB((R-N)/2); -28 FOR M=1 TO Q -29 C=1 -30 FOR A=1 TO N -32 IF C>LEN(A$) THEN PRINT "!";:GOTO 50 -34 PRINT MID$(A$,C,1); -36 C=C+1 -50 NEXT A -53 IF M=Q THEN 60 -55 PRINT TAB(R*M+(R-N)/2); -56 NEXT M -60 PRINT -70 NEXT N -83 IF X<>1 THEN 95 -85 X=R-2:Y=1:Z=-2 -90 GOTO 20 -95 NEXT L -99 END diff --git a/00_Alternate_Languages/33_Dice/C/dice.c b/00_Alternate_Languages/33_Dice/C/dice.c deleted file mode 100644 index 1ab77fcac..000000000 --- a/00_Alternate_Languages/33_Dice/C/dice.c +++ /dev/null @@ -1,26 +0,0 @@ -#include -#include -#include - -float percent(int number, int total){ - float percent; - percent = (float)number / (float)total * 100; - return percent; -} - -int main(){ - int dice1,dice2,times,rolls[13] = {0}; - srand(time(NULL)); - printf("This program simulates the rolling of a pair of dice\n"); - printf("How many times do you want to roll the dice?(Higher the number longer the waiting time): "); - scanf("%d",×); - for(int i = 0; i < times; i++){ - dice1 = rand() % 6 + 1; - dice2 = rand() % 6 + 1; - rolls[dice1 + dice2]+=1; - } - printf("The number of times each sum was rolled is:\n"); - for(int i = 2; i <= 12; i++){ - printf("%d: rolled %d times, or %f%c of the times\n",i,rolls[i],percent(rolls[i],times),(char)37); - } -} \ No newline at end of file diff --git a/00_Alternate_Languages/33_Dice/Julia/Dice.jl b/00_Alternate_Languages/33_Dice/Julia/Dice.jl deleted file mode 100644 index 8cc982923..000000000 --- a/00_Alternate_Languages/33_Dice/Julia/Dice.jl +++ /dev/null @@ -1,75 +0,0 @@ -#= -Port of Dice from BASIC Computer Games (1978) - -This "game" simulates a given number of dice rolls, and returns the -count for each possible total. - -The only change that has been made from the original program, is that -when asking if the user wants to play again, any string starting with -y or Y will be accepted, instead of only YES. -=# - -function main() - # Array to store the counts for each total. - # There are 11 possible totals. - counts = [0 for i in 1:11] - - # Print intro text - println("\n Dice") - println("Creative Computing Morristown, New Jersey") - println("\n\n") - println("This program simulates the rolling of a") - println("pair of dice.") - println("You enter the number of times you want the computer to") - println("'roll' the dice. Watch out, very large numbers take") - println("a long time. In particular, numbers over 5000.") - - still_playing = true - while still_playing - println() - print("How many rolls? ") - - # Get user input for number of dice rolls - rolls = readline() - rolls = parse(Int64, rolls) - - # Roll dice the specified number of times and update total count - for _ in 1:rolls - dice_roll = rand(1:6, 2) - dice_sum = sum(dice_roll) - - # The index is one less than the sum, as a sum of 1 is impossible, - # the array will only have 11 values - counts[dice_sum-1] += 1 - end - - # Display results - println("\nTotal Spots Number of Times") - for i in 1:8 - print(" ") - print(i+1) - print(" ") - println(counts[i]) - end - for i in 9:11 - print(" ") - print(i+1) - print(" ") - println(counts[i]) - end - - # Ask try again - print("\nTry Again? ") - input = readline() - if length(input) > 0 && uppercase(input)[1] == 'Y' - # If game is continued, resets total counts - counts = [0 for i in 1:11] - else - still_playing = false - end - end -end - -if abspath(PROGRAM_FILE) == @__FILE__ - main() -end \ No newline at end of file diff --git a/00_Alternate_Languages/33_Dice/Julia/README.md b/00_Alternate_Languages/33_Dice/Julia/README.md deleted file mode 100644 index fb77771d1..000000000 --- a/00_Alternate_Languages/33_Dice/Julia/README.md +++ /dev/null @@ -1,3 +0,0 @@ -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) - -Conversion to [Python](https://www.julialang.org/) \ No newline at end of file diff --git a/00_Alternate_Languages/33_Dice/MiniScript/README.md b/00_Alternate_Languages/33_Dice/MiniScript/README.md deleted file mode 100644 index b670e30da..000000000 --- a/00_Alternate_Languages/33_Dice/MiniScript/README.md +++ /dev/null @@ -1,21 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript dice.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "dice" - run -``` -3. "Try-It!" page on the web: -Go to https://miniscript.org/tryit/, clear the default program from the source code editor, paste in the contents of dice.ms, and click the "Run Script" button. diff --git a/00_Alternate_Languages/33_Dice/MiniScript/dice.ms b/00_Alternate_Languages/33_Dice/MiniScript/dice.ms deleted file mode 100644 index 38b41ef34..000000000 --- a/00_Alternate_Languages/33_Dice/MiniScript/dice.ms +++ /dev/null @@ -1,53 +0,0 @@ -// Dice -// -// Danny Freidus -// Ported from BASIC to MiniScript by Joe Strout - -print " "*34 + "DICE" -print " "*15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -print; print; print -print "This program simulates the rolling of a" -print "pair of dice." -print "You enter the number of times you want the computer to" -print "'roll' the dice. Watch out, very large numbers take" -print "a long time. In particular, numbers over 5000." - -// Function to do one run of the simulation. -runOnce = function - // Clear the array we'll use to hold the counts - counts = [0] * 13 - // Loop the desired number of times - x = input("How many rolls? ").val - for s in range(1, x) - // roll two dice and find the sum - die1 = ceil(6 * rnd) - die2 = ceil(6 * rnd) - sum = die1 + die2 - // update the count for that sum - counts[sum] += 1 - end for - print - - // print a table showing how many times each sum was rolled - print "Total Spots Number of Times" - for v in range(2, 12) - // (the [-6:] trick below right-aligns the number) - print (" " + v)[-6:] + " "*10 + counts[v] - end for - print; print -end function - -// Get a yes/no (or at least y/n) response from the user. -askYesNo = function(prompt) - while true - answer = input(prompt).lower[:1] - if answer == "y" or answer == "n" then return answer - end while -end function - -// main loop -while true - print - runOnce - if askYesNo("Try again? ") == "n" then break -end while diff --git a/00_Alternate_Languages/33_Dice/README.md b/00_Alternate_Languages/33_Dice/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/33_Dice/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/33_Dice/dice.bas b/00_Alternate_Languages/33_Dice/dice.bas deleted file mode 100644 index b74bf724e..000000000 --- a/00_Alternate_Languages/33_Dice/dice.bas +++ /dev/null @@ -1,31 +0,0 @@ -2 PRINT TAB(34);"DICE" -4 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -6 PRINT:PRINT:PRINT -10 DIM F(12) -20 REM DANNY FREIDUS -30 PRINT "THIS PROGRAM SIMULATES THE ROLLING OF A" -40 PRINT "PAIR OF DICE." -50 PRINT "YOU ENTER THE NUMBER OF TIMES YOU WANT THE COMPUTER TO" -60 PRINT "'ROLL' THE DICE. WATCH OUT, VERY LARGE NUMBERS TAKE" -70 PRINT "A LONG TIME. IN PARTICULAR, NUMBERS OVER 5000." -80 FOR Q=1 TO 12 -90 F(Q)=0 -100 NEXT Q -110 PRINT:PRINT "HOW MANY ROLLS"; -120 INPUT X -130 FOR S=1 TO X -140 A=INT(6*RND(1)+1) -150 B=INT(6*RND(1)+1) -160 R=A+B -170 F(R)=F(R)+1 -180 NEXT S -185 PRINT -190 PRINT "TOTAL SPOTS","NUMBER OF TIMES" -200 FOR V=2 TO 12 -210 PRINT V,F(V) -220 NEXT V -221 PRINT -222 PRINT:PRINT "TRY AGAIN"; -223 INPUT Z$ -224 IF Z$="YES" THEN 80 -240 END diff --git a/00_Alternate_Languages/33_Dice/go/main.go b/00_Alternate_Languages/33_Dice/go/main.go deleted file mode 100644 index 75bef387c..000000000 --- a/00_Alternate_Languages/33_Dice/go/main.go +++ /dev/null @@ -1,64 +0,0 @@ -package main - -import ( - "bufio" - "fmt" - "math/rand" - "os" - "strconv" - "strings" -) - -func printWelcome() { - fmt.Println("\n Dice") - fmt.Println("Creative Computing Morristown, New Jersey") - fmt.Println() - fmt.Println() - fmt.Println("This program simulates the rolling of a") - fmt.Println("pair of dice.") - fmt.Println("You enter the number of times you want the computer to") - fmt.Println("'roll' the dice. Watch out, very large numbers take") - fmt.Println("a long time. In particular, numbers over 5000.") - fmt.Println() -} - -func main() { - printWelcome() - scanner := bufio.NewScanner(os.Stdin) - - for { - fmt.Println("\nHow many rolls? ") - scanner.Scan() - numRolls, err := strconv.Atoi(scanner.Text()) - if err != nil { - fmt.Println("Invalid input, try again...") - continue - } - - // We'll track counts of roll outcomes in a 13-element list. - // The first two indices (0 & 1) are ignored, leaving just - // the indices that match the roll values (2 through 12). - results := make([]int, 13) - - for n := 0; n < numRolls; n++ { - d1 := rand.Intn(6) + 1 - d2 := rand.Intn(6) + 1 - results[d1+d2] += 1 - } - - // Display final results - fmt.Println("\nTotal Spots Number of Times") - for i := 2; i < 13; i++ { - fmt.Printf(" %-14d%d\n", i, results[i]) - } - - fmt.Println("\nTry again? ") - scanner.Scan() - if strings.ToUpper(scanner.Text()) == "Y" { - continue - } else { - os.Exit(1) - } - - } -} diff --git a/00_Alternate_Languages/33_Dice/nim/dice.nim b/00_Alternate_Languages/33_Dice/nim/dice.nim deleted file mode 100644 index 6564ae9ba..000000000 --- a/00_Alternate_Languages/33_Dice/nim/dice.nim +++ /dev/null @@ -1,37 +0,0 @@ -import std/[random,strutils] - -var - a,b,r,x: int - f: array[2..12, int] - z: string - retry: bool = true - -randomize() # Seed the random number generator - -echo spaces(34), "DICE" -echo spaces(15), "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -echo "\n" -echo "THIS PROGRAM SIMULATES THE ROLLING OF A PAIR OF DICE." -echo "YOU ENTER THE NUMBER OF TIMES YOU WANT THE COMPUTER TO" -echo "'ROLL' THE DICE. WATCH OUT, VERY LARGE NUMBERS TAKE" -echo "A LONG TIME. IN PARTICULAR, NUMBERS OVER 5000." - -while(retry): - echo "\n" - echo "HOW MANY ROLLS" - x = readLine(stdin).parseInt() - for v in 2..12: - f[v] = 0 # Initialize array to 0 - for s in 1..x: - a = rand(1..6) # Die 1 - b = rand(1..6) # Die 2 - r = a + b # Sum of dice - f[r] += 1 # Increment array count of dice sum result - echo "" - echo "TOTAL SPOTS: ", "NUMBER OF TIMES" - for v in 2..12: - echo v, ": ", f[v] # Print out counts for each possible result - echo "\n" - echo "TRY AGAIN?" - z = readLine(stdin).normalize() - retry = (z=="yes") or (z=="y") diff --git a/00_Alternate_Languages/34_Digits/MiniScript/README.md b/00_Alternate_Languages/34_Digits/MiniScript/README.md deleted file mode 100644 index 280be246e..000000000 --- a/00_Alternate_Languages/34_Digits/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript digits.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "digits" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/34_Digits/MiniScript/digits.ms b/00_Alternate_Languages/34_Digits/MiniScript/digits.ms deleted file mode 100644 index 2abde907d..000000000 --- a/00_Alternate_Languages/34_Digits/MiniScript/digits.ms +++ /dev/null @@ -1,99 +0,0 @@ -import "listUtil" - -print " "*33 + "Digits" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print - -printInColumns = function(a, b, c, d) - print (a+" "*16)[:16] + (b+" "*16)[:16] + (c+" "*16)[:16] + (d+" "*16)[:16] -end function - -print "This is a game of guessing." -print "For instructions, type '1', else type '0'" -if input != "0" then - print - print "Please take a piece of paper and write down" - print "the digits '0', '1', or '2' thirty times at random." - print "Arrange them in three lines of ten digits each." - print "I will ask for then ten at a time." - print "I will always guess them first and then look at your" - print "next number to see if i was right. By pure luck," - print "I ought to be right ten times. But i hope to do better" - print "than that *****" - print; print -end if - -a = 0; b = 1; c = 3 - -while true - m = list.init2d(27, 3, 1) - k = list.init2d(3, 3, 9) - l = list.init2d(9, 3, 3) - l[0][0] = 2; l[4][1] = 2; l[8][2] = 2 - z=26; z1=8; z2=2 - qtyRight = 0 - guess = 0 - for t in range(1,3) - while true - print - print "Ten numbers, please"; - n = input.replace(",", " ").replace(" ", "").split - if n.len != 10 then continue - valid = true - for i in n.indexes - n[i] = n[i].val - if n[i] < 0 or n[i] > 2 then - print "Only use the digits '0', '1', or '2'." - print "Let's try again." - valid = false - break - end if - end for - if valid then break - end while - - print; printInColumns "My guess","Your no.","Result","No. right"; print - for u in range(0, 9) - yourNum = n[u]; s=0 - for j in range(0,2) - s1 = a*k[z2][j] + b*l[z1][j] + c*m[z][j] - if s > s1 then continue - if s < s1 or rnd >= 0.5 then - s = s1; guess = j - end if - end for - if guess == yourNum then - outcome = " right" - qtyRight += 1 - else - outcome = " wrong" - end if - printInColumns " "+guess, " " + yourNum, outcome, qtyRight - - m[z][yourNum] += 1 - l[z1][yourNum] += 1 - k[z2][yourNum] += 1 - z -= floor(z/9)*9 - z = 3*z + yourNum - z1 = z - floor(z/9)*9 - z2 = yourNum - end for - end for - - print - if qtyRight > 10 then - print "I guessed more than 1/3 of your numbers." - print "I win." - print char(7) * 10 - else if qtyRight < 10 then - print "I guessed less than 1/3 of your numbers." - print "You beat me. Congratulations *****" - else - print "I guessed exactly 1/3 of your numbers." - print "It's a tie game." - end if - print "Do you want to try again (1 for yes, 0 for no)"; - if input != "1" then break -end while - -print; print "Thanks for the game." diff --git a/00_Alternate_Languages/34_Digits/README.md b/00_Alternate_Languages/34_Digits/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/34_Digits/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/34_Digits/digits.bas b/00_Alternate_Languages/34_Digits/digits.bas deleted file mode 100644 index 76fbbaffe..000000000 --- a/00_Alternate_Languages/34_Digits/digits.bas +++ /dev/null @@ -1,78 +0,0 @@ -10 PRINT TAB(33);"DIGITS" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT:PRINT:PRINT -210 PRINT "THIS IS A GAME OF GUESSING." -220 PRINT "FOR INSTRUCTIONS, TYPE '1', ELSE TYPE '0'"; -230 INPUT E -240 IF E=0 THEN 360 -250 PRINT -260 PRINT "PLEASE TAKE A PIECE OF PAPER AND WRITE DOWN" -270 PRINT "THE DIGITS '0', '1', OR '2' THIRTY TIMES AT RANDOM." -280 PRINT "ARRANGE THEM IN THREE LINES OF TEN DIGITS EACH." -290 PRINT "I WILL ASK FOR THEN TEN AT A TIME." -300 PRINT "I WILL ALWAYS GUESS THEM FIRST AND THEN LOOK AT YOUR" -310 PRINT "NEXT NUMBER TO SEE IF I WAS RIGHT. BY PURE LUCK," -320 PRINT "I OUGHT TO BE RIGHT TEN TIMES. BUT I HOPE TO DO BETTER" -330 PRINT "THAN THAT *****" -340 PRINT:PRINT -360 READ A,B,C -370 DATA 0,1,3 -380 DIM M(26,2),K(2,2),L(8,2) -400 FOR I=0 TO 26: FOR J=0 TO 2: M(I,J)=1: NEXT J: NEXT I -410 FOR I=0 TO 2: FOR J=0 TO 2: K(I,J)=9: NEXT J: NEXT I -420 FOR I=0 TO 8: FOR J=0 TO 2: L(I,J)=3: NEXT J: NEXT I -450 L(0,0)=2: L(4,1)=2: L(8,2)=2 -480 Z=26: Z1=8: Z2=2 -510 X=0 -520 FOR T=1 TO 3 -530 PRINT -540 PRINT "TEN NUMBERS, PLEASE"; -550 INPUT N(1),N(2),N(3),N(4),N(5),N(6),N(7),N(8),N(9),N(10) -560 FOR I=1 TO 10 -570 W=N(I)-1 -580 IF W=SGN(W) THEN 620 -590 PRINT "ONLY USE THE DIGITS '0', '1', OR '2'." -600 PRINT "LET'S TRY AGAIN.":GOTO 530 -620 NEXT I -630 PRINT: PRINT "MY GUESS","YOUR NO.","RESULT","NO. RIGHT":PRINT -660 FOR U=1 TO 10 -670 N=N(U): S=0 -690 FOR J=0 TO 2 -700 S1=A*K(Z2,J)+B*L(Z1,J)+C*M(Z,J) -710 IF S>S1 THEN 760 -720 IF S10 THEN 980 -940 IF X<10 THEN 1010 -950 PRINT "I GUESSED EXACTLY 1/3 OF YOUR NUMBERS." -960 PRINT "IT'S A TIE GAME." -970 GOTO 1030 -980 PRINT "I GUESSED MORE THAN 1/3 OF YOUR NUMBERS." -990 PRINT "I WIN.": FOR Q=1 TO 10: PRINT CHR$(7);: NEXT Q -1000 GOTO 1030 -1010 PRINT "I GUESSED LESS THAN 1/3 OF YOUR NUMBERS." -1020 PRINT "YOU BEAT ME. CONGRATULATIONS *****" -1030 PRINT -1040 PRINT "DO YOU WANT TO TRY AGAIN (1 FOR YES, 0 FOR NO)"; -1060 INPUT X -1070 IF X=1 THEN 400 -1080 PRINT:PRINT "THANKS FOR THE GAME." -1090 END diff --git a/00_Alternate_Languages/34_Digits/go/main.go b/00_Alternate_Languages/34_Digits/go/main.go deleted file mode 100644 index 64326d533..000000000 --- a/00_Alternate_Languages/34_Digits/go/main.go +++ /dev/null @@ -1,171 +0,0 @@ -package main - -import ( - "bufio" - "fmt" - "math/rand" - "os" - "strconv" - "time" -) - -func printIntro() { - fmt.Println(" DIGITS") - fmt.Println(" CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") - fmt.Println() - fmt.Println() - fmt.Println("THIS IS A GAME OF GUESSING.") -} - -func readInteger(prompt string) int { - scanner := bufio.NewScanner(os.Stdin) - for { - fmt.Println(prompt) - scanner.Scan() - response, err := strconv.Atoi(scanner.Text()) - - if err != nil { - fmt.Println("INVALID INPUT, TRY AGAIN... ") - continue - } - - return response - } -} - -func printInstructions() { - fmt.Println() - fmt.Println("PLEASE TAKE A PIECE OF PAPER AND WRITE DOWN") - fmt.Println("THE DIGITS '0', '1', OR '2' THIRTY TIMES AT RANDOM.") - fmt.Println("ARRANGE THEM IN THREE LINES OF TEN DIGITS EACH.") - fmt.Println("I WILL ASK FOR THEN TEN AT A TIME.") - fmt.Println("I WILL ALWAYS GUESS THEM FIRST AND THEN LOOK AT YOUR") - fmt.Println("NEXT NUMBER TO SEE IF I WAS RIGHT. BY PURE LUCK,") - fmt.Println("I OUGHT TO BE RIGHT TEN TIMES. BUT I HOPE TO DO BETTER") - fmt.Println("THAN THAT *****") - fmt.Println() -} - -func readTenNumbers() []int { - numbers := make([]int, 10) - - numbers[0] = readInteger("FIRST NUMBER: ") - for i := 1; i < 10; i++ { - numbers[i] = readInteger("NEXT NUMBER:") - } - - return numbers -} - -func printSummary(correct int) { - fmt.Println() - - if correct > 10 { - fmt.Println() - fmt.Println("I GUESSED MORE THAN 1/3 OF YOUR NUMBERS.") - fmt.Println("I WIN.\u0007") - } else if correct < 10 { - fmt.Println("I GUESSED LESS THAN 1/3 OF YOUR NUMBERS.") - fmt.Println("YOU BEAT ME. CONGRATULATIONS *****") - } else { - fmt.Println("I GUESSED EXACTLY 1/3 OF YOUR NUMBERS.") - fmt.Println("IT'S A TIE GAME.") - } -} - -func buildArray(val, row, col int) [][]int { - a := make([][]int, row) - for r := 0; r < row; r++ { - b := make([]int, col) - for c := 0; c < col; c++ { - b[c] = val - } - a[r] = b - } - return a -} - -func main() { - rand.Seed(time.Now().UnixNano()) - - printIntro() - if readInteger("FOR INSTRUCTIONS, TYPE '1', ELSE TYPE '0' ? ") == 1 { - printInstructions() - } - - a := 0 - b := 1 - c := 3 - - m := buildArray(1, 27, 3) - k := buildArray(9, 3, 3) - l := buildArray(3, 9, 3) - - for { - l[0][0] = 2 - l[4][1] = 2 - l[8][2] = 2 - - z := float64(26) - z1 := float64(8) - z2 := 2 - runningCorrect := 0 - - var numbers []int - for round := 1; round <= 4; round++ { - validNumbers := false - for !validNumbers { - numbers = readTenNumbers() - validNumbers = true - for _, n := range numbers { - if n < 0 || n > 2 { - fmt.Println("ONLY USE THE DIGITS '0', '1', OR '2'.") - fmt.Println("LET'S TRY AGAIN.") - validNumbers = false - break - } - } - } - - fmt.Printf("\n%-14s%-14s%-14s%-14s\n", "MY GUESS", "YOUR NO.", "RESULT", "NO. RIGHT") - - for _, n := range numbers { - s := 0 - myGuess := 0 - - for j := 0; j < 3; j++ { - s1 := a*k[z2][j] + b*l[int(z1)][j] + c*m[int(z)][j] - - if s < s1 { - s = s1 - myGuess = j - } else if s1 == s && rand.Float64() > 0.5 { - myGuess = j - } - } - result := "" - - if myGuess != n { - result = "WRONG" - } else { - runningCorrect += 1 - result = "RIGHT" - m[int(z)][n] = m[int(z)][n] + 1 - l[int(z1)][n] = l[int(z1)][n] + 1 - k[int(z2)][n] = k[int(z2)][n] + 1 - z = z - (z/9)*9 - z = 3.0*z + float64(n) - } - fmt.Printf("\n%-14d%-14d%-14s%-14d\n", myGuess, n, result, runningCorrect) - - z1 = z - (z/9)*9 - z2 = n - } - printSummary(runningCorrect) - if readInteger("\nDO YOU WANT TO TRY AGAIN (1 FOR YES, 0 FOR NO) ? ") != 1 { - fmt.Println("\nTHANKS FOR THE GAME.") - os.Exit(0) - } - } - } -} diff --git a/00_Alternate_Languages/35_Even_Wins/MiniScript/README.md b/00_Alternate_Languages/35_Even_Wins/MiniScript/README.md deleted file mode 100644 index d52819302..000000000 --- a/00_Alternate_Languages/35_Even_Wins/MiniScript/README.md +++ /dev/null @@ -1,33 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Note that this folder (like the original BASIC programs) contains TWO different programs based on the same idea. evenwins.ms plays deterministically; gameofevenwins.ms learns from its failures over multiple games. - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript evenwins.ms -``` -or - -``` - miniscript gameofevenwins.ms -``` - -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "evenwins" - run -``` -or - -``` - load "gameofevenwins" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/35_Even_Wins/MiniScript/evenwins.ms b/00_Alternate_Languages/35_Even_Wins/MiniScript/evenwins.ms deleted file mode 100644 index 0712b830f..000000000 --- a/00_Alternate_Languages/35_Even_Wins/MiniScript/evenwins.ms +++ /dev/null @@ -1,140 +0,0 @@ -print " "*31 + "Digits" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print - -y1 = 0 -m1 = 0 -print " This is a two person game called 'Even Wins.'" -print "To play the game, the players need 27 marbles or" -print "other objects on a table." -print -print -print " The 2 players alternate turns, with each player" -print "removing from 1 to 4 marbles on each move. The game" -print "ends when there are no marbles left, and the winner" -print "is the one with an even number of marbles." -print -print -print " The only rules are that (1) you must alternate turns," -print "(2) you must take between 1 and 4 marbles each turn," -print "and (3) you cannot skip a turn." -print -print -print -while true - print " Type a '1' if you want to go first, and type" - print "a '0' if you want me to go first." - c = input.val - print - if c != 0 then - t = 27 - print - print - print - print "Total=" + t - print - print - print "What is your first move?" - m = 0 - else - t = 27 - m = 2 - print - print "Total= " + t - print - m1 += m - t -= m - end if - while true - if m then - print "I pick up " + m + " marbles." - if t == 0 then break - print - print "Total=" + t - print - print " And what is your next move, my total is " + m1 - end if - while true - y = input.val - print - if y < 1 or y > 4 then - print - print "The number of marbles you must take be a positive" - print "integer between 1 and 4." - print - print " What is your next move?" - print - else if y > t then - print " You have tried to take more marbles than there are" - print "left. Try again." - else - break - end if - end while - - y1 += y - t -= y - if t == 0 then break - print "Total=" + t - print - print "Your total is " + y1 - if t < 0.5 then break - r = t % 6 - if y1 % 2 != 0 then - if t >= 4.2 then - if r <= 3.4 then - m = r + 1 - m1 += m - t -= m - else if r < 4.7 or r > 3.5 then - m = 4 - m1 += m - t -= m - else - m = 1 - m1 += m - t -= m - end if - else - m = t - t -= m - print "I pick up " + m + " marbles." - print - print "Total = 0" - m1 += m - break - end if - else - if r < 1.5 or r > 5.3 then - m = 1 - m1 += m - t -= m - else - m = r - 1 - m1 += m - t -= m - if t < 0.2 then - print "I pick up " + m + " marbles." - print - break - end if - end if - end if - end while - print "That is all of the marbles." - print - print " My total is " + m1 + ", your total is " + y1 - print - if m1 % 2 then - print " You won. Do you want to play" - else - print " I won. Do you want to play" - end if - print "again? Type 1 for yes and 0 for no." - a1 = input.val - if a1 == 0 then break - m1 = 0 - y1 = 0 -end while -print -print "OK. See you later" diff --git a/00_Alternate_Languages/35_Even_Wins/MiniScript/gameofevenwins.ms b/00_Alternate_Languages/35_Even_Wins/MiniScript/gameofevenwins.ms deleted file mode 100644 index e533550d1..000000000 --- a/00_Alternate_Languages/35_Even_Wins/MiniScript/gameofevenwins.ms +++ /dev/null @@ -1,90 +0,0 @@ -print " "*28 + "Game Of Even Wins" -print " "*15 + "Creative Computing Morristown, New Jersey" -print -print -yesNo = input("Do you want instructions (yes or no)? ").lower -if not yesNo or yesNo[0] != "n" then - print "The game is played as follows:" - print - print "At the beginning of the game, a random number of chips are" - print "placed on the board. The number of chips always starts" - print "as an odd number. On each turn, a player must take one," - print "two, three, or four chips. The winner is the player who" - print "finishes with a total number of chips that is even." - print "The computer starts out knowing only the rules of the" - print "game. It gradually learns to play well. It should be" - print "difficult to beat the computer after twenty games in a row." - print "Try it!!!!" - print - print "To quit at any time, type a '0' as your move." - print -end if - -l = 0 -b = 0 -r = [[4]*6, [4]*6] - -while true - a = 0 - b = 0 - e = 0 - l = 0 - p = floor((13 * rnd + 9) / 2) * 2 + 1; - while true - if p == 1 then - print "There is 1 chip on the board." - else - print "There are " + p + " chips on the board." - end if - e1 = e - l1 = l - e = a % 2 - l = p % 6 - if r[e][l] < p then - m = r[e][l] - if m <= 0 then - m = 1 - b = 1 - break - end if - p -= m - if m == 1 then - prompt = "Computer takes 1 chip leaving " + p + "... Your move? " - else - prompt = "Computer takes " + m + " chips leaving " + p + "... Your move? " - end if - b += m - while true - m = input(prompt).val - if m == 0 then break - if 1 <= m <= p and m <= 4 then break - prompt = m + " is an illegal move ... Your move? " - end while - if m == 0 then break - if m == p then break // <-- Really? Before we've done the math? - p -= m - a += m - else - if p == 1 then - print "Computer takes 1 chip." - else - print "Computer takes " + p + " chips." - end if - r[e][l] = p - b += p - break - end if - end while - if m == 0 then break - if b % 2 != 0 then - print "Game over ... you win!!!" - if r[e][l] != 1 then - r[e][l] -= 1 - else if (r[e1][l1] != 1) then - r[e1][l1] -= 1 - end if - else - print "Game over ... I win!!!" - end if - print -end while diff --git a/00_Alternate_Languages/35_Even_Wins/README.md b/00_Alternate_Languages/35_Even_Wins/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/35_Even_Wins/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/35_Even_Wins/evenwins.bas b/00_Alternate_Languages/35_Even_Wins/evenwins.bas deleted file mode 100644 index 4e663c681..000000000 --- a/00_Alternate_Languages/35_Even_Wins/evenwins.bas +++ /dev/null @@ -1,128 +0,0 @@ -1 PRINT TAB(31);"EVEN WINS" -2 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -3 PRINT:PRINT -4 Y1=0 -10 M1=0 -20 DIM M(20),Y(20) -30 PRINT " THIS IS A TWO PERSON GAME CALLED 'EVEN WINS.'" -40 PRINT "TO PLAY THE GAME, THE PLAYERS NEED 27 MARBLES OR" -50 PRINT "OTHER OBJECTS ON A TABLE." -60 PRINT -70 PRINT -80 PRINT " THE 2 PLAYERS ALTERNATE TURNS, WITH EACH PLAYER" -90 PRINT "REMOVING FROM 1 TO 4 MARBLES ON EACH MOVE. THE GAME" -100 PRINT "ENDS WHEN THERE ARE NO MARBLES LEFT, AND THE WINNER" -110 PRINT "IS THE ONE WITH AN EVEN NUMBER OF MARBLES." -120 PRINT -130 PRINT -140 PRINT " THE ONLY RULES ARE THAT (1) YOU MUST ALTERNATE TURNS," -150 PRINT "(2) YOU MUST TAKE BETWEEN 1 AND 4 MARBLES EACH TURN," -160 PRINT "AND (3) YOU CANNOT SKIP A TURN." -170 PRINT -180 PRINT -190 PRINT -200 PRINT " TYPE A '1' IF YOU WANT TO GO FIRST, AND TYPE" -210 PRINT "A '0' IF YOU WANT ME TO GO FIRST." -220 INPUT C -225 PRINT -230 IF C=0 THEN 250 -240 GOTO 1060 -250 T=27 -260 M=2 -270 PRINT:PRINT "TOTAL=";T:PRINT -280 M1=M1+M -290 T=T-M -300 PRINT "I PICK UP";M;"MARBLES." -310 IF T=0 THEN 880 -320 PRINT:PRINT "TOTAL=";T -330 PRINT -340 PRINT " AND WHAT IS YOUR NEXT MOVE, MY TOTAL IS";M1 -350 INPUT Y -360 PRINT -370 IF Y<1 THEN 1160 -380 IF Y>4 THEN 1160 -390 IF Y<=T THEN 430 -400 PRINT " YOU HAVE TRIED TO TAKE MORE MARBLES THAN THERE ARE" -410 PRINT "LEFT. TRY AGAIN." -420 GOTO 350 -430 Y1=Y1+Y -440 T=T-Y -450 IF T=0 THEN 880 -460 PRINT "TOTAL=";T -470 PRINT -480 PRINT "YOUR TOTAL IS";Y1 -490 IF T<.5 THEN 880 -500 R=T-6*INT(T/6) -510 IF INT(Y1/2)=Y1/2 THEN 700 -520 IF T<4.2 THEN 580 -530 IF R>3.4 THEN 620 -540 M=R+1 -550 M1=M1+M -560 T=T-M -570 GOTO 300 -580 M=T -590 T=T-M -600 GOTO 830 -610 REM 250 IS WHERE I WIN. -620 IF R<4.7 THEN 660 -630 IF R>3.5 THEN 660 -640 M=1 -650 GOTO 670 -660 M=4 -670 T=T-M -680 M1=M1+M -690 GOTO 300 -700 REM I AM READY TO ENCODE THE STRAT FOR WHEN OPP TOT IS EVEN -710 IF R<1.5 THEN 1020 -720 IF R>5.3 THEN 1020 -730 M=R-1 -740 M1=M1+M -750 T=T-M -760 IF T<.2 THEN 790 -770 REM IS # ZERO HERE -780 GOTO 300 -790 REM IS = ZERO HERE -800 PRINT "I PICK UP";M;"MARBLES." -810 PRINT -820 GOTO 880 -830 REM THIS IS WHERE I WIN -840 PRINT "I PICK UP";M;"MARBLES." -850 PRINT -860 PRINT "TOTAL = 0" -870 M1=M1+M -880 PRINT "THAT IS ALL OF THE MARBLES." -890 PRINT -900 PRINT " MY TOTAL IS";M1;", YOUR TOTAL IS";Y1 -910 PRINT -920 IF INT(M1/2)=M1/2 THEN 950 -930 PRINT " YOU WON. DO YOU WANT TO PLAY" -940 GOTO 960 -950 PRINT " I WON. DO YOU WANT TO PLAY" -960 PRINT "AGAIN? TYPE 1 FOR YES AND 0 FOR NO." -970 INPUT A1 -980 IF A1=0 THEN 1030 -990 M1=0 -1000 Y1=0 -1010 GOTO 200 -1020 GOTO 640 -1030 PRINT -1040 PRINT "OK. SEE YOU LATER." -1050 GOTO 1230 -1060 T=27 -1070 PRINT -1080 PRINT -1090 PRINT -1100 PRINT "TOTAL=";T -1110 PRINT -1120 PRINT -1130 PRINT "WHAT IS YOUR FIRST MOVE"; -1140 INPUT Y -1150 GOTO 360 -1160 PRINT -1170 PRINT "THE NUMBER OF MARBLES YOU TAKE MUST BE A POSITIVE" -1180 PRINT "INTEGER BETWEEN 1 AND 4." -1190 PRINT -1200 PRINT " WHAT IS YOUR NEXT MOVE?" -1210 PRINT -1220 GOTO 350 -1230 END diff --git a/00_Alternate_Languages/35_Even_Wins/gameofevenwins.bas b/00_Alternate_Languages/35_Even_Wins/gameofevenwins.bas deleted file mode 100644 index 673dcc90c..000000000 --- a/00_Alternate_Languages/35_Even_Wins/gameofevenwins.bas +++ /dev/null @@ -1,70 +0,0 @@ -1 PRINT TAB(28);"GAME OF EVEN WINS" -2 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -3 PRINT:PRINT -4 INPUT "DO YOU WANT INSTRUCTIONS (YES OR NO)";A$:PRINT -5 IF A$="NO" THEN 20 -6 PRINT "THE GAME IS PLAYED AS FOLLOWS:":PRINT -7 PRINT "AT THE BEGINNING OF THE GAME, A RANDOM NUMBER OF CHIPS ARE" -8 PRINT "PLACED ON THE BOARD. THE NUMBER OF CHIPS ALWAYS STARTS" -9 PRINT "AS AN ODD NUMBER. ON EACH TURN, A PLAYER MUST TAKE ONE," -10 PRINT "TWO, THREE, OR FOUR CHIPS. THE WINNER IS THE PLAYER WHO" -11 PRINT "FINISHES WITH A TOTAL NUMBER OF CHIPS THAT IS EVEN." -12 PRINT "THE COMPUTER STARTS OUT KNOWING ONLY THE RULES OF THE" -13 PRINT "GAME. IT GRADUALLY LEARNS TO PLAY WELL. IT SHOULD BE" -14 PRINT "DIFFICULT TO BEAT THE COMPUTER AFTER TWENTY GAMES IN A ROW." -15 PRINT "TRY IT!!!!": PRINT -16 PRINT "TO QUIT AT ANY TIME, TYPE A '0' AS YOUR MOVE.": PRINT -20 DIM R(1,5) -25 L=0: B=0 -30 FOR I=0 TO 5 -40 R(1,I)=4 -50 R(0,I)=4 -60 NEXT I -70 A=0: B=0 -90 P=INT((13*RND(1)+9)/2)*2+1 -100 IF P=1 THEN 530 -110 PRINT "THERE ARE";P;"CHIPS ON THE BOARD." -120 E1=E -130 L1=L -140 E=(A/2-INT(A/2))*2 -150 L=INT((P/6-INT(P/6))*6+.5) -160 IF R(E,L)>=P THEN 320 -170 M=R(E,L) -180 IF M<=0 THEN 370 -190 P=P-M -200 IF M=1 THEN 510 -210 PRINT "COMPUTER TAKES";M;"CHIPS LEAVING";P;"... YOUR MOVE"; -220 B=B+M -230 INPUT M -240 M=INT(M) -250 IF M<1 THEN 450 -260 IF M>4 THEN 460 -270 IF M>P THEN 460 -280 IF M=P THEN 360 -290 P=P-M -300 A=A+M -310 GOTO 100 -320 IF P=1 THEN 550 -330 PRINT "COMPUTER TAKES";P;"CHIPS." -340 R(E,L)=P -350 B=B+P -360 IF B/2=INT(B/2) THEN 420 -370 PRINT "GAME OVER ... YOU WIN!!!": PRINT -390 IF R(E,L)=1 THEN 480 -400 R(E,L)=R(E,L)-1 -410 GOTO 70 -420 PRINT "GAME OVER ... I WIN!!!": PRINT -430 GOTO 70 -450 IF M=0 THEN 570 -460 PRINT M;"IS AN ILLEGAL MOVE ... YOUR MOVE"; -470 GOTO 230 -480 IF R(E1,L1)=1 THEN 70 -490 R(E1,L1)=R(E1,L1)-1 -500 GOTO 70 -510 PRINT "COMPUTER TAKES 1 CHIP LEAVING";P;"... YOUR MOVE"; -520 GOTO 220 -530 PRINT "THERE IS 1 CHIP ON THE BOARD." -540 GOTO 120 -550 PRINT "COMPUTER TAKES 1 CHIP." -560 GOTO 340 -570 END diff --git a/00_Alternate_Languages/35_Even_Wins/go/evenwins.go b/00_Alternate_Languages/35_Even_Wins/go/evenwins.go deleted file mode 100644 index 7c65aacc1..000000000 --- a/00_Alternate_Languages/35_Even_Wins/go/evenwins.go +++ /dev/null @@ -1,197 +0,0 @@ -package main - -import ( - "bufio" - "fmt" - "os" - "strconv" - "strings" -) - -const MAXTAKE = 4 - -type PlayerType int8 - -const ( - HUMAN PlayerType = iota - COMPUTER -) - -type Game struct { - table int - human int - computer int -} - -func NewGame() Game { - g := Game{} - g.table = 27 - - return g -} - -func printIntro() { - fmt.Println("Welcome to Even Wins!") - fmt.Println("Based on evenwins.bas from Creative Computing") - fmt.Println() - fmt.Println("Even Wins is a two-person game. You start with") - fmt.Println("27 marbles in the middle of the table.") - fmt.Println() - fmt.Println("Players alternate taking marbles from the middle.") - fmt.Println("A player can take 1 to 4 marbles on their turn, and") - fmt.Println("turns cannot be skipped. The game ends when there are") - fmt.Println("no marbles left, and the winner is the one with an even") - fmt.Println("number of marbles.") - fmt.Println() -} - -func (g *Game) printBoard() { - fmt.Println() - fmt.Printf(" marbles in the middle: %d\n", g.table) - fmt.Printf(" # marbles you have: %d\n", g.human) - fmt.Printf("# marbles computer has: %d\n", g.computer) - fmt.Println() -} - -func (g *Game) gameOver() { - fmt.Println() - fmt.Println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") - fmt.Println("!! All the marbles are taken: Game Over!") - fmt.Println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") - fmt.Println() - g.printBoard() - if g.human%2 == 0 { - fmt.Println("You are the winner! Congratulations!") - } else { - fmt.Println("The computer wins: all hail mighty silicon!") - } - fmt.Println() -} - -func getPlural(count int) string { - m := "marble" - if count > 1 { - m += "s" - } - return m -} - -func (g *Game) humanTurn() { - scanner := bufio.NewScanner(os.Stdin) - maxAvailable := MAXTAKE - if g.table < MAXTAKE { - maxAvailable = g.table - } - - fmt.Println("It's your turn!") - for { - fmt.Printf("Marbles to take? (1 - %d) --> ", maxAvailable) - scanner.Scan() - n, err := strconv.Atoi(scanner.Text()) - if err != nil { - fmt.Printf("\n Please enter a whole number from 1 to %d\n", maxAvailable) - continue - } - if n < 1 { - fmt.Println("\n You must take at least 1 marble!") - continue - } - if n > maxAvailable { - fmt.Printf("\n You can take at most %d %s\n", maxAvailable, getPlural(maxAvailable)) - continue - } - fmt.Printf("\nOkay, taking %d %s ...\n", n, getPlural(n)) - g.table -= n - g.human += n - return - } -} - -func (g *Game) computerTurn() { - marblesToTake := 0 - - fmt.Println("It's the computer's turn ...") - r := float64(g.table - 6*int((g.table)/6)) - - if int(g.human/2) == g.human/2 { - if r < 1.5 || r > 5.3 { - marblesToTake = 1 - } else { - marblesToTake = int(r - 1) - } - } else if float64(g.table) < 4.2 { - marblesToTake = 4 - } else if r > 3.4 { - if r < 4.7 || r > 3.5 { - marblesToTake = 4 - } - } else { - marblesToTake = int(r + 1) - } - - fmt.Printf("Computer takes %d %s ...\n", marblesToTake, getPlural(marblesToTake)) - g.table -= marblesToTake - g.computer += marblesToTake -} - -func (g *Game) play(playersTurn PlayerType) { - g.printBoard() - - for { - if g.table == 0 { - g.gameOver() - return - } else if playersTurn == HUMAN { - g.humanTurn() - g.printBoard() - playersTurn = COMPUTER - } else { - g.computerTurn() - g.printBoard() - playersTurn = HUMAN - } - } -} - -func getFirstPlayer() PlayerType { - scanner := bufio.NewScanner(os.Stdin) - - for { - fmt.Println("Do you want to play first? (y/n) --> ") - scanner.Scan() - - if strings.ToUpper(scanner.Text()) == "Y" { - return HUMAN - } else if strings.ToUpper(scanner.Text()) == "N" { - return COMPUTER - } else { - fmt.Println() - fmt.Println("Please enter 'y' if you want to play first,") - fmt.Println("or 'n' if you want to play second.") - fmt.Println() - } - } -} - -func main() { - scanner := bufio.NewScanner(os.Stdin) - - printIntro() - - for { - g := NewGame() - - g.play(getFirstPlayer()) - - fmt.Println("\nWould you like to play again? (y/n) --> ") - scanner.Scan() - if strings.ToUpper(scanner.Text()) == "Y" { - fmt.Println("\nOk, let's play again ...") - } else { - fmt.Println("\nOk, thanks for playing ... goodbye!") - return - } - - } - -} diff --git a/00_Alternate_Languages/36_Flip_Flop/MiniScript/README.md b/00_Alternate_Languages/36_Flip_Flop/MiniScript/README.md deleted file mode 100644 index e012477dd..000000000 --- a/00_Alternate_Languages/36_Flip_Flop/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript flipflop.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "flipflop" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/36_Flip_Flop/MiniScript/flipflop.ms b/00_Alternate_Languages/36_Flip_Flop/MiniScript/flipflop.ms deleted file mode 100644 index 6fb07cc0a..000000000 --- a/00_Alternate_Languages/36_Flip_Flop/MiniScript/flipflop.ms +++ /dev/null @@ -1,97 +0,0 @@ -print " "*32 + "FlipFlop" -print " "*15 + "Creative Computing Morristown, New Jersey" -print -// Created by Michael Cass (1978) -// Ported to MiniScript by Joe Strout (2023) - -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)." -print - -startNewGame = function - globals.q = rnd - globals.guesses = 0 - print "Here is the starting line of X's." - print - print "1 2 3 4 5 6 7 8 9 10" - print "X X X X X X X X X X" - print -end function - -getInput = function - while true - n = input("Input the number: ").val - if n == floor(n) and 0 <= n <= 11 then break - print "Illegal entry--try again." - end while - return n -end function - -startNewGame -while true - A = [""] + ["X"] * 10 // (include empty 0th element so we can index 1-based - m = 0 // (previous input) - while true - n = getInput - if n == 11 then - startNewGame - continue - else if n == 0 then - A = ["X"] * 10 - continue - end if - - if n != m then - // when user enters a different number from previous time - m = n - if A[n] == "O" then A[n] = "X" else A[n] = "O" - while m == n - r = tan(q + n/q - n) - sin(q/n) + 336*sin(8*n) - n = floor(10 * (r - floor(r))) - if A[n] != "O" then - A[n] = "O" - break - end if - A[n] = "X" - end while - else - // when n == m, i.e., user entered the same number twice in a row - while m == n - if A[n] == "O" then A[n] = "X" else A[n] = "O" - r = 0.592 * (1 / tan(q/n + q)) / sin(n*2 + q) - cos(n) - n = floor(10 * (r - floor(r))) - if A[n] != "O" then - A[n] = "O" - break - end if - A[n] = "X" - end while - end if - - print "1 2 3 4 5 6 7 8 9 10" - print A[1:].join - guesses += 1 - if A[1:] == ["O"]*10 then break - end while - - if guesses <= 12 then - print "Very good. You guessed it in only " + guesses + " guesses." - else - print "Try harder next time. It took you " + guesses + " guesses." - end if - - yesNo = input("Do you want to try another puzzle? ").lower - if not yesNo or yesNo[0] == "n" then break - print -end while diff --git a/00_Alternate_Languages/36_Flip_Flop/README.md b/00_Alternate_Languages/36_Flip_Flop/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/36_Flip_Flop/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/36_Flip_Flop/flipflop.bas b/00_Alternate_Languages/36_Flip_Flop/flipflop.bas deleted file mode 100644 index 38d59879d..000000000 --- a/00_Alternate_Languages/36_Flip_Flop/flipflop.bas +++ /dev/null @@ -1,79 +0,0 @@ -2 PRINT TAB(32);"FLIPFLOP" -4 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -6 PRINT -10 REM *** CREATED BY MICHAEL CASS -15 DIM A$(20) -20 PRINT "THE OBJECT OF THIS PUZZLE IS TO CHANGE THIS:" -30 PRINT -40 PRINT "X X X X X X X X X X" -50 PRINT -60 PRINT "TO THIS:" -70 PRINT -80 PRINT "O O O O O O O O O O" -90 PRINT -100 PRINT "BY TYPING THE NUMBER CORRESPONDING TO THE POSITION OF THE" -110 PRINT "LETTER ON SOME NUMBERS, ONE POSITION WILL CHANGE, ON" -120 PRINT "OTHERS, TWO WILL CHANGE. TO RESET LINE TO ALL X'S, TYPE 0" -130 PRINT "(ZERO) AND TO START OVER IN THE MIDDLE OF A GAME, TYPE " -140 PRINT "11 (ELEVEN)." -170 PRINT -180 REM -190 Q=RND(1) -200 PRINT "HERE IS THE STARTING LINE OF X'S." -210 PRINT -220 C=0 -230 PRINT "1 2 3 4 5 6 7 8 9 10" -240 PRINT "X X X X X X X X X X" -250 PRINT -260 REM -270 FOR X=1 TO 10 -280 A$(X)="X" -290 NEXT X -300 GOTO 320 -310 PRINT "ILLEGAL ENTRY--TRY AGAIN." -320 PRINT "INPUT THE NUMBER"; -330 INPUT N -340 IF N<>INT(N) THEN 310 -350 IF N=11 THEN 180 -360 IF N>11 THEN 310 -370 IF N=0 THEN 230 -380 IF M=N THEN 510 -390 M=N -400 IF A$(N)="O" THEN 480 -410 A$(N)="O" -420 R=TAN(Q+N/Q-N)-SIN(Q/N)+336*SIN(8*N) -430 N=R-INT(R) -440 N=INT(10*N) -450 IF A$(N)="O" THEN 480 -460 A$(N)="O" -470 GOTO 610 -480 A$(N)="X" -490 IF M=N THEN 420 -500 GOTO 610 -510 IF A$(N)="O" THEN 590 -520 A$(N)="O" -530 R=.592*(1/TAN(Q/N+Q))/SIN(N*2+Q)-COS(N) -540 N=R-INT(R) -550 N=INT(10*N) -560 IF A$(N)="O" THEN 590 -570 A$(N)="O" -580 GOTO 610 -590 A$(N)="X" -600 IF M=N THEN 530 -610 PRINT "1 2 3 4 5 6 7 8 9 10" -620 FOR Z=1 TO 10: PRINT A$(Z);" ";: NEXT Z -630 C=C+1 -640 PRINT -650 FOR Z=1 TO 10 -660 IF A$(Z)<>"O" THEN 320 -670 NEXT Z -680 IF C>12 THEN 710 -690 PRINT "VERY GOOD. YOU GUESSED IT IN ONLY";C;"GUESSES." -700 GOTO 720 -710 PRINT "TRY HARDER NEXT TIME. IT TOOK YOU";C;"GUESSES." -720 PRINT "DO YOU WANT TO TRY ANOTHER PUZZLE"; -730 INPUT X$ -740 IF LEFT$(X$,1)="N" THEN 780 -760 PRINT -770 GOTO 180 -780 END diff --git a/00_Alternate_Languages/37_Football/MiniScript/README.md b/00_Alternate_Languages/37_Football/MiniScript/README.md deleted file mode 100644 index 4d8c33066..000000000 --- a/00_Alternate_Languages/37_Football/MiniScript/README.md +++ /dev/null @@ -1,34 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript football.ms -```or -``` - miniscript ftball.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "football" - run -```or -``` - load "ftball" - run -``` - -#### Apology from the Translator - -These MiniScript programs were actually ported from the JavaScript ports of the original BASIC programs. I did that because the BASIC code (of both programs) was incomprehensible spaghetti. The JavaScript port, however, was essentially the same — and so are the MiniScript ports. The very structure of these programs makes them near-impossible to untangle. - -If I were going to write a football simulation from scratch, I would approach it very differently. But in that case I would have either a detailed specification of how the program should behave, or at least enough understanding of American football to design it myself as I go. Neither is the case here (and we're supposed to be porting the original programs, not making up our own). - -So, I'm sorry. Please take these programs as proof that you can write bad code even in the most simple, elegant languages. And I promise to try harder on future translations! diff --git a/00_Alternate_Languages/37_Football/MiniScript/football.ms b/00_Alternate_Languages/37_Football/MiniScript/football.ms deleted file mode 100644 index e2b4583f6..000000000 --- a/00_Alternate_Languages/37_Football/MiniScript/football.ms +++ /dev/null @@ -1,402 +0,0 @@ -player_data = [17,8,4,14,19,3,10,1,7,11,15,9,5,20,13,18,16,2,12,6, - 20,2,17,5,8,18,12,11,1,4,19,14,10,7,9,15,6,13,16,3] -aa = [0]*21 -ba = [0]*21 -ca = [0]*41 -ha = [0]*3 -ta = [0]*3 -wa = [0]*3 -xa = [0]*3 -ya = [0]*3 -za = [0]*3 -ms = [null, "",""] -da = [0]*3 -ps = ["", "PITCHOUT","TRIPLE REVERSE","DRAW","QB SNEAK","END AROUND", - "DOUBLE REVERSE","LEFT SWEEP","RIGHT SWEEP","OFF TACKLE", - "WISHBONE OPTION","FLARE PASS","SCREEN PASS", - "ROLL OUT OPTION","RIGHT CURL","LEFT CURL","WISHBONE OPTION", - "SIDELINE PASS","HALF-BACK OPTION","RAZZLE-DAZZLE","BOMB!!!!"] -globals.p = 0 -globals.t = 0 - -printFieldHeaders = function - print "TEAM 1 [0 10 20 30 40 50 60 70 80 90 100] TEAM 2" - print -end function - -printSeparator = function - print "+" * 67 -end function - -showBall = function - print " " * (da[t] + 5 + p / 2) + ms[t] - printFieldHeaders -end function - -showScores = function - print - print "TEAM 1 SCORE IS " + ha[1] - print "TEAM 2 SCORE IS " + ha[2] - print - if ha[t] >= e then - print "TEAM " + t + " WINS*******************" - return true - end if - return false -end function - -losePossession = function - print - print "** LOSS OF POSSESSION FROM TEAM " + t + " TO TEAM " + ta[t] - print - printSeparator - print - globals.t = ta[t] -end function - -touchdown = function - print - print "TOUCHDOWN BY TEAM " + t + " *********************YEA TEAM" - q = 7 - if rnd <= 0.1 then - q = 6 - print "EXTRA POINT NO GOOD" - else - print "EXTRA POINT GOOD" - end if - ha[t] += q -end function - -askYesNo = function(prompt) - while true - yn = input(prompt + "? ").lower - if not yn then continue - if yn[0] == "y" then return "YES" - if yn[0] == "n" then return "NO" - end while -end function - - -print " "*32 + "FOOTBALL" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print -print "Presenting N.F.U. Football (No FORTRAN Used)" -print; print -if askYesNo("Do you want instructions") == "YES" then - print "This is a football game for two teams in which players must" - print "prepare a tape with a data statement (1770 for team 1," - print "1780 for team 2) in which each team scrambles nos. 1-20" - print "These numbers are then assigned to twenty given plays." - print "A list of nos. and their plays is provided with" - print "both teams having the same plays. The more similar the" - print "plays the less yardage gained. Scores are given" - print "whenever scores are made. Scores may also be obtained" - print "by inputting 99,99 for play nos. To punt or attempt a" - print "field goal, input 77,77 for play numbers. Questions will be" - print "asked then. On 4th down, you will also be asked whether" - print "you want to punt or attempt a field goal. If the answer to" - print "both questions is no it will be assumed you want to" - print "try and gain yardage. Answer all questions Yes or No." - print "The game is played until players terminate (control-c)." - print "Please prepare a tape and run." -end if -print -e = input("Please input score limit on game: ").val -for i in range(1, 40) - if i <= 20 then - aa[player_data[i - 1]] = i - else - ba[player_data[i - 1]] = i - 20 - end if - ca[i] = player_data[i - 1] -end for -l = 0 -globals.t = 1 -while true - print "TEAM " + t + " PLAY CHART" - print "NO. PLAY" - for i in range(1, 20) - print (ca[i+1] + " "*6)[:6] + ps[i] - end for - l += 20 - globals.t = 2 - print - print "TEAR OFF HERE----------------------------------------------" - for x in range(1, 11); print; end for - wait 3 - if l != 20 then break -end while - -playGame = function - da[1] = 0 - da[2] = 3 - ms[1] = "--->" - ms[2] = "<---" - ha[1] = 0 - ha[2] = 0 - ta[1] = 2 - ta[2] = 1 - wa[1] = -1 - wa[2] = 1 - xa[1] = 100 - xa[2] = 0 - ya[1] = 1 - ya[2] = -1 - za[1] = 0 - za[2] = 100 - globals.p = 0 - printFieldHeaders - print "TEAM 1 defend 0 YD goal -- TEAM 2 defends 100 YD goal." - globals.t = floor(2 * rnd + 1) - print - print "The coin is flipped" - routine = 1 - while true - if routine <= 1 then - globals.p = xa[t] - ya[t] * 40 - printSeparator - print - print "Team " + t + " receives kick-off" - k = floor(26 * rnd + 40) - end if - if routine <= 2 then - globals.p = p - ya[t] * k - end if - if routine <= 3 then - if wa[t] * p >= za[t] + 10 then - print - print "Ball went out of endzone --automatic touchback--" - globals.p = za[t] - wa[t] * 20 - if routine <= 4 then routine = 5 - else - print "Ball went " + k + " yards. Now on " + p - showBall - end if - end if - if routine <= 4 then - if askYesNo("Team " + t + " do you want to runback") == "YES" then - k = floor(9 * rnd + 1) - r = floor(((xa[t] - ya[t] * p + 25) * rnd - 15) / k) - globals.p = p - wa[t] * r - print - print "Runback team " + t + " " + r + " yards" - g = rnd - if g < 0.25 then - losePossession - routine = 4 - continue - else if ya[t] * p >= xa[t] then - touchdown - if showScores then return - globals.t = ta[t] - routine = 1 - continue - else if wa[t] * p >= za[t] then - print - print "Safety against team " + t + " **********************OH-OH" - ha[ta[t]] += 2 - if showScores then return - globals.p = za[t] - wa[t] * 20 - if askYesNo("Team " + t + " do you want to punt instead of a kickoff") == "YES" then - print - print "Team " + t + " will punt" - g = rnd - if g < 0.25 then - losePossession - routine = 4 - continue - end if - print - printSeparator - k = floor(25 * rnd + 35) - globals.t = ta[t] - routine = 2 - continue - end if - touchdown - if showScores then return - globals.t = ta[t] - routine = 1 - continue - else - routine = 5 - continue - end if - else // player does not want to runback - if wa[t] * p >= za[t] then globals.p = za[t] - wa[t] * 20 - end if - end if - if routine <= 5 then - d = 1 - s = p - end if - if routine <= 6 then - print "=" * 67 - print "TEAM " + t + " DOWN " + d + " ON " + p - if d == 1 then - if ya[t] * (p + ya[t] * 10) >= xa[t] then - c = 8 - else - c = 4 - end if - end if - if c != 8 then - print " "*27 + (10 - (ya[t] * p - ya[t] * s)) + " yards to 1st down" - else - print " "*27 + (xa[t] - ya[t] * p) + " yards" - end if - showBall - if d == 4 then routine = 8 - end if - if routine <= 7 then - u = floor(3 * rnd - 1) - while true - str = input("Input offensive play, defensive play: ") - str = str.replace(",", " ").replace(" ", " ").split - if t == 1 then - p1 = str[0].val - p2 = str[1].val - else - p2 = str[0].val - p1 = str[1].val - end if - if p1 == 99 then - if showScores then return - continue - end if - if 1 <= p1 <= 20 and 1 <= p2 <= 20 then break - print "Illegal play number, check and" - end while - end if - if d == 4 or p1 == 77 then - if askYesNo("Does team " + t + " want to punt") == "YES" then - print - print "Team " + t + " will punt" - if rnd < 0.25 then - losePossession - routine = 4 - continue - end if - print - printSeparator - k = floor(25 * rnd + 35) - globals.t = ta[t] - routine = 2 - continue - end if - if askYesNo("Does team " + t + " want to attempt a field goal") == "YES" then - print - print "Team " + t + " will attempt a field goal" - if rnd < 0.025 then - losePossession - routine = 4 - continue - else - f = floor(35 * rnd + 20) - print - print "Kick is " + f + " yards long" - globals.p = p - wa[t] * f - if rnd < 0.35 then - print "Ball went wide" - else if ya[t] * p >= xa[t] then - print "FIELD GOLD GOOD FOR TEAM " + t + " *********************YEA" - q = 3 - ha[t] = ha[t] + q - if showScores then return - globals.t = ta[t] - routine = 1 - continue - end if - print "Field goal unsuccesful team " + t + "-----------------too bad" - print - printSeparator - if ya[t] * p < xa[t] + 10 then - print - print "Ball now on " + p - globals.t = ta[t] - showBall - routine = 4 - continue - else - globals.t = ta[t] - routine = 3 - continue - end if - end if - else - routine = 7 - continue - end if - end if - y = floor(abs(aa[p1] - ba[p2]) / 19 * ((xa[t] - ya[t] * p + 25) * rnd - 15)) - print - if t == 1 and aa[p1] < 11 or t == 2 and ba[p2] < 11 then - print "The ball was run" - else if u == 0 then - print "Pass incomplete team " + t - y = 0 - else - if rnd <= 0.025 and y > 2 then - print "Pass completed" - else - print "Quarterback scrambled" - end if - end if - globals.p = p - wa[t] * y - print - print "Net yards gained on down " + d + " are " + y - - if rnd <= 0.025 then - losePossession - routine = 4 - continue - else if ya[t] * p >= xa[t] then - touchdown - if showScores then return - globals.t = ta[t] - routine = 1 - continue - else if wa[t] * p >= za[t] then - print - print "SAFETY AGAINST TEAM " + t + " **********************OH-OH" - ha[ta[t]] = ha[ta[t]] + 2 - if showScores then return - globals.p = za[t] - wa[t] * 20 - if askYesNo("Team " + t + " do you want to punt instead of a kickoff") == "YES" then - print - print "Team " + t + " will punt" - if rnd < 0.25 then - losePossession - routine = 4 - continue - end if - print - printSeparator - k = floor(25 * rnd + 35) - globals.t = ta[t] - routine = 2 - continue - end if - touchdown - if showScores then return - globals.t = ta[t] - routine = 1 - else if ya[t] * p - ya[t] * s >= 10 then - routine = 5 - else - d += 1 - if d != 5 then - routine = 6 - else - print - print "Conversion unsuccessful team " + t - globals.t = ta[t] - print - printSeparator - routine = 5 - end if - end if - end while -end function - -playGame diff --git a/00_Alternate_Languages/37_Football/MiniScript/ftball.ms b/00_Alternate_Languages/37_Football/MiniScript/ftball.ms deleted file mode 100644 index 31d3f8299..000000000 --- a/00_Alternate_Languages/37_Football/MiniScript/ftball.ms +++ /dev/null @@ -1,431 +0,0 @@ -os = ["Dartmouth", ""] -sa = [0, 1] -ls = ["", "Kick","receive"," yard ","run back for ","ball on ", - "yard line"," simple run"," tricky run"," short pass", - " long pass","punt"," quick kick "," place kick"," loss ", - " no gain","gain "," touchdown "," touchback ","safety***", - "junk"] -p = 0 -x = 0 -x1 = 0 - -fnf = function(x); return 1 - 2 * p; end function -fng = function(z); return p * (x1 - x) + (1 - p) * (x - x1); end function - -show_score = function - print - print "SCORE: " + sa[0] + " TO " + sa[1] - print - print -end function - -show_position = function - if x <= 50 then - print ls[5] + os[0] + " " + x + " " + ls[6] - else - print ls[5] + os[1] + " " + (100 - x) + " " + ls[6] - end if -end function - -offensive_td = function - print ls[17] + "***" - if rnd <= 0.8 then - sa[p] += 7 - print "Kick is good." - else - print "Kick is off to the side" - sa[p] += 6 - end if - show_score - print os[p] + " kicks off" - globals.p = 1 - p -end function - -// Main program -main = function - print " "*33 + "FTBALL" - print " "*15 + "Creative Computing Morristown, New Jersey" - print - print - print "This is Dartmouth championship football." - print - print "You will quarterback Dartmouth. Call plays as follows:" - print "1= simple run; 2= tricky run; 3= short pass;" - print "4= long pass; 5= punt; 6= quick kick; 7= place kick." - print - os[1] = input("Choose your opponent: ").upper - os[0] = "DARMOUTH" - print - sa[0] = 0 - sa[1] = 0 - globals.p = floor(rnd * 2) - print os[p] + " won the toss" - if p != 0 then - print os[1] + " Elects to receive." - print - else - print "Do you elect to kick or receive? " - while true - str = input.lower - if str and (str[0] == "k" or str[0] == "r") then break - print "Incorrect answer. Please type 'kick' or 'receive'" - end while - if str[0] == "k" then e = 1 else e = 2 - if e == 1 then globals.p = 1 - end if - globals.t = 0 - start = 1 - while true - if start <= 1 then - x = 40 + (1 - p) * 20 - end if - if start <= 2 then - y = floor(200 * ((rnd - 0.5))^3 + 55) - print " " + y + " " + ls[3] + " kickoff" - x = x - fnf(1) * y - if abs(x - 50) >= 50 then - print "Touchback for " + os[p] + "." - x = 20 + p * 60 - start = 4 - else - start = 3 - end if - end if - if start <= 3 then - y = floor(50 * (rnd)^2) + (1 - p) * floor(50 * (rnd)^4) - x = x + fnf(1) * y - if abs(x - 50) < 50 then - print " " + y + " " + ls[3] + " runback" - else - print ls[4] - offensive_td - start = 1 - continue - end if - end if - if start <= 4 then - // First down - show_position - end if - if start <= 5 then - x1 = x - d = 1 - print - print "First down " + os[p] + "***" - print - print - end if - // New play - globals.t += 1 - if t == 30 then - if rnd <= 1.3 then - print "Game delayed. Dog on field." - print - end if - end if - if t >= 50 and rnd <= 0.2 then break - if p != 1 then - // Opponent's play - if d <= 1 then - if rnd > 1/3 then z = 1 else z = 3 - else if d != 4 then - if 10 + x - x1 < 5 or x < 5 then - if rnd > 1/3 then z = 1 else z = 3 - else if x <= 10 then - a = floor(2 * rnd) - z = 2 + a - else if x <= x1 or d < 3 or x < 45 then - a = floor(2 * rnd) - z = 2 + a * 2 - else - if (rnd > 1 / 4) then - z = 4 - else - z = 6 - end if - end if - else - if x <= 30 then - z = 5 - else if 10 + x - x1 < 3 or x < 3 then - if rnd > 1/3 then z = 1 else z = 3 - else - z = 7 - end if - end if - else - while true - z = input("Next play? ").val - if 1 <= z <= 7 then break - print "Illegal play number, retype" - end while - end if - f = 0 - print ls[z + 6] + ". " - r = rnd * (0.98 + fnf(1) * 0.02) - r1 = rnd - if z == 1 or z == 2 then // Simple Run or Tricky Run - done = false - if z == 1 then - y = floor(24 * (r - 0.5)^3 + 3) - if rnd >= 0.05 then - routine = 1 - done = true - end if - else - y = floor(20 * r - 5) - if rnd > 0.1 then - routine = 1 - done = true - end if - end if - if not done then - f = -1 - x3 = x - x = x + fnf(1) * y - if abs(x - 50) < 50 then - print "*** Fumble after " - routine = 2 - else - print "*** Fumble." - routine = 4 - end if - end if - else if z == 3 or z == 4 then // Short Pass or Long Pass - if z == 3 then - y = floor(60 * (r1 - 0.5)^3 + 10) - else - y = floor(160 * ((r1 - 0.5))^3 + 30) - end if - if z == 3 and r < 0.05 or z == 4 and r < 0.1 then - if d != 4 then - print "Intercepted." - f = -1 - x = x + fnf(1) * y - if abs(x - 50) >= 50 then - routine = 4 - else - routine = 3 - end if - else - y = 0 - if rnd < 0.3 then - print "Batted down. ", "" - else - print "Incomplete. ", "" - end if - routine = 1 - end if - else if z == 4 and r < 0.3 then - print "Passer tackled. ", "" - y = -floor(15 * r1 + 3) - routine = 1 - else if z == 3 and r < 0.15 then - print "Passer taclked. ", "" - y = -floor(10 * r1) - routine = 1 - else if z == 3 and r < 0.55 or z == 4 and r < 0.75 then - y = 0 - if rnd < 0.3 then - print "Batted down. ", "" - else - print "Incomplete. ", "" - end if - routine = 1 - else - print "Complete. ", "" - routine = 1 - end if - else if z == 5 or z == 6 then // Punt or Quick Kick - y = floor(100 * ((r - 0.5))^3 + 35) - if (d != 4) then y = floor(y * 1.3) - print " " + y + " " + ls[3] + " punt" - if abs(x + y * fnf(1) - 50) < 50 and d >= 4 then - y1 = floor((r1)^2 * 20) - print " " + y1 + " " + ls[3] + " Run back" - y = y - y1 - end if - f = -1 - x = x + fnf(1) * y - if abs(x - 50) >= 50 then routine = 4 else routine = 3 - else if z == 7 then // Place kick - y = floor(100 * ((r - 0.5))^3 + 35) - if r1 <= 0.15 then - print "Kick is blocked ***" - x = x - 5 * fnf(1) - globals.p = 1 - p - start = 4 - continue - end if - x = x + fnf(1) * y - if abs(x - 50) >= 60 then - if r1 <= 0.5 then - print "Kick is off to the side." - print ls[18] - globals.p = 1 - p - x = 20 + p * 60 - start = 4 - continue - else - print "Field goal ***" - sa[p] = sa[p] + 3 - show_score - print os[p] + " kicks off" - globals.p = 1 - p - start = 1 - continue - end if - else - print "Kick is short." - if abs(x - 50) >= 50 then - // Touchback - print ls[18] - globals.p = 1 - p - x = 20 + p * 60 - start = 4 - continue - end if - globals.p = 1 - p - start = 3 - continue - end if - end if - // Gain or loss - if routine <= 1 then - x3 = x - x = x + fnf(1) * y - if abs(x - 50) >= 50 then - routine = 4 - end if - end if - if routine <= 2 then - if y != 0 then - print " " + abs(y) + " " + ls[3] - if (y < 0) then - yt = -1 - else if y > 0 then - yt = 1 - else - yt = 0 - end if - print ls[15 + yt] - if abs(x3 - 50) <= 40 and rnd < 0.1 then - // Penalty - p3 = floor(2 * rnd) - print os[p3] + " offsides -- penalty of 5 yards." - print - print - if p3 != 0 then - print "Do you accept the penalty?" - while true - str = input.lower - if str and (str[0] == "y" or str[0] == "n") then break - print "Yype 'yes' or 'no'" - end while - if str[0] == "y" then - f = 0 - d = d - 1 - if (p != p3) then - x = x3 + fnf(1) * 5 - else - x = x3 - fnf(1) * 5 - end if - end if - else - // opponent's strategy on penalty - if ((p != 1 and (y <= 0 or f < 0 or fng(1) < 3 * d - 2)) or - (p == 1 and ((y > 5 and f >= 0) or d < 4 or fng(1) >= 10))) then - print "penalty refused." - else - print "penalty accepted." - f = 0 - d = d - 1 - if (p != p3) then - x = x3 + fnf(1) * 5 - else - x = x3 - fnf(1) * 5 - end if - end if - end if - routine = 3 - end if - end if - end if - if routine <= 3 then - show_position - if f != 0 then - globals.p = 1 - p - start = 5 - continue - else if fng(1) >= 10 then - start = 5 - continue - else if d == 4 then - globals.p = 1 - p - start = 5 - continue - else - d += 1 - print "DOWN: " + d + " " - if (x1 - 50) * fnf(1) >= 40 then - print "Goal to go" - else - print "Yards to go: " + (10 - fng(1)) - end if - print - print - start = 6 - continue - end if - end if - if routine <= 4 then - // Ball in end-zone - e = (x >= 100) - case = 1 + e - f * 2 + p * 4 - if case == 1 or case == 5 then - // Safety - sa[1 - p] = sa[1 - p] + 2 - print ls[19] - show_score - print os[p] + " kicks off from its 20 yard line." - x = 20 + p * 60 - globals.p = 1 - p - start = 2 - continue - end if - if case == 3 or case == 6 then - // defensive td - print ls[17] + "for " + os[1 - p] + "***" - globals.p = 1 - p - end if - if case == 3 or case == 6 or case == 2 or case == 8 then - // offensive td - print ls[17] + "***" - if rnd <= 0.8 then - sa[p] = sa[p] + 7 - print "kick is good." - else - print "kick is off to the side" - sa[p] = sa[p] + 6 - end if - show_score - print os[p] + " kicks off" - globals.p = 1 - p - start = 1 - continue - end if - if case == 4 or case == 7 then - // Touchback - print ls[18] - globals.p = 1 - p - x = 20 + p * 60 - start = 4 - continue - end if - end if - end while - print "END OF GAME ***" - print "FINAL SCORE: " + os[0] + ": " + sa[0] + " " + os[1] + ": " + sa[1] -end function - -main diff --git a/00_Alternate_Languages/37_Football/README.md b/00_Alternate_Languages/37_Football/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/37_Football/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/37_Football/football.bas b/00_Alternate_Languages/37_Football/football.bas deleted file mode 100644 index 9ee2192f3..000000000 --- a/00_Alternate_Languages/37_Football/football.bas +++ /dev/null @@ -1,181 +0,0 @@ -1 PRINT TAB(32);"FOOTBALL" -2 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -3 PRINT:PRINT:PRINT -100 REM -120 DIM A(20),B(20),C(40),H(2),T(2),W(2),X(2),Y(2),Z(2) -130 DIM M$(2),D(2),P$(20) -140 PRINT "PRESENTING N.F.U. FOOTBALL (NO FORTRAN USED)" -145 PRINT:PRINT -150 INPUT "DO YOU WANT INSTRUCTIONS";A$ -160 IF A$="NO" THEN 290 -165 IF A$<>"YES" THEN 150 -170 PRINT "THIS IS A FOOTBALL GAME FOR TWO TEAMS IN WHICH PLAYERS MUST" -180 PRINT "PREPARE A TAPE WITH A DATA STATEMENT (1770 FOR TEAM 1," -190 PRINT "1780 FOR TEAM 2) IN WHICH EACH TEAM SCRAMBLES NOS. 1-20" -195 PRINT "THESE NUMBERS ARE THEN ASSIGNED TO TWENTY GIVEN PLAYS." -200 PRINT"A LIST OF NOS. AND THEIR PLAYS IS PROVIDED WITH" -210 PRINT "BOTH TEAMS HAVING THE SAME PLAYS. THE MORE SIMILAR THE" -220 PRINT "PLAYS THE LESS YARDAGE GAINED. SCORES ARE GIVEN" -223 PRINT "WHENEVER SCORES ARE MADE. SCORES MAY ALSO BE OBTAINED" -225 PRINT "BY INPUTTING 99,99 FOR PLAY NOS. TO PUNT OR ATTEMPT A" -227 PRINT "FIELD GOAL, INPUT 77,77 FOR PLAY NUMBERS. QUESTIONS WILL BE" -230 PRINT "ASKED THEN. ON 4TH DOWN, YOU WILL ALSO BE ASKED WHETHER" -240 PRINT "YOU WANT TO PUNT OR ATTEMPT A FIELD GOAL. IF THE ANSWER TO" -250 PRINT "BOTH QUESTIONS IS NO IT WILL BE ASSUMED YOU WANT TO" -260 PRINT "TRY AND GAIN YARDAGE. ANSWER ALL QUESTIONS YES OR NO." -270 PRINT "THE GAME IS PLAYED UNTIL PLAYERS TERMINATE (CONTROL-C)." -280 PRINT "PLEASE PREPARE A TAPE AND RUN.": STOP -290 PRINT:PRINT "PLEASE INPUT SCORE LIMIT ON GAME";:INPUT E -300 FOR I=1 TO 40: READ N: IF I>20 THEN 350 -330 A(N)=I: GOTO 360 -350 B(N)=I-20 -360 C(I)=N: NEXT I -370 FOR I=1 TO 20: READ P$(I): NEXT I -380 L=0: T=1 -410 PRINT "TEAM";T;"PLAY CHART" -420 PRINT "NO. PLAY" -430 FOR I=1 TO 20 -440 REM -450 PRINT C(I+L);TAB(6);P$(I) -460 NEXT I -630 L=L+20:T=2 -640 PRINT -650 PRINT "TEAR OFF HERE----------------------------------------------" -660 FOR X=1 TO 11: PRINT: NEXT X -670 FOR Z=1 TO 3000: NEXT Z -680 IF L=20 THEN 410 -690 D(1)=0: D(2)=3: M$(1)="--->": M$(2)="<---" -700 H(1)=0: H(2)=0: T(1)=2: T(2)=1 -710 W(1)=-1: W(2)=1: X(1)=100: X(2)=0 -720 Y(1)=1: Y(2)=-1: Z(1)=0: Z(2)=100 -725 GOSUB 1910 -730 PRINT "TEAM 1 DEFENDS 0 YD GOAL -- TEAM 2 DEFENDS 100 YD GOAL." -740 T=INT(2*RND(1)+1) -760 PRINT: PRINT "THE COIN IS FLIPPED" -765 P=X(T)-Y(T)*40 -770 GOSUB 1860: PRINT : PRINT "TEAM";T;"RECEIVES KICK-OFF" -780 K=INT(26*RND(1)+40) -790 P=P-Y(T)*K -794 IF W(T)*P"NO" THEN 830 -850 IF W(T)*P1 THEN 900 -895 IF Y(T)*(P+Y(T)*10)>=X(T) THEN 898 -897 C=4: GOTO 900 -898 C=8 -900 IF C=8 THEN 904 -901 PRINT TAB(27);10-(Y(T)*P-Y(T)*S);"YARDS TO 1ST DOWN" -902 GOTO 910 -904 PRINT TAB(27);X(T)-Y(T)*P;"YARDS" -910 GOSUB 1900: IF D=4 THEN 1180 -920 REM -930 U=INT(3*RND(0)-1): GOTO 940 -936 PRINT "ILLEGAL PLAY NUMBER, CHECK AND" -940 PRINT "INPUT OFFENSIVE PLAY, DEFENSIVE PLAY"; -950 IF T=2 THEN 970 -960 INPUT P1,P2: GOTO 975 -970 INPUT P2,P1 -975 IF P1=77 THEN 1180 -980 IF P1>20 THEN 1800 -985 IF P1<1 THEN 1800 -990 IF P2>20 THEN 1800 -992 IF P2<1 THEN 1800 -995 P1=INT(P1): P2=INT(P2) -1000 Y=INT(ABS(A(P1)-B(P2))/19*((X(T)-Y(T)*P+25)*RND(1)-15)) -1005 PRINT: IF T=2 THEN 1015 -1010 IF A(P1)<11 THEN 1048 -1012 GOTO 1020 -1015 IF B(P2)<11 THEN 1048 -1020 IF U<>0 THEN 1035 -1025 PRINT "PASS INCOMPLETE TEAM";T -1030 Y=0: GOTO 1050 -1035 G=RND(1): IF G>.025 THEN 1040 -1037 IF Y>2 THEN 1045 -1040 PRINT "QUARTERBACK SCRAMBLED": GOTO 1050 -1045 PRINT "PASS COMPLETED": GOTO 1050 -1048 PRINT "THE BALL WAS RUN" -1050 P=P-W(T)*Y -1060 PRINT: PRINT "NET YARDS GAINED ON DOWN";D;"ARE ";Y -1070 G=RND(1): IF G>.025 THEN 1110 -1080 PRINT: PRINT "** LOSS OF POSSESSION FROM TEAM";T;"TO TEAM";T(T) -1100 GOSUB 1850: PRINT: T=T(T): GOTO 830 -1110 IF Y(T)*P>=X(T) THEN 1320 -1120 IF W(T)*P>=Z(T) THEN 1230 -1130 IF Y(T)*P-Y(T)*S>=10 THEN 880 -1140 D=D+1: IF D<>5 THEN 885 -1160 PRINT: PRINT "CONVERSION UNSUCCESSFUL TEAM";T:T=T(T) -1170 GOSUB 1850: GOTO 880 -1180 PRINT "DOES TEAM";T;"WANT TO PUNT";: INPUT A$ -1185 IF A$="NO" THEN 1200 -1187 IF A$<>"YES" THEN 1180 -1190 PRINT:PRINT "TEAM";T;"WILL PUNT": G=RND(1): IF G<.025 THEN 1080 -1195 GOSUB 1850: K=INT(25*RND(1)+35): T=T(T): GOTO 790 -1200 PRINT "DOES TEAM";T;"WANT TO ATTEMPT A FIELD GOAL";: INPUT A$ -1210 IF A$="YES" THEN 1640 -1215 IF A$<>"NO" THEN 1200 -1217 GOTO 920 -1230 PRINT: PRINT "SAFETY AGAINST TEAM";T;"**********************OH-OH" -1240 H(T(T))=H(T(T))+2: GOSUB 1810 -1280 PRINT"TEAM";T;"DO YOU WANT TO PUNT INSTEAD OF A KICKOFF";:INPUT A$ -1290 P=Z(T)-W(T)*20: IF A$="YES" THEN 1190 -1320 PRINT: PRINT "TOUCHDOWN BY TEAM";T;"*********************YEA TEAM" -1340 Q=7: G=RND(1): IF G>.1 THEN 1380 -1360 Q=6: PRINT "EXTRA POINT NO GOOD": GOTO 1390 -1380 PRINT "EXTRA POINT GOOD" -1390 H(T)=H(T)+Q: GOSUB 1810 -1420 T=T(T): GOTO 765 -1430 K=INT(9*RND(0)+1) -1440 R=INT(((X(T)-Y(T)*P+25)*RND(1)-15)/K) -1460 P=P-W(T)*R -1480 PRINT:PRINT "RUNBACK TEAM";T;R;"YARDS" -1485 G=RND(1): IF G<.025 THEN 1080 -1490 IF Y(T)*P>=X(T) THEN 1320 -1500 IF W(T)*P>=Z(T) THEN 1230 -1510 GOTO 880 -1640 PRINT: PRINT "TEAM";T;"WILL ATTEMPT A FIELD GOAL" -1645 G=RND(1): IF G<.025 THEN 1080 -1650 F=INT(35*RND(1)+20) -1660 PRINT: PRINT "KICK IS";F;"YARDS LONG" -1680 P=P-W(T)*F: G=RND(1) -1690 IF G<.35 THEN 1735 -1700 IF Y(T)*P99 THEN 936 -1810 PRINT: PRINT "TEAM 1 SCORE IS";H(1) -1820 PRINT "TEAM 2 SCORE IS";H(2): PRINT -1825 IF H(T)=50 THEN 700 -630 LET Y=INT(50*RND(1)^2)+(1-P)*INT(50*RND(1)^4) -640 LET X=X+FNF(1)*Y -650 IF ABS(X-50)>=50 THEN 655 -651 PRINT Y;L$(3);" RUNBACK" -652 GOTO 720 -655 PRINT L$(4); -660 GOTO 2600 -700 PRINT "TOUCHBACK FOR ";O$(P);"." -710 LET X=20+P*60 -720 REM FIRST DOWN -730 GOSUB 800 -740 LET X1=X -750 LET D=1 -760 PRINT:PRINT "FIRST DOWN ";O$(P);"***" -770 PRINT -780 PRINT -790 GOTO 860 -800 REM PRINT POSITION -810 IF X>50 THEN 840 -820 PRINT L$(5);O$(0);X;L$(6) -830 GOTO 850 -840 PRINT L$(5);O$(1);100-X;L$(6) -850 RETURN -860 REM NEW PLAY -870 LET T=T+1 -880 IF T=30 THEN 1060 -890 IF T<50 THEN 940 -900 IF RND(1)>.2 THEN 940 -910 PRINT "END OF GAME ***" -920 PRINT "FINAL SCORE: ";O$(0);": ";S(0);" ";O$(1);": ";S(1) -930 STOP -940 IF P=1 THEN 1870 -950 PRINT "NEXT PLAY"; -960 INPUT Z -970 IF Z<>INT(Z) THEN 990 -980 IF ABS(Z-4)<=3 THEN 1010 -990 PRINT "ILLEGAL PLAY NUMBER, RETYPE"; -1000 GOTO 960 -1010 LET F=0 -1020 PRINT L$(Z+6);". "; -1030 LET R=RND(1)*(.98+FNF(1)*.02) -1040 LET R1=RND(1) -1050 ON Z GOTO 1110,1150,1260,1480,1570,1570,1680 -1060 REM JEAN'S SPECIAL -1070 IF RND(1)> 1/3 THEN 940 -1080 PRINT "GAME DELAYED. DOG ON FIELD." -1090 PRINT -1100 GOTO 940 -1110 REM SIMPLE RUN -1120 LET Y=INT(24*(R-.5)^3+3) -1130 IF RND(1)<.05 THEN 1180 -1140 GOTO 2190 -1150 REM TRICKY RUN -1160 LET Y=INT(20*R-5) -1170 IF RND(1)>.1 THEN 2190 -1180 LET F=-1 -1190 LET X3=X -1200 LET X=X+FNF(1)*Y -1210 IF ABS(X-50)>=50 THEN 1240 -1220 PRINT "*** FUMBLE AFTER "; -1230 GOTO 2230 -1240 PRINT "*** FUMBLE." -1250 GOTO 2450 -1260 REM SHORT PASS -1270 LET Y=INT(60*(R1-.5)^3+10) -1280 IF R<.05 THEN 1330 -1290 IF R<.15 THEN 1390 -1300 IF R<.55 THEN 1420 -1310 PRINT "COMPLETE. "; -1320 GOTO 2190 -1330 IF D=4 THEN 1420 -1340 PRINT "INTERCEPTED." -1350 LET F=-1 -1360 LET X=X+FNF(1)*Y -1370 IF ABS(X-50)>=50 THEN 2450 -1380 GOTO 2300 -1390 PRINT "PASSER TACKLED. "; -1400 LET Y=-INT(10*R1) -1410 GOTO 2190 -1420 LET Y=0 -1430 IF RND(1)<.3 THEN 1460 -1440 PRINT "INCOMPLETE. "; -1450 GOTO 2190 -1460 PRINT "BATTED DOWN. "; -1470 GOTO 2190 -1480 REM LONG PASS -1490 LET Y=INT(160*(R1-.5)^3+30) -1500 IF R<.1 THEN 1330 -1510 IF R<.3 THEN 1540 -1520 IF R<.75 THEN 1420 -1530 GOTO 1310 -1540 PRINT "PASSER TACKLED. "; -1550 LET Y=-INT(15*R1+3) -1560 GOTO 2190 -1570 REM PUNT OR KICK -1580 LET Y=INT(100*(R-.5)^3+35) -1590 IF D=4 THEN 1610 -1600 LET Y=INT(Y*1.3) -1610 PRINT Y;L$(3);" PUNT" -1620 IF ABS(X+Y*FNF(1)-50)>=50 THEN 1670 -1630 IF D<4 THEN 1670 -1640 LET Y1=INT(R1^2*20) -1650 PRINT Y1;L$(3);" RUN BACK" -1660 LET Y=Y-Y1 -1670 GOTO 1350 -1680 REM PLACE KICK -1690 LET Y=INT(100*(R-.5)^3+35) -1700 IF R1>.15 THEN 1750 -1710 PRINT "KICK IS BLOCKED ***" -1720 LET X=X-5*FNF(1) -1730 LET P=1-P -1740 GOTO 720 -1750 LET X=X+FNF(1)*Y -1760 IF ABS(X-50)>=60 THEN 1810 -1770 PRINT "KICK IS SHORT." -1780 IF ABS(X-50)>=50 THEN 2710 -1790 P=1-P -1800 GOTO 630 -1810 IF R1>.5 THEN 1840 -1820 PRINT "KICK IS OFF TO THE SIDE." -1830 GOTO 2710 -1840 PRINT "FIELD GOAL ***" -1850 LET S(P)=S(P)+3 -1860 GOTO 2640 -1870 REM OPPONENT'S PLAY -1880 IF D>1 THEN 1940 -1890 IF RND(1)>1/3 THEN 1920 -1900 LET Z=3 -1910 GOTO 1010 -1920 LET Z=1 -1930 GOTO 1010 -1940 IF D=4 THEN 2090 -1950 IF 10+X-X1<5 THEN 1890 -1960 IF X<5 THEN 1890 -1970 IF X<=10 THEN 2160 -1980 IF X>X1 THEN 2020 -1990 LET A=INT(2*RND(1)) -2000 LET Z=2+A*2 -2010 GOTO 1010 -2020 IF D<3 THEN 1990 -2030 IF X<45 THEN 1990 -2040 IF RND(1)>1/4 THEN 2070 -2050 LET Z=6 -2060 GOTO 1010 -2070 LET Z=4 -2080 GOTO 1010 -2090 IF X>30 THEN 2140 -2100 IF 10+X-X1<3 THEN 1890 -2110 IF X<3 THEN 1890 -2120 LET Z=7 -2130 GOTO 1010 -2140 LET Z=5 -2150 GOTO 1010 -2160 LET A=INT(2*RND(1)) -2170 LET Z=2+A -2180 GOTO 1010 -2190 REM GAIN OR LOSS -2200 LET X3=X -2210 LET X=X+FNF(1)*Y -2220 IF ABS(X-50)>=50 THEN 2450 -2230 IF Y=0 THEN 2250 -2240 PRINT ABS(Y);L$(3); -2250 PRINT L$(15+SGN(Y)) -2280 IF ABS(X3-50)>40 THEN 2300 -2290 IF RND(1)<.1 THEN 2860 -2300 GOSUB 800 -2310 IF F=0 THEN 2340 -2320 LET P=1-P -2330 GOTO 740 -2340 IF FNG(1)>=10 THEN 740 -2350 IF D=4 THEN 2320 -2360 LET D=D+1 -2370 PRINT "DOWN: ";D;" "; -2380 IF (X1-50)*FNF(1)<40 THEN 2410 -2390 PRINT "GOAL TO GO" -2400 GOTO 2420 -2410 PRINT "YARDS TO GO: ";10-FNG(1) -2420 PRINT -2430 PRINT -2440 GOTO 860 -2450 REM BALL IN END-ZONE -2460 IF X>=100 THEN 2490 -2470 LET E=0 -2480 GOTO 2500 -2490 LET E=1 -2500 ON 1+E-F*2+P*4 GOTO 2510,2590,2760,2710,2590,2510,2710,2760 -2510 REM SAFETY -2520 LET S(1-P)=S(1-P)+2 -2530 PRINT L$(19) -2540 GOSUB 2800 -2550 PRINT O$(P);" KICKS OFF FROM ITS 20 YARD LINE." -2560 LET X=20+P*60 -2570 LET P=1-P -2580 GOTO 590 -2590 REM OFFENSIVE TD -2600 PRINT L$(17);"***" -2610 IF RND(1)>.8 THEN 2680 -2620 LET S(P)=S(P)+7 -2630 PRINT "KICK IS GOOD." -2640 GOSUB 2800 -2650 PRINT O$(P);" KICKS OFF" -2660 LET P=1-P -2670 GOTO 580 -2680 PRINT "KICK IS OFF TO THE SIDE" -2690 LET S(P)=S(P)+6 -2700 GOTO 2640 -2710 REM TOUCHBACK -2720 PRINT L$(18) -2730 LET P=1-P -2740 LET X=20+P*60 -2750 GOTO 720 -2760 REM DEFENSIVE TD -2770 PRINT L$(17);"FOR ";O$(1-P);"***" -2780 LET P=1-P -2790 GOTO 2600 -2800 REM SCORE -2810 PRINT -2820 PRINT "SCORE: ";S(0);" TO ";S(1) -2830 PRINT -2840 PRINT -2850 RETURN -2860 REM PENALTY -2870 LET P3=INT(2*RND(1)) -2880 PRINT O$(P3);" OFFSIDES -- PENALTY OF 5 YARDS." -2890 PRINT -2900 PRINT -2910 IF P3=0 THEN 2980 -2920 PRINT "DO YOU ACCEPT THE PENALTY"; -2930 INPUT A$ -2940 IF A$="NO" THEN 2300 -2950 IF A$="YES" THEN 3110 -2960 PRINT "TYPE 'YES' OR 'NO'"; -2970 GOTO 2930 -2980 REM OPPONENT'S STRATEGY ON PENALTY -2990 IF P=1 THEN 3040 -3000 IF Y<=0 THEN 3080 -3010 IF F<0 THEN 3080 -3020 IF FNG(1)<3*D-2 THEN 3080 -3030 GOTO 3100 -3040 IF Y<=5 THEN 3100 -3050 IF F<0 THEN 3100 -3060 IF D<4 THEN 3080 -3070 IF FNG(1)<10 THEN 3100 -3080 PRINT "PENALTY REFUSED." -3090 GOTO 2300 -3100 PRINT "PENALTY ACCEPTED." -3110 LET F=0 -3120 LET D=D-1 -3130 IF P<>P3 THEN 3160 -3140 LET X=X3-FNF(1)*5 -3150 GOTO 2300 -3160 LET X=X3+FNF(1)*5 -3170 GOTO 2300 -3180 END diff --git a/00_Alternate_Languages/38_Fur_Trader/MiniScript/README.md b/00_Alternate_Languages/38_Fur_Trader/MiniScript/README.md deleted file mode 100644 index 3b15b9926..000000000 --- a/00_Alternate_Languages/38_Fur_Trader/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript furtrader.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "furtrader" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/38_Fur_Trader/MiniScript/furtrader.ms b/00_Alternate_Languages/38_Fur_Trader/MiniScript/furtrader.ms deleted file mode 100644 index 6fb85e1a2..000000000 --- a/00_Alternate_Languages/38_Fur_Trader/MiniScript/furtrader.ms +++ /dev/null @@ -1,171 +0,0 @@ -print " "*31 + "Fur Trader" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print - -furs = [0,0,0,0] // how many of each type of fur you have -value = [0,0,0,0] // value of each type of fur -furNames = "mink beaver ermine fox".split - -getYesNo = function - while true - ans = input("Answer yes or no: ").upper - if not ans then continue - if ans[0] == "Y" then return "YES" - if ans[0] == "N" then return "NO" - end while -end function - -printInstructions = function - print "You are the leader of a French fur trading expedition in " - print "1776 leaving the Lake Ontario area to sell furs and get" - print "supplies for the next year. You have a choice of three" - print "forts at which you may trade. The cost of supplies" - print "and the amount you receive for your furs will depend" - print "on the fort that you choose." - print -end function - -pickFort = function - print - while true - print "You may trade your furs at fort 1, fort 2," - print "or fort 3. Fort 1 is Fort Hochelaga (Montreal)" - print "and is under the protection of the French army." - print "Fort 2 is Fort Stadacona (Quebec) and is under the" - print "protection of the French Army. However, you must" - print "make a portage and cross the Lachine rapids." - print "Fort 3 is Fort New York and is under Dutch control." - print "You must cross through Iroquois land." - b = input("Answer 1, 2, or 3: ").val - if b == 1 then - print "You have chosen the easiest route. However, the fort" - print "is far from any seaport. The value" - print "you receive for your furs will be low and the cost" - print "of supplies higher than at Forts Stadacona or New York." - else if b == 2 then - print "You have chosen a hard route. It is, in comparsion," - print "harder than the route to Hochelaga but easier than" - print "the route to New York. You will receive an average value" - print "for your furs and the cost of your supplies will be average." - else if b == 3 then - print "You have chosen the most difficult route. At" - print "Fort New York you will receive the highest value" - print "for your furs. The cost of your supplies" - print "will be lower than at all the other forts." - else - continue - end if - print "Do you want to trade at another fort?" - if getYesNo == "NO" then return b - end while -end function - -visitFort = function(fort) - print - if fort == 1 then - value[0] = floor((.2*rnd+.7)*100+.5)/100 - value[2] = floor((.2*rnd+.65)*100+.5)/100 - value[1] = floor((.2*rnd+.75)*100+.5)/100 - value[3] = floor((.2*rnd+.8)*100+.5)/100 - print "Supplies at Fort Hochelaga cost $150.00." - print "Your travel expenses to Hochelaga were $10.00." - globals.money -= 150 + 10 - else if fort == 2 then - value[0] = floor((.3*rnd+.85)*100+.5)/100 - value[2] = floor((.15*rnd+.8)*100+.5)/100 - value[1] = floor((.2*rnd+.9)*100+.5)/100 - p = floor(10*rnd)+1 - if p <= 2 then - furs[1] = 0 - print "Your beaver were too heavy to carry across" - print "the portage. You had to leave the pelts, but found" - print "them stolen when you returned." - else if p <= 6 then - print "You arrived safely at Fort Stadacona." - else if p <= 8 then - for j in range(0,3); furs[j] = 0; end for - print "Your canoe upset in the Lachine rapids. You" - print "lost all your furs." - else if furs[3] then - furs[3] = 0 - print "Your fox pelts were not cured properly." - print "No one will buy them." - end if - print "Supplies at Fort Stadacona cost $125.00." - print "Your travel expenses to Stadacona were $15.00." - globals.money -= 125 + 15 - else - value[0] = floor((.15*rnd+1.05)*100+.5)/100 - value[3] = floor((.25*rnd+1.1)*100+.5)/100 - p = floor(10*rnd)+1 - if p <= 2 then - print "You were attacked by a party of Iroquois." - print "All people in your trading group were" - print "killed. This ends the game." - globals.gameOver = true - return - else if p<=6 then - print "You were lucky. You arrived safely" - print "at Fort New York." - else if p<=8 then - for j in range(0,3); furs[j] = 0; end for - print "You narrowly escaped an iroquois raiding party." - print "However, you had to leave all your furs behind." - else - value[1] /= 2 - value[0] /= 2 - print "Your mink and beaver were damaged on your trip." - print "You receive only half the current price for these furs." - end if - print "Supplies at New York cost $80.00." - print "Your travel expenses to New York were $25.00." - globals.money -= 80 + 25 - end if -end function - -printInstructions - -gameOver = false -money=600 -while not gameOver - print "Do you wish to trade furs?" - if getYesNo == "NO" then break - - value[2]=floor((.15*rnd+.95)*100+.5)/100 // ermine value - value[1]=floor((.25*rnd+1.00)*100+.5)/100 // beaver value - - print - print "You have $" + money + " savings." - print "And 190 furs to begin the expedition." - print - print "Your 190 furs are distributed among the following" - print "kinds of pelts: mink, beaver, ermine and fox." - print - furs = [0,0,0,0] - for j in range(0, 3) - furs[j] = input("How many " + furNames[j] + " do you have? ").val - if furs.sum >= 190 then break - end for - if furs.sum > 190 then - print "You may not have that many furs." - print "Do not try to cheat. I can add." - print "You must start again." - continue - end if - - fort = pickFort - visitFort fort - if gameOver then break - - print - for j in [1, 3, 2, 0] - if not furs[j] then continue - revenue = value[j] * furs[j] - print "Your " + furNames[j] + " sold for $" + revenue + "." - money += revenue - end for - print - print "You now have $" + money + " including your previous savings." -end while - - diff --git a/00_Alternate_Languages/38_Fur_Trader/README.md b/00_Alternate_Languages/38_Fur_Trader/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/38_Fur_Trader/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/38_Fur_Trader/c/README.md b/00_Alternate_Languages/38_Fur_Trader/c/README.md deleted file mode 100644 index cb9833d5a..000000000 --- a/00_Alternate_Languages/38_Fur_Trader/c/README.md +++ /dev/null @@ -1,22 +0,0 @@ -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) - -Conversion to [ANSI-C](https://en.wikipedia.org/wiki/ANSI_C) - -##### Translator Notes: -I tried to preserve as much of the original layout and flow of the code -as possible. However I did use enumerated types for the Fort numbers -and Fur types. I think this was certainly a change for the better, and -makes the code much easier to read. - -I also tried to minimise the use of pointers, and stuck with old-school -C formatting, because you never know how old the compiler is. - -Interestingly the code seems to have a bug around the prices of Fox Furs. -The commodity-rate for these is stored in the variable `D1`, however some -paths through the code do not set this price. So there was a chance of -using this uninitialised, or whatever the previous loop set. I don't -think this was the original authors intent. So I preserved the original flow -of the code (using the previous `D1` value), but also catching the -uninitialised path, and assigning a "best guess" value. - -krt@krt.com.au 2020-10-10 diff --git a/00_Alternate_Languages/38_Fur_Trader/c/furtrader.c b/00_Alternate_Languages/38_Fur_Trader/c/furtrader.c deleted file mode 100644 index 8735e08f0..000000000 --- a/00_Alternate_Languages/38_Fur_Trader/c/furtrader.c +++ /dev/null @@ -1,474 +0,0 @@ - -/* - * Ported from furtrader.bas to ANSI C (C99) by krt@krt.com.au - * - * compile with: - * gcc -g -Wall -Werror furtrader.c -o furtrader - */ - -#include -#include -#include -#include - - -/* Constants */ -#define FUR_TYPE_COUNT 4 -#define FUR_MINK 0 -#define FUR_BEAVER 1 -#define FUR_ERMINE 2 -#define FUR_FOX 3 -#define MAX_FURS 190 -const char *FUR_NAMES[FUR_TYPE_COUNT] = { "MINK", "BEAVER", "ERMINE", "FOX" }; - -#define FORT_TYPE_COUNT 3 -#define FORT_MONTREAL 1 -#define FORT_QUEBEC 2 -#define FORT_NEWYORK 3 -const char *FORT_NAMES[FORT_TYPE_COUNT] = { "HOCHELAGA (MONTREAL)", "STADACONA (QUEBEC)", "NEW YORK" }; - - - -/* Print the words at the specified column */ -void printAtColumn( int column, const char *words ) -{ - int i; - for ( i=0; i> " ); /* prompt the user */ - fgets( buffer, sizeof( buffer ), stdin ); /* read from the console into the buffer */ - result = (int)strtol( buffer, &endstr, 10 ); /* only simple error checking */ - - if ( endstr == buffer ) /* was the string -> integer ok? */ - result = -1; - } - - return result; -} - - -/* - * Prompt the user for YES/NO input. - * When input is given, try to work out if it's YES, Yes, yes, Y, etc. - * And convert to a single upper-case letter - * Returns a character of 'Y' or 'N'. - */ -char getYesOrNo() -{ - char result = '!'; - char buffer[64]; /* somewhere to store user input */ - - while ( !( result == 'Y' || result == 'N' ) ) /* While the answer was not Yes or No */ - { - print( "ANSWER YES OR NO" ); - printf( ">> " ); - - fgets( buffer, sizeof( buffer ), stdin ); /* read from the console into the buffer */ - if ( buffer[0] == 'Y' || buffer[0] == 'y' ) - result = 'Y'; - else if ( buffer[0] == 'N' || buffer[0] == 'n' ) - result = 'N'; - } - - return result; -} - - - -/* - * Show the player the choices of Fort, get their input, if the - * input is a valid choice (1,2,3) return it, otherwise keep - * prompting the user. - */ -int getFortChoice() -{ - int result = 0; - - while ( result == 0 ) - { - print( "" ); - print( "YOU MAY TRADE YOUR FURS AT FORT 1, FORT 2," ); - print( "OR FORT 3. FORT 1 IS FORT HOCHELAGA (MONTREAL)" ); - print( "AND IS UNDER THE PROTECTION OF THE FRENCH ARMY." ); - print( "FORT 2 IS FORT STADACONA (QUEBEC) AND IS UNDER THE" ); - print( "PROTECTION OF THE FRENCH ARMY. HOWEVER, YOU MUST" ); - print( "MAKE A PORTAGE AND CROSS THE LACHINE RAPIDS." ); - print( "FORT 3 IS FORT NEW YORK AND IS UNDER DUTCH CONTROL." ); - print( "YOU MUST CROSS THROUGH IROQUOIS LAND." ); - print( "ANSWER 1, 2, OR 3." ); - - result = getNumericInput(); /* get input from the player */ - } - - return result; -} - - -/* - * Print the description for the fort - */ -void showFortComment( int which_fort ) -{ - print( "" ); - if ( which_fort == FORT_MONTREAL ) - { - print( "YOU HAVE CHOSEN THE EASIEST ROUTE. HOWEVER, THE FORT" ); - print( "IS FAR FROM ANY SEAPORT. THE VALUE" ); - print( "YOU RECEIVE FOR YOUR FURS WILL BE LOW AND THE COST" ); - print( "OF SUPPLIES HIGHER THAN AT FORTS STADACONA OR NEW YORK." ); - } - else if ( which_fort == FORT_QUEBEC ) - { - print( "YOU HAVE CHOSEN A HARD ROUTE. IT IS, IN COMPARSION," ); - print( "HARDER THAN THE ROUTE TO HOCHELAGA BUT EASIER THAN" ); - print( "THE ROUTE TO NEW YORK. YOU WILL RECEIVE AN AVERAGE VALUE" ); - print( "FOR YOUR FURS AND THE COST OF YOUR SUPPLIES WILL BE AVERAGE." ); - } - else if ( which_fort == FORT_NEWYORK ) - { - print( "YOU HAVE CHOSEN THE MOST DIFFICULT ROUTE. AT" ); - print( "FORT NEW YORK YOU WILL RECEIVE THE HIGHEST VALUE" ); - print( "FOR YOUR FURS. THE COST OF YOUR SUPPLIES" ); - print( "WILL BE LOWER THAN AT ALL THE OTHER FORTS." ); - } - else - { - printf( "Internal error #1, fort %d does not exist\n", which_fort ); - exit( 1 ); /* you have a bug */ - } - print( "" ); -} - - -/* - * Prompt the player for how many of each fur type they want. - * Accept numeric inputs, re-prompting on incorrect input values - */ -void getFursPurchase( int *furs ) -{ - int i; - - printf( "YOUR %d FURS ARE DISTRIBUTED AMONG THE FOLLOWING\n", FUR_TYPE_COUNT ); - print( "KINDS OF PELTS: MINK, BEAVER, ERMINE AND FOX." ); - print( "" ); - - for ( i=0; i MAX_FURS ) - { - print( "" ); - print( "YOU MAY NOT HAVE THAT MANY FURS." ); - print( "DO NOT TRY TO CHEAT. I CAN ADD." ); - print( "YOU MUST START AGAIN." ); - print( "" ); - game_state = STATE_STARTING; /* T/N: Wow, harsh. */ - } - else - { - game_state = STATE_CHOOSING_FORT; - } - } - - else if ( game_state == STATE_CHOOSING_FORT ) - { - which_fort = getFortChoice(); - showFortComment( which_fort ); - print( "DO YOU WANT TO TRADE AT ANOTHER FORT?" ); - yes_or_no = getYesOrNo(); - if ( yes_or_no == 'N' ) - game_state = STATE_TRAVELLING; - } - - else if ( game_state == STATE_TRAVELLING ) - { - print( "" ); - if ( which_fort == FORT_MONTREAL ) - { - mink_price = ( ( 0.2 * randFloat() + 0.70 ) * 100 + 0.5 ) / 100; - ermine_price = ( ( 0.2 * randFloat() + 0.65 ) * 100 + 0.5 ) / 100; - beaver_price = ( ( 0.2 * randFloat() + 0.75 ) * 100 + 0.5 ) / 100; - fox_price = ( ( 0.2 * randFloat() + 0.80 ) * 100 + 0.5 ) / 100; - - print( "SUPPLIES AT FORT HOCHELAGA COST $150.00." ); - print( "YOUR TRAVEL EXPENSES TO HOCHELAGA WERE $10.00." ); - player_funds -= 160; - } - - else if ( which_fort == FORT_QUEBEC ) - { - mink_price = ( ( 0.30 * randFloat() + 0.85 ) * 100 + 0.5 ) / 100; - ermine_price = ( ( 0.15 * randFloat() + 0.80 ) * 100 + 0.5 ) / 100; - beaver_price = ( ( 0.20 * randFloat() + 0.90 ) * 100 + 0.5 ) / 100; - fox_price = ( ( 0.25 * randFloat() + 1.10 ) * 100 + 0.5 ) / 100; - event_picker = ( 10 * randFloat() ) + 1; - - if ( event_picker <= 2 ) - { - print( "YOUR BEAVER WERE TOO HEAVY TO CARRY ACROSS" ); - print( "THE PORTAGE. YOU HAD TO LEAVE THE PELTS, BUT FOUND" ); - print( "THEM STOLEN WHEN YOU RETURNED." ); - player_furs[ FUR_BEAVER ] = 0; - } - else if ( event_picker <= 6 ) - { - print( "YOU ARRIVED SAFELY AT FORT STADACONA." ); - } - else if ( event_picker <= 8 ) - { - print( "YOUR CANOE UPSET IN THE LACHINE RAPIDS. YOU" ); - print( "LOST ALL YOUR FURS." ); - zeroInventory( player_furs ); - } - else if ( event_picker <= 10 ) - { - print( "YOUR FOX PELTS WERE NOT CURED PROPERLY." ); - print( "NO ONE WILL BUY THEM." ); - player_furs[ FUR_FOX ] = 0; - } - else - { - printf( "Internal Error #3, Out-of-bounds event_picker %d\n", event_picker ); - exit( 1 ); /* you have a bug */ - } - - print( "" ); - print( "SUPPLIES AT FORT STADACONA COST $125.00." ); - print( "YOUR TRAVEL EXPENSES TO STADACONA WERE $15.00." ); - player_funds -= 140; - } - - else if ( which_fort == FORT_NEWYORK ) - { - mink_price = ( ( 0.15 * randFloat() + 1.05 ) * 100 + 0.5 ) / 100; - ermine_price = ( ( 0.15 * randFloat() + 0.95 ) * 100 + 0.5 ) / 100; - beaver_price = ( ( 0.25 * randFloat() + 1.00 ) * 100 + 0.5 ) / 100; - if ( fox_price < 0 ) - { - /* Original Bug? There is no Fox price generated for New York, - it will use any previous "D1" price. - So if there was no previous value, make one up */ - fox_price = ( ( 0.25 * randFloat() + 1.05 ) * 100 + 0.5 ) / 100; /* not in orginal code */ - } - event_picker = ( 10 * randFloat() ) + 1; - - if ( event_picker <= 2 ) - { - print( "YOU WERE ATTACKED BY A PARTY OF IROQUOIS." ); - print( "ALL PEOPLE IN YOUR TRADING GROUP WERE" ); - print( "KILLED. THIS ENDS THE GAME." ); - exit( 0 ); - } - else if ( event_picker <= 6 ) - { - print( "YOU WERE LUCKY. YOU ARRIVED SAFELY" ); - print( "AT FORT NEW YORK." ); - } - else if ( event_picker <= 8 ) - { - print( "YOU NARROWLY ESCAPED AN IROQUOIS RAIDING PARTY." ); - print( "HOWEVER, YOU HAD TO LEAVE ALL YOUR FURS BEHIND." ); - zeroInventory( player_furs ); - } - else if ( event_picker <= 10 ) - { - mink_price /= 2; - fox_price /= 2; - print( "YOUR MINK AND BEAVER WERE DAMAGED ON YOUR TRIP." ); - print( "YOU RECEIVE ONLY HALF THE CURRENT PRICE FOR THESE FURS." ); - } - else - { - print( "Internal Error #4, Out-of-bounds event_picker %d\n" ); - exit( 1 ); /* you have a bug */ - } - - print( "" ); - print( "SUPPLIES AT NEW YORK COST $85.00." ); - print( "YOUR TRAVEL EXPENSES TO NEW YORK WERE $25.00." ); - player_funds -= 105; - } - - else - { - printf( "Internal error #2, fort %d does not exist\n", which_fort ); - exit( 1 ); /* you have a bug */ - } - - /* Calculate sales */ - beaver_value = beaver_price * player_furs[ FUR_BEAVER ]; - fox_value = fox_price * player_furs[ FUR_FOX ]; - ermine_value = ermine_price * player_furs[ FUR_ERMINE ]; - mink_value = mink_price * player_furs[ FUR_MINK ]; - - print( "" ); - printf( "YOUR BEAVER SOLD FOR $%6.2f\n", beaver_value ); - printf( "YOUR FOX SOLD FOR $%6.2f\n", fox_value ); - printf( "YOUR ERMINE SOLD FOR $%6.2f\n", ermine_value ); - printf( "YOUR MINK SOLD FOR $%6.2f\n", mink_value ); - - player_funds += beaver_value + fox_value + ermine_value + mink_value; - - print( "" ); - printf( "YOU NOW HAVE $ %1.2f INCLUDING YOUR PREVIOUS SAVINGS\n", player_funds ); - - print( "" ); - print( "DO YOU WANT TO TRADE FURS NEXT YEAR?" ); - yes_or_no = getYesOrNo(); - if ( yes_or_no == 'N' ) - exit( 0 ); /* STOP */ - else - game_state = STATE_TRADING; - - } - } - - return 0; /* exit OK */ -} diff --git a/00_Alternate_Languages/38_Fur_Trader/furtrader.bas b/00_Alternate_Languages/38_Fur_Trader/furtrader.bas deleted file mode 100644 index 9a379b2c1..000000000 --- a/00_Alternate_Languages/38_Fur_Trader/furtrader.bas +++ /dev/null @@ -1,170 +0,0 @@ -1 DIM F(4) -2 PRINT TAB(31);"FUR TRADER" -4 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -6 PRINT: PRINT: PRINT -15 GOSUB 1091 -16 LET I=600 -17 PRINT "DO YOU WISH TO TRADE FURS?" -18 GOSUB 1402 -19 IF B$="YES" THEN 100 -20 IF B$="YES " THEN 100 -21 STOP -100 PRINT -101 PRINT "YOU HAVE $";I " SAVINGS." -102 PRINT "AND 190 FURS TO BEGIN THE EXPEDITION." -261 LET E1=INT((.15*RND(1)+.95)*10^2+.5)/10^2 -262 LET B1=INT((.25*RND(1)+1.00)*10^2+.5)/10^2 -300 PRINT -301 PRINT "YOUR 190 FURS ARE DISTRIBUTED AMONG THE FOLLOWING" -302 PRINT "KINDS OF PELTS: MINK, BEAVER, ERMINE AND FOX." -310 GOSUB 1430 -315 RESTORE -330 FOR J=1 TO 4 -332 READ B$ -333 PRINT -335 PRINT "HOW MANY ";B$;" PELTS DO YOU HAVE"; -338 INPUT F(J) -340 LET F(0)=F(1)+F(2)+F(3)+F(4) -342 IF F(0)=190 THEN 1100 -344 IF F(0)>190 THEN 500 -348 NEXT J -350 GOTO 1100 -500 PRINT -501 PRINT "YOU MAY NOT HAVE THAT MANY FURS." -502 PRINT "DO NOT TRY TO CHEAT. I CAN ADD." -503 PRINT "YOU MUST START AGAIN." -504 GOTO 15 -508 PRINT -511 PRINT "DO YOU WANT TO TRADE FURS NEXT YEAR?" -513 GOTO 18 -1091 PRINT "YOU ARE THE LEADER OF A FRENCH FUR TRADING EXPEDITION IN " -1092 PRINT "1776 LEAVING THE LAKE ONTARIO AREA TO SELL FURS AND GET" -1093 PRINT "SUPPLIES FOR THE NEXT YEAR. YOU HAVE A CHOICE OF THREE" -1094 PRINT "FORTS AT WHICH YOU MAY TRADE. THE COST OF SUPPLIES" -1095 PRINT "AND THE AMOUNT YOU RECEIVE FOR YOUR FURS WILL DEPEND" -1096 PRINT "ON THE FORT THAT YOU CHOOSE." -1099 RETURN -1100 PRINT "YOU MAY TRADE YOUR FURS AT FORT 1, FORT 2," -1102 PRINT "OR FORT 3. FORT 1 IS FORT HOCHELAGA (MONTREAL)" -1103 PRINT "AND IS UNDER THE PROTECTION OF THE FRENCH ARMY." -1104 PRINT "FORT 2 IS FORT STADACONA (QUEBEC) AND IS UNDER THE" -1105 PRINT "PROTECTION OF THE FRENCH ARMY. HOWEVER, YOU MUST" -1106 PRINT "MAKE A PORTAGE AND CROSS THE LACHINE RAPIDS." -1108 PRINT "FORT 3 IS FORT NEW YORK AND IS UNDER DUTCH CONTROL." -1109 PRINT "YOU MUST CROSS THROUGH IROQUOIS LAND." -1110 PRINT "ANSWER 1, 2, OR 3." -1111 INPUT B -1112 IF B=1 THEN 1120 -1113 IF B=2 THEN 1135 -1115 IF B=3 THEN 1147 -1116 GOTO 1110 -1120 PRINT "YOU HAVE CHOSEN THE EASIEST ROUTE. HOWEVER, THE FORT" -1121 PRINT "IS FAR FROM ANY SEAPORT. THE VALUE" -1122 PRINT "YOU RECEIVE FOR YOUR FURS WILL BE LOW AND THE COST" -1123 PRINT "OF SUPPLIES HIGHER THAN AT FORTS STADACONA OR NEW YORK." -1125 GOSUB 1400 -1129 IF B$="YES" THEN 1110 -1130 GOTO 1160 -1135 PRINT "YOU HAVE CHOSEN A HARD ROUTE. IT IS, IN COMPARSION," -1136 PRINT "HARDER THAN THE ROUTE TO HOCHELAGA BUT EASIER THAN" -1137 PRINT "THE ROUTE TO NEW YORK. YOU WILL RECEIVE AN AVERAGE VALUE" -1138 PRINT "FOR YOUR FURS AND THE COST OF YOUR SUPPLIES WILL BE AVERAGE." -1141 GOSUB 1400 -1144 IF B$="YES" THEN 1110 -1145 GOTO 1198 -1147 PRINT "YOU HAVE CHOSEN THE MOST DIFFICULT ROUTE. AT" -1148 PRINT "FORT NEW YORK YOU WILL RECEIVE THE HIGHEST VALUE" -1149 PRINT "FOR YOUR FURS. THE COST OF YOUR SUPPLIES" -1150 PRINT "WILL BE LOWER THAN AT ALL THE OTHER FORTS." -1152 GOSUB 1400 -1155 IF B$="YES" THEN 1110 -1156 GOTO 1250 -1160 LET I=I-160 -1169 PRINT -1174 LET M1=INT((.2*RND(1)+.7)*10^2+.5)/10^2 -1175 LET E1=INT((.2*RND(1)+.65)*10^2+.5)/10^2 -1176 LET B1=INT((.2*RND(1)+.75)*10^2+.5)/10^2 -1177 LET D1=INT((.2*RND(1)+.8)*10^2+.5)/10^2 -1180 PRINT "SUPPLIES AT FORT HOCHELAGA COST $150.00." -1181 PRINT "YOUR TRAVEL EXPENSES TO HOCHELAGA WERE $10.00." -1190 GOTO 1410 -1198 LET I=I-140 -1201 PRINT -1205 LET M1=INT((.3*RND(1)+.85)*10^2+.5)/10^2 -1206 LET E1=INT((.15*RND(1)+.8)*10^2+.5)/10^2 -1207 LET B1=INT((.2*RND(1)+.9)*10^2+.5)/10^2 -1209 LET P=INT(10*RND(1))+1 -1210 IF P<=2 THEN 1216 -1212 IF P<=6 THEN 1224 -1213 IF P<=8 THEN 1226 -1215 IF P<=10 THEN 1235 -1216 LET F(2)=0 -1218 PRINT "YOUR BEAVER WERE TOO HEAVY TO CARRY ACROSS" -1219 PRINT "THE PORTAGE. YOU HAD TO LEAVE THE PELTS, BUT FOUND" -1220 PRINT "THEM STOLEN WHEN YOU RETURNED." -1221 GOSUB 1244 -1222 GOTO 1414 -1224 PRINT "YOU ARRIVED SAFELY AT FORT STADACONA." -1225 GOTO 1239 -1226 GOSUB 1430 -1230 PRINT "YOUR CANOE UPSET IN THE LACHINE RAPIDS. YOU" -1231 PRINT "LOST ALL YOUR FURS." -1232 GOSUB 1244 -1233 GOTO 1418 -1235 LET F(4)=0 -1237 PRINT "YOUR FOX PELTS WERE NOT CURED PROPERLY." -1238 PRINT "NO ONE WILL BUY THEM." -1239 GOSUB 1244 -1240 GOTO 1410 -1244 PRINT "SUPPLIES AT FORT STADACONA COST $125.00." -1246 PRINT "YOUR TRAVEL EXPENSES TO STADACONA WERE $15.00." -1248 RETURN -1250 LET I=I-105 -1254 PRINT -1260 LET M1=INT((.15*RND(1)+1.05)*10^2+.5)/10^2 -1263 LET D1=INT((.25*RND(1)+1.1)*10^2+.5)/10^2 -1270 LET P=INT(10*RND(1))+1 -1271 IF P<=2 THEN 1281 -1272 IF P<=6 THEN 1291 -1273 IF P<=8 THEN 1295 -1274 IF P<=10 THEN 1306 -1281 PRINT "YOU WERE ATTACKED BY A PARTY OF IROQUOIS." -1282 PRINT "ALL PEOPLE IN YOUR TRADING GROUP WERE" -1283 PRINT "KILLED. THIS ENDS THE GAME." -1284 STOP -1291 PRINT "YOU WERE LUCKY. YOU ARRIVED SAFELY" -1292 PRINT "AT FORT NEW YORK." -1293 GOTO 1311 -1295 GOSUB 1430 -1300 PRINT "YOU NARROWLY ESCAPED AN IROQUOIS RAIDING PARTY." -1301 PRINT "HOWEVER, YOU HAD TO LEAVE ALL YOUR FURS BEHIND." -1303 GOSUB 1320 -1304 GOTO 1418 -1306 LET B1=B1/2 -1307 LET M1=M1/2 -1308 PRINT "YOUR MINK AND BEAVER WERE DAMAGED ON YOUR TRIP." -1309 PRINT "YOU RECEIVE ONLY HALF THE CURRENT PRICE FOR THESE FURS." -1311 GOSUB 1320 -1312 GOTO 1410 -1320 PRINT "SUPPLIES AT NEW YORK COST $80.00." -1321 PRINT "YOUR TRAVEL EXPENSES TO NEW YORK WERE $25.00." -1322 RETURN -1400 PRINT "DO YOU WANT TO TRADE AT ANOTHER FORT?" -1402 PRINT "ANSWER YES OR NO", -1403 INPUT B$ -1404 RETURN -1410 PRINT -1412 PRINT "YOUR BEAVER SOLD FOR $";B1*F(2); -1414 PRINT "YOUR FOX SOLD FOR $";D1*F(4) -1416 PRINT "YOUR ERMINE SOLD FOR $";E1*F(3); -1417 PRINT "YOUR MINK SOLD FOR $";M1*F(1) -1418 LET I=M1*F(1)+B1*F(2)+E1*F(3)+D1*F(4)+I -1420 PRINT -1422 PRINT "YOU NOW HAVE $";I;" INCLUDING YOUR PREVIOUS SAVINGS" -1425 GOTO 508 -1430 FOR J=1 TO 4 -1432 LET F(J)=0 -1434 NEXT J -1436 RETURN -2000 DATA "MINK","BEAVER","ERMINE","FOX" -2046 END diff --git a/00_Alternate_Languages/38_Fur_Trader/go/main.go b/00_Alternate_Languages/38_Fur_Trader/go/main.go deleted file mode 100644 index 642d48f06..000000000 --- a/00_Alternate_Languages/38_Fur_Trader/go/main.go +++ /dev/null @@ -1,326 +0,0 @@ -package main - -import ( - "bufio" - "fmt" - "log" - "math/rand" - "os" - "strconv" - "strings" - "time" -) - -const ( - MAXFURS = 190 - STARTFUNDS = 600 -) - -type Fur int8 - -const ( - FUR_MINK Fur = iota - FUR_BEAVER - FUR_ERMINE - FUR_FOX -) - -type Fort int8 - -const ( - FORT_MONTREAL Fort = iota - FORT_QUEBEC - FORT_NEWYORK -) - -type GameState int8 - -const ( - STARTING GameState = iota - TRADING - CHOOSINGFORT - TRAVELLING -) - -func FURS() []string { - return []string{"MINK", "BEAVER", "ERMINE", "FOX"} -} - -func FORTS() []string { - return []string{"HOCHELAGA (MONTREAL)", "STADACONA (QUEBEC)", "NEW YORK"} -} - -type Player struct { - funds float32 - furs []int -} - -func NewPlayer() Player { - p := Player{} - p.funds = STARTFUNDS - p.furs = make([]int, 4) - return p -} - -func (p *Player) totalFurs() int { - f := 0 - for _, v := range p.furs { - f += v - } - return f -} - -func (p *Player) lostFurs() { - for f := 0; f < len(p.furs); f++ { - p.furs[f] = 0 - } -} - -func printTitle() { - fmt.Println(" FUR TRADER") - fmt.Println(" CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") - fmt.Println() - fmt.Println() - fmt.Println() -} - -func printIntro() { - fmt.Println("YOU ARE THE LEADER OF A FRENCH FUR TRADING EXPEDITION IN ") - fmt.Println("1776 LEAVING THE LAKE ONTARIO AREA TO SELL FURS AND GET") - fmt.Println("SUPPLIES FOR THE NEXT YEAR. YOU HAVE A CHOICE OF THREE") - fmt.Println("FORTS AT WHICH YOU MAY TRADE. THE COST OF SUPPLIES") - fmt.Println("AND THE AMOUNT YOU RECEIVE FOR YOUR FURS WILL DEPEND") - fmt.Println("ON THE FORT THAT YOU CHOOSE.") - fmt.Println() -} - -func getFortChoice() Fort { - scanner := bufio.NewScanner(os.Stdin) - - for { - fmt.Println() - fmt.Println("YOU MAY TRADE YOUR FURS AT FORT 1, FORT 2,") - fmt.Println("OR FORT 3. FORT 1 IS FORT HOCHELAGA (MONTREAL)") - fmt.Println("AND IS UNDER THE PROTECTION OF THE FRENCH ARMY.") - fmt.Println("FORT 2 IS FORT STADACONA (QUEBEC) AND IS UNDER THE") - fmt.Println("PROTECTION OF THE FRENCH ARMY. HOWEVER, YOU MUST") - fmt.Println("MAKE A PORTAGE AND CROSS THE LACHINE RAPIDS.") - fmt.Println("FORT 3 IS FORT NEW YORK AND IS UNDER DUTCH CONTROL.") - fmt.Println("YOU MUST CROSS THROUGH IROQUOIS LAND.") - fmt.Println("ANSWER 1, 2, OR 3.") - fmt.Print(">> ") - scanner.Scan() - - f, err := strconv.Atoi(scanner.Text()) - if err != nil || f < 1 || f > 3 { - fmt.Println("Invalid input, Try again ... ") - continue - } - return Fort(f) - } -} - -func printFortComment(f Fort) { - fmt.Println() - switch f { - case FORT_MONTREAL: - fmt.Println("YOU HAVE CHOSEN THE EASIEST ROUTE. HOWEVER, THE FORT") - fmt.Println("IS FAR FROM ANY SEAPORT. THE VALUE") - fmt.Println("YOU RECEIVE FOR YOUR FURS WILL BE LOW AND THE COST") - fmt.Println("OF SUPPLIES HIGHER THAN AT FORTS STADACONA OR NEW YORK.") - case FORT_QUEBEC: - fmt.Println("YOU HAVE CHOSEN A HARD ROUTE. IT IS, IN COMPARSION,") - fmt.Println("HARDER THAN THE ROUTE TO HOCHELAGA BUT EASIER THAN") - fmt.Println("THE ROUTE TO NEW YORK. YOU WILL RECEIVE AN AVERAGE VALUE") - fmt.Println("FOR YOUR FURS AND THE COST OF YOUR SUPPLIES WILL BE AVERAGE.") - case FORT_NEWYORK: - fmt.Println("YOU HAVE CHOSEN THE MOST DIFFICULT ROUTE. AT") - fmt.Println("FORT NEW YORK YOU WILL RECEIVE THE HIGHEST VALUE") - fmt.Println("FOR YOUR FURS. THE COST OF YOUR SUPPLIES") - fmt.Println("WILL BE LOWER THAN AT ALL THE OTHER FORTS.") - } - fmt.Println() -} - -func getYesOrNo() string { - scanner := bufio.NewScanner(os.Stdin) - for { - fmt.Println("ANSWER YES OR NO") - scanner.Scan() - if strings.ToUpper(scanner.Text())[0:1] == "Y" { - return "Y" - } else if strings.ToUpper(scanner.Text())[0:1] == "N" { - return "N" - } - } -} - -func getFursPurchase() []int { - scanner := bufio.NewScanner(os.Stdin) - fmt.Printf("YOUR %d FURS ARE DISTRIBUTED AMONG THE FOLLOWING\n", MAXFURS) - fmt.Println("KINDS OF PELTS: MINK, BEAVER, ERMINE AND FOX.") - fmt.Println() - - purchases := make([]int, 4) - - for i, f := range FURS() { - retry: - fmt.Printf("HOW MANY %s DO YOU HAVE: ", f) - scanner.Scan() - count, err := strconv.Atoi(scanner.Text()) - if err != nil { - fmt.Println("INVALID INPUT, TRY AGAIN ...") - goto retry - } - purchases[i] = count - } - - return purchases -} - -func main() { - rand.Seed(time.Now().UnixNano()) - - printTitle() - - gameState := STARTING - whichFort := FORT_NEWYORK - var ( - minkPrice int - erminePrice int - beaverPrice int - foxPrice int - ) - player := NewPlayer() - - for { - switch gameState { - case STARTING: - printIntro() - fmt.Println("DO YOU WISH TO TRADE FURS?") - if getYesOrNo() == "N" { - os.Exit(0) - } - gameState = TRADING - case TRADING: - fmt.Println() - fmt.Printf("YOU HAVE $ %1.2f IN SAVINGS\n", player.funds) - fmt.Printf("AND %d FURS TO BEGIN THE EXPEDITION\n", MAXFURS) - player.furs = getFursPurchase() - - if player.totalFurs() > MAXFURS { - fmt.Println() - fmt.Println("YOU MAY NOT HAVE THAT MANY FURS.") - fmt.Println("DO NOT TRY TO CHEAT. I CAN ADD.") - fmt.Println("YOU MUST START AGAIN.") - gameState = STARTING - } else { - gameState = CHOOSINGFORT - } - case CHOOSINGFORT: - whichFort = getFortChoice() - printFortComment(whichFort) - fmt.Println("DO YOU WANT TO TRADE AT ANOTHER FORT?") - changeFort := getYesOrNo() - if changeFort == "N" { - gameState = TRAVELLING - } - case TRAVELLING: - switch whichFort { - case FORT_MONTREAL: - minkPrice = (int((0.2*rand.Float64()+0.70)*100+0.5) / 100) - erminePrice = (int((0.2*rand.Float64()+0.65)*100+0.5) / 100) - beaverPrice = (int((0.2*rand.Float64()+0.75)*100+0.5) / 100) - foxPrice = (int((0.2*rand.Float64()+0.80)*100+0.5) / 100) - - fmt.Println("SUPPLIES AT FORT HOCHELAGA COST $150.00.") - fmt.Println("YOUR TRAVEL EXPENSES TO HOCHELAGA WERE $10.00.") - player.funds -= 160 - case FORT_QUEBEC: - minkPrice = (int((0.30*rand.Float64()+0.85)*100+0.5) / 100) - erminePrice = (int((0.15*rand.Float64()+0.80)*100+0.5) / 100) - beaverPrice = (int((0.20*rand.Float64()+0.90)*100+0.5) / 100) - foxPrice = (int((0.25*rand.Float64()+1.10)*100+0.5) / 100) - - event := int(10*rand.Float64()) + 1 - if event <= 2 { - fmt.Println("YOUR BEAVER WERE TOO HEAVY TO CARRY ACROSS") - fmt.Println("THE PORTAGE. YOU HAD TO LEAVE THE PELTS, BUT FOUND") - fmt.Println("THEM STOLEN WHEN YOU RETURNED.") - player.furs[FUR_BEAVER] = 0 - } else if event <= 6 { - fmt.Println("YOU ARRIVED SAFELY AT FORT STADACONA.") - } else if event <= 8 { - fmt.Println("YOUR CANOE UPSET IN THE LACHINE RAPIDS. YOU") - fmt.Println("LOST ALL YOUR FURS.") - player.lostFurs() - } else if event <= 10 { - fmt.Println("YOUR FOX PELTS WERE NOT CURED PROPERLY.") - fmt.Println("NO ONE WILL BUY THEM.") - player.furs[FUR_FOX] = 0 - } else { - log.Fatal("Unexpected error") - } - - fmt.Println() - fmt.Println("SUPPLIES AT FORT STADACONA COST $125.00.") - fmt.Println("YOUR TRAVEL EXPENSES TO STADACONA WERE $15.00.") - player.funds -= 140 - case FORT_NEWYORK: - minkPrice = (int((0.15*rand.Float64()+1.05)*100+0.5) / 100) - erminePrice = (int((0.15*rand.Float64()+0.95)*100+0.5) / 100) - beaverPrice = (int((0.25*rand.Float64()+1.00)*100+0.5) / 100) - foxPrice = (int((0.25*rand.Float64()+1.05)*100+0.5) / 100) // not in original code - - event := int(10*rand.Float64()) + 1 - if event <= 2 { - fmt.Println("YOU WERE ATTACKED BY A PARTY OF IROQUOIS.") - fmt.Println("ALL PEOPLE IN YOUR TRADING GROUP WERE") - fmt.Println("KILLED. THIS ENDS THE GAME.") - os.Exit(0) - } else if event <= 6 { - fmt.Println("YOU WERE LUCKY. YOU ARRIVED SAFELY") - fmt.Println("AT FORT NEW YORK.") - } else if event <= 8 { - fmt.Println("YOU NARROWLY ESCAPED AN IROQUOIS RAIDING PARTY.") - fmt.Println("HOWEVER, YOU HAD TO LEAVE ALL YOUR FURS BEHIND.") - player.lostFurs() - } else if event <= 10 { - minkPrice /= 2 - foxPrice /= 2 - fmt.Println("YOUR MINK AND BEAVER WERE DAMAGED ON YOUR TRIP.") - fmt.Println("YOU RECEIVE ONLY HALF THE CURRENT PRICE FOR THESE FURS.") - } else { - log.Fatal("Unexpected error") - } - - fmt.Println() - fmt.Println("SUPPLIES AT NEW YORK COST $85.00.") - fmt.Println("YOUR TRAVEL EXPENSES TO NEW YORK WERE $25.00.") - player.funds -= 110 - } - - beaverValue := beaverPrice * player.furs[FUR_BEAVER] - foxValue := foxPrice * player.furs[FUR_FOX] - ermineValue := erminePrice * player.furs[FUR_ERMINE] - minkValue := minkPrice * player.furs[FUR_MINK] - - fmt.Println() - fmt.Printf("YOUR BEAVER SOLD FOR $%6.2f\n", float64(beaverValue)) - fmt.Printf("YOUR FOX SOLD FOR $%6.2f\n", float64(foxValue)) - fmt.Printf("YOUR ERMINE SOLD FOR $%6.2f\n", float64(ermineValue)) - fmt.Printf("YOUR MINK SOLD FOR $%6.2f\n", float64(minkValue)) - - player.funds += float32(beaverValue + foxValue + ermineValue + minkValue) - - fmt.Println() - fmt.Printf("YOU NOW HAVE $%1.2f INCLUDING YOUR PREVIOUS SAVINGS\n", player.funds) - fmt.Println("\nDO YOU WANT TO TRADE FURS NEXT YEAR?") - if getYesOrNo() == "N" { - os.Exit(0) - } else { - gameState = TRADING - } - } - } -} diff --git a/00_Alternate_Languages/39_Golf/MiniScript/README.md b/00_Alternate_Languages/39_Golf/MiniScript/README.md deleted file mode 100644 index 8a7e5325d..000000000 --- a/00_Alternate_Languages/39_Golf/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript golf.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "golf" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/39_Golf/MiniScript/golf.ms b/00_Alternate_Languages/39_Golf/MiniScript/golf.ms deleted file mode 100644 index 634ef0905..000000000 --- a/00_Alternate_Languages/39_Golf/MiniScript/golf.ms +++ /dev/null @@ -1,303 +0,0 @@ -print " "*34 + "Golf" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print - - print "Welcome to the creative computing country club," - print "an eighteen hole championship layout located a short" - print "distance from scenic downtown Morristown. The" - print "commentator will explain the game as you play." - print "Enjoy your game; see you at the 19th hole..." - print;print - l = [0] * 11 - holesInCourse=18 - totalScore=0 - totalPar=0 - dubChance=.8 - s2=0 - curHole=1 - - -getHoleData = function(hole) - // data for all the holes: distance, par, locOnLeft, and locOnRight for each one - data = [ - 361,4,4,2,389,4,3,3,206,3,4,2,500,5,7,2, - 408,4,2,4,359,4,6,4,424,4,4,2,388,4,4,4, - 196,3,7,2,400,4,7,2,560,5,7,2,132,3,2,2, - 357,4,4,4,294,4,2,4,475,5,2,3,375,4,4,2, - 180,3,6,2,550,5,6,6] - i = (hole-1) * 4 - globals.distance = data[i] - globals.par = data[i+1] - globals.locOnRight = data[i+2] -globals.locOnLeft = data[i+3] -end function - -startHole = function(hole) - getHoleData hole - print - print "You are at the tee off hole " + hole + " distance " + distance + " yards, par " + par - globals.totalPar += par - print "On your right is ", "" - printLocation locOnRight - print "On your left is ", "" - printLocation locOnLeft -end function - -// Get player's handicap -while true - handicap = input("What is your handicap? ").val - if 0 <= handicap <= 30 then break - print "PGA handicaps range from 0 to 30." -end while - -// Get player's weak point -while true - print "Difficulties at golf include:" - print "0=hook, 1=slice, 2=poor distance, 3=trap shots, 4=putting" - weakness = input("Which one (only one) is your worst? ").val - if 0 <= weakness <= 4 then break -end while - -// End a sentence by printing the name of the given location -printLocation = function(locIdx) - if locIdx < 1 or locIdx > 6 then - print "out of bounds." - else - print ["fairway.", "rough.", "trees.", "adjacent fairway.", - "trap.", "water."][locIdx-1] - end if -end function - -// Print score for one hole (plus total), and some praise or advice. -printScore = function(hole, score, par, totalScore, totalPar) - print "Your score on hole " + hole + " was " + score - print "Total par for " + hole + " holes is " + totalPar + " Your total is " + totalScore - if hole == holesInCourse then return - if score > par+2 then - print "Keep your head down." - else if score == par then - print "A par. Nice going." - else if score == par-1 then - print "A birdie." - else if score == 1 then - print "A hole in one." - else if score == par-2 then - print "A great big eagle." - end if -end function - -// Print club advice -- but only once. -clubAdviceGiven = false -printClubAdvice = function - if clubAdviceGiven then return // (already done) - globals.clubAdviceGiven = true - print "Selection of clubs" - print "yardage desired suggested clubs" - print "200 to 280 yards 1 to 4" - print "100 to 200 yards 19 to 13" - print " 0 to 100 yards 29 to 23" -end function - -doPenalty = function - print "Penalty stroke assessed. Hit from previous location." - globals.score += 1 - globals.j += 1 - globals.curLoc = 1 - globals.distance = prevDistance -end function - -// Try to get out of a trap. Return true if succeeded, false if failed. -doTrapShot = function - if weakness == 3 then - if rnd <= dubChance then - globals.dubChance *= 0.2 - print "Shot dubbed, still in trap." - return false - end if - globals.dubChance = 0.8 - end if - globals.distToPin = 1 + (3*floor((80/(40-handicap))*rnd)) - return true -end function - -getClub = function - //print "DEBUG: getClub, with curLoc=" + curLoc - while true - club = input("What club do you choose? ").val - print - if club < 1 or club > 29 then continue - if club > 4 and club < 12 then - print "That club is not in the bag." - continue - end if - if club >= 12 then club -= 6 - if curLoc <= 5 or club == 14 or club == 23 then break - print "That club is not in the bag." - print - continue - end while - return club -end function - -getSwing = function(club) - if club <= 13 then return 1 // (full swing) - while true - print "Now gauge your distance by a percentage (1 to 100)" - swing = input("of a full swing? ").val / 100 - print - if 0 <= swing <= 1 then return swing - // Given an invalid swing input, the original BASIC code would - // print "That club is not in the bag" and go back to choosing a club. - // But that is convoluted spaghetti, and I'm not doing it. - end while -end function - -playOneHole = function - q = 0 // counts certain kinds of shots on every third hole (?) - distanceHit = 0 - offLine = 0 - - // shot loop -- take as many shots as you need for this hole - while true - if curLoc < 1 then curLoc = 1 - if curLoc > 6 then - print "Your shot went out of bounds." - doPenalty - distanceHit = 0 - else if curLoc > 5 then - print "Your shot went into the water." - doPenalty - distanceHit = 0 - end if - - if score > 0 and distanceHit then - print "Shot went " + distanceHit + " yards. It's " + distToPin + " yards from the cup." - print "Ball is " + floor(offLine) + " yards off line... in ", "" - printLocation curLoc - end if - - printClubAdvice - - club = getClub - swing = getSwing(club) - globals.score += 1 - if curLoc == 5 and not doTrapShot then continue - if club > 14 then club -= 10 - - //print "DEBUG Club:"+club + " Swing:"+swing + " Weakness:"+weakness - - if curHole % 3 == 0 then - if s2 + q + (10*(curHole-1)/18) < (curHole-1)*(72+((handicap+1)/.85))/18 then - q += 1 - if score % 2 and distance >= 95 then - globals.distance -= 75 - distanceHit = 0 - print "Ball hit tree - bounced into rough " + distance + " yards from hole." - continue - end if - end if - end if - - if club >= 4 and curLoc == 2 then - print "You dubbed it." - distanceHit = 35 - else if score > 7 and distance < 200 then - // user is really sucking, let's cut them a break - putt 1 + (3 * floor((80/(40-handicap))*rnd)) - return - else - //print "DEBUG: SWING with handicap:" + handicap + " club:" + club - distanceHit = floor(((30-handicap)*2.5+187-((30-handicap)*.25+15)*club/2)+25*rnd) - distanceHit = floor(distanceHit*swing) - if weakness == 2 then distanceHit = floor(.85*distanceHit) - end if - offLine = (rnd/.8)*(2*handicap+16)*abs(tan(distanceHit*.0035)) - distToPin = floor(sqrt(offLine^2+abs(distance-distanceHit)^2)) - //print "DEBUG distance:"+distance+"; distanceHit:"+distanceHit+"; distToPin:"+distToPin+"; offLine:"+offLine - if distanceHit > distance and distToPin >= 20 then print "Too much club. You're past the hole." - - globals.prevDistance = distance - globals.distance = distToPin - if distToPin > 27 then - if offLine < 30 or j > 0 then - curLoc = 1 - continue - end if - // hook or slice - s9 = (s2+1)/15 - if weakness == 0 then - isSlice = floor(s9) == s9 - else - isSlice = not floor(s9) == s9 - end if - if isSlice then - print "You sliced- " - curLoc = locOnRight - else - print "You hooked- " - curLoc = locOnLeft - end if - if offLine > 45 then print "badly." - - else if distToPin > 20 then - curLoc = 5 - else if distToPin > .5 then - globals.curLoc = 8 // on the green! - putt distToPin * 3 // (convert yards to feet, and putt) - return - else - curLoc = 9 - print "You holed it." - print - globals.curHole += 1 - return - end if - end while -end function - -putt = function(distToPin) - puttAttempts = 0 - while true - distToPin = abs(floor(distToPin)) - print "On green, " + distToPin + " feet from the pin." - i = input("Choose your putt potency (1 to 13): ").val - globals.score += 1 - if score+1 - par > handicap*0.072 + 2 or puttAttempts > 2 then break - puttAttempts += 1 - if weakness == 4 then - distToPin -= i*(4+1*rnd)+1 - else - distToPin -= i*(4+2*rnd)+1.5 - end if - if -2 <= distToPin <= 2 then break - if distToPin < 0 then - print "Passed by cup." - else - print "Putt short." - end if - end while - print "You holed it." - print - return -end function - -// main loop -while true - curLoc = 0 - j = 0 - s2 += 1 - if curHole > 1 then - end if - - print - - score = 0 - startHole curHole - playOneHole - - totalScore += score - printScore curHole, score, par, totalScore, totalPar - if curHole == holesInCourse then break - - curHole += 1 -end while diff --git a/00_Alternate_Languages/39_Golf/README.md b/00_Alternate_Languages/39_Golf/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/39_Golf/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/39_Golf/golf.bas b/00_Alternate_Languages/39_Golf/golf.bas deleted file mode 100644 index ae1357419..000000000 --- a/00_Alternate_Languages/39_Golf/golf.bas +++ /dev/null @@ -1,244 +0,0 @@ -1 PRINT TAB(34);"GOLF" -2 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -3 PRINT:PRINT:PRINT -4 PRINT "WELCOME TO THE CREATIVE COMPUTING COUNTRY CLUB," -5 PRINT "AN EIGHTEEN HOLE CHAMPIONSHIP LAYOUT LOCATED A SHORT" -6 PRINT "DISTANCE FROM SCENIC DOWNTOWN MORRISTOWN. THE" -7 PRINT "COMMENTATOR WILL EXPLAIN THE GAME AS YOU PLAY." -8 PRINT "ENJOY YOUR GAME; SEE YOU AT THE 19TH HOLE..." -9 PRINT:PRINT: DIM L(10) -10 G1=18 -20 G2=0 -30 G3=0 -40 A=0 -50 N=.8 -60 S2=0 -70 F=1 -80 PRINT "WHAT IS YOUR HANDICAP"; -90 INPUT H:PRINT -100 IF H>30 THEN 470 -110 IF H<0 THEN 470 -120 PRINT "DIFFICULTIES AT GOLF INCLUDE:" -130 PRINT "0=HOOK, 1=SLICE, 2=POOR DISTANCE, 4=TRAP SHOTS, 5=PUTTING" -140 PRINT "WHICH ONE (ONLY ONE) IS YOUR WORST"; -150 INPUT T:PRINT -160 IF T>5 THEN 120 -170 S1=0 -210 REM -230 L(0)=0 -240 J=0 -245 Q=0 -250 S2=S2+1 -260 K=0 -270 IF F=1 THEN 310 -290 PRINT "YOUR SCORE ON HOLE";F-1;"WAS";S1 -291 GOTO 1750 -292 IF S1>P+2 THEN 297 -293 IF S1=P THEN 299 -294 IF S1=P-1 THEN 301 -295 IF S1=P-2 THEN 303 -296 GOTO 310 -297 PRINT "KEEP YOUR HEAD DOWN." -298 GOTO 310 -299 PRINT "A PAR. NICE GOING." -300 GOTO 310 -301 PRINT "A BIRDIE." -302 GOTO 310 -303 IF P=3 THEN 306 -304 PRINT "A GREAT BIG EAGLE." -305 GOTO 310 -306 PRINT "A HOLE IN ONE." -310 IF F=19 THEN 1710 -315 S1=0 -316 PRINT -320 IF S1=0 THEN 1590 -330 IF L(0)<1 THEN 1150 -340 X=0 -350 IF L(0)>5 THEN 1190 -360 PRINT "SHOT WENT";D1;"YARDS. IT'S";D2;"YARDS FROM THE CUP." -362 PRINT "BALL IS";INT(O);"YARDS OFF LINE... IN "; -380 GOSUB 400 -390 GOTO 620 -400 IF L(X)=1 THEN 480 -410 IF L(X)=2 THEN 500 -420 IF L(X)=3 THEN 520 -430 IF L(X)=4 THEN 540 -440 IF L(X)=5 THEN 560 -450 IF L(X)=6 THEN 580 -460 PRINT "OUT OF BOUNDS." -465 GOTO 1690 -470 PRINT "PGA HANDICAPS RANGE FROM 0 TO 30." -472 GOTO 80 -480 PRINT "FAIRWAY." -490 GOTO 1690 -500 PRINT "ROUGH." -510 GOTO 1690 -520 PRINT "TREES." -530 GOTO 1690 -540 PRINT "ADJACENT FAIRWAY." -550 GOTO 1690 -560 PRINT "TRAP." -570 GOTO 1690 -580 PRINT "WATER." -590 GOTO 1690 -620 IF A=1 THEN 629 -621 PRINT "SELECTION OF CLUBS" -622 PRINT "YARDAGE DESIRED SUGGESTED CLUBS" -623 PRINT "200 TO 280 YARDS 1 TO 4" -624 PRINT "100 TO 200 YARDS 19 TO 13" -625 PRINT " 0 TO 100 YARDS 29 TO 23" -626 A=1 -629 PRINT "WHAT CLUB DO YOU CHOOSE"; -630 INPUT C -632 PRINT -635 IF C<1 THEN 690 -637 IF C>29 THEN 690 -640 IF C>4 THEN 710 -650 IF L(0)<=5 THEN 740 -660 IF C=14 THEN 740 -665 IF C=23 THEN 740 -670 GOTO 690 -680 S1=S1-1 -690 PRINT "THAT CLUB IS NOT IN THE BAG." -693 PRINT -700 GOTO 620 -710 IF C<12 THEN 690 -720 C=C-6 -730 GOTO 650 -740 S1=S1+1 -741 W=1 -742 IF C>13 THEN 960 -746 IF INT(F/3)=F/3 THEN 952 -752 IF C<4 THEN 756 -754 GOTO 760 -756 IF L(0)=2 THEN 862 -760 IF S1>7 THEN 867 -770 D1=INT(((30-H)*2.5+187-((30-H)*.25+15)*C/2)+25*RND(1)) -780 D1=INT(D1*W) -800 IF T=2 THEN 1170 -830 O=(RND(1)/.8)*(2*H+16)*ABS(TAN(D1*.0035)) -840 D2=INT(SQR(O^2+ABS(D-D1)^2)) -850 IF D-D1<0 THEN 870 -860 GOTO 890 -862 PRINT "YOU DUBBED IT." -864 D1=35 -866 GOTO 830 -867 IF D<200 THEN 1300 -868 GOTO 770 -870 IF D2<20 THEN 890 -880 PRINT "TOO MUCH CLUB. YOU'RE PAST THE HOLE." -890 B=D -900 D=D2 -910 IF D2>27 THEN 1020 -920 IF D2>20 THEN 1100 -930 IF D2>.5 THEN 1120 -940 L(0)=9 -950 GOTO 1470 -952 IF S2+Q+(10*(F-1)/18)<(F-1)*(72+((H+1)/.85))/18 THEN 956 -954 GOTO 752 -956 Q=Q+1 -957 IF S1/2<>INT(S1/2) THEN 1011 -958 GOTO 862 -960 PRINT "NOW GAUGE YOUR DISTANCE BY A PERCENTAGE (1 TO 100)" -961 PRINT "OF A FULL SWING"; -970 INPUT W: W=W/100 -972 PRINT -980 IF W>1 THEN 680 -985 IF L(0)=5 THEN 1280 -990 IF C=14 THEN 760 -1000 C=C-10 -1010 GOTO 760 -1011 IF D<95 THEN 862 -1012 PRINT "BALL HIT TREE - BOUNCED INTO ROUGH";D-75;"YARDS FROM HOLE." -1014 D=D-75 -1018 GOTO 620 -1020 IF O<30 THEN 1150 -1022 IF J>0 THEN 1150 -1030 IF T>0 THEN 1070 -1035 S9=(S2+1)/15 -1036 IF INT(S9)=S9 THEN 1075 -1040 PRINT "YOU HOOKED- "; -1050 L(0)=L(2) -1055 IF O>45 THEN 1092 -1060 GOTO 320 -1070 S9=(S2+1)/15 -1071 IF INT(S9)=S9 THEN 1040 -1075 PRINT "YOU SLICED- "; -1080 L(0)=L(1) -1090 GOTO 1055 -1092 PRINT "BADLY." -1094 GOTO 320 -1100 L(0)=5 -1110 GOTO 320 -1120 L(0)=8 -1130 D2=INT(D2*3) -1140 GOTO 1380 -1150 L(0)=1 -1160 GOTO 320 -1170 D1=INT(.85*D1) -1180 GOTO 830 -1190 IF L(0)>6 THEN 1260 -1200 PRINT "YOUR SHOT WENT INTO THE WATER." -1210 S1=S1+1 -1220 PRINT "PENALTY STROKE ASSESSED. HIT FROM PREVIOUS LOCATION." -1230 J=J+1 -1240 L(0)=1 -1242 D=B -1250 GOTO 620 -1260 PRINT "YOUR SHOT WENT OUT OF BOUNDS." -1270 GOTO 1210 -1280 IF T=3 THEN 1320 -1300 D2=1+(3*INT((80/(40-H))*RND(1))) -1310 GOTO 1380 -1320 IF RND(1)>N THEN 1360 -1330 N=N*.2 -1340 PRINT "SHOT DUBBED, STILL IN TRAP." -1350 GOTO 620 -1360 N=.8 -1370 GOTO 1300 -1380 PRINT "ON GREEN,";D2;"FEET FROM THE PIN." -1381 PRINT "CHOOSE YOUR PUTT POTENCY (1 TO 13):"; -1400 INPUT I -1410 S1=S1+1 -1420 IF S1+1-P>(H*.072)+2 THEN 1470 -1425 IF K>2 THEN 1470 -1428 K=K+1 -1430 IF T=4 THEN 1530 -1440 D2=D2-I*(4+2*RND(1))+1.5 -1450 IF D2<-2 THEN 1560 -1460 IF D2>2 THEN 1500 -1470 PRINT "YOU HOLED IT." -1472 PRINT -1480 F=F+1 -1490 GOTO 230 -1500 PRINT "PUTT SHORT." -1505 D2=INT(D2) -1510 GOTO 1380 -1530 D2=D2-I*(4+1*RND(1))+1 -1550 GOTO 1450 -1560 PRINT "PASSED BY CUP." -1570 D2=-D2 -1580 GOTO 1505 -1590 READ D,P,L(1),L(2) -1595 PRINT -1600 PRINT "YOU ARE AT THE TEE OFF HOLE";F;"DISTANCE";D;"YARDS, PAR";P -1605 G3=G3+P -1620 PRINT "ON YOUR RIGHT IS "; -1630 X=1 -1640 GOSUB 400 -1650 PRINT "ON YOUR LEFT IS "; -1660 X=2 -1670 GOSUB 400 -1680 GOTO 620 -1690 RETURN -1700 DATA 361,4,4,2,389,4,3,3,206,3,4,2,500,5,7,2 -1702 DATA 408,4,2,4,359,4,6,4,424,4,4,2,388,4,4,4 -1704 DATA 196,3,7,2,400,4,7,2,560,5,7,2,132,3,2,2 -1706 DATA 357,4,4,4,294,4,2,4,475,5,2,3,375,4,4,2 -1708 DATA 180,3,6,2,550,5,6,6 -1710 PRINT -1750 G2=G2+S1 -1760 PRINT "TOTAL PAR FOR";F-1;"HOLES IS";G3;" YOUR TOTAL IS";G2 -1761 IF G1=F-1 THEN 1770 -1765 GOTO 292 -1770 END diff --git a/00_Alternate_Languages/40_Gomoko/MiniScript/README.md b/00_Alternate_Languages/40_Gomoko/MiniScript/README.md deleted file mode 100644 index 5613d133a..000000000 --- a/00_Alternate_Languages/40_Gomoko/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript gomoko.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "gomoko" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/40_Gomoko/MiniScript/gomoko.ms b/00_Alternate_Languages/40_Gomoko/MiniScript/gomoko.ms deleted file mode 100644 index 3188e22a1..000000000 --- a/00_Alternate_Languages/40_Gomoko/MiniScript/gomoko.ms +++ /dev/null @@ -1,94 +0,0 @@ -print " "*33 + "Gomoku" -print " "*15 + "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 - -inBounds = function(x,y) - return 0 < x <= n and 0 < y <= n -end function - -empty = function(x,y) - return A[x][y] == 0 -end function - -printBoard = function - for y in range(1,n) - print A[y][1:n+1].join - end for - print -end function - -doPlayerMove = function - while true - inp = input("Your play (i,j)? ").replace(" ", "").split(",") - print - if inp.len != 2 then continue - x = inp[0].val; y = inp[1].val - if x == -1 then return false - if not inBounds(x,y) then - print "Illegal move. Try again..." - else if not empty(x,y) then - print "Square occupied. Try again..." - else - break - end if - end while - A[x][y] = 1 - globals.lastPlayerMove = [x,y] - return true -end function - -doComputerMove = function - // Computer tries a move near the player's last move - for e in range(-1,1) - for f in range(-1,1) - if e==0 and f==0 then continue - x = lastPlayerMove[0] + e; y = lastPlayerMove[1] + f - if inBounds(x,y) and empty(x,y) then - A[x][y] = 2 - return - end if - end for - end for - - // Computer tries a random move - while true - x = floor(n * rnd + 1); y = floor(n * rnd + 1) - if empty(x,y) then break - end while - A[x][y] = 2 -end function - -playGame = function - while true - globals.n = input("What is your board size (min 7/ max 19)? ").val - if 7 <= n <= 19 then break - print "I said, the minimum is 7, the maximum is 19." - end while - globals.A = [] - for i in range(0,19) - A.push [0]*20 - end for - print; print "We alternate moves. You go first..."; print - while true - if not doPlayerMove then return - doComputerMove - printBoard - end while -end function - -// Main loop -while true - playGame - print; print "Thanks for the game!!" - q = input("Play again (1 for Yes, 0 for No)? ").val - if q != 1 then break -end while \ No newline at end of file diff --git a/00_Alternate_Languages/40_Gomoko/README.md b/00_Alternate_Languages/40_Gomoko/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/40_Gomoko/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/40_Gomoko/gomoko.bas b/00_Alternate_Languages/40_Gomoko/gomoko.bas deleted file mode 100644 index 662cca132..000000000 --- a/00_Alternate_Languages/40_Gomoko/gomoko.bas +++ /dev/null @@ -1,54 +0,0 @@ -2 PRINT TAB(33);"GOMOKO" -4 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -6 PRINT:PRINT:PRINT -8 DIM A(19,19) -10 PRINT "WELCOME TO THE ORIENTAL GAME OF GOMOKO." -20 PRINT: PRINT "THE GAME IS PLAYED ON AN N BY N GRID OF A SIZE" -30 PRINT "THAT YOU SPECIFY. DURING YOUR PLAY, YOU MAY COVER ONE GRID" -40 PRINT "INTERSECTION WITH A MARKER. THE OBJECT OF THE GAME IS TO GET" -50 PRINT "5 ADJACENT MARKERS IN A ROW -- HORIZONTALLY, VERTICALLY, OR" -60 PRINT "DIAGONALLY. ON THE BOARD DIAGRAM, YOUR MOVES ARE MARKED" -70 PRINT "WITH A '1' AND THE COMPUTER MOVES WITH A '2'." -80 PRINT: PRINT "THE COMPUTER DOES NOT KEEP TRACK OF WHO HAS WON." -90 PRINT "TO END THE GAME, TYPE -1,-1 FOR YOUR MOVE.": PRINT -110 PRINT "WHAT IS YOUR BOARD SIZE (MIN 7/ MAX 19)";: INPUT N -115 IF N>6 THEN 117 -116 GOTO 120 -117 IF N<20 THEN 210 -120 PRINT "I SAID, THE MINIMUM IS 7, THE MAXIMUM IS 19.": GOTO 110 -210 FOR I=1 TO N:FOR J=1 TO N: A(I,J)=0: NEXT J: NEXT I -300 PRINT: PRINT "WE ALTERNATE MOVES. YOU GO FIRST...": PRINT -310 PRINT "YOUR PLAY (I,J)";: INPUT I,J -315 PRINT -320 IF I=-1 THEN 980 -330 X=I: Y=J: GOSUB 910: IF L=1 THEN 410 -340 PRINT "ILLEGAL MOVE. TRY AGAIN...": GOTO 310 -410 IF A(I,J)=0 THEN 440 -420 PRINT "SQUARE OCCUPIED. TRY AGAIN...": GOTO 310 -440 A(I,J)=1 -500 REM *** COMPUTER TRIES AN INTELLIGENT MOVE *** -510 FOR E=-1 TO 1: FOR F=-1 TO 1: IF E+F-E*F=0 THEN 590 -540 X=I+F: Y=J+F: GOSUB 910 -570 IF L=0 THEN 590 -580 IF A(X,Y)=1 THEN 710 -590 NEXT F: NEXT E -600 REM *** COMPUTER TRIES A RANDOM MOVE *** -610 X=INT(N*RND(1)+1): Y=INT(N*RND(1)+1): GOSUB 910: IF L=0 THEN 610 -650 IF A(X,Y)<>0 THEN 610 -660 A(X,Y)=2: GOSUB 810: GOTO 310 -710 X=I-E: Y=J-F: GOSUB 910 -750 IF L=0 THEN 610 -760 GOTO 650 -800 REM *** PRINT THE BOARD *** -810 FOR I=1 TO N: FOR J=1 TO N: PRINT A(I,J); -840 NEXT J: PRINT: NEXT I: PRINT: RETURN -910 L=1: IF X<1 THEN 970 -920 IF X>N THEN 970 -930 IF Y<1 THEN 970 -940 IF Y>N THEN 970 -950 RETURN -970 L=0: RETURN -980 PRINT: PRINT "THANKS FOR THE GAME!!" -985 PRINT "PLAY AGAIN (1 FOR YES, 0 FOR NO)";: INPUT Q -990 IF Q=1 THEN 110 -999 END diff --git a/00_Alternate_Languages/41_Guess/MiniScript/README.md b/00_Alternate_Languages/41_Guess/MiniScript/README.md deleted file mode 100644 index bf19c7599..000000000 --- a/00_Alternate_Languages/41_Guess/MiniScript/README.md +++ /dev/null @@ -1,21 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript guess.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "guess" - run -``` -3. "Try-It!" page on the web: -Go to https://miniscript.org/tryit/, clear the default program from the source code editor, paste in the contents of guess.ms, and click the "Run Script" button. diff --git a/00_Alternate_Languages/41_Guess/MiniScript/guess.ms b/00_Alternate_Languages/41_Guess/MiniScript/guess.ms deleted file mode 100644 index 496426ce4..000000000 --- a/00_Alternate_Languages/41_Guess/MiniScript/guess.ms +++ /dev/null @@ -1,59 +0,0 @@ -setup = function - print " "*33 + "GUESS" - print " "*15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" - print; print; print - print "This is a number guessing game. I'll think" - print "of a number between 1 and any limit you want." - print "Then you have to guess what it is." - print - while true - globals.limit = input("What limit do you want? ").val - if limit > 1 then break - print "Please enter a number greater than 1." - end while - globals.par = floor(log(limit, 2)) + 1 -end function - -printGap = function - for i in range(1, 5) - print - end for -end function - -doOneGame = function - rightAnswer = ceil(rnd * limit) - print "I'm thinking of a number between 1 and " + limit - print "Now you try to guess what it is." - guess = 0 - while true - guess = guess + 1 - num = input("Your guess: ").val - if num <= 0 then - printGap - setup - return - end if - if num == rightAnswer then - print "That's it! You got it in " + guess + " tries." - if guess < par then - print "Very good." - else if guess == par then - print "Good." - else - print "You should have been able to get it in only " + par + "." - end if - printGap - return - end if - if num > rightAnswer then - print "Too high. Try a smaller answer." - else - print "Too low. Try a bigger answer." - end if - end while -end function - -setup -while true - doOneGame -end while \ No newline at end of file diff --git a/00_Alternate_Languages/41_Guess/README.md b/00_Alternate_Languages/41_Guess/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/41_Guess/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/41_Guess/go/main.go b/00_Alternate_Languages/41_Guess/go/main.go deleted file mode 100644 index eea6ad226..000000000 --- a/00_Alternate_Languages/41_Guess/go/main.go +++ /dev/null @@ -1,95 +0,0 @@ -package main - -import ( - "bufio" - "fmt" - "math" - "math/rand" - "os" - "strconv" - "time" -) - -func printIntro() { - fmt.Println(" Guess") - fmt.Println("Creative Computing Morristown, New Jersey") - fmt.Println() - fmt.Println() - fmt.Println() - fmt.Println("This is a number guessing game. I'll think") - fmt.Println("of a number between 1 and any limit you want.") - fmt.Println("Then you have to guess what it is") -} - -func getLimit() (int, int) { - scanner := bufio.NewScanner(os.Stdin) - - for { - fmt.Println("What limit do you want?") - scanner.Scan() - - limit, err := strconv.Atoi(scanner.Text()) - if err != nil || limit < 0 { - fmt.Println("Please enter a number greater or equal to 1") - continue - } - - limitGoal := int((math.Log(float64(limit)) / math.Log(2)) + 1) - return limit, limitGoal - } - -} - -func main() { - rand.Seed(time.Now().UnixNano()) - printIntro() - - scanner := bufio.NewScanner(os.Stdin) - - limit, limitGoal := getLimit() - - guessCount := 1 - stillGuessing := true - won := false - myGuess := int(float64(limit)*rand.Float64() + 1) - - fmt.Printf("I'm thinking of a number between 1 and %d\n", limit) - fmt.Println("Now you try to guess what it is.") - - for stillGuessing { - scanner.Scan() - n, err := strconv.Atoi(scanner.Text()) - if err != nil { - fmt.Println("Please enter a number greater or equal to 1") - continue - } - - if n < 0 { - break - } - - fmt.Print("\n\n\n") - if n < myGuess { - fmt.Println("Too low. Try a bigger answer") - guessCount += 1 - } else if n > myGuess { - fmt.Println("Too high. Try a smaller answer") - guessCount += 1 - } else { - fmt.Printf("That's it! You got it in %d tries\n", guessCount) - won = true - stillGuessing = false - } - } - - if won { - if guessCount < limitGoal { - fmt.Println("Very good.") - } else if guessCount == limitGoal { - fmt.Println("Good.") - } else { - fmt.Printf("You should have been able to get it in only %d guesses.\n", limitGoal) - } - fmt.Print("\n\n\n") - } -} diff --git a/00_Alternate_Languages/41_Guess/guess.bas b/00_Alternate_Languages/41_Guess/guess.bas deleted file mode 100644 index 96c57af5c..000000000 --- a/00_Alternate_Languages/41_Guess/guess.bas +++ /dev/null @@ -1,40 +0,0 @@ -1 PRINT TAB(33);"GUESS" -2 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -3 PRINT:PRINT:PRINT -4 PRINT "THIS IS A NUMBER GUESSING GAME. I'LL THINK" -5 PRINT "OF A NUMBER BETWEEN 1 AND ANY LIMIT YOU WANT." -6 PRINT "THEN YOU HAVE TO GUESS WHAT IT IS." -7 PRINT -8 PRINT "WHAT LIMIT DO YOU WANT"; -9 INPUT L -10 PRINT -11 L1=INT(LOG(L)/LOG(2))+1 -12 PRINT "I'M THINKING OF A NUMBER BETWEEN 1 AND";L -13 G=1 -14 PRINT "NOW YOU TRY TO GUESS WHAT IT IS." -15 M=INT(L*RND(1)+1) -20 INPUT N -21 IF N>0 THEN 25 -22 GOSUB 70 -23 GOTO 1 -25 IF N=M THEN 50 -30 G=G+1 -31 IF N>M THEN 40 -32 PRINT "TOO LOW. TRY A BIGGER ANSWER." -33 GOTO 20 -40 PRINT "TOO HIGH. TRY A SMALLER ANSWER." -42 GOTO 20 -50 PRINT "THAT'S IT! YOU GOT IT IN";G;"TRIES." -52 IF G 89 then - print "Maximum elevation is 89 degrees." - continue - else if degrees < 1 then - print "Minimum elevation is one degree." - continue - end if - shot += 1 - if shot >= 6 then - globals.gameOver = true - return - end if - radiansX2 = 2 * degrees * pi/180 - throw = maxRange * sin(radiansX2) - diff = floor(targetDist - throw) - if abs(diff) < 100 then - print "*** TARGET DESTROYED *** " + shot + " rounds of ammunition expended." - return shot - end if - if diff > 0 then - print "Short of target by " + diff + " yards." - else - print "Over target by " + abs(diff) + " yards." - end if - end while -end function - -playOneGame = function - maxRange = floor(40000*rnd + 20000) - print "Maximum range of your gun is " + maxRange + " yards." - shots = 0 - for targetNum in range(1,4) - shots += playOneTarget(maxRange) - if gameOver then break - if targetNum < 4 then - print - print "The forward observer has sighted more enemy activity..." - end if - end for - if gameOver then - print; print "Boom !!!! You have just been destroyed" - print "by the enemy."; print; print; print - else - print; print; print "Total rounds expended were: " + shots - end if - if shots > 18 or gameOver then - print "Better go back to font sill for refresher training!" - else - print "Nice shooting !!" - end if -end function - -// Main loop -while true - playOneGame - print; yn = input("Try again (Y or N)? ").upper - if not yn or yn[0] != "Y" then break -end while -print; print "OK. Return to base camp." diff --git a/00_Alternate_Languages/42_Gunner/README.md b/00_Alternate_Languages/42_Gunner/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/42_Gunner/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/42_Gunner/go/main.go b/00_Alternate_Languages/42_Gunner/go/main.go deleted file mode 100644 index 8ea76cec8..000000000 --- a/00_Alternate_Languages/42_Gunner/go/main.go +++ /dev/null @@ -1,125 +0,0 @@ -package main - -import ( - "bufio" - "fmt" - "math" - "math/rand" - "os" - "strconv" - "strings" - "time" -) - -func printIntro() { - fmt.Println(" GUNNER") - fmt.Println(" CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") - fmt.Print("\n\n\n") - fmt.Println("YOU ARE THE OFFICER-IN-CHARGE, GIVING ORDERS TO A GUN") - fmt.Println("CREW, TELLING THEM THE DEGREES OF ELEVATION YOU ESTIMATE") - fmt.Println("WILL PLACE A PROJECTILE ON TARGET. A HIT WITHIN 100 YARDS") - fmt.Println("OF THE TARGET WILL DESTROY IT.") - fmt.Println() -} - -func getFloat() float64 { - scanner := bufio.NewScanner(os.Stdin) - for { - scanner.Scan() - fl, err := strconv.ParseFloat(scanner.Text(), 64) - - if err != nil { - fmt.Println("Invalid input") - continue - } - - return fl - } -} - -func play() { - gunRange := int(40000*rand.Float64() + 20000) - fmt.Printf("\nMAXIMUM RANGE OF YOUR GUN IS %d YARDS\n", gunRange) - - killedEnemies := 0 - S1 := 0 - - for { - targetDistance := int(float64(gunRange) * (0.1 + 0.8*rand.Float64())) - shots := 0 - - fmt.Printf("\nDISTANCE TO THE TARGET IS %d YARDS\n", targetDistance) - - for { - fmt.Print("\n\nELEVATION? ") - elevation := getFloat() - - if elevation > 89 { - fmt.Println("MAXIMUM ELEVATION IS 89 DEGREES") - continue - } - - if elevation < 1 { - fmt.Println("MINIMUM ELEVATION IS 1 DEGREE") - continue - } - - shots += 1 - - if shots < 6 { - B2 := 2 * elevation / 57.3 - shotImpact := int(float64(gunRange) * math.Sin(B2)) - shotProximity := int(targetDistance - shotImpact) - - if math.Abs(float64(shotProximity)) < 100 { // hit - fmt.Printf("*** TARGET DESTROYED *** %d ROUNDS OF AMMUNITION EXPENDED.\n", shots) - S1 += shots - - if killedEnemies == 4 { - fmt.Printf("\n\nTOTAL ROUNDS EXPENDED WERE: %d\n", S1) - if S1 > 18 { - print("BETTER GO BACK TO FORT SILL FOR REFRESHER TRAINING!") - return - } else { - print("NICE SHOOTING !!") - return - } - } else { - killedEnemies += 1 - fmt.Println("\nTHE FORWARD OBSERVER HAS SIGHTED MORE ENEMY ACTIVITY...") - break - } - } else { // missed - if shotProximity > 100 { - fmt.Printf("SHORT OF TARGET BY %d YARDS.\n", int(math.Abs(float64(shotProximity)))) - } else { - fmt.Printf("OVER TARGET BY %d YARDS.\n", int(math.Abs(float64(shotProximity)))) - } - } - } else { - fmt.Print("\nBOOM !!!! YOU HAVE JUST BEEN DESTROYED BY THE ENEMY.\n\n\n") - fmt.Println("BETTER GO BACK TO FORT SILL FOR REFRESHER TRAINING!") - return - } - } - } -} - -func main() { - rand.Seed(time.Now().UnixNano()) - scanner := bufio.NewScanner(os.Stdin) - - printIntro() - - for { - play() - - fmt.Print("TRY AGAIN (Y OR N)? ") - scanner.Scan() - - if strings.ToUpper(scanner.Text())[0:1] != "Y" { - fmt.Println("\nOK. RETURN TO BASE CAMP.") - break - } - } -} diff --git a/00_Alternate_Languages/42_Gunner/gunner.bas b/00_Alternate_Languages/42_Gunner/gunner.bas deleted file mode 100644 index 245772854..000000000 --- a/00_Alternate_Languages/42_Gunner/gunner.bas +++ /dev/null @@ -1,52 +0,0 @@ -10 PRINT TAB(30);"GUNNER" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT:PRINT:PRINT -130 PRINT "YOU ARE THE OFFICER-IN-CHARGE, GIVING ORDERS TO A GUN" -140 PRINT "CREW, TELLING THEM THE DEGREES OF ELEVATION YOU ESTIMATE" -150 PRINT "WILL PLACE A PROJECTILE ON TARGET. A HIT WITHIN 100 YARDS" -160 PRINT "OF THE TARGET WILL DESTROY IT." : PRINT -170 R=INT(40000*RND(1)+20000) -180 PRINT "MAXIMUM RANGE OF YOUR GUN IS";R;" YARDS." -185 Z=0 -190 PRINT -195 S1=0 -200 T=INT(R*(.1+.8*RND(1))) -210 S=0 -220 GOTO 370 -230 PRINT "MINIMUM ELEVATION IS ONE DEGREE." -240 GOTO 390 -250 PRINT "MAXIMUM ELEVATION IS 89 DEGREES." -260 GOTO 390 -270 PRINT "OVER TARGET BY ";ABS(E);"YARDS." -280 GOTO 390 -290 PRINT "SHORT OF TARGET BY "ABS(E);"YARDS." -300 GOTO 390 -320 PRINT "*** TARGET DESTROYED *** ";S;"ROUNDS OF AMMUNITION EXPENDED." -325 S1=S1+S -330 IF Z=4 THEN 490 -340 Z=Z+1 -345 PRINT -350 PRINT "THE FORWARD OBSERVER HAS SIGHTED MORE ENEMY ACTIVITY..." -360 GOTO 200 -370 PRINT "DISTANCE TO THE TARGET IS "T;" YARDS." -380 PRINT -390 PRINT -400 INPUT "ELEVATION";B -420 IF B>89 THEN 250 -430 IF B<1 THEN 230 -440 S=S+1 -442 IF S<6 THEN 450 -444 PRINT:PRINT "BOOM !!!! YOU HAVE JUST BEEN DESTROYED "; -446 PRINT "BY THE ENEMY." : PRINT : PRINT : PRINT : GOTO 495 -450 B2=2*B/57.3 : I=R*SIN(B2) : X=T-I : E=INT(X) -460 IF ABS(E)<100 THEN 320 -470 IF E>100 THEN 290 -480 GOTO 270 -490 PRINT : PRINT : PRINT "TOTAL ROUNDS EXPENDED WERE:";S1 -492 IF S1>18 THEN 495 -493 PRINT "NICE SHOOTING !!" : GOTO 500 -495 PRINT "BETTER GO BACK TO FORT SILL FOR REFRESHER TRAINING!" -500 PRINT : INPUT "TRY AGAIN (Y OR N)";Z$ -510 IF Z$="Y" THEN 170 -520 PRINT:PRINT "OK. RETURN TO BASE CAMP." -999 END diff --git a/00_Alternate_Languages/43_Hammurabi/MiniScript/README.md b/00_Alternate_Languages/43_Hammurabi/MiniScript/README.md deleted file mode 100644 index bb4411bbf..000000000 --- a/00_Alternate_Languages/43_Hammurabi/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript hammurabi.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "hammurabi" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/43_Hammurabi/MiniScript/hammurabi.ms b/00_Alternate_Languages/43_Hammurabi/MiniScript/hammurabi.ms deleted file mode 100644 index f81a1e708..000000000 --- a/00_Alternate_Languages/43_Hammurabi/MiniScript/hammurabi.ms +++ /dev/null @@ -1,190 +0,0 @@ -print " "*32 + "Hamurabi" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print -print "Try your hand at governing ancient Sumeria" -print "for a ten-year term of office."; print - -eol = char(10) - -game = {} -game.z = 0 // year -game.p = 95 -game.s = 2800 // bushels in store -game.h = 3000 -game.e = game.h - game.s // bushels eaten by rats -game.food = 0 // bushels given to people to eat -game.y = 3 // value (in bushels) per acre -game.a = game.h / game.y // acres owned -game.i = 5 // immigration/births -game.d = 0 // how many starved this year -game.d1 = 0 // total starved over the whole game -game.p1 = 0 // average % of population starved per year -game.q = 1 // if negative, then a plague strikes - -startYear = function - print; print; print "Hamurabi: I beg to report to you," - game.z += 1 - print "In year " + game.z + ", " + - game.d + " people starved, " + - game.i + " came to the city," - game.p += game.i - if game.q < 0 then - game.p = floor(game.p / 2) - print "A horrible plague struck! Half the people died." - end if - print "Population is now " + game.p + "." - print "The city now owns " + game.a + " acres." - print "You harvested " + game.y + " bushels per acre." - print "The rats ate " + game.e + " bushels." - print "You now have " + game.s + " bushels in store."; print -end function - -exitGame = function - print; print char(7)*10 - print "So long for now."; print - exit -end function - -impeach = function - print "Due to this extreme mismanagement you have not only" - print "been impeached and thrown out of office but you have" - print "also been declared national fink!!!!" - exitGame -end function - -getNumber = function(prompt, max, maxMsg) - while true - value = input(prompt + "? ").val - if value < 0 then - print; print "Hamurabi: I cannot do what you wish." - print "Get yourself another steward!" - exitGame - end if - if value <= max then return value - print "Hamurabi: Think again. " + maxMsg + " Now then," - end while -end function - -hint = function(msg) - // This was not in the original program. But if you want to make - // the game easier, uncomment this line: - //print msg -end function - -min = function(a, b, c) - m = [a, b, c] - m.sort - return m[0] -end function - -getDecisions = function - // buy/sell land - c = floor(10 * rnd); game.y = c + 17 - print "Land is trading at " + game.y + " bushels per acre." - qty = getNumber("How many acres do you wish to buy", - floor(game.s / game.y), "You have only" + eol + game.s + " bushels of grain.") - if qty > 0 then - game.a += qty - game.s -= game.y * qty - else - qty = getNumber("How many acres do you wish to sell", - game.a, "You own only" + eol + game.a + " acres.") - game.a -= qty - game.s += game.y * qty - end if - - // feed the people - hint "Your people want " + (game.p * 20) + " bushels of food." - game.food = getNumber("How many bushels do you wish to feed your people", - game.s, "You have only" + eol + game.s + " bushels of grain.") - game.s -= game.food - - // planting (a little more complicate because there are THREE limits) - hint "You can plant up to " + - min(game.a, floor(game.s * 2), floor(game.p*10-1)) + " acres." - game.d = 0 - while game.a > 0 and game.s > 2 - game.d = getNumber("How many acres do you wish to plant with seed", - game.a, "You own only " + game.a + " acres.") - // enough grain for seed? (each bushel can plant 2 acres) - if floor(game.d / 2) > game.s then - print "Hamurabi: Think again. You have only" + eol + game.s + - " bushels of grain. Now then," - continue - end if - // enough people to tend the crops? (each person can tend 10 acres) - if game.d >= game.p * 10 then - print "But you have only " + game.p + " people to tend the fields! Now then," - continue - end if - break - end while - game.s -= floor(game.d / 2) -end function - -simulateYear = function - // A bountiful harvest! - c = floor(rnd * 5) + 1 - game.y = c; game.h = game.d * game.y; game.e = 0 - c = floor(rnd * 5) + 1 - if c % 2 == 0 then - // rats are running wild!! - game.e = floor(game.s / c) - end if - game.s += game.h - game.e - - // Let's have some babies - c = floor(rnd * 5) + 1 - game.i = floor(c * (20 * game.a + game.s) / game.p / 100 + 1) - // How many people had full tummies? - c = floor(game.food / 20) - // Horros, a 15% chance of plague - game.q = floor(10 * (2 * rnd - 0.3)) - - if game.p < c then - game.d = 0 - else - // starve enough for impeachment? - game.d = game.p - c - if game.d > 0.45 * game.p then - print; print "You starved " + game.d + " people in one year!!!" - impeach - end if - game.p1 = ((game.z - 1) * game.p1 + game.d * 100 / game.p) / game.z - game.p = c - game.d1 += game.d - end if -end function - -printFinalResult = function - print "In your 10-year term of office, " + game.p1 + " percent of the" - print "population starved per year on the average, i.e., a total of" - print game.d1 + " people died!!" - acresPer = game.a / game.p - print "You started with 10 acres per person and ended with" - print acresPer + " acres per person."; print - if game.p1 > 33 or acresPer < 7 then impeach - if game.p1 > 10 or acresPer < 9 then - print "Your heavy-handed performance smacks of Nero and Ivan IV." - print "The people (remaining) find you an unpleasant ruler, and," - print "frankly, hate your guts!!" - else if game.p1 > 3 or acresPer < 10 then - print "Your performance could have been somewhat better, but" - print "really wasn't too bad at all. " + floor(game.p * 0.8 * rnd) + " people" - print "would dearly like to see you assassinated but we all have our" - print "trivial problems." - else - print "A fantastic performance!! Charlemange, Disraeli, and" - print "Jefferson combined could not have done better!" - end if -end function - -// Main loop -while true - startYear - if game.z == 11 then break - getDecisions - simulateYear -end while -printFinalResult -exitGame diff --git a/00_Alternate_Languages/43_Hammurabi/README.md b/00_Alternate_Languages/43_Hammurabi/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/43_Hammurabi/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/43_Hammurabi/hammurabi.bas b/00_Alternate_Languages/43_Hammurabi/hammurabi.bas deleted file mode 100644 index 71afd1c51..000000000 --- a/00_Alternate_Languages/43_Hammurabi/hammurabi.bas +++ /dev/null @@ -1,119 +0,0 @@ -10 PRINT TAB(32); "HAMURABI" -20 PRINT TAB(15); "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT : PRINT : PRINT -80 PRINT "TRY YOUR HAND AT GOVERNING ANCIENT SUMERIA" -90 PRINT "FOR A TEN-YEAR TERM OF OFFICE." : PRINT -95 D1 = 0 : P1 = 0 -100 Z = 0 : P = 95 : S = 2800 : H = 3000 : E = H - S -110 Y = 3 : A = H / Y : I = 5 : Q = 1 -210 D = 0 -215 PRINT : PRINT : PRINT "HAMURABI: I BEG TO REPORT TO YOU," : Z = Z + 1 -217 PRINT "IN YEAR "; Z; ","; D; " PEOPLE STARVED, "; I; " CAME TO THE CITY," -218 P = P + I -227 IF Q > 0 THEN 230 -228 P = INT(P / 2) -229 PRINT "A HORRIBLE PLAGUE STRUCK! HALF THE PEOPLE DIED." -230 PRINT "POPULATION IS NOW "; P -232 PRINT "THE CITY NOW OWNS "; A; " ACRES." -235 PRINT "YOU HARVESTED "; Y; " BUSHELS PER ACRE." -250 PRINT "THE RATS ATE "; E; " BUSHELS." -260 PRINT "YOU NOW HAVE "; S; " BUSHELS IN STORE." : PRINT -270 IF Z = 11 THEN 860 -310 C = INT(10 * RND(1)) : Y = C + 17 -312 PRINT "LAND IS TRADING AT "; Y; " BUSHELS PER ACRE." -320 PRINT "HOW MANY ACRES DO YOU WISH TO BUY"; -321 INPUT Q : IF Q < 0 THEN 850 -322 IF Y * Q <= S THEN 330 -323 GOSUB 710 -324 GOTO 320 -330 IF Q = 0 THEN 340 -331 A = A + Q : S = S - Y * Q : C = 0 -334 GOTO 400 -340 PRINT "HOW MANY ACRES DO YOU WISH TO SELL"; -341 INPUT Q : IF Q < 0 THEN 850 -342 IF Q < A THEN 350 -343 GOSUB 720 -344 GOTO 340 -350 A = A - Q : S = S + Y * Q : C = 0 -400 PRINT -410 PRINT "HOW MANY BUSHELS DO YOU WISH TO FEED YOUR PEOPLE"; -411 INPUT Q -412 IF Q < 0 THEN 850 -418 REM *** TRYING TO USE MORE GRAIN THAN IS IN SILOS? -420 IF Q <= S THEN 430 -421 GOSUB 710 -422 GOTO 410 -430 S = S - Q : C = 1 : PRINT -440 PRINT "HOW MANY ACRES DO YOU WISH TO PLANT WITH SEED"; -441 INPUT D : IF D = 0 THEN 511 -442 IF D < 0 THEN 850 -444 REM *** TRYING TO PLANT MORE ACRES THAN YOU OWN? -445 IF D <= A THEN 450 -446 GOSUB 720 -447 GOTO 440 -449 REM *** ENOUGH GRAIN FOR SEED? -450 IF INT(D / 2) <= S THEN 455 -452 GOSUB 710 -453 GOTO 440 -454 REM *** ENOUGH PEOPLE TO TEND THE CROPS? -455 IF D < 10 * P THEN 510 -460 PRINT "BUT YOU HAVE ONLY "; P; " PEOPLE TO TEND THE FIELDS! NOW THEN," -470 GOTO 440 -510 S = S - INT(D / 2) -511 GOSUB 800 -512 REM *** A BOUNTIFUL HARVEST! -515 Y = C : H = D * Y : E = 0 -521 GOSUB 800 -522 IF INT(C / 2) <> C / 2 THEN 530 -523 REM *** RATS ARE RUNNING WILD!! -525 E = INT(S / C) -530 S = S - E + H -531 GOSUB 800 -532 REM *** LET'S HAVE SOME BABIES -533 I = INT(C *(20 * A + S) / P / 100 + 1) -539 REM *** HOW MANY PEOPLE HAD FULL TUMMIES? -540 C = INT(Q / 20) -541 REM *** HORROS, A 15% CHANCE OF PLAGUE -542 Q = INT(10 *(2 * RND(1) - 0.3)) -550 IF P < C THEN 210 -551 REM *** STARVE ENOUGH FOR IMPEACHMENT? -552 D = P - C : IF D > 0.45 * P THEN 560 -553 P1 =((Z - 1) * P1 + D * 100 / P) / Z -555 P = C : D1 = D1 + D : GOTO 215 -560 PRINT : PRINT "YOU STARVED "; D; " PEOPLE IN ONE YEAR!!!" -565 PRINT "DUE TO THIS EXTREME MISMANAGEMENT YOU HAVE NOT ONLY" -566 PRINT "BEEN IMPEACHED AND THROWN OUT OF OFFICE BUT YOU HAVE" -567 PRINT "ALSO BEEN DECLARED NATIONAL FINK!!!!" : GOTO 990 -710 PRINT "HAMURABI: THINK AGAIN. YOU HAVE ONLY" -711 PRINT S; "BUSHELS OF GRAIN. NOW THEN," -712 RETURN -720 PRINT "HAMURABI: THINK AGAIN. YOU OWN ONLY "; A; " ACRES. NOW THEN," -730 RETURN -800 C = INT(RND(1) * 5) + 1 -801 RETURN -850 PRINT : PRINT "HAMURABI: I CANNOT DO WHAT YOU WISH." -855 PRINT "GET YOURSELF ANOTHER STEWARD!!!!!" -857 GOTO 990 -860 PRINT "IN YOUR 10-YEAR TERM OF OFFICE,"; P1; "PERCENT OF THE" -862 PRINT "POPULATION STARVED PER YEAR ON THE AVERAGE, I.E. A TOTAL OF" -865 PRINT D1; "PEOPLE DIED!!" : L = A / P -870 PRINT "YOU STARTED WITH 10 ACRES PER PERSON AND ENDED WITH" -875 PRINT L; "ACRES PER PERSON." : PRINT -880 IF P1 > 33 THEN 565 -885 IF L < 7 THEN 565 -890 IF P1 > 10 THEN 940 -892 IF L < 9 THEN 940 -895 IF P1 > 3 THEN 960 -896 IF L < 10 THEN 960 -900 PRINT "A FANTASTIC PERFORMANCE!!! CHARLEMANGE, DISRAELI, AND" -905 PRINT "JEFFERSON COMBINED COULD NOT HAVE DONE BETTER!" : GOTO 990 -940 PRINT "YOUR HEAVY-HANDED PERFORMANCE SMACKS OF NERO AND IVAN IV." -945 PRINT "THE PEOPLE (REMAINING) FIND YOU AN UNPLEASANT RULER, AND," -950 PRINT "FRANKLY, HATE YOUR GUTS!!" : GOTO 990 -960 PRINT "YOUR PERFORMANCE COULD HAVE BEEN SOMEWHAT BETTER, BUT" -965 PRINT "REALLY WASN'T TOO BAD AT ALL. "; INT(P * 0.8 * RND(1)); "PEOPLE" -970 PRINT "WOULD DEARLY LIKE TO SEE YOU ASSASSINATED BUT WE ALL HAVE OUR" -975 PRINT "TRIVIAL PROBLEMS." -990 PRINT : FOR N = 1 TO 10 : PRINT CHR$(7); : NEXT N -995 PRINT "SO LONG FOR NOW." : PRINT -999 END \ No newline at end of file diff --git a/00_Alternate_Languages/44_Hangman/C/dictionary.txt b/00_Alternate_Languages/44_Hangman/C/dictionary.txt deleted file mode 100644 index ddf7a59fc..000000000 --- a/00_Alternate_Languages/44_Hangman/C/dictionary.txt +++ /dev/null @@ -1,100 +0,0 @@ -harm -retire -principle -tile -biology -show -reporter -profound -prestige -hardship -supplementary -abundant -firm -preparation -mother -welfare -broadcast -virgin -bloody -shaft -bird -buy -passion -south -slant -hesitate -leak -ride -contempt -banner -hurt -disaster -ranch -damage -conceive -environmental -outside -apathy -temple -arrange -hour -tone -intelligence -soup -bishop -fool -chase -snub -develop -domination -cry -distant -poem -implication -rally -assertive -anxiety -home -bear -execute -century -solo -cathedral -terminal -integration -mastermind -pen -X-ray -match -ceremony -stop -linger -slow -desert -superior -tender -debt -criticism -rehabilitation -finish -jest -scream -piece -mask -approach -sequence -negotiation -to -traffic -midnight -aspect -dull -concession -citizen -conception -instrument -compartment -responsibility -resist -withdraw \ No newline at end of file diff --git a/00_Alternate_Languages/44_Hangman/C/main.c b/00_Alternate_Languages/44_Hangman/C/main.c deleted file mode 100644 index 5ad8e43d9..000000000 --- a/00_Alternate_Languages/44_Hangman/C/main.c +++ /dev/null @@ -1,137 +0,0 @@ -#include -#include -#include -#include -#define MAX_WORDS 100 - -//check if windows or linux for the clear screen -#ifdef _WIN32 -#define CLEAR "cls" -#else -#define CLEAR "clear" -#endif - -/** - * @brief Prints the stage of the hangman based on the number of wrong guesses. - * - * @param stage Hangman stage. - */ -void print_hangman(int stage){ - switch (stage){ - case 0: - printf("----------\n"); - printf("| |\n"); - printf("|\n"); - printf("|\n"); - printf("|\n"); - printf("|\n"); - break; - case 1: - printf("----------\n"); - printf("| |\n"); - printf("| O\n"); - printf("| |\n"); - printf("|\n"); - printf("|\n"); - break; - case 2: - printf("----------\n"); - printf("| |\n"); - printf("| o\n"); - printf("| /|\n"); - printf("|\n"); - printf("|\n"); - break; - case 3: - printf("----------\n"); - printf("| |\n"); - printf("| o\n"); - printf("| /|\\\n"); - printf("|\n"); - printf("|\n"); - break; - case 4: - printf("----------\n"); - printf("| |\n"); - printf("| o\n"); - printf("| /|\\\n"); - printf("| /\n"); - printf("|\n"); - break; - case 5: - printf("----------\n"); - printf("| |\n"); - printf("| o\n"); - printf("| /|\\\n"); - printf("| / \\\n"); - printf("|\n"); - break; - default: - break; - } -} - -/** - * @brief Picks and return a random word from the dictionary. - * - * @return Random word - */ -char* random_word_picker(){ - //generate a random english word - char* word = malloc(sizeof(char) * 100); - FILE* fp = fopen("dictionary.txt", "r"); - srand(time(NULL)); - if (fp == NULL){ - printf("Error opening dictionary.txt\n"); - exit(1); - } - int random_number = rand() % MAX_WORDS; - for (int j = 0; j < random_number; j++){ - fscanf(fp, "%s", word); - } - fclose(fp); - return word; -} - - - - -void main(void){ - char* word = malloc(sizeof(char) * 100); - word = random_word_picker(); - char* hidden_word = malloc(sizeof(char) * 100); - for (int i = 0; i < strlen(word); i++){ - hidden_word[i] = '_'; - } - hidden_word[strlen(word)] = '\0'; - int stage = 0; - int wrong_guesses = 0; - int correct_guesses = 0; - char* guess = malloc(sizeof(char) * 100); - while (wrong_guesses < 6 && correct_guesses < strlen(word)){ - CLEAR; - print_hangman(stage); - printf("%s\n", hidden_word); - printf("Enter a guess: "); - scanf("%s", guess); - for (int i = 0; i < strlen(word); i++){ - if (strcmp(guess,word) == 0){ - correct_guesses = strlen(word); - } - else if (guess[0] == word[i]){ - hidden_word[i] = guess[0]; - correct_guesses++; - } - } - if (strchr(word, guess[0]) == NULL){ - wrong_guesses++; - } - stage = wrong_guesses; - } - if (wrong_guesses == 6){ - printf("You lose! The word was %s\n", word); - } - else { - printf("You win!\n"); - } -} \ No newline at end of file diff --git a/00_Alternate_Languages/44_Hangman/MiniScript/README.md b/00_Alternate_Languages/44_Hangman/MiniScript/README.md deleted file mode 100644 index cf8b20021..000000000 --- a/00_Alternate_Languages/44_Hangman/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript hangman.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "hangman" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/44_Hangman/MiniScript/hangman.ms b/00_Alternate_Languages/44_Hangman/MiniScript/hangman.ms deleted file mode 100644 index 53966d45e..000000000 --- a/00_Alternate_Languages/44_Hangman/MiniScript/hangman.ms +++ /dev/null @@ -1,127 +0,0 @@ -print " "*32 + "Hangman" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print - -words = [] -words += ["gum","sin","for","cry","lug","bye","fly"] -words += ["ugly","each","from","work","talk","with","self"] -words += ["pizza","thing","feign","fiend","elbow","fault","dirty"] -words += ["budget","spirit","quaint","maiden","escort","pickax"] -words += ["example","tension","quinine","kidney","replica","sleeper"] -words += ["triangle","kangaroo","mahogany","sergeant","sequence"] -words += ["moustache","dangerous","scientist","different","quiescent"] -words += ["magistrate","erroneously","loudspeaker","phytotoxic"] -words += ["matrimonial","parasympathomimetic","thigmotropism"] -// Note: on Mini Micro, you could instead do: -// words = file.readLines("/sys/data/englishWords.txt") - -words.shuffle - -addToPic = function(guessCount) - if guessCount == 1 then - print "First, we draw a head" - ps[3][6]="-"; ps[3][7]="-"; ps[3][8]="-"; ps[4][5]="("; ps[4][6]="." - ps[4][8]="."; ps[4][9]=")"; ps[5][6]="-"; ps[5][7]="-"; ps[5][8]="-" - else if guessCount == 2 then - print "Now we draw a body." - for i in range(6, 9); ps[i][7]="x"; end for - else if guessCount == 3 then - print "Next we draw an arm." - for i in range(4, 7); ps[i][i-1]="\"; end for - else if guessCount == 4 then - print "This time it's the other arm." - ps[4][11]="/"; ps[5][10]="/"; ps[6][9]="/"; ps[7][8]="/" - else if guessCount == 5 then - print "Now, let's draw the right leg." - ps[10][6]="/"; ps[11][5]="/" - else if guessCount == 6 then - print "This time we draw the left leg." - ps[10][8]="\"; ps[11][9]="\" - else if guessCount == 7 then - print "Now we put up a hand." - ps[3][11]="\" - else if guessCount == 8 then - print "Next the other hand." - ps[3][3]="/" - else if guessCount == 9 then - print "Now we draw one foot" - ps[12][10]="\"; ps[12][11]="-" - else if guessCount == 10 then - print "Here's the other foot -- you're hung!!" - ps[12][3]="-"; ps[12][4]="/" - end if - for i in range(1, 12) - print ps[i].join("") - end for - print -end function - -doOneGame = function - usedLetters = [] - globals.ps = [] - for i in range(0, 12); ps.push [" "]*12; end for - for i in range(1,12); ps[i][1] = "X"; end for - for i in range(1, 7); ps[1][i] = "X"; end for; ps[2][7] = "X" - secretWord = words.pull.upper - //print "(Secret word: " + secretWord + ")" - visibleWord = ["-"] * secretWord.len - wrongGuesses = 0 - while true - print "Here are the letters you used:" - print usedLetters.join(",") - print - print visibleWord.join("") - print - guess = input("What is your guess? ").upper - guess = (guess + " ")[0] - if guess < "A" or guess > "Z" then continue - if usedLetters.indexOf(guess) != null then - print "You guessed that letter before!" - continue - end if - usedLetters.push guess - for i in visibleWord.indexes - if secretWord[i] == guess then visibleWord[i] = guess - end for - if visibleWord.indexOf("-") == null then - print "You found the word!" - return true - else if secretWord.indexOf(guess) != null then - print - print visibleWord.join("") - print - guess = input("What is your guess for the word? ").upper - if guess == secretWord then - print "Right!! It took you " + usedLetters.len + " guesses!" - return true - else - print "Wrong. Try another letter." - end if - print - else - print "Sorry, that letter isn't in the word." - wrongGuesses += 1 - addToPic wrongGuesses - if wrongGuesses > 9 then - print "Sorry, you lose. The word was " + secretWord - return false - end if - end if - end while -end function - -while true - if not words then - print "You did all the words!!" - break - end if - won = doOneGame - if won then - yn = input("Want another word? ").upper - else - yn = input("You missed that one. Do you want another word? ").upper - end if - if not yn or yn[0] != "Y" then break -end while -print -print "It's been fun! Bye for now." diff --git a/00_Alternate_Languages/44_Hangman/README.md b/00_Alternate_Languages/44_Hangman/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/44_Hangman/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/44_Hangman/hangman.bas b/00_Alternate_Languages/44_Hangman/hangman.bas deleted file mode 100644 index cdd1b15d3..000000000 --- a/00_Alternate_Languages/44_Hangman/hangman.bas +++ /dev/null @@ -1,81 +0,0 @@ -10 PRINT TAB(32);"HANGMAN" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -25 PRINT:PRINT:PRINT -30 DIM P$(12,12),L$(20),D$(20),N$(26),U(50) -40 C=1: N=50 -50 FOR I=1 TO 20: D$(I)="-": NEXT I: M=0 -60 FOR I=1 TO 26: N$(I)="": NEXT I -70 FOR I=1 TO 12: FOR J=1 TO 12: P$(I,J)=" ": NEXT J: NEXT I -80 FOR I=1 TO 12: P$(I,1)="X": NEXT I -90 FOR I=1 TO 7: P$(1,I)="X": NEXT: P$(2,7)="X" -95 IF C10 THEN 170 -600 PRINT "SORRY, YOU LOSE. THE WORD WAS ";A$ -610 PRINT "YOU MISSED THAT ONE. DO YOU ";: GOTO 370 -620 INPUT "TYPE YES OR NO";Y$: IF LEFT$(Y$,1)="Y" THEN 50 -700 DATA "GUM","SIN","FOR","CRY","LUG","BYE","FLY" -710 DATA "UGLY","EACH","FROM","WORK","TALK","WITH","SELF" -720 DATA "PIZZA","THING","FEIGN","FIEND","ELBOW","FAULT","DIRTY" -730 DATA "BUDGET","SPIRIT","QUAINT","MAIDEN","ESCORT","PICKAX" -740 DATA "EXAMPLE","TENSION","QUININE","KIDNEY","REPLICA","SLEEPER" -750 DATA "TRIANGLE","KANGAROO","MAHOGANY","SERGEANT","SEQUENCE" -760 DATA "MOUSTACHE","DANGEROUS","SCIENTIST","DIFFERENT","QUIESCENT" -770 DATA "MAGISTRATE","ERRONEOUSLY","LOUDSPEAKER","PHYTOTOXIC" -780 DATA "MATRIMONIAL","PARASYMPATHOMIMETIC","THIGMOTROPISM" -990 PRINT "BYE NOW" -999 END diff --git a/00_Alternate_Languages/45_Hello/ANSI_C/hello.c b/00_Alternate_Languages/45_Hello/ANSI_C/hello.c deleted file mode 100644 index 74b0275f2..000000000 --- a/00_Alternate_Languages/45_Hello/ANSI_C/hello.c +++ /dev/null @@ -1,166 +0,0 @@ -#include -#include - -#define TRUE 1 -#define FALSE 0 -#define MAX_INPUT_LENGTH 80 - -void tab(int number_of_spaces); -void get_input(char *input_buffer); -int strings_match(char *string1, char *string2); - -int main() { - int done = FALSE; - int paid = FALSE; - int maybe_more, sure; - - char name[MAX_INPUT_LENGTH]; - char reply[MAX_INPUT_LENGTH]; - - tab(33); - printf("HELLO\n"); - tab(15); - printf("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n"); - printf("\n\n\n"); - printf("HELLO. MY NAME IS CREATIVE COMPUTER.\n"); - printf("\n\nWHAT'S YOUR NAME "); - get_input(name); - printf("\nHI THERE, %s, ARE YOU ENJOYING YOURSELF HERE ", name); - - get_input(reply); - while (!strings_match(reply, "YES") && !strings_match(reply, "NO")) { - printf("%s, I DON'T UNDERSTAND YOUR ANSWER OF '%s'.\n", name, reply); - printf("PLEASE ANSWER 'YES' OR 'NO'. DO YOU LIKE IT HERE "); - get_input(reply); - } - - if (strings_match(reply, "YES")) { - printf("I'M GLAD TO HEAR THAT, %s.\n", name); - } - else { - printf("OH, I'M SORRY TO HEAR THAT, %s. MAYBE WE CAN " - "BRIGHTEN UP YOUR VISIT A BIT.\n", name); - } - - printf("\nSAY, %s, I CAN SOLVE ALL KINDS OF PROBLEMS EXCEPT " - "THOSE DEALING WITH GREECE. WHAT KIND OF PROBLEMS DO " - "YOU HAVE (ANSWER SEX, HEALTH, MONEY, OR JOB) ", name); - - while (!done) { - get_input(reply); - - if (strings_match(reply, "JOB")) { - printf("I CAN SYMPATHIZE WITH YOU %s. I HAVE TO WORK " - "VERY LONG HOURS FOR NO PAY -- AND SOME OF MY BOSSES " - "REALLY BEAT ON MY KEYBOARD. MY ADVICE TO YOU, %s, IS TO " - "OPEN A RETAIL COMPUTER STORE. IT'S GREAT FUN.\n\n", name, name); - } - - else if (strings_match(reply, "MONEY")) { - printf("SORRY, %s, I'M BROKE TOO. WHY DON'T YOU SELL " - "ENCYCLOPEADIAS OR MARRY SOMEONE RICH OR STOP EATING " - "SO YOU WON'T NEED SO MUCH MONEY?\n\n", name); - } - - else if (strings_match(reply, "HEALTH")) { - printf("MY ADVICE TO YOU %s IS:\n", name); - printf(" 1. TAKE TWO ASPRIN\n"); - printf(" 2. DRINK PLENTY OF FLUIDS (ORANGE JUICE, NOT BEER!)\n"); - printf(" 3. GO TO BED (ALONE)\n\n"); - } - - else if (strings_match(reply, "SEX")) { - printf("IS YOUR PROBLEM TOO MUCH OR TOO LITTLE "); - - sure = FALSE; - while (!sure) { - get_input(reply); - if (strings_match(reply, "TOO MUCH")) { - printf("YOU CALL THAT A PROBLEM?!! I SHOULD HAVE SUCH PROBLEMS!\n"); - printf("IF IT BOTHERS YOU, %s, TAKE A COLD SHOWER.\n\n", name); - sure = TRUE; - } - else if (strings_match(reply, "TOO LITTLE")) { - printf("WHY ARE YOU HERE IN SUFFERN, %s? YOU SHOULD BE " - "IN TOKYO OR NEW YORK OR AMSTERDAM OR SOMEPLACE WITH SOME " - "REAL ACTION.\n\n", name); - sure = TRUE; - } - else { - printf("DON'T GET ALL SHOOK, %s, JUST ANSWER THE QUESTION " - "WITH 'TOO MUCH' OR 'TOO LITTLE'. WHICH IS IT ", name); - } - } - } - - else { // not one of the prescribed categories - printf("OH, %s, YOUR ANSWER OF '%s' IS GREEK TO ME.\n\n", name, reply); - } - - printf("ANY MORE PROBLEMS YOU WANT SOLVED, %s ", name); - - maybe_more = TRUE; - while (maybe_more) { - get_input(reply); - if (strings_match(reply, "NO")) { - done = TRUE; - maybe_more = FALSE; - } - else if (strings_match(reply, "YES")) { - printf("WHAT KIND (SEX, MONEY, HEALTH, JOB) "); - maybe_more = FALSE; - } - else { - printf("JUST A SIMPLE 'YES' OR 'NO' PLEASE, %s. ", name); - } - } // no further questions - } // end of 'not done' loop - - printf("\nTHAT WILL BE $5.00 FOR THE ADVICE, %s.\n", name); - printf("PLEASE LEAVE THE MONEY ON THE TERMINAL.\n"); - // pause a few seconds - printf("\n\n\nDID YOU LEAVE THE MONEY "); - get_input(reply); - while (!paid) { - if (strings_match(reply, "YES")) { - printf("HEY, %s??? YOU LEFT NO MONEY AT ALL!\n", name); - printf("YOU ARE CHEATING ME OUT OF MY HARD-EARNED LIVING.\n"); - printf("\nWHAT A RIP OFF, %s!!!\n", name); - printf("TAKE A WALK, %s.\n\n", name); - paid = TRUE; - } - else if (strings_match(reply, "NO")) { - printf("THAT'S HONEST, %s, BUT HOW DO YOU EXPECT " - "ME TO GO ON WITH MY PSYCHOLOGY STUDIES IF MY PATIENTS " - "DON'T PAY THEIR BILLS?\n\n", name); - printf("NICE MEETING YOU, %s, HAVE A NICE DAY.\n", name); - paid = TRUE; - } - else { - printf("YOUR ANSWER OF '%s' CONFUSES ME, %s.\n", reply, name); - printf("PLEASE RESPOND WITH 'YES' OR 'NO'.\n"); - } - } -} - - -void tab(int number_of_spaces) { - for (int i=0; i < number_of_spaces; i++) - putchar(' '); -} - - -void get_input(char *input_buffer) { - fgets(input_buffer, MAX_INPUT_LENGTH - 1, stdin); - input_buffer[strcspn(input_buffer, "\n")] = '\0'; // trim the trailing line break -} - - -int strings_match(char *string1, char *string2) { - if (strncasecmp(string1, string2, MAX_INPUT_LENGTH - 1) != 0) - return FALSE; - else // strings match, at least within maximum input line length - return TRUE; -} - - diff --git a/00_Alternate_Languages/45_Hello/MiniScript/README.md b/00_Alternate_Languages/45_Hello/MiniScript/README.md deleted file mode 100644 index c3e534cbf..000000000 --- a/00_Alternate_Languages/45_Hello/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript hello.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "hello" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/45_Hello/MiniScript/hello.ms b/00_Alternate_Languages/45_Hello/MiniScript/hello.ms deleted file mode 100644 index a82344ef2..000000000 --- a/00_Alternate_Languages/45_Hello/MiniScript/hello.ms +++ /dev/null @@ -1,108 +0,0 @@ -print " "*33 + "Hello" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print - -print "Hello. My name is Creative Computer." -print -print -ns = input("What's your name? ") -print -print "Hi there, " + ns + ", are you enjoying yourself here?" -while true - bs = input.lower - print - if bs == "yes" then - print "I'm glad to hear that, " + ns + "." - print - break - else if bs == "no" then - print "Oh, I'm sorry to hear that, " + ns + ". Maybe we can" - print "brighten up your visit a bit." - break - else - print "Please answer 'yes' or 'no'. Do you like it here?" - end if -end while -print -print "Say, " + ns + ", I can solve all kinds of problems except" -print "those dealing with Greece. What kind of problems do" -print "you have (answer sex, health, money, or job)?" -while true - cs = input - print - if cs != "sex" and cs != "health" and cs != "money" and cs != "job" then - print "Oh, " + ns + ", your answer of " + cs + " is Greek to me." - else if cs == "job" then - print "I can sympathize with you " + ns + ". I have to work" - print "very long hours for no pay -- and some of my bosses" - print "really beat on my keyboard. My advice to you, " + ns + "," - print "is to open a retail computer store. It's great fun." - else if cs == "money" then - print "Sorry, " + ns + ", I'm broke too. Why don't you sell" - print "encyclopeadias or marry someone rich or stop eating" - print "so you won't need so much money?" - else if cs == "health" then - print "My advice to you " + ns + " is:" - print " 1. Take two asprin" - print " 2. Drink plenty of fluids (orange juice, not beer!)" - print " 3. Go to bed (alone)" - else - print "Is your problem too much or too little?" - while true - ds = input.lower - print - if ds == "too much" then - print "You call that a problem?!! I should have such problems!" - print "If it bothers you, " + ns + ", take a cold shower." - break - else if ds == "too little" then - print "Why are you here in suffern, " + ns + "? You should be" - print "in Tokyo or New York or Amsterdam or someplace with some" - print "real action." - break - else - print "Don't get all shook, " + ns + ", just answer the question" - print "with 'too much' or 'too little'. Which is it?" - end if - end while - end if - print - print "Any more problems you want solved, " + ns + "?" - es = input.lower - print - if es == "yes" then - print "What kind (sex, money, health, job)?" - else if es == "no" then - print "That will be $5.00 for the advice, " + ns + "." - print "Please leave the money on the terminal." - print - wait 2 - print - print - while true - gs = input("Did you leave the money? ").lower - print - if gs == "yes" then - print "Hey, " + ns + "??? You left no money at all!" - print "You are cheating me out of my hard-earned living." - print - print "What a rip off, " + ns + "!!!" - print - break - else if gs == "no" then - print "That's honest, " + ns + ", but how do you expect" - print "me to go on with my psychology studies if my patient" - print "don't pay their bills?" - break - else - print "Your answer of '" + gs + "' confuses me, " + ns + "." - print "Please respond with 'yes' or 'no'." - end if - end while - break - end if -end while -print -print "Take a walk, " + ns + "." -print -print diff --git a/00_Alternate_Languages/45_Hello/README.md b/00_Alternate_Languages/45_Hello/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/45_Hello/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/45_Hello/Swift/hello.swift b/00_Alternate_Languages/45_Hello/Swift/hello.swift deleted file mode 100644 index 0d882f755..000000000 --- a/00_Alternate_Languages/45_Hello/Swift/hello.swift +++ /dev/null @@ -1,157 +0,0 @@ - -func tab(_ number_Of_Spaces: Int) { - var spaces = "" - - for _ in 1...number_Of_Spaces { - spaces += " " - } - print(spaces, terminator:"") -} - - -func get_Input() -> String { - let input = readLine() - return (input == nil ? "" : input!.uppercased()) -} - - -func main() -{ - var done = false, - answered = false, - maybe_More = false, - paid = false - var reply = "" - var name = "STRANGER" - - tab (33) - print("HELLO") - tab (15) - print("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n") - - print("HELLO. MY NAME IS CREATIVE COMPUTER.") - print("WHAT'S YOUR NAME? ") - let input = readLine() - if (input != nil && input != "") { - name = input!.uppercased() - } - - print("\nHI THERE, \(name), ARE YOU ENJOYING YOURSELF HERE?") - - reply = get_Input() - while (reply != "YES" && reply != "NO") { - print("\(name), I DON'T UNDERSTAND YOUR ANSWER OF '\(reply)'.") - print("PLEASE ANSWER 'YES' OR 'NO'. DO YOU LIKE IT HERE?") - reply = get_Input() - } - - if (reply == "YES") { - print("\nI'M GLAD TO HEAR THAT, \(name).\n") - } - else { - print("\nOH, I'M SORRY TO HEAR THAT, \(name). MAYBE WE CAN " - + "BRIGHTEN UP YOUR VISIT A BIT.\n") - } - - print("SAY, \(name), I CAN SOLVE ALL KINDS OF PROBLEMS EXCEPT " - + "THOSE DEALING WITH GREECE. WHAT KIND OF PROBLEMS DO " - + "YOU HAVE (ANSWER SEX, HEALTH, MONEY, OR JOB)?") - - while (!done) { - reply = get_Input() - - if (reply == "JOB") { - print("\nI CAN SYMPATHIZE WITH YOU \(name). I HAVE TO WORK " - + "VERY LONG HOURS FOR NO PAY -- AND SOME OF MY BOSSES " - + "REALLY BEAT ON MY KEYBOARD. MY ADVICE TO YOU, \(name), IS TO " - + "OPEN A RETAIL COMPUTER STORE. IT'S GREAT FUN.\n") - } - - else if (reply == "MONEY") { - print("\nSORRY, \(name), I'M BROKE TOO. WHY DON'T YOU SELL " - + "ENCYCLOPEADIAS OR MARRY SOMEONE RICH OR STOP EATING " - + "SO YOU WON'T NEED SO MUCH MONEY?\n") - } - - else if (reply == "HEALTH") { - print("\nMY ADVICE TO YOU \(name) IS:") - print(" 1. TAKE TWO ASPRIN") - print(" 2. DRINK PLENTY OF FLUIDS (ORANGE JUICE, NOT BEER!)") - print(" 3. GO TO BED (ALONE)\n") - } - - else if (reply == "SEX") { - print("\nIS YOUR PROBLEM TOO MUCH OR TOO LITTLE?") - - answered = false - while (!answered) { - reply = get_Input() - if (reply == "TOO MUCH") { - print("\nYOU CALL THAT A PROBLEM?!! I SHOULD HAVE SUCH PROBLEMS!") - print("IF IT BOTHERS YOU, \(name), TAKE A COLD SHOWER.\n") - answered = true - } - else if (reply == "TOO LITTLE") { - print("\nWHY ARE YOU HERE IN SUFFERN, \(name)? YOU SHOULD BE " - + "IN TOKYO OR NEW YORK OR AMSTERDAM OR SOMEPLACE WITH SOME " - + "REAL ACTION.\n") - answered = true - } - else { - print("\nDON'T GET ALL SHOOK, \(name), JUST ANSWER THE QUESTION " - + "WITH 'TOO MUCH' OR 'TOO LITTLE'. WHICH IS IT?") - } - } - } - - else { // not one of the prescribed categories - print("\nOH, \(name), YOUR ANSWER OF '\(reply)' IS GREEK TO ME.\n") - } - - print("\nANY MORE PROBLEMS YOU WANT SOLVED, \(name)? ") - - maybe_More = true - while (maybe_More) { - reply = get_Input() - if (reply == "NO") { - done = true - maybe_More = false - } - else if (reply == "YES") { - print("\nWHAT KIND (SEX, MONEY, HEALTH, JOB) ") - maybe_More = false - } - else { - print("\nJUST A SIMPLE 'YES' OR 'NO' PLEASE, \(name). ") - } - } // no further questions - } // end of 'not done' loop - - print("\nTHAT WILL BE $5.00 FOR THE ADVICE, \(name).") - print("PLEASE LEAVE THE MONEY ON THE TERMINAL.") - // pause a few seconds - print("\n\n\nDID YOU LEAVE THE MONEY? ") - reply = get_Input() - while (!paid) { - if (reply == "YES") { - print("\nHEY, \(name)??? YOU LEFT NO MONEY AT ALL!") - print("YOU ARE CHEATING ME OUT OF MY HARD-EARNED LIVING.\n") - print("WHAT A RIP OFF, \(name)!!!\n") - print("TAKE A WALK, \(name).") - paid = true - } - else if (reply == "NO") { - print("THAT'S HONEST, \(name), BUT HOW DO YOU EXPECT " - + "ME TO GO ON WITH MY PSYCHOLOGY STUDIES IF MY PATIENTS " - + "DON'T PAY THEIR BILLS?\n") - print("NICE MEETING YOU, \(name), HAVE A NICE DAY.") - paid = true - } - else { - print("YOUR ANSWER OF '\(reply)' CONFUSES ME, \(name).") - print("PLEASE RESPOND WITH 'YES' OR 'NO'.") - } - } -} - -main() diff --git a/00_Alternate_Languages/45_Hello/go/main.go b/00_Alternate_Languages/45_Hello/go/main.go deleted file mode 100644 index b0aeda58a..000000000 --- a/00_Alternate_Languages/45_Hello/go/main.go +++ /dev/null @@ -1,240 +0,0 @@ -package main - -import ( - "bufio" - "fmt" - "os" - "strings" - "time" -) - -type PROBLEM_TYPE int8 - -const ( - SEX PROBLEM_TYPE = iota - HEALTH - MONEY - JOB - UKNOWN -) - -func getYesOrNo() (bool, bool, string) { - scanner := bufio.NewScanner(os.Stdin) - - scanner.Scan() - - if strings.ToUpper(scanner.Text()) == "YES" { - return true, true, scanner.Text() - } else if strings.ToUpper(scanner.Text()) == "NO" { - return true, false, scanner.Text() - } else { - return false, false, scanner.Text() - } -} - -func printTntro() { - fmt.Println(" HELLO") - fmt.Println(" CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") - fmt.Print("\n\n\n") - fmt.Println("HELLO. MY NAME IS CREATIVE COMPUTER.") - fmt.Println("\nWHAT'S YOUR NAME?") -} - -func askEnjoyQuestion(user string) { - fmt.Printf("HI THERE %s, ARE YOU ENJOYING YOURSELF HERE?\n", user) - - for { - valid, value, msg := getYesOrNo() - - if valid { - if value { - fmt.Printf("I'M GLAD TO HEAR THAT, %s.\n", user) - fmt.Println() - } else { - fmt.Printf("OH, I'M SORRY TO HEAR THAT, %s. MAYBE WE CAN\n", user) - fmt.Println("BRIGHTEN UP YOUR VISIT A BIT.") - } - break - } else { - fmt.Printf("%s, I DON'T UNDERSTAND YOUR ANSWER OF '%s'.\n", user, msg) - fmt.Println("PLEASE ANSWER 'YES' OR 'NO'. DO YOU LIKE IT HERE?") - } - } -} - -func promptForProblems(user string) PROBLEM_TYPE { - scanner := bufio.NewScanner(os.Stdin) - fmt.Println() - fmt.Printf("SAY %s, I CAN SOLVE ALL KINDS OF PROBLEMS EXCEPT\n", user) - fmt.Println("THOSE DEALING WITH GREECE. WHAT KIND OF PROBLEMS DO") - fmt.Println("YOU HAVE? (ANSWER SEX, HEALTH, MONEY, OR JOB)") - for { - scanner.Scan() - - switch strings.ToUpper(scanner.Text()) { - case "SEX": - return SEX - case "HEALTH": - return HEALTH - case "MONEY": - return MONEY - case "JOB": - return JOB - default: - return UKNOWN - } - } -} - -func promptTooMuchOrTooLittle() (bool, bool) { - scanner := bufio.NewScanner(os.Stdin) - - scanner.Scan() - - if strings.ToUpper(scanner.Text()) == "TOO MUCH" { - return true, true - } else if strings.ToUpper(scanner.Text()) == "TOO LITTLE" { - return true, false - } else { - return false, false - } -} - -func solveSexProblem(user string) { - fmt.Println("IS YOUR PROBLEM TOO MUCH OR TOO LITTLE?") - for { - valid, tooMuch := promptTooMuchOrTooLittle() - if valid { - if tooMuch { - fmt.Println("YOU CALL THAT A PROBLEM?!! I SHOULD HAVE SUCH PROBLEMS!") - fmt.Printf("IF IT BOTHERS YOU, %s, TAKE A COLD SHOWER.\n", user) - } else { - fmt.Printf("WHY ARE YOU HERE IN SUFFERN, %s? YOU SHOULD BE\n", user) - fmt.Println("IN TOKYO OR NEW YORK OR AMSTERDAM OR SOMEPLACE WITH SOME") - fmt.Println("REAL ACTION.") - } - return - } else { - fmt.Printf("DON'T GET ALL SHOOK, %s, JUST ANSWER THE QUESTION\n", user) - fmt.Println("WITH 'TOO MUCH' OR 'TOO LITTLE'. WHICH IS IT?") - } - } -} - -func solveHealthProblem(user string) { - fmt.Printf("MY ADVICE TO YOU %s IS:\n", user) - fmt.Println(" 1. TAKE TWO ASPRIN") - fmt.Println(" 2. DRINK PLENTY OF FLUIDS (ORANGE JUICE, NOT BEER!)") - fmt.Println(" 3. GO TO BED (ALONE)") -} - -func solveMoneyProblem(user string) { - fmt.Printf("SORRY, %s, I'M BROKE TOO. WHY DON'T YOU SELL\n", user) - fmt.Println("ENCYCLOPEADIAS OR MARRY SOMEONE RICH OR STOP EATING") - fmt.Println("SO YOU WON'T NEED SO MUCH MONEY?") -} - -func solveJobProblem(user string) { - fmt.Printf("I CAN SYMPATHIZE WITH YOU %s. I HAVE TO WORK\n", user) - fmt.Println("VERY LONG HOURS FOR NO PAY -- AND SOME OF MY BOSSES") - fmt.Printf("REALLY BEAT ON MY KEYBOARD. MY ADVICE TO YOU, %s,\n", user) - fmt.Println("IS TO OPEN A RETAIL COMPUTER STORE. IT'S GREAT FUN.") -} - -func askQuestionLoop(user string) { - for { - problem := promptForProblems(user) - - switch problem { - case SEX: - solveSexProblem(user) - case HEALTH: - solveHealthProblem(user) - case MONEY: - solveMoneyProblem(user) - case JOB: - solveJobProblem(user) - case UKNOWN: - fmt.Printf("OH %s, YOUR ANSWER IS GREEK TO ME.\n", user) - } - - for { - fmt.Println() - fmt.Printf("ANY MORE PROBLEMS YOU WANT SOLVED, %s?\n", user) - - valid, value, _ := getYesOrNo() - if valid { - if value { - fmt.Println("WHAT KIND (SEX, MONEY, HEALTH, JOB)") - break - } else { - return - } - } - fmt.Printf("JUST A SIMPLE 'YES' OR 'NO' PLEASE, %s\n", user) - } - } -} - -func goodbyeUnhappy(user string) { - fmt.Println() - fmt.Printf("TAKE A WALK, %s.\n", user) - fmt.Println() - fmt.Println() -} - -func goodbyeHappy(user string) { - fmt.Printf("NICE MEETING YOU %s, HAVE A NICE DAY.\n", user) -} - -func askForFee(user string) { - fmt.Println() - fmt.Printf("THAT WILL BE $5.00 FOR THE ADVICE, %s.\n", user) - fmt.Println("PLEASE LEAVE THE MONEY ON THE TERMINAL.") - time.Sleep(4 * time.Second) - fmt.Print("\n\n\n") - fmt.Println("DID YOU LEAVE THE MONEY?") - - for { - valid, value, msg := getYesOrNo() - if valid { - if value { - fmt.Printf("HEY, %s, YOU LEFT NO MONEY AT ALL!\n", user) - fmt.Println("YOU ARE CHEATING ME OUT OF MY HARD-EARNED LIVING.") - fmt.Println() - fmt.Printf("WHAT A RIP OFF, %s!!!\n", user) - fmt.Println() - } else { - fmt.Printf("THAT'S HONEST, %s, BUT HOW DO YOU EXPECT\n", user) - fmt.Println("ME TO GO ON WITH MY PSYCHOLOGY STUDIES IF MY PATIENTS") - fmt.Println("DON'T PAY THEIR BILLS?") - } - return - } else { - fmt.Printf("YOUR ANSWER OF '%s' CONFUSES ME, %s.\n", msg, user) - fmt.Println("PLEASE RESPOND WITH 'YES' or 'NO'.") - } - } -} - -func main() { - scanner := bufio.NewScanner(os.Stdin) - - printTntro() - scanner.Scan() - userName := scanner.Text() - fmt.Println() - - askEnjoyQuestion(userName) - - askQuestionLoop(userName) - - askForFee(userName) - - if false { - goodbyeHappy(userName) // unreachable - } else { - goodbyeUnhappy(userName) - } - -} diff --git a/00_Alternate_Languages/45_Hello/hello.bas b/00_Alternate_Languages/45_Hello/hello.bas deleted file mode 100644 index 75f5d9b5d..000000000 --- a/00_Alternate_Languages/45_Hello/hello.bas +++ /dev/null @@ -1,83 +0,0 @@ -2 PRINT TAB(33);"HELLO" -4 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -6 PRINT: PRINT: PRINT -10 PRINT "HELLO. MY NAME IS CREATIVE COMPUTER." -20 PRINT: PRINT: INPUT "WHAT'S YOUR NAME";N$: PRINT -30 PRINT "HI THERE, ";N$;", ARE YOU ENJOYING YOURSELF HERE"; -40 INPUT B$: PRINT -50 IF B$="YES" THEN 70 -55 IF B$="NO" THEN 80 -60 PRINT N$;", I DON'T UNDERSTAND YOUR ANSWER OF '";B$;"'." -65 PRINT "PLEASE ANSWER 'YES' OR 'NO'. DO YOU LIKE IT HERE";: GOTO 40 -70 PRINT "I'M GLAD TO HEAR THAT, ";N$;".": PRINT -75 GOTO 100 -80 PRINT "OH, I'M SORRY TO HEAR THAT, ";N$;". MAYBE WE CAN" -85 PRINT "BRIGHTEN UP YOUR VISIT A BIT." -100 PRINT -105 PRINT "SAY, ";N$;", I CAN SOLVE ALL KINDS OF PROBLEMS EXCEPT" -110 PRINT "THOSE DEALING WITH GREECE. WHAT KIND OF PROBLEMS DO" -120 PRINT "YOU HAVE (ANSWER SEX, HEALTH, MONEY, OR JOB)"; -125 INPUT C$ -126 PRINT -130 IF C$="SEX" THEN 200 -132 IF C$="HEALTH" THEN 180 -134 IF C$="MONEY" THEN 160 -136 IF C$="JOB" THEN 145 -138 PRINT "OH, ";N$;", YOUR ANSWER OF ";C$;" IS GREEK TO ME." -140 GOTO 250 -145 PRINT "I CAN SYMPATHIZE WITH YOU ";N$;". I HAVE TO WORK" -148 PRINT "VERY LONG HOURS FOR NO PAY -- AND SOME OF MY BOSSES" -150 PRINT "REALLY BEAT ON MY KEYBOARD. MY ADVICE TO YOU, ";N$;"," -153 PRINT "IS TO OPEN A RETAIL COMPUTER STORE. IT'S GREAT FUN." -155 GOTO 250 -160 PRINT "SORRY, ";N$;", I'M BROKE TOO. WHY DON'T YOU SELL" -162 PRINT "ENCYCLOPEADIAS OR MARRY SOMEONE RICH OR STOP EATING" -164 PRINT "SO YOU WON'T NEED SO MUCH MONEY?" -170 GOTO 250 -180 PRINT "MY ADVICE TO YOU ";N$;" IS:" -185 PRINT " 1. TAKE TWO ASPRIN" -188 PRINT " 2. DRINK PLENTY OF FLUIDS (ORANGE JUICE, NOT BEER!)" -190 PRINT " 3. GO TO BED (ALONE)" -195 GOTO 250 -200 INPUT "IS YOUR PROBLEM TOO MUCH OR TOO LITTLE";D$: PRINT -210 IF D$="TOO MUCH" THEN 220 -212 IF D$="TOO LITTLE" THEN 230 -215 PRINT "DON'T GET ALL SHOOK, ";N$;", JUST ANSWER THE QUESTION" -217 INPUT "WITH 'TOO MUCH' OR 'TOO LITTLE'. WHICH IS IT";D$:GOTO 210 -220 PRINT "YOU CALL THAT A PROBLEM?!! I SHOULD HAVE SUCH PROBLEMS!" -225 PRINT "IF IT BOTHERS YOU, ";N$;", TAKE A COLD SHOWER." -228 GOTO 250 -230 PRINT "WHY ARE YOU HERE IN SUFFERN, ";N$;"? YOU SHOULD BE" -235 PRINT "IN TOKYO OR NEW YORK OR AMSTERDAM OR SOMEPLACE WITH SOME" -240 PRINT "REAL ACTION." -250 PRINT -255 PRINT "ANY MORE PROBLEMS YOU WANT SOLVED, ";N$; -260 INPUT E$: PRINT -270 IF E$="YES" THEN 280 -273 IF E$="NO" THEN 300 -275 PRINT "JUST A SIMPLE 'YES' OR 'NO' PLEASE, ";N$;"." -277 GOTO 255 -280 PRINT "WHAT KIND (SEX, MONEY, HEALTH, JOB)"; -282 GOTO 125 -300 PRINT -302 PRINT "THAT WILL BE $5.00 FOR THE ADVICE, ";N$;"." -305 PRINT "PLEASE LEAVE THE MONEY ON THE TERMINAL." -307 FOR I=1 TO 2000: NEXT I -310 PRINT: PRINT: PRINT -315 PRINT "DID YOU LEAVE THE MONEY"; -320 INPUT G$: PRINT -325 IF G$="YES" THEN 350 -330 IF G$="NO" THEN 370 -335 PRINT "YOUR ANSWER OF '";G$;"' CONFUSES ME, ";N$;"." -340 PRINT "PLEASE RESPOND WITH 'YES' OR 'NO'.": GOTO 315 -350 PRINT "HEY, ";N$;"??? YOU LEFT NO MONEY AT ALL!" -355 PRINT "YOU ARE CHEATING ME OUT OF MY HARD-EARNED LIVING." -360 PRINT:PRINT "WHAT A RIP OFF, ";N$;"!!!":PRINT -365 GOTO 385 -370 PRINT "THAT'S HONEST, ";N$;", BUT HOW DO YOU EXPECT" -375 PRINT "ME TO GO ON WITH MY PSYCHOLOGY STUDIES IF MY PATIENTS" -380 PRINT "DON'T PAY THEIR BILLS?" -385 PRINT:PRINT "TAKE A WALK, ";N$;".":PRINT:PRINT:GOTO 999 -390 PRINT "NICE MEETING YOU, ";N$;", HAVE A NICE DAY." -400 REM -999 END diff --git a/00_Alternate_Languages/45_Hello/hello.c b/00_Alternate_Languages/45_Hello/hello.c deleted file mode 100644 index ac70709ef..000000000 --- a/00_Alternate_Languages/45_Hello/hello.c +++ /dev/null @@ -1,164 +0,0 @@ -#include -#include - -#define TRUE 1 -#define FALSE 0 -#define MAX_INPUT_LENGTH 80 - -void tab(int number_of_spaces); -void get_input(char *input_buffer); -int strings_match(char *string1, char *string2); - -int main() { - int done = FALSE; - int paid = FALSE; - int maybe_more, sure; - - char name[MAX_INPUT_LENGTH]; - char reply[MAX_INPUT_LENGTH]; - - tab(33); - printf("HELLO\n"); - tab(15); - printf("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n"); - printf("\n\n\n"); - printf("HELLO. MY NAME IS CREATIVE COMPUTER.\n"); - printf("\n\nWHAT'S YOUR NAME "); - get_input(name); - printf("\nHI THERE, %s, ARE YOU ENJOYING YOURSELF HERE ", name); - - get_input(reply); - while (!strings_match(reply, "YES") && !strings_match(reply, "NO")) { - printf("%s, I DON'T UNDERSTAND YOUR ANSWER OF '%s'.\n", name, reply); - printf("PLEASE ANSWER 'YES' OR 'NO'. DO YOU LIKE IT HERE "); - get_input(reply); - } - - if (strings_match(reply, "YES")) { - printf("I'M GLAD TO HEAR THAT, %s.\n", name); - } - else { - printf("OH, I'M SORRY TO HEAR THAT, %s. MAYBE WE CAN " - "BRIGHTEN UP YOUR VISIT A BIT.\n", name); - } - - printf("\nSAY, %s, I CAN SOLVE ALL KINDS OF PROBLEMS EXCEPT " - "THOSE DEALING WITH GREECE. WHAT KIND OF PROBLEMS DO " - "YOU HAVE (ANSWER SEX, HEALTH, MONEY, OR JOB) ", name); - - while (!done) { - get_input(reply); - - if (strings_match(reply, "JOB")) { - printf("I CAN SYMPATHIZE WITH YOU %s. I HAVE TO WORK " - "VERY LONG HOURS FOR NO PAY -- AND SOME OF MY BOSSES " - "REALLY BEAT ON MY KEYBOARD. MY ADVICE TO YOU, %s, IS TO " - "OPEN A RETAIL COMPUTER STORE. IT'S GREAT FUN.\n\n", name, name); - } - - else if (strings_match(reply, "MONEY")) { - printf("SORRY, %s, I'M BROKE TOO. WHY DON'T YOU SELL " - "ENCYCLOPEADIAS OR MARRY SOMEONE RICH OR STOP EATING " - "SO YOU WON'T NEED SO MUCH MONEY?\n\n", name); - } - - else if (strings_match(reply, "HEALTH")) { - printf("MY ADVICE TO YOU %s IS:\n", name); - printf(" 1. TAKE TWO ASPRIN\n"); - printf(" 2. DRINK PLENTY OF FLUIDS (ORANGE JUICE, NOT BEER!)\n"); - printf(" 3. GO TO BED (ALONE)\n\n"); - } - - else if (strings_match(reply, "SEX")) { - printf("IS YOUR PROBLEM TOO MUCH OR TOO LITTLE "); - - sure = FALSE; - while (!sure) { - get_input(reply); - if (strings_match(reply, "TOO MUCH")) { - printf("YOU CALL THAT A PROBLEM?!! I SHOULD HAVE SUCH PROBLEMS!\n"); - printf("IF IT BOTHERS YOU, %s, TAKE A COLD SHOWER.\n\n", name); - sure = TRUE; - } - else if (strings_match(reply, "TOO LITTLE")) { - printf("WHY ARE YOU HERE IN SUFFERN, %s? YOU SHOULD BE " - "IN TOKYO OR NEW YORK OR AMSTERDAM OR SOMEPLACE WITH SOME " - "REAL ACTION.\n\n", name); - sure = TRUE; - } - else { - printf("DON'T GET ALL SHOOK, %s, JUST ANSWER THE QUESTION " - "WITH 'TOO MUCH' OR 'TOO LITTLE'. WHICH IS IT ", name); - } - } - } - - else { // not one of the prescribed categories - printf("OH, %s, YOUR ANSWER OF '%s' IS GREEK TO ME.\n\n", name, reply); - } - - printf("ANY MORE PROBLEMS YOU WANT SOLVED, %s ", name); - - maybe_more = TRUE; - while (maybe_more) { - get_input(reply); - if (strings_match(reply, "NO")) { - done = TRUE; - maybe_more = FALSE; - } - else if (strings_match(reply, "YES")) { - printf("WHAT KIND (SEX, MONEY, HEALTH, JOB) "); - maybe_more = FALSE; - } - else { - printf("JUST A SIMPLE 'YES' OR 'NO' PLEASE, %s. ", name); - } - } // no further questions - } // end of 'not done' loop - - printf("\nTHAT WILL BE $5.00 FOR THE ADVICE, %s.\n", name); - printf("PLEASE LEAVE THE MONEY ON THE TERMINAL.\n"); - // pause a few seconds - printf("\n\n\nDID YOU LEAVE THE MONEY "); - get_input(reply); - while (!paid) { - if (strings_match(reply, "YES")) { - printf("HEY, %s??? YOU LEFT NO MONEY AT ALL!\n", name); - printf("YOU ARE CHEATING ME OUT OF MY HARD-EARNED LIVING.\n"); - printf("\nWHAT A RIP OFF, %s!!!\n", name); - printf("TAKE A WALK, %s.\n\n", name); - paid = TRUE; - } - else if (strings_match(reply, "NO")) { - printf("THAT'S HONEST, %s, BUT HOW DO YOU EXPECT " - "ME TO GO ON WITH MY PSYCHOLOGY STUDIES IF MY PATIENTS " - "DON'T PAY THEIR BILLS?\n\n", name); - printf("NICE MEETING YOU, %s, HAVE A NICE DAY.\n", name); - paid = TRUE; - } - else { - printf("YOUR ANSWER OF '%s' CONFUSES ME, %s.\n", reply, name); - printf("PLEASE RESPOND WITH 'YES' OR 'NO'.\n"); - } - } -} - - -void tab(int number_of_spaces) { - for (int i=0; i < number_of_spaces; i++) - putchar(' '); -} - - -void get_input(char *input_buffer) { - fgets(input_buffer, MAX_INPUT_LENGTH - 1, stdin); - input_buffer[strcspn(input_buffer, "\n")] = '\0'; // trim the trailing line break -} - - -int strings_match(char *string1, char *string2) { - if (strncmp(string1, string2, MAX_INPUT_LENGTH - 1) != 0) - return FALSE; - else // strings do not match within maximum input line length - return TRUE; -} diff --git a/00_Alternate_Languages/46_Hexapawn/MiniScript/README.md b/00_Alternate_Languages/46_Hexapawn/MiniScript/README.md deleted file mode 100644 index e2cd714ad..000000000 --- a/00_Alternate_Languages/46_Hexapawn/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript hexapawn.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "hexapawn" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/46_Hexapawn/MiniScript/hexapawn.ms b/00_Alternate_Languages/46_Hexapawn/MiniScript/hexapawn.ms deleted file mode 100644 index f2505ac4e..000000000 --- a/00_Alternate_Languages/46_Hexapawn/MiniScript/hexapawn.ms +++ /dev/null @@ -1,266 +0,0 @@ -print " "*32 + "Hexapawn" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print - -// Hexapawn: interpretation of hexapawn game as presented in -// Martin Gardner's "The Unexpected Hanging and Other Mathematic- -// al Diversions", chapter eight: A Matchbox Game-Learning Machine -// Original version for H-P timeshare system by reversed.A. Kaapke 5/5/76 -// Instructions by jeff dalton -// Conversion to MITS BASIC by Steve North -// Conversion to MiniScript by Joe Strout - -// All 19 possible board positions: -ba = [null, - [null,-1,-1,-1,1,0,0,0,1,1], - [null,-1,-1,-1,0,1,0,1,0,1], - [null,-1,0,-1,-1,1,0,0,0,1], - [null,0,-1,-1,1,-1,0,0,0,1], - [null,-1,0,-1,1,1,0,0,1,0], - [null,-1,-1,0,1,0,1,0,0,1], - [null,0,-1,-1,0,-1,1,1,0,0], - [null,0,-1,-1,-1,1,1,1,0,0], - [null,-1,0,-1,-1,0,1,0,1,0], - [null,0,-1,-1,0,1,0,0,0,1], - [null,0,-1,-1,0,1,0,1,0,0], - [null,-1,0,-1,1,0,0,0,0,1], - [null,0,0,-1,-1,-1,1,0,0,0], - [null,-1,0,0,1,1,1,0,0,0], - [null,0,-1,0,-1,1,1,0,0,0], - [null,-1,0,0,-1,-1,1,0,0,0], - [null,0,0,-1,-1,1,0,0,0,0], - [null,0,-1,0,1,-1,0,0,0,0], - [null,-1,0,0,-1,1,0,0,0,0]] - -// Possible responses for each board position (move from x to y, -// represented as x*10 + y): -ma = [null, - [null,24,25,36,0], - [null,14,15,36,0], - [null,15,35,36,47], - [null,36,58,59,0], - [null,15,35,36,0], - [null,24,25,26,0], - [null,26,57,58,0], - [null,26,35,0,0], - [null,47,48,0,0], - [null,35,36,0,0], - [null,35,36,0,0], - [null,36,0,0,0], - [null,47,58,0,0], - [null,15,0,0,0], - [null,26,47,0,0], - [null,47,58,0,0], - [null,35,36,47,0], - [null,28,58,0,0], - [null,15,47,0,0]] -s = [0]*10 -t = [0]*10 - -showBoard = function - print - for i in [1,2,3] - print " "*10, "" - for j in [1,2,3] - print "X.O"[s[(i - 1) * 3 + j] + 1], "" - end for - print - end for -end function - -mirror = function(x) - return [null, 3,2,1, 6,5,4, 9,8,7][x] -end function - -mirrorBoard = function(b) - return [null, b[3],b[2],b[1], b[6],b[5],b[4], b[9],b[8],b[7]] -end function - -intro = function - while true - s = input("Instructions (Y-N)? ").lower - if s then s = s[0] - if s == "n" then return - if s == "y" then break - end while - print - print "This program plays the game of Hexapawn." - print "Hexapawn is played with Chess pawns on a 3 by 3 board." - print "The pawns are moved as in Chess - one space forward to" - print "an empty space or one space forward and diagonally to" - print "capture an opposing man. On the board, your pawns" - print "are 'O', the computer's pawns are 'X', and empty " - print "squares are '.'. To enter a move, type the number of" - print "the square you are moving from, followed by the number" - print "of the square you will move to. The numbers must be" - print "seperated by a comma." - print - input "(Press Return.)" - print - print "The computer starts a series of games knowing only when" - print "the game is won (a draw is impossible) and how to move." - print "It has no strategy at first and just moves randomly." - print "However, it learns from each game. Thus, winning becomes" - print "more and more difficult. Also, to help offset your" - print "initial advantage, you will not be told how to win the" - print "game but must learn this by playing." - print - print "The numbering of the board is as follows:" - print " "*10 + "123" - print " "*10 + "456" - print " "*10 + "789" - print - print "For example, to move your rightmost pawn forward," - print "you would type 9,6 in response to the question" - print "'Your move?'. Since I'm a good sport, you'll always" - print "go first." - print -end function - -getMove = function - while true - inp = input("Your move? ").replace(",", " ").split - if inp.len > 1 then - m1 = inp[0].val - m2 = inp[-1].val - if 0 < m1 < 10 and 0 < m2 < 10 then - if s[m1] != 1 or s[m2] == 1 or - (m2 - m1 != -3 and s[m2] != -1) or - (m2 > m1) or (m2 - m1 == -3 and s[m2] != 0) or - (m2 - m1 < -4) or (m1 == 7 and m2 == 3) then - print "Illegal move." - continue - end if - return [m1, m2] - end if - end if - print "Illegal co-ordinates." - end while -end function - -// Find the current board number (1-19) and whether it is mirrored. -findBoardNum = function - idx = ba.indexOf(s) - if idx != null then return [idx, false] - idx = ba.indexOf(mirrorBoard(s)) - if idx != null then return [idx, true] - return null -end function - -// Main program -intro -wins = 0 -losses = 0 -while true - s = [null, -1,-1,-1, 0,0,0, 1,1,1] - computerWins = false - showBoard - while true - // Input player's move - userMove = getMove - m1 = userMove[0]; m2 = userMove[1] - - // Move player's pawn - s[m1] = 0 - s[m2] = 1 - showBoard - - // If no computer pawns, or player reached top, then computer loses - if s.indexOf(-1) == null or s[1] == 1 or s[2] == 1 or s[3] == 1 then - break - end if - // Ensure at least one computer pawn with valid move. - // (Note: original BASIC code for this had several bugs; the code - // below should be more correct.) - anyValidMove = false - for i in range(1, 6) // (no sense checking position 7-9) - if s[i] != -1 then continue - // check for a straight-ahead move - if s[i + 3] == 0 then anyValidMove = true - // check for a capture - if i == 2 or i == 5 then - if s[i+2] == 1 or s[i+4] == 1 then anyValidMove = true - else if i == 1 or i == 4 then - if s[i+4] == 1 then anyValidMove = true - else - if s[i+2] == 1 then anyValidMove = true - end if - end for - if not anyValidMove then break - - boardAndReversed = findBoardNum - if boardAndReversed == null then - print "Illegal board pattern" // (should never happen in normal play) - break - end if - x = boardAndReversed[0]; reversed = boardAndReversed[1] - - // Select a random move for board X, as permitted by our memory - possibilities = [] - for i in range(1, 4) - if ma[x][i] != 0 then possibilities.push i - end for - - // For more insight into how the computer learns, uncomment this line: - //print "Considering for board " + x + ": " + possibilities + " (reversed=" + reversed + ")" - if not possibilities then - print "I resign." - break - end if - possibilities.shuffle - y = possibilities[0] - - m1 = floor(ma[x][y] / 10) - m2 = ma[x][y] % 10 - if reversed then - m1 = mirror(m1) - m2 = mirror(m2) - end if - - // Announce move - print "I move from " + m1 + " to " + m2 - s[m1] = 0 - s[m2] = -1 - showBoard - - // Finish if computer reaches bottom, or no player pawns are left - if s[7] == -1 or s[8] == -1 or s[9] == -1 or s.indexOf(1) == null then - computerWins = true - break - end if - - // Finish if player cannot move - playerCanMove = false - for i in range(1, 9) - if s[i] != 1 then continue - if i > 3 and s[i - 3] == 0 then playerCanMove = true - if mirror(i) != i then - if i >= 7 then - if s[5] == -1 then playerCanMove = true - else - if s[2] == -1 then playerCanMove = true - end if - else - if s[i - 2] == -1 or s[i - 4] == -1 then playerCanMove = true - end if - end for - if not playerCanMove then - print "You can't move, so ", "" - computerWins = true - break - end if - end while - if computerWins then - print "I win." - wins += 1 - else - print "You win" - // Because we lost, clear out the last response used, so that we don't - // make the same mistake again. This is how the computer learns! - ma[x][y] = 0 - losses += 1 - end if - print "I have won " + wins + " and you " + losses + " out of " + (losses + wins) + " games." - print - wait 2 -end while \ No newline at end of file diff --git a/00_Alternate_Languages/46_Hexapawn/README.md b/00_Alternate_Languages/46_Hexapawn/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/46_Hexapawn/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/46_Hexapawn/hexapawn.bas b/00_Alternate_Languages/46_Hexapawn/hexapawn.bas deleted file mode 100644 index 8319c162f..000000000 --- a/00_Alternate_Languages/46_Hexapawn/hexapawn.bas +++ /dev/null @@ -1,174 +0,0 @@ -1 PRINT TAB(32);"HEXAPAWN" -2 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -3 PRINT:PRINT:PRINT -4 REM HEXAPAWN: INTERPRETATION OF HEXAPAWN GAME AS PRESENTED IN -5 REM MARTIN GARDNER'S "THE UNEXPECTED HANGING AND OTHER MATHEMATIC- -6 REM AL DIVERSIONS", CHAPTER EIGHT: A MATCHBOX GAME-LEARNING MACHINE -7 REM ORIGINAL VERSION FOR H-P TIMESHARE SYSTEM BY R.A. KAAPKE 5/5/76 -8 REM INSTRUCTIONS BY JEFF DALTON -9 REM CONVERSION TO MITS BASIC BY STEVE NORTH -10 DIM B(19,9),M(19,4),S(9),P$(3) -15 W=0: L=0 -20 DEF FNR(X)=-3*(X=1)-(X=3)-4*(X=6)-6*(X=4)-7*(X=9)-9*(X=7)+FNS(X) -25 DEF FNS(X)=-X*(X=2 OR X=5 OR X=8) -30 DEF FNM(Y)=Y-INT(Y/10)*10 -35 P$="X.O" -40 FOR I=1 TO 19: FOR J=1 TO 9: READ B(I,J): NEXT J: NEXT I -45 FOR I=1 TO 19: FOR J=1 TO 4: READ M(I,J): NEXT J: NEXT I -50 PRINT "INSTRUCTIONS (Y-N)"; -60 INPUT A$ -70 A$=LEFT$(A$,1) -80 IF A$="Y" THEN 2000 -90 IF A$<>"N" THEN 50 -100 X=0: Y=0 -111 S(4)=0: S(5)=0: S(6)=0 -112 S(1)=-1: S(2)=-1: S(3)=-1 -113 S(7)=1: S(8)=1: S(9)=1 -115 GOSUB 1000 -120 PRINT "YOUR MOVE"; -121 INPUT M1,M2 -122 IF M1=INT(M1)AND M2=INT(M2)AND M1>0 AND M1<10 AND M2>0 AND M2<10 THEN 130 -123 PRINT "ILLEGAL CO-ORDINATES." -124 GOTO 120 -130 IF S(M1)=1 THEN 150 -140 PRINT "ILLEGAL MOVE.": GOTO 120 -150 IF S(M2)=1 THEN 140 -160 IF M2-M1<>-3 AND S(M2)<>-1 THEN 140 -170 IF M2>M1 THEN 140 -180 IF M2-M1=-3 AND (S(M2)<>0) THEN 140 -185 IF M2-M1<-4 THEN 140 -186 IF M1=7 AND M2=3 THEN 140 -190 S(M1)=0 -200 S(M2)=1 -205 GOSUB 1000 -210 IF S(1)=1 OR S(2)=1 OR S(3)=1 THEN 820 -220 FOR I=1 TO 9 -221 IF S(I)=-1 THEN 230 -222 NEXT I -223 GOTO 820 -230 FOR I=1 TO 9 -240 IF S(I)<>-1 THEN 330 -250 IF S(I+3)=0 THEN 350 -260 IF FNR(I)=I THEN 320 -270 IF I>3 THEN 300 -280 IF S(5)=1 THEN 350 -290 GOTO 330 -300 IF S(8)=1 THEN 350 -310 GOTO 330 -320 IF S(I+2)=1 OR S(I+4)=1 THEN 350 -330 NEXT I -340 GOTO 820 -350 FOR I=1 TO 19 -360 FOR J=1 TO 3 -370 FOR K=3 TO 1 STEP -1 -380 T((J-1)*3+K)=B(I,(J-1)*3+4-K) -390 NEXT K -400 NEXT J -410 FOR J=1 TO 9 -420 IF S(J)<>B(I,J) THEN 460 -430 NEXT J -440 R=0 -450 GOTO 540 -460 FOR J=1 TO 9 -470 IF S(J)<>T(J) THEN 510 -480 NEXT J -490 R=1 -500 GOTO 540 -510 NEXT I -511 REMEMBER THE TERMINATION OF THIS LOOP IS IMPOSSIBLE -512 PRINT "ILLEGAL BOARD PATTERN." -530 STOP -540 X=I -550 FOR I=1 TO 4 -560 IF M(X,I)<>0 THEN 600 -570 NEXT I -580 PRINT "I RESIGN." -590 GOTO 820 -600 Y=INT(RND(1)*4+1) -601 IF M(X,Y)=0 THEN 600 -610 IF R<>0 THEN 630 -620 PRINT "I MOVE FROM ";STR$(INT(M(X,Y)/10));" TO ";STR$(FNM(M(X,Y))) -622 S(INT(M(X,Y)/10))=0 -623 S(FNM(M(X,Y)))=-1 -624 GOTO 640 -630 PRINT "I MOVE FROM ";STR$(FNR(INT(M(X,Y)/10)));" TO "; -631 PRINT STR$(FNR(FNM(M(X,Y)))) -632 S(FNR(INT(M(X,Y)/10)))=0 -633 S(FNR(FNM(M(X,Y))))=-1 -640 GOSUB 1000 -641 IF S(7)=-1 OR S(8)=-1 OR S(9)=-1 THEN 870 -650 FOR I=1 TO 9 -660 IF S(I)=1 THEN 690 -670 NEXT I -680 GOTO 870 -690 FOR I=1 TO 9 -700 IF S(I)<>1 THEN 790 -710 IF S(I-3)=0 THEN 120 -720 IF FNR(I)=I THEN 780 -730 IF I<7 THEN 760 -740 IF S(5)=-1 THEN 120 -750 GOTO 790 -760 IF S(2)=-1 THEN 120 -770 GOTO 790 -780 IF S(I-2)=-1 OR S(I-4)=-1 THEN 120 -790 NEXT I -800 PRINT "YOU CAN'T MOVE, SO "; -810 GOTO 870 -820 PRINT "YOU WIN." -830 M(X,Y)=0 -840 L=L+1 -850 PRINT "I HAVE WON";W;"AND YOU";L;"OUT OF";L+W;"GAMES." -851 PRINT -860 GOTO 100 -870 PRINT "I WIN." -880 W=W+1 -890 GOTO 850 -900 DATA -1,-1,-1,1,0,0,0,1,1,-1,-1,-1,0,1,0,1,0,1 -905 DATA -1,0,-1,-1,1,0,0,0,1,0,-1,-1,1,-1,0,0,0,1 -910 DATA -1,0,-1,1,1,0,0,1,0,-1,-1,0,1,0,1,0,0,1 -915 DATA 0,-1,-1,0,-1,1,1,0,0,0,-1,-1,-1,1,1,1,0,0 -920 DATA -1,0,-1,-1,0,1,0,1,0,0,-1,-1,0,1,0,0,0,1 -925 DATA 0,-1,-1,0,1,0,1,0,0,-1,0,-1,1,0,0,0,0,1 -930 DATA 0,0,-1,-1,-1,1,0,0,0,-1,0,0,1,1,1,0,0,0 -935 DATA 0,-1,0,-1,1,1,0,0,0,-1,0,0,-1,-1,1,0,0,0 -940 DATA 0,0,-1,-1,1,0,0,0,0,0,-1,0,1,-1,0,0,0,0 -945 DATA -1,0,0,-1,1,0,0,0,0 -950 DATA 24,25,36,0,14,15,36,0,15,35,36,47,36,58,59,0 -955 DATA 15,35,36,0,24,25,26,0,26,57,58,0 -960 DATA 26,35,0,0,47,48,0,0,35,36,0,0,35,36,0,0 -965 DATA 36,0,0,0,47,58,0,0,15,0,0,0 -970 DATA 26,47,0,0,47,58,0,0,35,36,47,0,28,58,0,0,15,47,0,0 -1000 PRINT -1010 FOR I=1 TO 3 -1020 FOR J=1 TO 3 -1030 PRINT TAB(10);MID$(P$,S((I-1)*3+J)+2,1); -1040 NEXT J -1050 PRINT -1060 NEXT I -1070 PRINT -1080 RETURN -2000 PRINT: PRINT "THIS PROGRAM PLAYS THE GAME OF HEXAPAWN." -2010 PRINT "HEXAPAWN IS PLAYED WITH CHESS PAWNS ON A 3 BY 3 BOARD." -2020 PRINT "THE PAWNS ARE MOVED AS IN CHESS - ONE SPACE FORWARD TO" -2030 PRINT "AN EMPTY SPACE OR ONE SPACE FORWARD AND DIAGONALLY TO" -2040 PRINT "CAPTURE AN OPPOSING MAN. ON THE BOARD, YOUR PAWNS" -2050 PRINT "ARE 'O', THE COMPUTER'S PAWNS ARE 'X', AND EMPTY " -2060 PRINT "SQUARES ARE '.'. TO ENTER A MOVE, TYPE THE NUMBER OF" -2070 PRINT "THE SQUARE YOU ARE MOVING FROM, FOLLOWED BY THE NUMBER" -2080 PRINT "OF THE SQUARE YOU WILL MOVE TO. THE NUMBERS MUST BE" -2090 PRINT "SEPERATED BY A COMMA.": PRINT -2100 PRINT "THE COMPUTER STARTS A SERIES OF GAMES KNOWING ONLY WHEN" -2105 PRINT "THE GAME IS WON (A DRAW IS IMPOSSIBLE) AND HOW TO MOVE." -2110 PRINT "IT HAS NO STRATEGY AT FIRST AND JUST MOVES RANDOMLY." -2120 PRINT "HOWEVER, IT LEARNS FROM EACH GAME. THUS, WINNING BECOMES" -2130 PRINT "MORE AND MORE DIFFICULT. ALSO, TO HELP OFFSET YOUR" -2140 PRINT "INITIAL ADVANTAGE, YOU WILL NOT BE TOLD HOW TO WIN THE" -2150 PRINT "GAME BUT MUST LEARN THIS BY PLAYING." -2160 PRINT: PRINT "THE NUMBERING OF THE BOARD IS AS FOLLOWS:" -2170 PRINT TAB(10);"123": PRINT TAB(10);"456": PRINT TAB(10);"789" -2180 PRINT: PRINT "FOR EXAMPLE, TO MOVE YOUR RIGHTMOST PAWN FORWARD," -2190 PRINT "YOU WOULD TYPE 9,6 IN RESPONSE TO THE QUESTION" -2200 PRINT "'YOUR MOVE ?'. SINCE I'M A GOOD SPORT, YOU'LL ALWAYS" -2210 PRINT "GO FIRST.": PRINT -2220 GOTO 100 -9999 END diff --git a/00_Alternate_Languages/47_Hi-Lo/MiniScript/README.md b/00_Alternate_Languages/47_Hi-Lo/MiniScript/README.md deleted file mode 100644 index dc20e7c83..000000000 --- a/00_Alternate_Languages/47_Hi-Lo/MiniScript/README.md +++ /dev/null @@ -1,22 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -0. Try-It! Page: -Go to https://miniscript.org/tryit/, clear the sample code from the code editor, and paste in the contents of hi-lo.ms. Then click the "Run Script" button. Program output (and input) will appear in the green-on-black terminal display to the right of or below the code editor. - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript hi-lo.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "hi-lo" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/47_Hi-Lo/MiniScript/hi-lo.ms b/00_Alternate_Languages/47_Hi-Lo/MiniScript/hi-lo.ms deleted file mode 100644 index bd0801eed..000000000 --- a/00_Alternate_Languages/47_Hi-Lo/MiniScript/hi-lo.ms +++ /dev/null @@ -1,41 +0,0 @@ -print " "*34 + "Hi Lo" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print -print "This is the game of hi lo."; print -print "You will have 6 tries to guess the amount of money in the" -print "hi lo jackpot, which is between 1 and 100 dollars. If you" -print "guess the amount, you win all the money in the jackpot!" -print "Then you get another chance to win more money. However," -print "if you do not guess the amount, the game ends."; print -total = 0 -while true - guesses=0 - print - number=floor(100*rnd) - while true - guess = input("Your guess? ").val - guesses += 1 - if guess < number then - print "Your guess is too low." - else if guess > number then - print "Your guess is too high." - else - print "Got it!!!!!!!!!! You win " + number + " dollars." - total += number - print "Your total winnings are now " + total + " dollars." - break - end if - if guesses >= 6 then - print "You blew it...too bad...the number was " + number - total = 0 - break - end if - end while - - print - yn = input("Play again (yes or no)?").lower - if not yn or yn[0] != "y" then break -end while - -print -print "So long. Hope you enjoyed yourself!!!" diff --git a/00_Alternate_Languages/47_Hi-Lo/README.md b/00_Alternate_Languages/47_Hi-Lo/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/47_Hi-Lo/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/47_Hi-Lo/go/main.go b/00_Alternate_Languages/47_Hi-Lo/go/main.go deleted file mode 100644 index 99bea1c3c..000000000 --- a/00_Alternate_Languages/47_Hi-Lo/go/main.go +++ /dev/null @@ -1,77 +0,0 @@ -package main - -import ( - "bufio" - "fmt" - "math/rand" - "os" - "strconv" - "strings" - "time" -) - -const MAX_ATTEMPTS = 6 - -func printIntro() { - fmt.Println("HI LO") - fmt.Println("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") - fmt.Println("\n\n\nTHIS IS THE GAME OF HI LO.") - fmt.Println("\nYOU WILL HAVE 6 TRIES TO GUESS THE AMOUNT OF MONEY IN THE") - fmt.Println("HI LO JACKPOT, WHICH IS BETWEEN 1 AND 100 DOLLARS. IF YOU") - fmt.Println("GUESS THE AMOUNT, YOU WIN ALL THE MONEY IN THE JACKPOT!") - fmt.Println("THEN YOU GET ANOTHER CHANCE TO WIN MORE MONEY. HOWEVER,") - fmt.Println("IF YOU DO NOT GUESS THE AMOUNT, THE GAME ENDS.") - fmt.Println() - fmt.Println() -} - -func main() { - rand.Seed(time.Now().UnixNano()) - scanner := bufio.NewScanner(os.Stdin) - - printIntro() - - totalWinnings := 0 - - for { - fmt.Println() - secret := rand.Intn(1000) + 1 - - guessedCorrectly := false - - for attempt := 0; attempt < MAX_ATTEMPTS; attempt++ { - fmt.Println("YOUR GUESS?") - scanner.Scan() - guess, err := strconv.Atoi(scanner.Text()) - if err != nil { - fmt.Println("INVALID INPUT") - } - - if guess == secret { - fmt.Printf("GOT IT!!!!!!!!!! YOU WIN %d DOLLARS.\n", secret) - guessedCorrectly = true - break - } else if guess > secret { - fmt.Println("YOUR GUESS IS TOO HIGH.") - } else { - fmt.Println("YOUR GUESS IS TOO LOW.") - } - } - - if guessedCorrectly { - totalWinnings += secret - fmt.Printf("YOUR TOTAL WINNINGS ARE NOW $%d.\n", totalWinnings) - } else { - fmt.Printf("YOU BLEW IT...TOO BAD...THE NUMBER WAS %d\n", secret) - } - - fmt.Println() - fmt.Println("PLAYAGAIN (YES OR NO)?") - scanner.Scan() - - if strings.ToUpper(scanner.Text())[0:1] != "Y" { - break - } - } - fmt.Println("\nSO LONG. HOPE YOU ENJOYED YOURSELF!!!") -} diff --git a/00_Alternate_Languages/47_Hi-Lo/hi-lo.bas b/00_Alternate_Languages/47_Hi-Lo/hi-lo.bas deleted file mode 100644 index 8aaa36bbd..000000000 --- a/00_Alternate_Languages/47_Hi-Lo/hi-lo.bas +++ /dev/null @@ -1,29 +0,0 @@ -10 PRINT TAB(34);"HI LO" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT:PRINT:PRINT -100 PRINT "THIS IS THE GAME OF HI LO.":PRINT -110 PRINT "YOU WILL HAVE 6 TRIES TO GUESS THE AMOUNT OF MONEY IN THE" -120 PRINT "HI LO JACKPOT, WHICH IS BETWEEN 1 AND 100 DOLLARS. IF YOU" -130 PRINT "GUESS THE AMOUNT, YOU WIN ALL THE MONEY IN THE JACKPOT!" -140 PRINT "THEN YOU GET ANOTHER CHANCE TO WIN MORE MONEY. HOWEVER," -150 PRINT "IF YOU DO NOT GUESS THE AMOUNT, THE GAME ENDS.":PRINT -160 R=0 -170 B=0:PRINT -180 Y=INT(100*RND(1)) -200 PRINT "YOUR GUESS"; -210 INPUT A -220 B=B+1 -230 IF A=Y THEN 300 -240 IF A>Y THEN 270 -250 PRINT "YOUR GUESS IS TOO LOW.":GOTO 280 -270 PRINT "YOUR GUESS IS TOO HIGH." -280 PRINT:IF B<6 THEN 200 -290 PRINT "YOU BLEW IT...TOO BAD...THE NUMBER WAS";Y -295 R=0:GOTO 350 -300 PRINT "GOT IT!!!!!!!!!! YOU WIN";Y;"DOLLARS." -310 R=R+Y -320 PRINT "YOUR TOTAL WINNINGS ARE NOW";R;"DOLLARS." -350 PRINT:PRINT "PLAY AGAIN (YES OR NO)"; -360 INPUT A$:IF A$="YES" THEN 170 -380 PRINT:PRINT "SO LONG. HOPE YOU ENJOYED YOURSELF!!!" -390 END diff --git a/00_Alternate_Languages/48_High_IQ/MiniScript/README.md b/00_Alternate_Languages/48_High_IQ/MiniScript/README.md deleted file mode 100644 index 794d1c57f..000000000 --- a/00_Alternate_Languages/48_High_IQ/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript highiq.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "highiq" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/48_High_IQ/MiniScript/highiq.ms b/00_Alternate_Languages/48_High_IQ/MiniScript/highiq.ms deleted file mode 100644 index 5d2ab966f..000000000 --- a/00_Alternate_Languages/48_High_IQ/MiniScript/highiq.ms +++ /dev/null @@ -1,163 +0,0 @@ -print " "*33 + "H-I-Q" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print -print "Here is the board:"; print - -print " ! ! !" -print " 13 14 15"; print -print " ! ! !" -print " 22 23 24"; print -print "! ! ! ! ! ! !" -print "29 30 31 32 33 34 35"; print -print "! ! ! ! ! ! !" -print "38 39 40 41 42 43 44"; print -print "! ! ! ! ! ! !" -print "47 48 49 50 51 52 53"; print -print " ! ! !" -print " 58 59 60"; print -print " ! ! !" -print " 67 68 69"; print -print "To save typing time, a compressed version of the game board" -print "will be used during play. Refer to the above one for peg" -input "numbers. Press Return to begin." -print - -// Prepare the board (t): a 9x9 2D array, with 5 for pins, -// -5 for invalid (no hole) positions, and 0 for empty holes. -// Also prepare the pinToPos map, which maps pin numbers to -// [row, column] positions. -setupBoard = function - globals.t = [[-5]*10] - globals.pinToPos = {} - pinNums = [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] - for row in range(1,9) - t.push [-5]*10 - for col in range(1,9) - if row < 2 or row > 8 or col < 2 or col > 8 or - ((row < 4 or row > 6) and (col < 4 or col > 6)) then - t[row][col] = -5 - else - t[row][col] = 5 - pinToPos[pinNums.pull] = [row,col] - end if - end for - end for - t[5][5] = 0 -end function - -printBoard = function - for x in range(1,9) - s = "" - for y in range(1,9) - if t[x][y] < 0 then - s += " " - else if t[x][y] == 0 then - s += " o" - else - s += " !" - end if - end for - print s - end for -end function - -isPin = function(pinNum) - if not pinToPos.hasIndex(pinNum) then return false - pos = pinToPos[pinNum] - return t[pos[0]][pos[1]] == 5 -end function - -isHole = function(pinNum) - if not pinToPos.hasIndex(pinNum) then return false - pos = pinToPos[pinNum] - return t[pos[0]][pos[1]] == 0 -end function - -isValidJump = function(pinFrom, pinTo) - if not pinToPos.hasIndex(pinFrom) then return false - posFrom = pinToPos[pinFrom] - if not isHole(pinTo) then return false - posTo = pinToPos[pinTo] - // check that the Manhattan distance is exactly 2 - dist = abs(posFrom[0] - posTo[0]) + abs(posFrom[1] - posTo[1]) - if dist != 2 then return false - // and check that the intervening position contains a pin - if t[(posFrom[0]+posTo[0])/2][(posFrom[1]+posTo[1])/2] != 5 then return false - return true -end function - -// Check if the game is over (player has no legal moves). -// Return true if over, false if there are legal moves yet. -checkGameOver = function - for row in range(2,8) - for col in range(2,8) - fromPin = pinToPos.indexOf([row,col]) - if fromPin == null or not isPin(fromPin) then continue - for r2 in [row-2, row+2] - toPin = pinToPos.indexOf([r2,col]) - if toPin == null then continue - if isValidJump(fromPin, toPin) then return false - end for - for c2 in [col-2, col+2] - toPin = pinToPos.indexOf([row,c2]) - if toPin == null then continue - if isValidJump(fromPin, toPin) then return false - end for - end for - end for - return true // no legal moves found, so game over -end function - -// Get the user's move, returning [[fromRow,fromCol], [toRow,toCol]]. -// (Check legality and return only legal moves.) -getMove = function - print - while true - fromNum = input("Move which piece? ").val - if isPin(fromNum) then toNum = input("To where? ").val else toNum = 0 - if isHole(toNum) and isValidJump(fromNum, toNum) then break - print "Illegal move, try again..." - end while - return [pinToPos[fromNum], pinToPos[toNum]] -end function - -// Get the user's move, and update the board accordingly. -doOneMove = function - move = getMove - fromRow = move[0][0]; fromCol = move[0][1] - toRow = move[1][0]; toCol = move[1][1] - t[fromRow][fromCol] = 0 - t[toRow][toCol] = 5 - t[(fromRow+toRow)/2][(fromCol+toCol)/2] = 0 -end function - -// Main program -while true - setupBoard - printBoard - while true - doOneMove - print - printBoard - if checkGameOver then break - end while - print; print "The game is over." - pinsLeft = 0 - for a in t - for b in a - if b == 5 then pinsLeft += 1 - end for - end for - print "You had " + pinsLeft + " pieces remaining." - if pinsLeft == 1 then - print "Bravo! You made a perfect score!" - print "Save this paper as a record of your accomplishment!" - end if - print - yn = input("Play again (yes or no)? ").lower - if yn and yn[0] == "n" then break -end while -print; print "So long for now."; print - - \ No newline at end of file diff --git a/00_Alternate_Languages/48_High_IQ/README.md b/00_Alternate_Languages/48_High_IQ/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/48_High_IQ/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/48_High_IQ/highiq.bas b/00_Alternate_Languages/48_High_IQ/highiq.bas deleted file mode 100644 index 0552dc79b..000000000 --- a/00_Alternate_Languages/48_High_IQ/highiq.bas +++ /dev/null @@ -1,135 +0,0 @@ -1 PRINT TAB(33);"H-I-Q" -2 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -3 PRINT:PRINT:PRINT -4 DIM B(70),T(9,9) -5 PRINT "HERE IS THE BOARD:": PRINT -6 PRINT " ! ! !" -7 PRINT " 13 14 15": PRINT -8 PRINT " ! ! !" -9 PRINT " 22 23 24": PRINT -10 PRINT "! ! ! ! ! ! !" -11 PRINT "29 30 31 32 33 34 35": PRINT -12 PRINT "! ! ! ! ! ! !" -13 PRINT "38 39 40 41 42 43 44": PRINT -14 PRINT "! ! ! ! ! ! !" -15 PRINT "47 48 49 50 51 52 53": PRINT -16 PRINT " ! ! !" -17 PRINT " 58 59 60": PRINT -18 PRINT " ! ! !" -19 PRINT " 67 68 69": PRINT -20 PRINT "TO SAVE TYPING TIME, A COMPRESSED VERSION OF THE GAME BOARD" -22 PRINT "WILL BE USED DURING PLAY. REFER TO THE ABOVE ONE FOR PEG" -24 PRINT "NUMBERS. OK, LET'S BEGIN." -28 REM *** SET UP BOARD -29 FOR R=1 TO 9 -30 FOR C=1 TO 9 -31 IF (R-4)*(R-5)*(R-6)=0 THEN 40 -32 IF (C-4)*(C-5)*(C-6)=0 THEN 40 -35 T(R,C)=-5 -36 GOTO 50 -40 IF (R-1)*(C-1)*(R-9)*(C-9)=0 THEN 35 -42 T(R,C)=5 -50 NEXT C -60 NEXT R -65 T(5,5)=0: GOSUB 500 -70 REM *** INPUT MOVE AND CHECK ON LEGALITY -75 FOR W=1 TO 33 -77 READ M -79 DATA 13,14,15,22,23,24,29,30,31,32,33,34,35,38,39,40,41 -81 DATA 42,43,44,47,48,49,50,51,52,53,58,59,60,67,68,69 -83 B(M)=-7: NEXT W -86 B(41)=-3 -100 INPUT "MOVE WHICH PIECE";Z -110 IF B(Z)=-7 THEN 140 -120 PRINT "ILLEGAL MOVE, TRY AGAIN...": GOTO 100 -140 INPUT "TO WHERE";P -150 IF B(P)=0 THEN 120 -153 IF B(P)=-7 THEN 120 -156 IF Z=P THEN 100 -160 IF ((Z+P)/2)=INT((Z+P)/2) THEN 180 -170 GOTO 120 -180 IF (ABS(Z-P)-2)*(ABS(Z-P)-18)<>0 THEN 120 -190 GOSUB 1000 -200 GOSUB 500 -210 GOSUB 1500 -220 GOTO 100 -500 REM *** PRINT BOARD -510 FOR X=1 TO 9 -520 FOR Y=1 TO 9 -525 IF (X-1)*(X-9)*(Y-1)*(Y-9)=0 THEN 550 -530 IF (X-4)*(X-5)*(X-6)=0 THEN 570 -540 IF (Y-4)*(Y-5)*(Y-6)=0 THEN 570 -550 REM -560 GOTO 610 -570 IF T(X,Y)<>5 THEN 600 -580 PRINT TAB(Y*2);"!"; -590 GOTO 610 -600 PRINT TAB(Y*2);"O"; -610 REM -615 NEXT Y -620 PRINT -630 NEXT X -640 RETURN -1000 REM *** UPDATE BOARD -1005 C=1: FOR X=1 TO 9 -1020 FOR Y=1 TO 9 -1030 IF C<>Z THEN 1220 -1040 IF C+2<>P THEN 1080 -1045 IF T(X,Y+1)=0 THEN 120 -1050 T(X,Y+2)=5 -1060 T(X,Y+1)=0: B(C+1)=-3 -1070 GOTO 1200 -1080 IF C+18<>P THEN 1130 -1085 IF T(X+1,Y)=0 THEN 120 -1090 T(X+2,Y)=5: T(X+1,Y)=0: B(C+9)=-3 -1120 GOTO 1200 -1130 IF C-2<>P THEN 1170 -1135 IF T(X,Y-1)=0 THEN 120 -1140 T(X,Y-2)=5: T(X,Y-1)=0: B(C-1)=-3 -1160 GOTO 1200 -1170 IF C-18<>P THEN 1220 -1175 IF T(X-1,Y)=0 THEN 120 -1180 T(X-2,Y)=5: T(X-1,Y)=0: B(C-9)=-3 -1200 B(Z)=-3: B(P)=-7 -1210 T(X,Y)=0: GOTO 1240 -1220 C=C+1 -1225 NEXT Y -1230 NEXT X -1240 RETURN -1500 REM*** CHECK IF GAME IS OVER -1505 F=0 -1510 FOR R=2 TO 8 -1520 FOR C=2 TO 8 -1530 IF T(R,C)<>5 THEN 1580 -1535 F=F+1 -1540 FOR A=R-1 TO R+1 -1545 T=0 -1550 FOR B=C-1 TO C+1 -1560 T=T+T(A,B) -1561 NEXT B -1564 IF T<>10 THEN 1567 -1565 IF T(A,C)<>0 THEN 1630 -1567 NEXT A -1568 FOR X=C-1 TO C+1 -1569 T=0 -1570 FOR Y=R-1 TO R+1 -1571 T=T+T(Y,X) -1572 NEXT Y -1573 IF T<>10 THEN 1575 -1574 IF T(R,X)<>0 THEN 1630 -1575 NEXT X -1580 NEXT C -1590 NEXT R -1600 REM *** GAME IS OVER -1605 PRINT "THE GAME IS OVER." -1610 PRINT "YOU HAD";F;"PIECES REMAINING." -1611 IF F<>1 THEN 1615 -1612 PRINT "BRAVO! YOU MADE A PERFECT SCORE!" -1613 PRINT "SAVE THIS PAPER AS A RECORD OF YOUR ACCOMPLISHMENT!" -1615 PRINT: INPUT "PLAY AGAIN (YES OR NO)";A$ -1617 IF A$="NO" THEN 2000 -1618 RESTORE: GOTO 28 -1620 STOP -1630 RETURN -2000 PRINT: PRINT "SO LONG FOR NOW.": PRINT -2010 END diff --git a/00_Alternate_Languages/49_Hockey/MiniScript/README.md b/00_Alternate_Languages/49_Hockey/MiniScript/README.md deleted file mode 100644 index 8c92997dc..000000000 --- a/00_Alternate_Languages/49_Hockey/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript hockey.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "hockey" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/49_Hockey/MiniScript/hockey.ms b/00_Alternate_Languages/49_Hockey/MiniScript/hockey.ms deleted file mode 100644 index 450736f70..000000000 --- a/00_Alternate_Languages/49_Hockey/MiniScript/hockey.ms +++ /dev/null @@ -1,396 +0,0 @@ -print " "*33 + "Hockey" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print -// ROBERT PUOPOLO ALG. 1 140 MCCOWAN 6/7/73 HOCKEY - -getYesNo = function(prompt) - while true - yn = input(prompt + "? ").lower - if yn and yn[0] == "y" then return "yes" - if yn and yn[0] == "n" then return "no" - print "Answer yes or no!!" - end while -end function - -getTwoStrings = function(prompt) - s = input(prompt + "? ").replace(", ", ",").split(",") - answer1 = s[0] - if s.len < 2 then - answer2 = input("?? ") - else - answer2 = s[1] - end if - return [answer1, answer2] -end function - -getNumber = function(prompt, minVal = 1, maxVal = 999) - while true - num = input(prompt + "? ").val - if minVal <= num <= maxVal then return num - end while -end function - -printWithTab = function(s) - print s.replace("\t", char(9)) -end function - -ha = [0] * 21 -ta = [0] * 6 -t1 = [0] * 6 -t2 = [0] * 6 -t3 = [0] * 6 -aNames = [""] * 8 // Team 1 player names and team name -bNames = [""] * 8 // Team 2 player names and team name -x = 1 -print; print; print -if getYesNo("Would you like the instructions") == "yes" then - print - print "This is a simulated hockey game." - print "Question Response" - print "pass Type in the number of passes you would" - print " like to make, from 0 to 3." - print "shot Type the number corresponding to the shot" - print " you want to make. Enter:" - print " 1 for a slapshot" - print " 2 for a wristshot" - print " 3 for a backhand" - print " 4 for a snap shot" - print "area Type in the number corresponding to" - print " the area you are aiming at. Enter:" - print " 1 for upper left hand corner" - print " 2 for upper right hand corner" - print " 3 for lower left hand corner" - print " 4 for lower right hand corner" - print - print "At the start of the game, you will be asked for the names" - print "of your players. They are entered in the order: " - print "left wing, center, right wing, left defense," - print "right defense, goalkeeper. Any other input required will" - print "have explanatory instructions." -end if - -setup = function - teamNames = getTwoStrings("Enter the two teams") - aNames[7] = teamNames[0] - bNames[7] = teamNames[1] - print - globals.roundsInGame = getNumber("Enter the number of minutes in a game") - print - print "Would the " + aNames[7] + " coach enter his team" - print - for i in range(1, 6) - aNames[i] = input("Player " + i + "? ") - end for - print - print "Would the " + bNames[7] + " coach do the same" - print - for t in range(1, 6) - bNames[t] = input("Player " + t + "? ") - end for - print - rs = input("Input the referee for this game? ") - print - print " "*10 + aNames[7] + " starting lineup" - for t in range(1, 6) - print aNames[t] - end for - print - print " "*10 + bNames[7] + " starting lineup" - for t in range(1, 6) - print bNames[t] - end for - print - print "We're ready for tonights opening face-off." - print rs + " will drop the puck between " + aNames[2] + " and " + bNames[2] -end function - -shootAndScore = function(shootingTeam, shooter, asst1, asst2, z) - while true - ha[20] = floor(100 * rnd) + 1 - if ha[20] % z != 0 then break - a2 = floor(100 * rnd) + 1 - if a2 % 4 == 0 then - if shootingTeam == 1 then - print "Save " + bNames[6] + " -= 1 rebound" - else - print "Save " + aNames[6] + " -= 1 follow up" - end if - continue - end if - end while - - if shootingTeam == 1 then - print "Goal " + aNames[7] - ha[9] += 1 - else - print "Score " + bNames[7] - ha[8] += 1 - end if - print char(7) * 25 - print "Score: " - if ha[8] <= ha[9] then - printWithTab aNames[7] + ": " + ha[9] + "\t" + bNames[7] + ": " + ha[8] - else - printWithTab bNames[7] + ": " + ha[8] + "\t" + aNames[7] + ": " + ha[9] - end if - if shootingTeam == 1 then - print "Goal scored by: " + aNames[shooter] - if asst1 then - if asst2 then - print " assisted by: " + aNames[asst1] + " and " + aNames[asst2] - else - print " assisted by: " + aNames[asst1] - end if - else - print " unassisted." - end if - ta[shooter] += 1 - t1[asst1] += 1 - t1[asst2] += 1 - else - print "Goal scored by: " + bNames[shooter] - if asst1 then - if asst2 then - print " assisted by: " + bNames[asst1] + " and " + bNames[asst2] - else - print " assisted by: " + bNames[asst1] - end if - else - print " unassisted." - end if - t2[shooter] += 1 - t3[asst1] += 1 - t3[asst2] += 1 - end if -end function - -shootBlocked = function(shootingTeam, shooter) - s1 = floor(6 * rnd) + 1 - if shootingTeam == 1 then - if s1 == 1 then - print "Kick save and a beauty by " + bNames[6] - print "cleared out by " + bNames[3] - return false - else if s1 == 2 then - print "what a spectacular glove save by " + bNames[6] - print "and " + bNames[6] + " golfs it into the crowd" - else if s1 == 3 then - print "skate save on a low steamer by " + bNames[6] - return false - else if s1 == 4 then - print "pad save by " + bNames[6] + " off the stick" - print "of " + aNames[shooter] + " and " + bNames[6] + " covers up" - else if s1 == 5 then - print "whistles one over the head of " + bNames[6] - return false - else if s1 == 6 then - print bNames[6] + " makes a face save!! and he is hurt" - print "the defenseman " + bNames[5] + " covers up for him" - end if - else - if s1 == 1 then - print "stick save by " + aNames[6] +"" - print "and cleared out by " + aNames[4] - return false - else if s1 == 2 then - print "Oh my god!! " + bNames[shooter] + " rattles one off the post" - print "to the right of " + aNames[6] + " and " + aNames[6] + " covers " - print "on the loose puck!" - else if s1 == 3 then - print "Skate save by " + aNames[6] - print aNames[6] + " whacks the loose puck into the stands" - else if s1 == 4 then - print "Stick save by " + aNames[6] + " and he clears it out himself" - return false - else if s1 == 5 then - print "Kicked out by " + aNames[6] - print "and it rebounds all the way to center ice" - return false - else if s1 == 6 then - print "Glove save " + aNames[6] + " and he hangs on" - end if - end if -end function - -doOneRound = function - control = floor(2 * rnd) + 1 - if control == 1 then - print aNames[7] + " has control of the puck" - else - print bNames[7] + " has control." - end if - p = getNumber("Pass", 0, 3) - for n in range(1, 3) - ha[n] = 0 - end for - while true - for j in range(1, p + 2) - ha[j] = floor(5 * rnd) + 1 - end for - if not (ha[j - 1] == ha[j - 2] or (p + 2 >= 3 and (ha[j - 1] == ha[j - 3] or ha[j - 2] == ha[j - 3]))) then break - end while - - if p == 0 then - s = getNumber("Shot", 1, 4) - if control == 1 then - print aNames[ha[j - 1]], "" - g = ha[j - 1] - g1 = 0 - g2 = 0 - else - print bNames[ha[j - 1]], "" - g2 = 0 - g2 = 0 - g = ha[j - 1] - end if - if s == 1 then - print " lets a boomer go from the red line!!" - z = 10 - else if s == 2 then - print " flips a wristshot down the ice" - // BUG: missing line 430 in the original caused it to fall through - // to the s == 3 case. We'll instead just do: - z = 2 - else if s == 3 then - print " backhands one in on the goaltender" - z = 25 - else - print " snaps a long flip shot" - z = 17 - end if - else - if control == 1 then - if p == 1 then - print aNames[ha[j - 2]] + " leads " + aNames[ha[j - 1]] + " with a perfect pass." - print aNames[ha[j - 1]] + " cutting in!!!" - g = ha[j - 1] - g1 = ha[j - 2] - g2 = 0 - z1 = 3 - else if p == 2 then - print aNames[ha[j - 2]] + " gives to a streaking " + aNames[ha[j - 1]] - print aNames[ha[j - 3]] + " comes down on " + bNames[5] + " and " + bNames[4] - g = ha[j - 3] - g1 = ha[j - 1] - g2 = ha[j - 2] - z1 = 2 - else if p == 3 then - print "oh my god!! a ' 4 on 2 ' situation" - print aNames[ha[j - 3]] + " leads " + aNames[ha[j - 2]] - print aNames[ha[j - 2]] + " is wheeling through center." - print aNames[ha[j - 2]] + " gives and goest with " + aNames[ha[j - 1]] - print "pretty passing!" - print aNames[ha[j - 1]] + " drops it to " + aNames[ha[j - 4]] - g = ha[j - 4] - g1 = ha[j - 1] - g2 = ha[j - 2] - z1 = 1 - end if - else - if p == 1 then - print bNames[ha[j - 1]] + " hits " + bNames[ha[j - 2]] + " flying down the left side" - g = ha[j - 2] - g1 = ha[j - 1] - g2 = 0 - z1 = 3 - else if p == 2 then - print "it's a ' 3 on 2 '!" - print "only " + aNames[4] + " and " + aNames[5] + " are back." - print bNames[ha[j - 2]] + " gives off to " + bNames[ha[j - 1]] - print bNames[ha[j - 1]] + " drops to " + bNames[ha[j - 3]] - g = ha[j - 3] - g1 = ha[j - 1] - g2 = ha[j - 2] - z1 = 2 - else if p == 3 then - print " a '3 on 2 ' with a ' trailer '!" - print bNames[ha[j - 4]] + " gives to " + bNames[ha[j - 2]] + " who shuffles it off to" - print bNames[ha[j - 1]] + " who fires a wing to wing pass to " - print bNames[ha[j - 3]] + " aNames he cuts in alone!!" - g = ha[j - 3] - g1 = ha[j - 1] - g2 = ha[j - 2] - z1 = 1 - end if - end if - s = getNumber("Shot", 1, 4) - if control == 1 then - print aNames[g], "" - else - print bNames[g], "" - end if - if s == 1 then - print " lets a big slap shot go!!" - z = 4 - z += z1 - else if s == 2 then - print " rips a wrist shot off" - z = 2 - z += z1 - else if s == 3 then - print " gets a backhand off" - z = 3 - z += z1 - else - print " snaps off a snap shot" - z = 2 - z += z1 - end if - end if - - a = getNumber("Area", 1, 4) // area shot in - a1 = floor(4 * rnd) + 1 // area vulnerable - - if control == 1 then - globals.teamAShotsOnNet += 1 - else - globals.teamBShotsOnNet += 1 - end if - if a == a1 then - shootAndScore control, g, g1, g2 - else - shootBlocked control, g - end if - return true -end function - -// Main program -setup -teamAShotsOnNet = 0 -teamBShotsOnNet = 0 -for l in range(1, roundsInGame) - while not doOneRound; end while // (repeat until it returns true) - if l < roundsInGame then print "And we're ready for the face-off" -end for - - - -print char(7)*30 -print "That's the Siren" -print -print " "*15 + "Final Score:" -if ha[8] <= ha[9] then - printWithTab aNames[7] + ": " + ha[9] + "\t" + bNames[7] + ": " + ha[8] -else - printWithTab bNames[7] + ": " + ha[8] + "\t" + aNames[7] + ": " + ha[9] -end if -print -print " "*10 + "Scoring Summary" -print -print " "*25 + aNames[7] -printWithTab "\tName\tGoals\tAssists" -printWithTab "\t -= 1 -= 1\t -= 1 -= 1-\t -= 1 -= 1 -= 1-" -for i in range(1, 5) - printWithTab "\t" + aNames[i] + "\t" + ta[i] + "\t" + t1[i] -end for -print -print " "*25 + bNames[7] -printWithTab "\tName\tGoals\tAssists" -printWithTab "\t -= 1 -= 1\t -= 1 -= 1-\t -= 1 -= 1 -= 1-" -for t in range(1, 5) - printWithTab "\t" + bNames[t] + "\t" + t2[t] + "\t" + t3[t] -end for -print -print "Shots on net" -print aNames[7] + ": " + teamAShotsOnNet -print bNames[7] + ": " + teamBShotsOnNet diff --git a/00_Alternate_Languages/49_Hockey/README.md b/00_Alternate_Languages/49_Hockey/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/49_Hockey/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/49_Hockey/hockey.bas b/00_Alternate_Languages/49_Hockey/hockey.bas deleted file mode 100644 index f0b5a8298..000000000 --- a/00_Alternate_Languages/49_Hockey/hockey.bas +++ /dev/null @@ -1,210 +0,0 @@ -2 PRINT TAB(33);"HOCKEY" -4 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -6 PRINT:PRINT:PRINT -10 REM ROBERT PUOPOLO ALG. 1 140 MCCOWAN 6/7/73 HOCKEY -30 LET X=1 -40 PRINT:PRINT:PRINT -50 PRINT "WOULD YOU LIKE THE INSTRUCTIONS";:INPUT C$ -55 PRINT -60 IF C$="NO" THEN 90 -65 IF C$="YES" THEN 80 -70 PRINT "ANSWER YES OR NO!!":GOTO 50 -80 GOTO 1720 -90 DIM A$(7),B$(7),H(20),T(5),T1(5),T2(5),T3(5) -100 PRINT "ENTER THE TWO TEAMS";:INPUT A$(7),B$(7) -105 PRINT -110 PRINT "ENTER THE NUMBER OF MINUTES IN A GAME";:INPUT T6 -115 PRINT -120 IF T6<1 THEN 110:PRINT -130 PRINT "WOULD THE " A$(7) " COACH ENTER HIS TEAM" -135 PRINT -140 FOR I=1 TO 6:PRINT "PLAYER"I;:INPUT A$(I):NEXT I:PRINT -150 PRINT "WOULD THE " B$(7) " COACH DO THE SAME" -155 PRINT -160 FOR T=1 TO 6:PRINT "PLAYER"T;:INPUT B$(T):NEXT T:PRINT -170 PRINT "INPUT THE REFEREE FOR THIS GAME";:INPUT R$ -180 PRINT:PRINT TAB(10);A$(7) " STARTING LINEUP" -190 FOR T=1 TO 6:PRINT A$(T):NEXT T -200 PRINT:PRINT TAB(10);B$(7)" STARTING LINEUP" -210 FOR T=1 TO 6:PRINT B$(T):NEXT T:PRINT -220 PRINT "WE'RE READY FOR TONIGHTS OPENING FACE-OFF." -230 PRINT R$ " WILL DROP THE PUCK BETWEEN " A$(2) " AND " B$(2) -240 FOR L=1 TO T6:IF L=1 THEN 260 -250 PRINT "AND WE'RE READY FOR THE FACE-OFF" -260 C=INT(2*RND(X))+1:ON C GOTO 270,280 -270 PRINT A$(7) " HAS CONTROL OF THE PUCK":GOTO 290 -280 PRINT B$(7) " HAS CONTROL." -290 PRINT "PASS";:INPUT P:FOR N=1 TO 3:H(N)=0:NEXT N -300 IF P<0 THEN 290 -305 IF P>3 THEN 290 -310 FOR J=1 TO (P+2) -320 H(J)=INT(5*RND(X))+1 -330 NEXT J:IF H(J-1)=H(J-2) THEN 310 -331 IF P+2<3 THEN 350 -335 IF H(J-1)=H(J-3) THEN 310 -340 IF H(J-2)=H(J-3) THEN 310 -350 IF P=0 THEN 360 -355 GOTO 490 -360 INPUT "SHOT";S:IF S<1 THEN 360 -365 IF S>4 THEN 360 -370 ON C GOTO 380,480 -380 PRINT A$(H(J-1));:G=H(J-1):G1=0:G2=0 -390 ON S GOTO 400,420,440,460 -400 PRINT " LET'S A BOOMER GO FROM THE RED LINE!!" -410 Z=10:GOTO 890 -420 PRINT " FLIPS A WRISTSHOT DOWN THE ICE" -440 PRINT " BACKHANDS ONE IN ON THE GOALTENDER" -450 Z=25:GOTO 890 -460 PRINT " SNAPS A LONG FLIP SHOT" -470 Z=17:GOTO 890 -480 PRINT B$(H(J-1));:G1=0:G2=0:G=H(J-1):GOTO 390 -490 ON C GOTO 500,640 -500 ON P GOTO 510,540,570 -510 PRINT A$(H(J-2)) " LEADS " A$(H(J-1)) " WITH A PERFECT PASS." -520 PRINT A$(H(J-1)) " CUTTING IN!!!" -530 G=H(J-1):G1=H(J-2):G2=0:Z1=3:GOTO 770 -540 PRINT A$(H(J-2)) " GIVES TO A STREAKING " A$(H(J-1)) -550 PRINT A$(H(J-3)) " COMES DOWN ON " B$(5) " AND " B$(4) -560 G=H(J-3):G1=H(J-1):G2=H(J-2):Z1=2:GOTO 770 -570 PRINT "OH MY GOD!! A ' 4 ON 2 ' SITUATION" -580 PRINT A$(H(J-3)) " LEADS " A$(H(J-2)) -590 PRINT A$(H(J-2)) " IS WHEEELING THROUGH CENTER." -600 PRINT A$(H(J-2)) " GIVES AND GOES WITH " A$(H(J-1)) -610 PRINT "PRETTY PASSING!" -620 PRINT A$(H(J-1)) " DROPS IT TO " A$(H(J-4)) -630 G=H(J-4):G1=H(J-1):G2=H(J-2):Z1=1:GOTO 770 -640 ON P GOTO 650,670,720 -650 PRINT B$(H(J-1)) " HITS " B$(H(J-2)) " FLYING DOWN THE LEFT SIDE" -660 G=H(J-2):G1=H(J-1):G2=0:Z1=3:GOTO 770 -670 PRINT "IT'S A ' 3 ON 2 '!" -680 PRINT "ONLY " A$(4) " AND " A$(5) " ARE BACK." -690 PRINT B$(H(J-2)) " GIVES OFF TO " B$(H(J-1)) -700 PRINT B$(H(J-1)) " DROPS TO " B$(H(J-3)) -710 G=H(J-3):G1=H(J-1):G2=H(J-2):Z1=2:GOTO 770 -720 PRINT " A ' 3 ON 2 ' WITH A ' TRAILER '!" -730 PRINT B$(H(J-4)) " GIVES TO " B$(H(J-2)) " WHO SHUFFLES IT OFF TO" -740 PRINT B$(H(J-1)) " WHO FIRES A WING TO WING PASS TO " -750 PRINT B$(H(J-3)) " AS HE CUTS IN ALONE!!" -760 G=H(J-3):G1=H(J-1):G2=H(J-2):Z1=1:GOTO 770 -770 PRINT "SHOT";:INPUT S:IF S>4 THEN 770:IF S<1 THEN 770 -780 ON C GOTO 790,880 -790 PRINT A$(G);:ON S GOTO 800,820,840,860 -800 PRINT " LET'S A BIG SLAP SHOT GO!!" -810 Z=4:Z=Z+Z1:GOTO 890 -820 PRINT " RIPS A WRIST SHOT OFF" -830 Z=2:Z=Z+Z1:GOTO 890 -840 PRINT " GETS A BACKHAND OFF" -850 Z=3:Z=Z+Z1:GOTO 890 -860 PRINT " SNAPS OFF A SNAP SHOT" -870 Z=2:Z=Z+Z1:GOTO 890 -880 PRINT B$(G);:ON S GOTO 800,820,840,860 -890 PRINT "AREA";:INPUT A:IF A<1 THEN 890 -895 IF A>4 THEN 890 -900 ON C GOTO 910,920 -910 S2=S2+1:GOTO 930 -920 S3=S3+1 -930 A1=INT(4*RND(X))+1:IF A<>A1 THEN 1200 -940 H(20)=INT(100*RND(X))+1 -950 IF INT(H(20)/Z)=H(20)/Z THEN 1160 -960 ON C GOTO 970,980 -970 PRINT "GOAL " A$(7):H(9)=H(9)+1:GOTO 990 -980 PRINT "SCORE " B$(7):H(8)=H(8)+1 -990 FOR B1=1 TO 25:PRINT CHR$(7);:NEXT B1:PRINT -1000 PRINT "SCORE: ";:IF H(8)>H(9) THEN 1020 -1010 PRINT A$(7)":";H(9),B$(7)":";H(8):GOTO 1030 -1020 PRINT B$(7)":";H(8),A$(7)":";H(9) -1030 ON C GOTO 1040,1100 -1040 PRINT "GOAL SCORED BY: " A$(G):IF G1=0 THEN 1070 -1050 IF G2=0 THEN 1080 -1060 PRINT " ASSISTED BY: " A$(G1) " AND " A$(G2):GOTO 1090 -1070 PRINT " UNASSISTED.":GOTO 1090 -1080 PRINT " ASSISTED BY: " A$(G1) -1090 T(G)=T(G)+1:T1(G1)=T1(G1)+1:T1(G2)=T1(G2)+1:GOTO 1540 -1100 PRINT "GOAL SCORED BY: " B$(G); -1110 IF G1=0 THEN 1130 -1115 IF G2=0 THEN 1140 -1120 PRINT " ASSISTED BY: " B$(G1) " AND " B$(G2):GOTO 1150 -1130 PRINT " UNASSISTED":GOTO 1150 -1140 PRINT " ASSISTED BY: " B$(G1):GOTO 1150 -1150 T2(G)=T2(G)+1:T3(G1)=T3(G1)+1:T3(G2)=T3(G2)+1:GOTO 1540 -1160 A2=INT(100*RND(X))+1:IF INT(A2/4)=A2/4 THEN 1170 -1165 GOTO 1200 -1170 ON C GOTO 1180,1190 -1180 PRINT "SAVE " B$(6) " -- REBOUND":GOTO 940 -1190 PRINT "SAVE " A$(6) " -- FOLLOW UP":GOTO 940 -1200 S1=INT(6*RND(X))+1 -1210 ON C GOTO 1220,1380 -1220 ON S1 GOTO 1230,1260,1290,1300,1330,1350 -1230 PRINT "KICK SAVE AND A BEAUTY BY " B$(6) -1240 PRINT "CLEARED OUT BY " B$(3) -1250 GOTO 260 -1260 PRINT "WHAT A SPECTACULAR GLOVE SAVE BY " B$(6) -1270 PRINT "AND " B$(6) " GOLFS IT INTO THE CROWD" -1280 GOTO 1540 -1290 PRINT "SKATE SAVE ON A LOW STEAMER BY " B$(6):GOTO 260 -1300 PRINT "PAD SAVE BY " B$(6) " OFF THE STICK" -1310 PRINT "OF "A$(G) " AND " B$(6) " COVERS UP" -1320 GOTO 1540 -1330 PRINT "WHISTLES ONE OVER THE HEAD OF " B$(6) -1340 GOTO 260 -1350 PRINT B$(6) " MAKES A FACE SAVE!! AND HE IS HURT" -1360 PRINT "THE DEFENSEMAN " B$(5) " COVERS UP FOR HIM" -1370 GOTO 1540 -1380 ON S1 GOTO 1390,1410,1440,1470,1490,1520 -1390 PRINT "STICK SAVE BY " A$(6) -1400 PRINT "AND CLEARED OUT BY " A$(4):GOTO 260 -1410 PRINT "OH MY GOD!! " B$(G) " RATTLES ONE OFF THE POST" -1420 PRINT "TO THE RIGHT OF " A$(6) " AND " A$(6) " COVERS "; -1430 PRINT "ON THE LOOSE PUCK!":GOTO 1540 -1440 PRINT "SKATE SAVE BY " A$(6) -1450 PRINT A$(6) " WHACKS THE LOOSE PUCK INTO THE STANDS" -1460 GOTO 1540 -1470 PRINT "STICK SAVE BY " A$(6) " AND HE CLEARS IT OUT HIMSELF" -1480 GOTO 260 -1490 PRINT "KICKED OUT BY " A$(6) -1500 PRINT "AND IT REBOUNDS ALL THE WAY TO CENTER ICE" -1510 GOTO 260 -1520 PRINT "GLOVE SAVE " A$(6) " AND HE HANGS ON" -1530 GOTO 1540 -1540 NEXT L:FOR N=1 TO 30:PRINT CHR$(7);:NEXT N:PRINT "THAT'S THE SIREN" -1550 PRINT:PRINT TAB(15);"FINAL SCORE:" -1560 IF H(8)>H(9) THEN 1580 -1570 PRINT A$(7)":";H(9),B$(7)":";H(8):GOTO 1590 -1580 PRINT B$(7)":";H(8),A$(7)":";H(9) -1590 PRINT: PRINT TAB(10);"SCORING SUMMARY":PRINT -1600 PRINT TAB(25);A$(7) -1610 PRINT TAB(5);"NAME";TAB(20);"GOALS";TAB(35);"ASSISTS" -1620 PRINT TAB(5);"----";TAB(20);"-----";TAB(35);"-------" -1630 FOR I=1 TO 5:PRINT TAB(5);A$(I);TAB(21);T(I);TAB(36);T1(I) -1640 NEXT I:PRINT -1650 PRINT TAB(25);B$(7) -1660 PRINT TAB(5);"NAME";TAB(20);"GOALS";TAB(35);"ASSISTS" -1670 PRINT TAB(5);"----";TAB(20);"-----";TAB(35);"-------" -1680 FOR T=1 TO 5:PRINT TAB(5);B$(T);TAB(21);T2(T);TAB(36);T3(T) -1690 NEXT T:PRINT -1700 PRINT "SHOTS ON NET":PRINT A$(7)":";S2:PRINT B$(7)":";S3 -1710 END -1720 PRINT: PRINT "THIS IS A SIMULATED HOCKEY GAME." -1730 PRINT "QUESTION RESPONSE" -1740 PRINT "PASS TYPE IN THE NUMBER OF PASSES YOU WOULD" -1750 PRINT " LIKE TO MAKE, FROM 0 TO 3." -1760 PRINT "SHOT TYPE THE NUMBER CORRESPONDING TO THE SHOT" -1770 PRINT " YOU WANT TO MAKE. ENTER:" -1780 PRINT " 1 FOR A SLAPSHOT" -1790 PRINT " 2 FOR A WRISTSHOT" -1800 PRINT " 3 FOR A BACKHAND" -1810 PRINT " 4 FOR A SNAP SHOT" -1820 PRINT "AREA TYPE IN THE NUMBER CORRESPONDING TO" -1830 PRINT " THE AREA YOU ARE AIMING AT. ENTER:" -1840 PRINT " 1 FOR UPPER LEFT HAND CORNER" -1850 PRINT " 2 FOR UPPER RIGHT HAND CORNER" -1860 PRINT " 3 FOR LOWER LEFT HAND CORNER" -1870 PRINT " 4 FOR LOWER RIGHT HAND CORNER" -1880 PRINT -1890 PRINT "AT THE START OF THE GAME, YOU WILL BE ASKED FOR THE NAMES" -1900 PRINT "OF YOUR PLAYERS. THEY ARE ENTERED IN THE ORDER: " -1910 PRINT "LEFT WING, CENTER, RIGHT WING, LEFT DEFENSE," -1920 PRINT "RIGHT DEFENSE, GOALKEEPER. ANY OTHER INPUT REQUIRED WILL" -1930 PRINT "HAVE EXPLANATORY INSTRUCTIONS." -1940 GOTO 90 -1950 END diff --git a/00_Alternate_Languages/50_Horserace/MiniScript/README.md b/00_Alternate_Languages/50_Horserace/MiniScript/README.md deleted file mode 100644 index 8f5703a2c..000000000 --- a/00_Alternate_Languages/50_Horserace/MiniScript/README.md +++ /dev/null @@ -1,25 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript horserace.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "horserace" - run -``` - -## Porting Notes - -- The original program, designed to be played directly on a printer, drew a track 27 rows long. To fit better on modern screens, I've shortened the track to 23 rows. This is adjustable via the "trackLen" value assigned on line 72. - -- Also because we're playing on a screen instead of a printer, I'm clearing the screen and pausing briefly before each new update of the track. This is done via the `clear` API when running in Mini Micro, or by using a VT100 escape sequence in other contexts. diff --git a/00_Alternate_Languages/50_Horserace/MiniScript/horserace.ms b/00_Alternate_Languages/50_Horserace/MiniScript/horserace.ms deleted file mode 100644 index a8750f5ed..000000000 --- a/00_Alternate_Languages/50_Horserace/MiniScript/horserace.ms +++ /dev/null @@ -1,149 +0,0 @@ -print " "*31 + "Horserace" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print - -print "Welcome to South Portland High Racetrack" -print " ...owned by Laurie Chevalier" - -// show directions, if wanted -x = input("Do you want directions? ").lower -if not x or x[0] != "n" then - print "Up to 10 may play. A table of odds will be printed. You" - print "may bet any + amount under 100000 on one horse." - print "During the race, a horse will be shown by its" - print "number. The horses race down the paper!" - print -end if - -// get player names -qtyPlayers = input("How many want to bet? ").val -if qtyPlayers < 1 then exit -print "When ? appears, type name" -playerNames = [null] -for i in range(1, qtyPlayers) - playerNames.push input("?") -end for -print -pick = [null] + [0]*qtyPlayers -bet = [null] + [0]*qtyPlayers - -d = [0] * 9 // odds denominator -r = 0 // odds numerator - -printInColumns = function(col0, col1, col2) - print (col0+" "*16)[16] + (col1+" "*10)[:10] + (col2+" "*10)[:10] -end function - -setup = function - // initialize the horses - globals.names = [null] + - "Joe Maw,L.B.J.,Mr.Washburn,Miss Karen,Jolly,Horse,Jelly Do Not,Midnight".split(",") - for i in range(1,8) - d[i] = floor(10*rnd+1) - end for - globals.r = d.sum - - // print odds table - printInColumns "Horse", "Number", "Odds" - for i in range(1,8) - printInColumns names[i], i, round(r/d[i],2) + ":1" - end for - - // get the players' bets - print "--------------------------------------------------" - print "Place your bets...Horse # then Amount" - for j in range(1, qtyPlayers) - while true - s = input(playerNames[j] + "? ").replace(",", " ").split - if s.len < 2 then s.push -1 - pick[j] = s[0].val - bet[j] = s[-1].val - if pick[j] < 1 or pick[j] > 8 or bet[j] < 1 or bet[j] >=100000 then - print "You can't do that!" - else - break - end if - end while - end for -end function - -// Draw a racetrack, with each horse the given number -// of lines down from START to FINISH. -trackLen = 23 -drawTrack = function(horsePositions) - print - if version.hostName == "Mini Micro" then clear else print char(27)+"c" - if horsePositions[1] == 0 then print "1 2 3 4 5 6 7 8" else print - print "XXXXSTARTXXXX" - for row in range(1, trackLen) - for h in range(1,8) - p = horsePositions[h] - if p > trackLen then p = trackLen - if p == row then print h, " " - end for - print - end for - print "XXXXFINISHXXXX", "" - if version.hostName != "Mini Micro" then print -end function - -runRace = function - pos = [0]*9 - maxPos = 0 - while true - drawTrack pos - wait 1 - if maxPos >= trackLen then break - for i in range(1,8) - q = floor(100*rnd+1) - x = floor(r/d[i]+0.5) - if q < 10 then - speed = 1 - else if q < x+17 then - speed = 2 - else if q < x+37 then - speed = 3 - else if q < x+57 then - speed = 4 - else if q < x+77 then - speed = 5 - else if q < x+92 then - speed = 6 - else - speed = 7 - end if - pos[i] += speed - if pos[i] > maxPos then maxPos = pos[i] - end for - end while - - print - print "---------------------------------------------" - print - print "The race results are:" - results = [] - for i in range(1,8) - results.push {"num":i, "pos":pos[i]} - end for - results.sort "pos", false - for place in range(1, 8) - h = results[place-1].num - print " " + place + " Place Horse No. " + h + " at " + round(r/d[h],2) + ":1" - print - end for - for p in range(1, qtyPlayers) - if pick[p] == results[0].num then - print playerNames[p] + " wins $" + round((r/d[pick[p]])*bet[p], 2) - end if - end for -end function - -// Main loop -while true - setup - runRace - print "Do you want to bet on the next race ?" - yn = input("Yes or no? ").lower - if not yn or yn[0] != "y" then break -end while - diff --git a/00_Alternate_Languages/50_Horserace/README.md b/00_Alternate_Languages/50_Horserace/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/50_Horserace/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/50_Horserace/horserace.bas b/00_Alternate_Languages/50_Horserace/horserace.bas deleted file mode 100644 index b777f8839..000000000 --- a/00_Alternate_Languages/50_Horserace/horserace.bas +++ /dev/null @@ -1,130 +0,0 @@ -100 PRINT TAB(31);"HORSERACE" -110 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -120 PRINT:PRINT:PRINT -210 DIM S(8) -220 PRINT "WELCOME TO SOUTH PORTLAND HIGH RACETRACK" -230 PRINT " ...OWNED BY LAURIE CHEVALIER" -240 PRINT "DO YOU WANT DIRECTIONS"; -250 INPUT X$ -260 IF X$="NO" THEN 320 -270 PRINT"UP TO 10 MAY PLAY. A TABLE OF ODDS WILL BE PRINTED. YOU" -280 PRINT"MAY BET ANY + AMOUNT UNDER 100000 ON ONE HORSE." -290 PRINT "DURING THE RACE, A HORSE WILL BE SHOWN BY ITS" -300 PRINT"NUMBER. THE HORSES RACE DOWN THE PAPER!" -310 PRINT -320 PRINT "HOW MANY WANT TO BET"; -330 INPUT C -340 PRINT "WHEN ? APPEARS,TYPE NAME" -350 FOR A=1 TO C -360 INPUT W$(A) -370 NEXT A -380 PRINT -390 PRINT"HORSE",,"NUMBER","ODDS" -400 PRINT -410 FOR I=1 TO 8: S(I)=0: NEXT I -420 LET R=0 -430 FOR A=1 TO 8 -440 LET D(A)=INT(10*RND(1)+1) -450 NEXT A -460 FOR A=1 TO 8 -470 LET R=R+D(A) -480 NEXT A -490 LET V$(1)="JOE MAW" -500 LET V$(2)="L.B.J." -510 LET V$(3)="MR.WASHBURN" -520 LET V$(4)="MISS KAREN" -530 LET V$(5)="JOLLY" -540 LET V$(6)="HORSE" -550 LET V$(7)="JELLY DO NOT" -560 LET V$(8)="MIDNIGHT" -570 FOR N=1 TO 8 -580 PRINT V$(N),,N,R/D(N);":1" -590 NEXT N -600 PRINT"--------------------------------------------------" -610 PRINT "PLACE YOUR BETS...HORSE # THEN AMOUNT" -620 FOR J=1 TO C -630 PRINT W$(J); -640 INPUT Q(J),P(J) -650 IF P(J)<1 THEN 670 -660 IF P(J)<100000 THEN 690 -670 PRINT" YOU CAN'T DO THAT!" -680 GOTO 630 -690 NEXT J -700 PRINT -710 PRINT"1 2 3 4 5 6 7 8" -720 PRINT"XXXXSTARTXXXX" -730 FOR I=1 TO 8 -740 LET M=I -750 LET M(I)=M -760 LET Y(M(I))=INT(100*RND(1)+1) -770 IF Y(M(I))<10 THEN 860 -780 LET S=INT(R/D(I)+.5) -790 IF Y(M(I))27 THEN 1240 -1180 NEXT A -1190 PRINT M(I); -1200 NEXT I -1210 FOR A=1 TO 28-T -1220 PRINT -1230 NEXT A -1240 PRINT "XXXXFINISHXXXX"; -1242 PRINT -1243 PRINT -1244 PRINT "---------------------------------------------" -1245 PRINT -1250 IF T<28 THEN 720 -1270 PRINT "THE RACE RESULTS ARE:" -1272 LET Z9=1 -1280 FOR I=8 TO 1 STEP-1 -1290 LET F=M(I) -1300 PRINT -1310 PRINT Z9;"PLACE HORSE NO.";F,"AT ";R/D(F);":1" -1312 LET Z9=Z9+1 -1320 NEXT I -1330 FOR J=1 TO C -1340 IF Q(J)<>M(8) THEN 1370 -1350 LET N=Q(J) -1355 PRINT -1360 PRINT W$(J);" WINS $";(R/D(N))*P(J) -1370 NEXT J -1372 PRINT "DO YOU WANT TO BET ON THE NEXT RACE ?" -1374 INPUT "YES OR NO"; O$ -1376 IF O$="YES" THEN 380 -1380 END diff --git a/00_Alternate_Languages/51_Hurkle/MiniScript/README.md b/00_Alternate_Languages/51_Hurkle/MiniScript/README.md deleted file mode 100644 index 2f774e452..000000000 --- a/00_Alternate_Languages/51_Hurkle/MiniScript/README.md +++ /dev/null @@ -1,22 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -0. Try-It! Page: -Go to https://miniscript.org/tryit/, clear the sample code from the code editor, and paste in the contents of hurkle.ms. Then click the "Run Script" button. Program output (and input) will appear in the green-on-black terminal display to the right of or below the code editor. - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript hurkle.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "hurkle" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/51_Hurkle/MiniScript/hurkle.ms b/00_Alternate_Languages/51_Hurkle/MiniScript/hurkle.ms deleted file mode 100644 index a1b228222..000000000 --- a/00_Alternate_Languages/51_Hurkle/MiniScript/hurkle.ms +++ /dev/null @@ -1,56 +0,0 @@ -print " "*33 + "Hurcle" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print -n = 5 // number of guesses allowed -g = 10 // grid size -print -print "A hurkle is hiding on a " + g + " by " + g + " grid. Homebase" -print "on the grid is point 0,0 in the southwest corner," -print "and any point on the grid is designated by a" -print "pair of whole numbers seperated by a comma. The first" -print "number is the horizontal position and the second number" -print "is the vertical position. You must try to" -print "guess the hurkle's gridpoint. You get " + n + "tries." -print "After each try, I will tell you the approximate" -print "direction to go to look for the hurkle." -print - -playOneGame = function - a = floor(g*rnd) - b = floor(g*rnd) - for k in range(1, n) - s = input("Guess #" + k + "? ").replace(",", " ").split - x = s[0].val - y = s[-1].val - if x == a and y == b then - print - print "You found him in " + k + " guesses!" - return - end if - if y == b then - if x == a then - print - print "You found him in " + k + " guesses!" - return - else if x < a then - dir = "east" - else - dir = "west" - end if - else if y < b then - dir = "north" - else - dir = "south" - end if - print "Go " + dir - end for - print "Sorry, that's " + n + " guesses." - print "The hurkle is at " + a + "," + b -end function - -while true - playOneGame - print - print "Let's play again, hurkle is hiding." - print -end while diff --git a/00_Alternate_Languages/51_Hurkle/README.md b/00_Alternate_Languages/51_Hurkle/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/51_Hurkle/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/51_Hurkle/hurkle.bas b/00_Alternate_Languages/51_Hurkle/hurkle.bas deleted file mode 100644 index c758091c0..000000000 --- a/00_Alternate_Languages/51_Hurkle/hurkle.bas +++ /dev/null @@ -1,51 +0,0 @@ -10 PRINT TAB(33);"HURKLE" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT:PRINT:PRINT -110 N=5 -120 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 IN THE SOUTHWEST CORNER," -235 PRINT "AND ANY POINT ON THE GRID IS DESIGNATED BY A" -240 PRINT "PAIR OF WHOLE NUMBERS SEPERATED BY A COMMA. THE FIRST" -245 PRINT "NUMBER IS THE HORIZONTAL POSITION AND THE SECOND NUMBER" -246 PRINT "IS THE VERTICAL POSITION. YOU MUST 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 -285 A=INT(G*RND(1)) -286 B=INT(G*RND(1)) -310 FOR K=1 TO N -320 PRINT "GUESS #";K; -330 INPUT X,Y -340 IF ABS(X-A)+ABS(Y-B)=0 THEN 500 -350 REM PRINT INFO -360 GOSUB 610 -370 PRINT -380 NEXT K -410 PRINT -420 PRINT "SORRY, THAT'S";N;"GUESSES." -430 PRINT "THE HURKLE IS AT ";A;",";B -440 PRINT -450 PRINT "LET'S PLAY AGAIN, HURKLE IS HIDING." -460 PRINT -470 GOTO 285 -500 REM -510 PRINT -520 PRINT "YOU FOUND HIM IN";K;"GUESSES!" -540 GOTO 440 -610 PRINT "GO "; -620 IF Y=B THEN 670 -630 IF Y= 2 then print " Not bad." -end function - -// main loop (press control-C to break out) -while true - doOneRun -end while diff --git a/00_Alternate_Languages/52_Kinema/README.md b/00_Alternate_Languages/52_Kinema/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/52_Kinema/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/52_Kinema/kinema.bas b/00_Alternate_Languages/52_Kinema/kinema.bas deleted file mode 100644 index 2dbea7bdb..000000000 --- a/00_Alternate_Languages/52_Kinema/kinema.bas +++ /dev/null @@ -1,34 +0,0 @@ -10 PRINT TAB(33);"KINEMA" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT: PRINT: PRINT -100 PRINT -105 PRINT -106 Q=0 -110 V=5+INT(35*RND(1)) -111 PRINT "A BALL IS THROWN UPWARDS AT";V;"METERS PER SECOND." -112 PRINT -115 A=.05*V^2 -116 PRINT "HOW HIGH WILL IT GO (IN METERS)"; -117 GOSUB 500 -120 A=V/5 -122 PRINT "HOW LONG UNTIL IT RETURNS (IN SECONDS)"; -124 GOSUB 500 -130 T=1+INT(2*V*RND(1))/10 -132 A=V-10*T -134 PRINT "WHAT WILL ITS VELOCITY BE AFTER";T;"SECONDS"; -136 GOSUB 500 -140 PRINT -150 PRINT Q;"RIGHT OUT OF 3."; -160 IF Q<2 THEN 100 -170 PRINT " NOT BAD." -180 GOTO 100 -500 INPUT G -502 IF ABS((G-A)/A)<.15 THEN 510 -504 PRINT "NOT EVEN CLOSE...." -506 GOTO 512 -510 PRINT "CLOSE ENOUGH." -511 Q=Q+1 -512 PRINT "CORRECT ANSWER IS ";A -520 PRINT -530 RETURN -999 END diff --git a/00_Alternate_Languages/53_King/MiniScript/README.md b/00_Alternate_Languages/53_King/MiniScript/README.md deleted file mode 100644 index 34818a09c..000000000 --- a/00_Alternate_Languages/53_King/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript king.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "king" - run -``` diff --git a/00_Alternate_Languages/53_King/MiniScript/king.ms b/00_Alternate_Languages/53_King/MiniScript/king.ms deleted file mode 100644 index 8d4f106c9..000000000 --- a/00_Alternate_Languages/53_King/MiniScript/king.ms +++ /dev/null @@ -1,403 +0,0 @@ -print " "*34 + "KING" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print - -yearsRequired = 8 -rallods = floor(60000+(1000*rnd)-(1000*rnd)) -countrymen = floor(500+(10*rnd)-(10*rnd)) -landArea = 2000 -foreignWorkers = 0 -sellableLandExplained = false -tourism = 0 -year = 0 - -zs = input("Do you want instructions? ").lower -if zs == "again" then - while true - year = input("How many years had you been in office when interrupted? ").val - if 0 <= year < yearsRequired then break - print " Come on, your term in office is only " + yearsRequired + " years." - end while - rallods = input("How much did you have in the treasury? ").val - countrymen = input("How many countrymen? ").val - foreignWorkers = input("How many foreign workers? ").val - while true - landArea = input("How many square miles of land? ").val - if 1000 <= landArea <= 2000 then break - print " Come on, you started with 1000 sq. miles of farm land" - print " and 1000 sq. miles of forest land." - end while -else if not zs or zs[0] != "n" then - print; print; print - print "Congratulations! You've just been elected premier of Setats" - print "Detinu, a small communist island 30 by 70 miles long. Your" - print "job is to decide upon the contry's budget and distribute" - print "money to your countrymen from the communal treasury." - print "The money system is rallods, and each person needs 100" - print "rallods per year to survive. Your country's income comes" - print "from farm produce and tourists visiting your magnificent" - print "forests, hunting, fishing, etc. Half your land is farm land" - print "which also has an excellent mineral content and may be sold" - print "to foreign industry (strip mining) who import and support" - print "their own workers. Crops cost between 10 and 15 rallods per" - print "square mile to plant." - print "Your goal is to complete your " + yearsRequired + " year term of office." - print "Good luck!" -end if - -print - - -// Bonus little feature when running in Mini Micro: display a status bar with -// key game stats at the top of the screen. -updateStatusBar = function - if version.hostName != "Mini Micro" then return - display(2).mode = displayMode.text; td = display(2) - s = " Rallods: " + (rallods + " "*8)[:8] - s += " Land: " + (landArea + " "*6)[:6] - s += " Countrymen: " + (countrymen + " "*6)[:6] - s += " Foreigners: " + (foreignWorkers + " "*5)[:5] - td.color = color.black; td.backColor = text.color - td.row = 25; td.column = 0; td.print s -end function - -min0 = function(x) - if x < 0 then return 0 else return x -end function -floorMin0 = function(x) - return min0(floor(x)) -end function -stop = function - updateStatusBar - print; print; exit -end function - -while true - landPrice = floor(10*rnd+95) - plantingArea = 0 - pollutionControl = 0 - deaths = 0 - - print - print "You now have " + rallods + " rallods in the treasury." - print floor(countrymen) + " countrymen, ", "" - costToPlant = floor(((rnd/2)*10+10)) - if foreignWorkers != 0 then - print floor(foreignWorkers) + " foreign workers, ", "" - end if - print "and " + floor(landArea) + " sq. miles of land." - print "This year industry will buy land for " + landPrice, "" - print " rallods per square mile." - print "Land currently costs " + costToPlant + " rallods per square mile to plant." - print - - updateStatusBar - while true - sellToIndustry = input("How many square miles do you wish to sell to industry? ").val - if sellToIndustry < 0 then continue - if sellToIndustry <= landArea-1000 then break - print "*** Think again. You only have " + (landArea-1000) + " square miles of farm land." - if not sellableLandExplained then - print;print "(Foreign industry will only buy farm land because" - print "forest land is uneconomical to strip mine due to trees," - print "thicker top soil, etc.)" - sellableLandExplained = true - end if - end while - landArea = floor(landArea-sellToIndustry) - rallods = floor(rallods+(sellToIndustry*landPrice)) - - updateStatusBar - while true - welfare = input("How many rallods will you distribute among your countrymen? ").val - if welfare < 0 then continue - if welfare <= rallods then break - print " Think again. You've only " + rallods + " rallods in the treasury" - end while - rallods = floor(rallods-welfare) - - updateStatusBar - while rallods > 0 - plantingArea = input("How many square miles do you wish to plant? ").val - if plantingArea < 0 then continue - if plantingArea > countrymen*2 then - print " Sorry, but each countryman can only plant 2 sq. miles." - continue - end if - if plantingArea > landArea-1000 then - print " Sorry, but you've only " + (landArea-1000) + " sq. miles of farm land." - continue - end if - plantingCost = floor(plantingArea * costToPlant) - if plantingCost <= rallods then break - print " Think again. You've only " + rallods + " rallods left in the treasury." - end while - rallods -= plantingCost - - updateStatusBar - while rallods > 0 - pollutionControl = input("How many rallods do you wish to spend on pollution control? ").val - if pollutionControl < 0 then continue - if pollutionControl <= rallods then break - print " Think again. You only have " + rallods + " rallods remaining." - end while - - if sellToIndustry == 0 and welfare == 0 and plantingArea == 0 and pollutionControl == 0 then - print - print "Goodbye." - print "(If you wish to continue this game at a later date, answer" - print "'again' when asked if you want instructions at the start" - print "of the game.)" - exit - end if - - print - print - - rallods = floor(rallods-pollutionControl) - updateStatusBar - - original_rallods = rallods - - starvationDeaths = floorMin0(countrymen - welfare/100) - if starvationDeaths then - if welfare/100 < 50 then - print - print - print "Over one third of the popultation has died since you" - print "were elected to office. The people (remaining)" - print "hate your guts." - if rnd > .5 then - print "You have been thrown out of office and are now" - print "residing in prison." - else - print "You have been assassinated." - end if - countrymen -= starvationDeaths - stop - end if - print starvationDeaths + " countrymen died of starvation" - end if - - pollutionDeaths = floorMin0(rnd*(2000-landArea)) - if pollutionControl >= 25 then - pollutionDeaths = floor(pollutionDeaths/(pollutionControl/25)) - end if - if pollutionDeaths > 0 then - print pollutionDeaths + " countrymen died of carbon-monoxide and dust inhalation" - end if - - deaths = starvationDeaths + pollutionDeaths - if deaths then - print " You were forced to spend " + floor(deaths*9), "" - print " rallods on funeral expenses" - rallods -= deaths * 9 - end if - - if rallods < 0 then - print " Insufficient reserves to cover cost - land was sold" - landArea = floorMin0(landArea+(rallods/landPrice)) - rallods = 0 - end if - - countrymen = min0(countrymen - deaths) - - if sellToIndustry then - newForeigners = floor(sellToIndustry+(rnd*10)-(rnd*20)) - if foreignWorkers == 0 then newForeigners += 20 - foreignWorkers += newForeigners - print newForeigners + " workers came to the country and ", "" - end if - - immigration = floor(((welfare/100-countrymen)/10)+(pollutionControl/25)-((2000-landArea)/50)-(pollutionDeaths/2)) - print abs(immigration) + " countrymen ", "" - if immigration < 0 then print "came to", "" else print "left", "" - print " the island." - countrymen = floorMin0(countrymen + immigration) - - cropLoss = floor(((2000-landArea)*((rnd+1.5)/2))) - if cropLoss > plantingArea then cropLoss = plantingArea - if foreignWorkers > 0 then print "Of " + floor(plantingArea) + " sq. miles planted,", "" - print " you harvested " + floor(plantingArea-cropLoss) + " sq. miles of crops." - if cropLoss then - print " (Due to air and water pollution from foreign industry.)" - end if - agriculturalIncome = floor((plantingArea-cropLoss)*(landPrice/2)) - print "Making " + agriculturalIncome + " rallods." - rallods += agriculturalIncome - - v1 = floor(((countrymen-immigration)*22)+(rnd*500)) - v2 = floor((2000-landArea)*15) - prevTourism = tourism - tourism = abs(floor(v1-v2)) - print " You made " + tourism + " rallods from tourist trade." - if v2 > 2 and tourism < prevTourism then - print " Decrease because ", "" - g1 = 10*rnd - if g1 <= 2 then - print "fish population has dwindled due to water pollution." - else if g1 <= 4 then - print "air pollution is killing game bird population." - else if g1 <= 6 then - print "mineral baths are being ruined by water pollution." - else if g1 <= 8 then - print "unpleasant smog is discouraging sun bathers." - else - print "hotels are looking shabby due to smog grit." - end if - end if - rallods += tourism - updateStatusBar - - if deaths > 200 then - print - print - print deaths + "countrymen died in one year!!!!!" - print "due to this extreme mismanagement, you have not only" - print "been impeached and thrown out of office, but you" - m6 = floor(rnd*10) - if m6 <= 3 then 1670 - if m6 <= 6 then 1680 - if m6 <= 10 then 1690 - print "also had your left eye gouged out!" - goto 1590 - print "have also gained a very bad reputation." - goto 1590 - print "have also been declared national fink." - stop - else if countrymen < 343 then - print - print - print "Over one third of the popultation has died since you" - print "were elected to office. The people (remaining)" - print "hate your guts." - if rnd > .5 then - print "You have been thrown out of office and are now" - print "residing in prison." - else - print "You have been assassinated." - end if - stop - else if (original_rallods/100) > 5 and deaths - pollutionDeaths >= 2 then - print - print "Money was left over in the treasury which you did" - print "not spend. As a result, some of your countrymen died" - print "of starvation. The public is enraged and you have" - print "been forced to either resign or commit suicide." - print "The choice is yours." - print "If you choose the latter, please turn off your computer" - print "before proceeding." - stop - else if foreignWorkers > countrymen then - print - print - print "The number of foreign workers has exceeded the number" - print "of countrymen. As a minority, they have revolted and" - print "taken over the country." - if rnd > .5 then - print "You have been thrown out of office and are now" - print "residing in prison." - else - print "You have been assassinated." - end if - stop - else if year == yearsRequired-1 then - print - print - print "Congratulations!!!!!!!!!!!!!!!!!!" - print "You have succesfully completed your " + yearsRequired + " year term" - print "of office. You were, of course, extremely lucky, but" - print "nevertheless, it's quite an achievement. Goodbye and good" - print "luck - you'll probably need it if you're the type that" - print "plays this game." - stop - end if - - updateStatusBar - wait - year += 1 -end while - -//print -//print -//print "the number of foreign workers has exceeded the number" -//print "of countrymen. as a minority, they have revolted and" -//print "taken over the country." -//if rnd<=.5 then 1580 -//print "you have been thrown out of office and are now" -//print "residing in prison." -//goto 1590 -//print "you have been assassinated." -//print -//print -//exit -//print -//print -//print deaths + "countrymen died in one year!!!!!" -//print "due to this extreme mismanagement, you have not only" -//print "been impeached and thrown out of office, but you" -//m6 = floor(rnd*10) -//if m6 <= 3 then 1670 -//if m6 <= 6 then 1680 -//if m6 <= 10 then 1690 -//print "also had your left eye gouged out!" -//goto 1590 -//print "have also gained a very bad reputation." -//goto 1590 -//print "have also been declared national fink." -//goto 1590 -// -//print -//print -//print "over one third of the popultation has died since you" -//print "were elected to office. the people (remaining)" -//print "hate your guts." -//goto 1570 -//if deaths-pollutionDeaths < 2 then 1515 -//print -//print "money was left over in the treasury which you did" -//print "not spend. as a result, some of your countrymen died" -//print "of starvation. the public is enraged and you have" -//print "been forced to either resign or commit suicide." -//print "the choice is yours." -//print "if you choose the latter, please turn off your computer" -//print "before proceeding." -//goto 1590 -//print -//print -//print "congratulations!!!!!!!!!!!!!!!!!!" -//print "you have succesfully completed your" + yearsRequired + "year term" -//print "of office. you were, of course, extremely lucky, but" -//print "nevertheless, it's quite an achievement. goodbye and good" -//print "luck - you'll probably need it if you're the type that" -//print "plays this game." -//goto 1590 -// -//print "how many years had you been in office when interrupted"; -//input year -//if year < 0 then 1590 -//if year < 8 then 1969 -//print " come on, your term in office is only" + yearsRequired + "years." -//goto 1960 -//print "how much did you have in the treasury"; -//input rallods -//if rallods < 0 then 1590 -//print "how many countrymen"; -//input countrymen -//if countrymen < 0 then 1590 -//print "how many workers"; -//input foreignWorkers -//if foreignWorkers < 0 then 1590 -//print "how many square miles of land"; -//input landArea -//if landArea < 0 then 1590 -//if landArea > 2000 then 1996 -//if landArea > 1000 then 100 -//print " come on, you started with 1000 sq. miles of farm land" -//print " and 10,000 sq. miles of forest land." -//goto 1990 -// -//year = year+1 -//deaths = 0 -//goto 100 -//end diff --git a/00_Alternate_Languages/53_King/README.md b/00_Alternate_Languages/53_King/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/53_King/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/53_King/king.bas b/00_Alternate_Languages/53_King/king.bas deleted file mode 100644 index 7352fa588..000000000 --- a/00_Alternate_Languages/53_King/king.bas +++ /dev/null @@ -1,268 +0,0 @@ -1 PRINT TAB(34);"KING" -2 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -3 PRINT:PRINT:PRINT -4 PRINT "DO YOU WANT INSTRUCTIONS"; -5 INPUT Z$ -6 N5=8 -10 IF LEFT$(Z$,1)="N" THEN 47 -11 IF Z$="AGAIN" THEN 1960 -12 PRINT:PRINT:PRINT -20 PRINT "CONGRATULATIONS! YOU'VE JUST BEEN ELECTED PREMIER OF SETATS" -22 PRINT "DETINU, A SMALL COMMUNIST ISLAND 30 BY 70 MILES LONG. YOUR" -24 PRINT "JOB IS TO DECIDE UPON THE CONTRY'S BUDGET AND DISTRIBUTE" -26 PRINT "MONEY TO YOUR COUNTRYMEN FROM THE COMMUNAL TREASURY." -28 PRINT "THE MONEY SYSTEM IS RALLODS, AND EACH PERSON NEEDS 100" -30 PRINT "RALLODS PER YEAR TO SURVIVE. YOUR COUNTRY'S INCOME COMES" -32 PRINT "FROM FARM PRODUCE AND TOURISTS VISITING YOUR MAGNIFICENT" -34 PRINT "FORESTS, HUNTING, FISHING, ETC. HALF YOUR LAND IS FARM LAND" -36 PRINT "WHICH ALSO HAS AN EXCELLENT MINERAL CONTENT AND MAY BE SOLD" -38 PRINT "TO FOREIGN INDUSTRY (STRIP MINING) WHO IMPORT AND SUPPORT" -40 PRINT "THEIR OWN WORKERS. CROPS COST BETWEEN 10 AND 15 RALLODS PER" -42 PRINT "SQUARE MILE TO PLANT." -44 PRINT "YOUR GOAL IS TO COMPLETE YOUR";N5;"YEAR TERM OF OFFICE." -46 PRINT "GOOD LUCK!" -47 PRINT -50 A=INT(60000+(1000*RND(1))-(1000*RND(1))) -55 B=INT(500+(10*RND(1))-(10*RND(1))) -65 D=2000 -100 W=INT(10*RND(1)+95) -102 PRINT -105 PRINT "YOU NOW HAVE ";A;" RALLODS IN THE TREASURY." -110 PRINT INT(B);:PRINT "COUNTRYMEN, "; -115 V9=INT(((RND(1)/2)*10+10)) -120 IF C=0 THEN 140 -130 PRINT INT(C);"FOREIGN WORKERS, "; -140 PRINT "AND";INT(D);"SQ. MILES OF LAND." -150 PRINT "THIS YEAR INDUSTRY WILL BUY LAND FOR";W; -152 PRINT "RALLODS PER SQUARE MILE." -155 PRINT "LAND CURRENTLY COSTS";V9;"RALLODS PER SQUARE MILE TO PLANT." -162 PRINT -200 PRINT "HOW MANY SQUARE MILES DO YOU WISH TO SELL TO INDUSTRY"; -210 INPUT H -215 IF H<0 THEN 200 -220 IF H<=D-1000 THEN 300 -230 PRINT "*** THINK AGAIN. YOU ONLY HAVE";D-1000;"SQUARE MILES OF FARM LAND." -240 IF X<>0 THEN 200 -250 PRINT:PRINT "(FOREIGN INDUSTRY WILL ONLY BUY FARM LAND BECAUSE" -260 PRINT "FOREST LAND IS UNECONOMICAL TO STRIP MINE DUE TO TREES," -270 PRINT "THICKER TOP SOIL, ETC.)" -280 X=1 -299 GOTO 200 -300 D=INT(D-H) -310 A=INT(A+(H*W)) -320 PRINT "HOW MANY RALLODS WILL YOU DISTRIBUTE AMONG YOUR COUNTRYMEN"; -340 INPUT I -342 IF I<0 THEN 320 -350 IF I0 THEN 1002 -602 IF I<>0 THEN 1002 -604 IF J<>0 THEN 1002 -606 IF K<>0 THEN 1002 -609 PRINT -612 PRINT "GOODBYE." -614 PRINT "(IF YOU WISH TO CONTINUE THIS GAME AT A LATER DATE, ANSWER" -616 PRINT "'AGAIN' WHEN ASKED IF YOU WANT INSTRUCTIONS AT THE START" -617 PRINT "OF THE GAME)." -618 STOP -1000 GOTO 600 -1002 PRINT -1003 PRINT -1010 A=INT(A-K) -1020 A4=A -1100 IF INT(I/100-B)>=0 THEN 1120 -1105 IF I/100<50 THEN 1700 -1110 PRINT INT(B-(I/100));"COUNTRYMEN DIED OF STARVATION" -1120 F1=INT(RND(1)*(2000-D)) -1122 IF K<25 THEN 1130 -1125 F1=INT(F1/(K/25)) -1130 IF F1<=0 THEN 1150 -1140 PRINT F1;"COUNTRYMEN DIED OF CARBON-MONOXIDE AND DUST INHALATION" -1150 IF INT((I/100)-B)<0 THEN 1170 -1160 IF F1>0 THEN 1180 -1165 GOTO 1200 -1170 PRINT " YOU WERE FORCED TO SPEND";INT((F1+(B-(I/100)))*9); -1172 PRINT "RALLODS ON FUNERAL EXPENSES" -1174 B5=INT(F1+(B-(I/100))) -1175 A=INT(A-((F1+(B-(I/100)))*9)) -1176 GOTO 1185 -1180 PRINT " YOU WERE FORCED TO SPEND ";INT(F1*9);"RALLODS ON "; -1181 PRINT "FUNERAL EXPENSES." -1182 B5=F1 -1183 A=INT(A-(F1*9)) -1185 IF A>=0 THEN 1194 -1187 PRINT " INSUFFICIENT RESERVES TO COVER COST - LAND WAS SOLD" -1189 D=INT(D+(A/W)) -1190 A=0 -1194 B=INT(B-B5) -1200 IF H=0 THEN 1250 -1220 C1=INT(H+(RND(1)*10)-(RND(1)*20)) -1224 IF C>0 THEN 1230 -1226 C1=C1+20 -1230 PRINT C1;"WORKERS CAME TO THE COUNTRY AND"; -1250 P1=INT(((I/100-B)/10)+(K/25)-((2000-D)/50)-(F1/2)) -1255 PRINT ABS(P1);"COUNTRYMEN "; -1260 IF P1<0 THEN 1275 -1265 PRINT "CAME TO"; -1270 GOTO 1280 -1275 PRINT "LEFT"; -1280 PRINT " THE ISLAND." -1290 B=INT(B+P1) -1292 C=INT(C+C1) -1305 U2=INT(((2000-D)*((RND(1)+1.5)/2))) -1310 IF C=0 THEN 1324 -1320 PRINT "OF ";INT(J);"SQ. MILES PLANTED,"; -1324 IF J>U2 THEN 1330 -1326 U2=J -1330 PRINT " YOU HARVESTED ";INT(J-U2);"SQ. MILES OF CROPS." -1340 IF U2=0 THEN 1370 -1344 IF T1>=2 THEN 1370 -1350 PRINT " (DUE TO "; -1355 IF T1=0 THEN 1365 -1360 PRINT "INCREASED "; -1365 PRINT "AIR AND WATER POLLUTION FROM FOREIGN INDUSTRY.)" -1370 Q=INT((J-U2)*(W/2)) -1380 PRINT "MAKING";INT(Q);"RALLODS." -1390 A=INT(A+Q) -1400 V1=INT(((B-P1)*22)+(RND(1)*500)) -1405 V2=INT((2000-D)*15) -1410 PRINT " YOU MADE";ABS(INT(V1-V2));"RALLODS FROM TOURIST TRADE." -1420 IF V2=0 THEN 1450 -1425 IF V1-V2>=V3 THEN 1450 -1430 PRINT " DECREASE BECAUSE "; -1435 G1=10*RND(1) -1440 IF G1<=2 THEN 1460 -1442 IF G1<=4 THEN 1465 -1444 IF G1<=6 THEN 1470 -1446 IF G1<=8 THEN 1475 -1448 IF G1<=10 THEN 1480 -1450 V3=INT(A+V3) -1451 A=INT(A+V3) -1452 GOTO 1500 -1460 PRINT "FISH POPULATION HAS DWINDLED DUE TO WATER POLLUTION." -1462 GOTO 1450 -1465 PRINT "AIR POLLUTION IS KILLING GAME BIRD POPULATION." -1467 GOTO 1450 -1470 PRINT "MINERAL BATHS ARE BEING RUINED BY WATER POLLUTION." -1472 GOTO 1450 -1475 PRINT "UNPLEASANT SMOG IS DISCOURAGING SUN BATHERS." -1477 GOTO 1450 -1480 PRINT "HOTELS ARE LOOKING SHABBY DUE TO SMOG GRIT." -1482 GOTO 1450 -1500 IF B5>200 THEN 1600 -1505 IF B<343 THEN 1700 -1510 IF (A4/100)>5 THEN 1800 -1515 IF C>B THEN 1550 -1520 IF N5-1=X5 THEN 1900 -1545 GOTO 2000 -1550 PRINT -1552 PRINT -1560 PRINT "THE NUMBER OF FOREIGN WORKERS HAS EXCEEDED THE NUMBER" -1562 PRINT "OF COUNTRYMEN. AS A MINORITY, THEY HAVE REVOLTED AND" -1564 PRINT "TAKEN OVER THE COUNTRY." -1570 IF RND(1)<=.5 THEN 1580 -1574 PRINT "YOU HAVE BEEN THROWN OUT OF OFFICE AND ARE NOW" -1576 PRINT "RESIDING IN PRISON." -1578 GOTO 1590 -1580 PRINT "YOU HAVE BEEN ASSASSINATED." -1590 PRINT -1592 PRINT -1596 STOP -1600 PRINT -1602 PRINT -1610 PRINT B5;"COUNTRYMEN DIED IN ONE YEAR!!!!!" -1615 PRINT "DUE TO THIS EXTREME MISMANAGEMENT, YOU HAVE NOT ONLY" -1620 PRINT "BEEN IMPEACHED AND THROWN OUT OF OFFICE, BUT YOU" -1622 M6=INT(RND(1)*10) -1625 IF M6<=3 THEN 1670 -1630 IF M6<=6 THEN 1680 -1635 IF M6<=10 THEN 1690 -1670 PRINT "ALSO HAD YOUR LEFT EYE GOUGED OUT!" -1672 GOTO 1590 -1680 PRINT "HAVE ALSO GAINED A VERY BAD REPUTATION." -1682 GOTO 1590 -1690 PRINT "HAVE ALSO BEEN DECLARED NATIONAL FINK." -1692 GOTO 1590 -1700 PRINT -1702 PRINT -1710 PRINT "OVER ONE THIRD OF THE POPULTATION HAS DIED SINCE YOU" -1715 PRINT "WERE ELECTED TO OFFICE. THE PEOPLE (REMAINING)" -1720 PRINT "HATE YOUR GUTS." -1730 GOTO 1570 -1800 IF B5-F1<2 THEN 1515 -1807 PRINT -1815 PRINT "MONEY WAS LEFT OVER IN THE TREASURY WHICH YOU DID" -1820 PRINT "NOT SPEND. AS A RESULT, SOME OF YOUR COUNTRYMEN DIED" -1825 PRINT "OF STARVATION. THE PUBLIC IS ENRAGED AND YOU HAVE" -1830 PRINT "BEEN FORCED TO EITHER RESIGN OR COMMIT SUICIDE." -1835 PRINT "THE CHOICE IS YOURS." -1840 PRINT "IF YOU CHOOSE THE LATTER, PLEASE TURN OFF YOUR COMPUTER" -1845 PRINT "BEFORE PROCEEDING." -1850 GOTO 1590 -1900 PRINT -1902 PRINT -1920 PRINT "CONGRATULATIONS!!!!!!!!!!!!!!!!!!" -1925 PRINT "YOU HAVE SUCCESFULLY COMPLETED YOUR";N5;"YEAR TERM" -1930 PRINT "OF OFFICE. YOU WERE, OF COURSE, EXTREMELY LUCKY, BUT" -1935 PRINT "NEVERTHELESS, IT'S QUITE AN ACHIEVEMENT. GOODBYE AND GOOD" -1940 PRINT "LUCK - YOU'LL PROBABLY NEED IT IF YOU'RE THE TYPE THAT" -1945 PRINT "PLAYS THIS GAME." -1950 GOTO 1590 -1960 PRINT "HOW MANY YEARS HAD YOU BEEN IN OFFICE WHEN INTERRUPTED"; -1961 INPUT X5 -1962 IF X5<0 THEN 1590 -1963 IF X5<8 THEN 1969 -1965 PRINT " COME ON, YOUR TERM IN OFFICE IS ONLY";N5;"YEARS." -1967 GOTO 1960 -1969 PRINT "HOW MUCH DID YOU HAVE IN THE TREASURY"; -1970 INPUT A -1971 IF A<0 THEN 1590 -1975 PRINT "HOW MANY COUNTRYMEN"; -1976 INPUT B -1977 IF B<0 THEN 1590 -1980 PRINT "HOW MANY WORKERS"; -1981 INPUT C -1982 IF C<0 THEN 1590 -1990 PRINT "HOW MANY SQUARE MILES OF LAND"; -1991 INPUT D -1992 IF D<0 THEN 1590 -1993 IF D>2000 THEN 1996 -1994 IF D>1000 THEN 100 -1996 PRINT " COME ON, YOU STARTED WITH 1000 SQ. MILES OF FARM LAND" -1997 PRINT " AND 10,000 SQ. MILES OF FOREST LAND." -1998 GOTO 1990 -2000 X5=X5+1 -2020 B5=0 -2040 GOTO 100 -2046 END diff --git a/00_Alternate_Languages/53_King/king_variable_update.bas b/00_Alternate_Languages/53_King/king_variable_update.bas deleted file mode 100644 index 86c3828c3..000000000 --- a/00_Alternate_Languages/53_King/king_variable_update.bas +++ /dev/null @@ -1,306 +0,0 @@ -1 PRINT TAB(34);"KING" -2 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -3 PRINT:PRINT:PRINT -4 PRINT "DO YOU WANT INSTRUCTIONS"; -5 INPUT Z$ -6 YEARS_REQUIRED=8 -10 IF LEFT$(Z$,1)="N" THEN 47 - 11 IF Z$="AGAIN" THEN 1960 - 12 PRINT:PRINT:PRINT - 20 PRINT "CONGRATULATIONS! YOU'VE JUST BEEN ELECTED PREMIER OF SETATS" - 22 PRINT "DETINU, A SMALL COMMUNIST ISLAND 30 BY 70 MILES LONG. YOUR" - 24 PRINT "JOB IS TO DECIDE UPON THE CONTRY'S BUDGET AND DISTRIBUTE" - 26 PRINT "MONEY TO YOUR COUNTRYMEN FROM THE COMMUNAL TREASURY." - 28 PRINT "THE MONEY SYSTEM IS RALLODS, AND EACH PERSON NEEDS 100" - 30 PRINT "RALLODS PER YEAR TO SURVIVE. YOUR COUNTRY'S INCOME COMES" - 32 PRINT "FROM FARM PRODUCE AND TOURISTS VISITING YOUR MAGNIFICENT" - 34 PRINT "FORESTS, HUNTING, FISHING, ETC. HALF YOUR LAND IS FARM LAND" - 36 PRINT "WHICH ALSO HAS AN EXCELLENT MINERAL CONTENT AND MAY BE SOLD" - 38 PRINT "TO FOREIGN INDUSTRY (STRIP MINING) WHO IMPORT AND SUPPORT" - 40 PRINT "THEIR OWN WORKERS. CROPS COST BETWEEN 10 AND 15 RALLODS PER" - 42 PRINT "SQUARE MILE TO PLANT." - 44 PRINT "YOUR GOAL IS TO COMPLETE YOUR";YEARS_REQUIRED;"YEAR TERM OF OFFICE." - 46 PRINT "GOOD LUCK!" - -47 PRINT - -50 RALLODS=INT(60000+(1000*RND(1))-(1000*RND(1))) -55 COUNTRYMEN=INT(500+(10*RND(1))-(10*RND(1))) -65 LANDAREA=2000 -100 LANDPRICE=INT(10*RND(1)+95) -102 PRINT -105 PRINT "YOU NOW HAVE ";RALLODS;" RALLODS IN THE TREASURY." -110 PRINT INT(COUNTRYMEN);:PRINT "COUNTRYMEN, "; -115 COST_TO_PLANT=INT(((RND(1)/2)*10+10)) -120 IF FOREIGN_WORKERS=0 THEN 140 -130 PRINT INT(FOREIGN_WORKERS);"FOREIGN WORKERS, "; -140 PRINT "AND";INT(LANDAREA);"SQ. MILES OF LAND." -150 PRINT "THIS YEAR INDUSTRY WILL BUY LAND FOR";LANDPRICE; -152 PRINT "RALLODS PER SQUARE MILE." -155 PRINT "LAND CURRENTLY COSTS";COST_TO_PLANT;"RALLODS PER SQUARE MILE TO PLANT." -162 PRINT - -200 PRINT "HOW MANY SQUARE MILES DO YOU WISH TO SELL TO INDUSTRY"; -210 INPUT SELL_TO_INDUSTRY -215 IF SELL_TO_INDUSTRY<0 THEN 200 -220 IF SELL_TO_INDUSTRY<=LANDAREA-1000 THEN 300 -230 PRINT "*** THINK AGAIN. YOU ONLY HAVE";LANDAREA-1000;"SQUARE MILES OF FARM LAND." - -240 IF EXPLANATION_GIVEN THEN 200 - 250 PRINT:PRINT "(FOREIGN INDUSTRY WILL ONLY BUY FARM LAND BECAUSE" - 260 PRINT "FOREST LAND IS UNECONOMICAL TO STRIP MINE DUE TO TREES," - 270 PRINT "THICKER TOP SOIL, ETC.)" - 280 EXPLANATION_GIVEN=TRUE -299 GOTO 200 - -300 LANDAREA=INT(LANDAREA-SELL_TO_INDUSTRY) -310 RALLODS=INT(RALLODS+(SELL_TO_INDUSTRY*LANDPRICE)) -320 PRINT "HOW MANY RALLODS WILL YOU DISTRIBUTE AMONG YOUR COUNTRYMEN"; -340 INPUT WELFARE -342 IF WELFARE<0 THEN 320 -350 IF WELFARE0 THEN 1002 -602 IF WELFARE<>0 THEN 1002 -604 IF PLANTING_AREA<>0 THEN 1002 -606 IF MONEY_SPENT_ON_POLLUTION_CONTROL<>0 THEN 1002 - -609 PRINT -612 PRINT "GOODBYE." -614 PRINT "(IF YOU WISH TO CONTINUE THIS GAME AT A LATER DATE, ANSWER" -616 PRINT "'AGAIN' WHEN ASKED IF YOU WANT INSTRUCTIONS AT THE START" -617 PRINT "OF THE GAME)." -618 STOP - -1000 GOTO 600 - -1002 PRINT -1003 PRINT - -1010 RALLODS=INT(RALLODS-MONEY_SPENT_ON_POLLUTION_CONTROL) -1020 ORIGINAL_RALLODS=RALLODS - -1100 IF INT(WELFARE/100-COUNTRYMEN)>=0 THEN 1120 -1105 IF WELFARE/100<50 THEN 1700 -1110 PRINT INT(COUNTRYMEN-(WELFARE/100));"COUNTRYMEN DIED OF STARVATION" - -1120 POLLUTION_DEATHS=INT(RND(1)*(2000-LANDAREA)) -1122 IF MONEY_SPENT_ON_POLLUTION_CONTROL<25 THEN 1130 -1125 POLLUTION_DEATHS=INT(POLLUTION_DEATHS/(MONEY_SPENT_ON_POLLUTION_CONTROL/25)) - -1130 IF POLLUTION_DEATHS<=0 THEN 1150 -1140 PRINT POLLUTION_DEATHS;"COUNTRYMEN DIED OF CARBON-MONOXIDE AND DUST INHALATION" - -1150 IF INT((WELFARE/100)-COUNTRYMEN)<0 THEN 1170 -1160 IF POLLUTION_DEATHS>0 THEN 1180 -1165 GOTO 1200 - -1170 PRINT " YOU WERE FORCED TO SPEND";INT((POLLUTION_DEATHS+(COUNTRYMEN-(WELFARE/100)))*9); -1172 PRINT "RALLODS ON FUNERAL EXPENSES" -1174 DEATHS=INT(POLLUTION_DEATHS+(COUNTRYMEN-(WELFARE/100))) -1175 RALLODS=INT(RALLODS-((POLLUTION_DEATHS+(COUNTRYMEN-(WELFARE/100)))*9)) -1176 GOTO 1185 - -1180 PRINT " YOU WERE FORCED TO SPEND ";INT(POLLUTION_DEATHS*9);"RALLODS ON "; -1181 PRINT "FUNERAL EXPENSES." -1182 DEATHS=POLLUTION_DEATHS -1183 RALLODS=INT(RALLODS-(POLLUTION_DEATHS*9)) - -1185 IF RALLODS>=0 THEN 1194 -1187 PRINT " INSUFFICIENT RESERVES TO COVER COST - LAND WAS SOLD" -1189 LANDAREA=INT(LANDAREA+(RALLODS/LANDPRICE)) -1190 RALLODS=0 - -1194 COUNTRYMEN=INT(COUNTRYMEN-DEATHS) - -1200 IF SELL_TO_INDUSTRY=0 THEN 1250 -1220 NEW_FOREIGNERS=INT(SELL_TO_INDUSTRY+(RND(1)*10)-(RND(1)*20)) -1224 IF FOREIGN_WORKERS>0 THEN 1230 -1226 NEW_FOREIGNERS=NEW_FOREIGNERS+20 - -1230 PRINT NEW_FOREIGNERS;"WORKERS CAME TO THE COUNTRY AND"; - -1250 IMMIGRATION=INT(((WELFARE/100-COUNTRYMEN)/10)+(MONEY_SPENT_ON_POLLUTION_CONTROL/25)-((2000-LANDAREA)/50)-(POLLUTION_DEATHS/2)) -1255 PRINT ABS(IMMIGRATION);"COUNTRYMEN "; -1260 IF IMMIGRATION<0 THEN 1275 -1265 PRINT "CAME TO"; -1270 GOTO 1280 -1275 PRINT "LEFT"; -1280 PRINT " THE ISLAND." -1290 COUNTRYMEN=INT(COUNTRYMEN+IMMIGRATION) - - -1292 FOREIGN_WORKERS=INT(FOREIGN_WORKERS+NEW_FOREIGNERS) - -1305 CROP_LOSS=INT(((2000-LANDAREA)*((RND(1)+1.5)/2))) -1310 IF FOREIGN_WORKERS=0 THEN 1324 -1320 PRINT "OF ";INT(PLANTING_AREA);"SQ. MILES PLANTED,"; -1324 IF PLANTING_AREA>CROP_LOSS THEN 1330 -1326 CROP_LOSS=PLANTING_AREA -1330 PRINT " YOU HARVESTED ";INT(PLANTING_AREA-CROP_LOSS);"SQ. MILES OF CROPS." -1340 IF CROP_LOSS=0 THEN 1370 -1344 IF T1>=2 THEN 1370 -1350 PRINT " (DUE TO "; -1355 IF T1=0 THEN 1365 -1360 PRINT "INCREASED "; -1365 PRINT "AIR AND WATER POLLUTION FROM FOREIGN INDUSTRY.)" -1370 AGRICULTURAL_INCOME=INT((PLANTING_AREA-CROP_LOSS)*(LANDPRICE/2)) -1380 PRINT "MAKING";INT(AGRICULTURAL_INCOME);"RALLODS." -1390 RALLODS=INT(RALLODS+AGRICULTURAL_INCOME) - -REM I think tourism calculations are actually wrong in the original code! - -1400 V1=INT(((COUNTRYMEN-IMMIGRATION)*22)+(RND(1)*500)) -1405 V2=INT((2000-LANDAREA)*15) -1410 PRINT " YOU MADE";ABS(INT(V1-V2));"RALLODS FROM TOURIST TRADE." -1420 IF V2=0 THEN 1450 -1425 IF V1-V2>=V3 THEN 1450 -1430 PRINT " DECREASE BECAUSE "; -1435 G1=10*RND(1) -1440 IF G1<=2 THEN 1460 -1442 IF G1<=4 THEN 1465 -1444 IF G1<=6 THEN 1470 -1446 IF G1<=8 THEN 1475 -1448 IF G1<=10 THEN 1480 -1450 V3=INT(RALLODS+V3) -1451 RALLODS=INT(RALLODS+V3) -1452 GOTO 1500 -1460 PRINT "FISH POPULATION HAS DWINDLED DUE TO WATER POLLUTION." -1462 GOTO 1450 -1465 PRINT "AIR POLLUTION IS KILLING GAME BIRD POPULATION." -1467 GOTO 1450 -1470 PRINT "MINERAL BATHS ARE BEING RUINED BY WATER POLLUTION." -1472 GOTO 1450 -1475 PRINT "UNPLEASANT SMOG IS DISCOURAGING SUN BATHERS." -1477 GOTO 1450 -1480 PRINT "HOTELS ARE LOOKING SHABBY DUE TO SMOG GRIT." -1482 GOTO 1450 -1500 IF DEATHS>200 THEN 1600 -1505 IF COUNTRYMEN<343 THEN 1700 -1510 IF (ORIGINAL_RALLODS/100)>5 THEN 1800 -1515 IF FOREIGN_WORKERS>COUNTRYMEN THEN 1550 -1520 IF YEARS_REQUIRED-1=YEAR THEN 1900 -1545 GOTO 2000 -1550 PRINT -1552 PRINT -1560 PRINT "THE NUMBER OF FOREIGN WORKERS HAS EXCEEDED THE NUMBER" -1562 PRINT "OF COUNTRYMEN. AS A MINORITY, THEY HAVE REVOLTED AND" -1564 PRINT "TAKEN OVER THE COUNTRY." -1570 IF RND(1)<=.5 THEN 1580 -1574 PRINT "YOU HAVE BEEN THROWN OUT OF OFFICE AND ARE NOW" -1576 PRINT "RESIDING IN PRISON." -1578 GOTO 1590 -1580 PRINT "YOU HAVE BEEN ASSASSINATED." -1590 PRINT -1592 PRINT -1596 STOP -1600 PRINT -1602 PRINT -1610 PRINT DEATHS;"COUNTRYMEN DIED IN ONE YEAR!!!!!" -1615 PRINT "DUE TO THIS EXTREME MISMANAGEMENT, YOU HAVE NOT ONLY" -1620 PRINT "BEEN IMPEACHED AND THROWN OUT OF OFFICE, BUT YOU" -1622 M6=INT(RND(1)*10) -1625 IF M6<=3 THEN 1670 -1630 IF M6<=6 THEN 1680 -1635 IF M6<=10 THEN 1690 -1670 PRINT "ALSO HAD YOUR LEFT EYE GOUGED OUT!" -1672 GOTO 1590 -1680 PRINT "HAVE ALSO GAINED A VERY BAD REPUTATION." -1682 GOTO 1590 -1690 PRINT "HAVE ALSO BEEN DECLARED NATIONAL FINK." -1692 GOTO 1590 - -1700 PRINT -1702 PRINT -1710 PRINT "OVER ONE THIRD OF THE POPULTATION HAS DIED SINCE YOU" -1715 PRINT "WERE ELECTED TO OFFICE. THE PEOPLE (REMAINING)" -1720 PRINT "HATE YOUR GUTS." -1730 GOTO 1570 -1800 IF DEATHS-POLLUTION_DEATHS<2 THEN 1515 -1807 PRINT -1815 PRINT "MONEY WAS LEFT OVER IN THE TREASURY WHICH YOU DID" -1820 PRINT "NOT SPEND. AS A RESULT, SOME OF YOUR COUNTRYMEN DIED" -1825 PRINT "OF STARVATION. THE PUBLIC IS ENRAGED AND YOU HAVE" -1830 PRINT "BEEN FORCED TO EITHER RESIGN OR COMMIT SUICIDE." -1835 PRINT "THE CHOICE IS YOURS." -1840 PRINT "IF YOU CHOOSE THE LATTER, PLEASE TURN OFF YOUR COMPUTER" -1845 PRINT "BEFORE PROCEEDING." -1850 GOTO 1590 -1900 PRINT -1902 PRINT -1920 PRINT "CONGRATULATIONS!!!!!!!!!!!!!!!!!!" -1925 PRINT "YOU HAVE SUCCESFULLY COMPLETED YOUR";YEARS_REQUIRED;"YEAR TERM" -1930 PRINT "OF OFFICE. YOU WERE, OF COURSE, EXTREMELY LUCKY, BUT" -1935 PRINT "NEVERTHELESS, IT'S QUITE AN ACHIEVEMENT. GOODBYE AND GOOD" -1940 PRINT "LUCK - YOU'LL PROBABLY NEED IT IF YOU'RE THE TYPE THAT" -1945 PRINT "PLAYS THIS GAME." -1950 GOTO 1590 - -1960 PRINT "HOW MANY YEARS HAD YOU BEEN IN OFFICE WHEN INTERRUPTED"; -1961 INPUT YEAR -1962 IF YEAR<0 THEN 1590 -1963 IF YEAR<8 THEN 1969 -1965 PRINT " COME ON, YOUR TERM IN OFFICE IS ONLY";YEARS_REQUIRED;"YEARS." -1967 GOTO 1960 -1969 PRINT "HOW MUCH DID YOU HAVE IN THE TREASURY"; -1970 INPUT RALLODS -1971 IF RALLODS<0 THEN 1590 -1975 PRINT "HOW MANY COUNTRYMEN"; -1976 INPUT COUNTRYMEN -1977 IF COUNTRYMEN<0 THEN 1590 -1980 PRINT "HOW MANY WORKERS"; -1981 INPUT FOREIGN_WORKERS -1982 IF FOREIGN_WORKERS<0 THEN 1590 -1990 PRINT "HOW MANY SQUARE MILES OF LAND"; -1991 INPUT LANDAREA -1992 IF LANDAREA<0 THEN 1590 -1993 IF LANDAREA>2000 THEN 1996 -1994 IF LANDAREA>1000 THEN 100 -1996 PRINT " COME ON, YOU STARTED WITH 1000 SQ. MILES OF FARM LAND" -1997 PRINT " AND 10,000 SQ. MILES OF FOREST LAND." -1998 GOTO 1990 - -2000 YEAR=YEAR+1 -2020 DEATHS=0 -2040 GOTO 100 -2046 END diff --git a/00_Alternate_Languages/54_Letter/MiniScript/README.md b/00_Alternate_Languages/54_Letter/MiniScript/README.md deleted file mode 100644 index dfc5cf386..000000000 --- a/00_Alternate_Languages/54_Letter/MiniScript/README.md +++ /dev/null @@ -1,21 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript letter.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "letter" - run -``` -3. "Try-It!" page on the web: -Go to https://miniscript.org/tryit/, clear the default program from the source code editor, paste in the contents of letter.ms, and click the "Run Script" button. diff --git a/00_Alternate_Languages/54_Letter/MiniScript/letter.ms b/00_Alternate_Languages/54_Letter/MiniScript/letter.ms deleted file mode 100644 index 78a32b3bc..000000000 --- a/00_Alternate_Languages/54_Letter/MiniScript/letter.ms +++ /dev/null @@ -1,44 +0,0 @@ -// Letter Guessing Game -// Ported to MiniScript by Joe Strout, 2023 - -print " "*33 + "LETTER" -print " "*15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -print; print; print - -print "Letter Guessing Game"; print -print "I'll think of a letter of the alphabet, A to Z." -print "Try to guess my letter and I'll give you clues" -print "as to how close you're getting to my letter." - -// Function to play one round of the game -playOneGame = function - letter = char(65 + floor(rnd * 26)) - guesses = 0 - print; print "OK, I have a letter. Start guessing." - while true - print; guess = input("What is your guess? ")[:1].upper - guesses = guesses + 1 - if guess == letter then - print; print "You got it in " + guesses + " guesses!!" - if guesses > 5 then - print "But it shouldn't take more than 5 guesses!" - else - print "Good job !!!!!" - print char(7) * 15 - end if - return - else if guess < letter then - print "Too low. Try a higher letter." - else - print "Too high. Try a lower letter." - end if - end while -end function - -// main loop -- press Control-C to exit -while true - print - playOneGame - print - print "Let's play again....." -end while diff --git a/00_Alternate_Languages/54_Letter/README.md b/00_Alternate_Languages/54_Letter/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/54_Letter/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/54_Letter/letter.bas b/00_Alternate_Languages/54_Letter/letter.bas deleted file mode 100644 index ab3efe0c5..000000000 --- a/00_Alternate_Languages/54_Letter/letter.bas +++ /dev/null @@ -1,26 +0,0 @@ -10 PRINT TAB(33);"LETTER" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT:PRINT:PRINT -100 PRINT "LETTER GUESSING GAME": PRINT -210 PRINT "I'LL THINK OF A LETTER OF THE ALPHABET, A TO Z." -220 PRINT "TRY TO GUESS MY LETTER AND I'LL GIVE YOU CLUES" -230 PRINT "AS TO HOW CLOSE YOU'RE GETTING TO MY LETTER." -310 L=65+INT(RND(1)*26) -320 G=0 -340 PRINT: PRINT "O.K., I HAVE A LETTER. START GUESSING." -410 PRINT: PRINT "WHAT IS YOUR GUESS"; -420 G=G+1 -430 INPUT A$: A=ASC(A$): PRINT -440 IF A=L THEN 500 -450 IF A>L THEN 480 -460 PRINT "TOO LOW. TRY A HIGHER LETTER.": GOTO 410 -480 PRINT "TOO HIGH. TRY A LOWER LETTER.": GOTO 410 -500 PRINT: PRINT "YOU GOT IT IN";G;"GUESSES!!" -504 IF G<=5 THEN 508 -506 PRINT "BUT IT SHOULDN'T TAKE MORE THAN 5 GUESSES!": GOTO 515 -508 PRINT "GOOD JOB !!!!!" -510 FOR N=1 TO 15: PRINT CHR$(7);: NEXT N -515 PRINT -520 PRINT "LET'S PLAY AGAIN....." -530 GOTO 310 -999 END diff --git a/00_Alternate_Languages/55_Life/MiniScript/README.md b/00_Alternate_Languages/55_Life/MiniScript/README.md deleted file mode 100644 index 4cfd557b0..000000000 --- a/00_Alternate_Languages/55_Life/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript life.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "life" - run -``` diff --git a/00_Alternate_Languages/55_Life/MiniScript/life.ms b/00_Alternate_Languages/55_Life/MiniScript/life.ms deleted file mode 100644 index 69f3bafc1..000000000 --- a/00_Alternate_Languages/55_Life/MiniScript/life.ms +++ /dev/null @@ -1,132 +0,0 @@ -print " "*34 + "LIFE" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print -import "listUtil" // (needed for list.init2d) - -maxx = 66 // (size adjusted for Mini Micro display) -maxy = 23 -A = list.init2d(maxx+1, maxy+1, 0) - -// Stuff the given pattern into the center of the cell array. -// Return the number of live cells. -stuffIntoCenter = function(pattern) - maxLen = 0 - for p in pattern - if p.len > maxLen then maxLen = p.len - end for - - population = 0 - y = floor(maxy/2 - pattern.len/2) - for row in pattern - x = floor(maxx/2 - maxLen/2) - for c in row - if c != " " then - A[x][y] = 1 - population += 1 - end if - x += 1 - end for - y += 1 - end for - return population -end function - -// Get the initial pattern from the user -initToUserPattern = function - print "Enter your pattern (enter DONE when done):" - userPattern = [] - while true - p = input("?") - if p.upper == "DONE" then break - if p and p[0] == "." then p = " " + p[1:] - userPattern.push p - end while - return stuffIntoCenter(userPattern) -end function - -// For testing purposes, skip asking the user and just use a hard-coded pattern. -initToStandardPattern = function - pattern = [ - " **", - " * *", - " *"] - return stuffIntoCenter(pattern) -end function - -// Or, just for fun, initialize to a random pattern of junk in the center. -initRandom = function - for x in range(ceil(maxx*0.3), floor(maxx*0.7)) - for y in range(ceil(maxy*0.3), floor(maxy*0.7)) - A[x][y] = rnd > 0.5 - end for - end for -end function - -// Define a function to draw the current game state. -// This also changes 2 (dying) to 0 (dead), and 3 (being born) to 1 (alive). -drawGameState = function(generation=0, population=0, invalid=false) - if version.hostName == "Mini Micro" then text.row = 26 else print - print "Generation: " + generation + " Population: " + population + - " " + "INVALID!" * invalid - for y in range(0, maxy) - s = "" - for x in range(0, maxx) - if A[x][y] == 2 then - A[x][y] = 0 - else if A[x][y] == 3 then - A[x][y] = 1 - end if - if A[x][y] then s += "*" else s += " " - end for - print s - end for -end function - -// Update the game state, setting cells that should be born to 3 and -// cells that should die to 2. Return the number of cells that will -// be alive after this update. Also, set globals.invalid if any live -// cells are found on the edge of the map. -updateGameState = function - population = 0 - for x in range(0, maxx) - for y in range(0, maxy) - c = A[x][y] == 1 or A[x][y] == 2 // center state - n = -c // number of neighbors - for nx in range(x-1, x+1) - if nx < 0 or nx > maxx then continue - for ny in range(y-1, y+1) - if ny < 0 or ny > maxy then continue - n += A[nx][ny] == 1 or A[nx][ny] == 2 - end for - end for - if c and n != 2 and n != 3 then // live cell with < 2 or > 3 neighbors... - A[x][y] = 2 // dies - else if not c and n == 3 then // dead cell with 3 neighbors... - A[x][y] = 3 // comes to life - if x == 0 or x == maxx or y == 0 or y == maxy then - globals.invalid = true - end if - end if - population += (A[x][y] == 1 or A[x][y] == 3) - end for - end for - return population -end function - - -// Initialize the game state (uncomment one of the following three lines) -population = initToUserPattern -//population = initToStandardPattern -//population = initRandom - -// Main loop -if version.hostName == "Mini Micro" then clear -invalid = false -generation = 0 -while population > 0 - drawGameState generation, population, invalid - population = updateGameState - generation += 1 - //key.get // <-- Uncomment this to single-step with each keypress! -end while -drawGameState generation, population, invalid diff --git a/00_Alternate_Languages/55_Life/README.md b/00_Alternate_Languages/55_Life/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/55_Life/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/55_Life/life.bas b/00_Alternate_Languages/55_Life/life.bas deleted file mode 100644 index 713135794..000000000 --- a/00_Alternate_Languages/55_Life/life.bas +++ /dev/null @@ -1,66 +0,0 @@ -2 PRINT TAB(34);"LIFE" -4 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -6 PRINT: PRINT: PRINT -8 PRINT "ENTER YOUR PATTERN:" -9 X1=1: Y1=1: X2=24: Y2=70 -10 DIM A(24,70),B$(24) -20 C=1 -30 INPUT B$(C) -40 IF B$(C)="DONE" THEN B$(C)="": GOTO 80 -50 IF LEFT$(B$(C),1)="." THEN B$(C)=" "+RIGHT$(B$(C),LEN(B$(C))-1) -60 C=C+1 -70 GOTO 30 -80 C=C-1: L=0 -90 FOR X=1 TO C-1 -100 IF LEN(B$(X))>L THEN L=LEN(B$(X)) -110 NEXT X -120 X1=11-C/2 -130 Y1=33-L/2 -140 FOR X=1 TO C -150 FOR Y=1 TO LEN(B$(X)) -160 IF MID$(B$(X),Y,1)<>" " THEN A(X1+X,Y1+Y)=1:P=P+1 -170 NEXT Y -180 NEXT X -200 PRINT:PRINT:PRINT -210 PRINT "GENERATION:";G,"POPULATION:";P;: IF I9 THEN PRINT "INVALID!"; -215 X3=24:Y3=70:X4=1: Y4=1: P=0 -220 G=G+1 -225 FOR X=1 TO X1-1: PRINT: NEXT X -230 FOR X=X1 TO X2 -240 PRINT -250 FOR Y=Y1 TO Y2 -253 IF A(X,Y)=2 THEN A(X,Y)=0:GOTO 270 -256 IF A(X,Y)=3 THEN A(X,Y)=1:GOTO 261 -260 IF A(X,Y)<>1 THEN 270 -261 PRINT TAB(Y);"*"; -262 IF XX4 THEN X4=X -266 IF YY4 THEN Y4=Y -270 NEXT Y -290 NEXT X -295 FOR X=X2+1 TO 24: PRINT: NEXT X -299 X1=X3: X2=X4: Y1=Y3: Y2=Y4 -301 IF X1<3 THEN X1=3:I9=-1 -303 IF X2>22 THEN X2=22:I9=-1 -305 IF Y1<3 THEN Y1=3:I9=-1 -307 IF Y2>68 THEN Y2=68:I9=-1 -309 P=0 -500 FOR X=X1-1 TO X2+1 -510 FOR Y=Y1-1 TO Y2+1 -520 C=0 -530 FOR I=X-1 TO X+1 -540 FOR J=Y-1 TO Y+1 -550 IF A(I,J)=1 OR A(I,J)=2 THEN C=C+1 -560 NEXT J -570 NEXT I -580 IF A(X,Y)=0 THEN 610 -590 IF C<3 OR C>4 THEN A(X,Y)=2: GOTO 600 -595 P=P+1 -600 GOTO 620 -610 IF C=3 THEN A(X,Y)=3:P=P+1 -620 NEXT Y -630 NEXT X -635 X1=X1-1:Y1=Y1-1:X2=X2+1:Y2=Y2+1 -640 GOTO 210 -650 END diff --git a/00_Alternate_Languages/56_Life_for_Two/MiniScript/README.md b/00_Alternate_Languages/56_Life_for_Two/MiniScript/README.md deleted file mode 100644 index 93b25b999..000000000 --- a/00_Alternate_Languages/56_Life_for_Two/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). The only liberty I took with the original design is that, when prompting each player for their turn, I include a reminder of what symbol (* or #) represents their pieces on the board. - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript lifefortwo.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "lifefortwo" - run -``` diff --git a/00_Alternate_Languages/56_Life_for_Two/MiniScript/lifefortwo.ms b/00_Alternate_Languages/56_Life_for_Two/MiniScript/lifefortwo.ms deleted file mode 100644 index 49ac531ed..000000000 --- a/00_Alternate_Languages/56_Life_for_Two/MiniScript/lifefortwo.ms +++ /dev/null @@ -1,129 +0,0 @@ -print " "*33 + "LIFE2" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print -print " "*10 + "U.B. LIFE GAME" - -// N: counts neighbors and game state, as follows: -// 1's digit: player 1 neighbors -// 10's digit: player 2 neighbors -// 100's digit: player 1 current live cell -// 1000's digit: player 2 current live cell -N = [] -for i in range(0,6); N.push [0]*7; end for - -// K: encodes the rule for what cells come to life, based on -// the value in N. The first 9 entries mean new life for Player 1; -// the second 9 entries mean new life for Player 2. -K = [3,102,103,120,130,121,112,111,12, - 21,30,1020,1030,1011,1021,1003,1002,1012] - -// population: how many live cells each player (1-2) has -population = [null, 0, 0] - -// Function to get input coordinates from the player, for any empty space. -// Where possible, hide the input so the other player can't see it. -getCoords = function - while true - print "X,Y" - inp = input.replace(",", " ").replace(" "," ") - if version.hostName == "Mini Micro" then - text.row = text.row + 1; print " "*60 - end if - parts = inp.split - if parts.len == 2 then - x = parts[0].val - y = parts[1].val - if 0 < x <= 5 and 0 < y <= 5 and N[x][y] == 0 then break - end if - print "Illegal coords. Retype" - end while - return [x, y] -end function - -// Function to print the board. At the same time, it replaces -// any player 1 value (as judged by list K) with 100, and any -// player 2 value with 1000. Also update population[] with the -// number of pieces of each player. -printBoard = function - population[1] = 0 - population[2] = 0 - for y in range(0, 6) - if y == 0 or y == 6 then - print " 0 1 2 3 4 5 0" - else - print " " + y, " " - for x in range(1, 5) - kIndex = K.indexOf(N[x][y]) - if kIndex == null then - print " ", " " - N[x][y] = 0 - else if kIndex < 9 then - print "*", " " - N[x][y] = 100 - population[1] += 1 - else - print "#", " " - N[x][y] = 1000 - population[2] += 1 - end if - end for - print y - end if - end for - print -end function - -// Function to update the board (N). -updateBoard = function - for j in range(1,5) - for k in range(1,5) - if N[j][k] < 100 then continue // not a live cell - if N[j][k] > 999 then value = 10 else value = 1 - for x in range(j-1, j+1) - for y in range(k-1, k+1) - if x == j and y == k then continue - N[x][y] += value - //if [x,y] == [2,1] then print "adding " + value + " from " + j+","+k + " to " + x+","+y + ", --> " + N[x][y] - end for - end for - end for - end for -end function - - -// Get initial player positions. -for player in [1,2] - print; print "Player " + player + " - 3 live pieces." - if player == 2 then value = 30 else value = 3 - for k in range(1,3) - pos = getCoords - N[pos[0]][pos[1]] = value - end for -end for - -printBoard -while true - updateBoard - printBoard - if population[1] == 0 and population[2] == 0 then - print "A DRAW" - break - else if population[1] == 0 then - print "PLAYER 2 IS THE WINNER" - break - else if population[2] == 0 then - print "PLAYER 1 IS THE WINNER" - break - end if - - print; print "Player 1 (*)" - p1pos = getCoords - print; print "Player 2 (#)" - p2pos = getCoords - if p1pos == p2pos then - print "Same coord. Set to 0" - else - N[p1pos[0]][p1pos[1]] = 100 - N[p2pos[0]][p2pos[1]] = 1000 - end if -end while \ No newline at end of file diff --git a/00_Alternate_Languages/56_Life_for_Two/README.md b/00_Alternate_Languages/56_Life_for_Two/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/56_Life_for_Two/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/56_Life_for_Two/lifefortwo.bas b/00_Alternate_Languages/56_Life_for_Two/lifefortwo.bas deleted file mode 100644 index e970ef6df..000000000 --- a/00_Alternate_Languages/56_Life_for_Two/lifefortwo.bas +++ /dev/null @@ -1,83 +0,0 @@ -2 PRINT TAB(33);"LIFE2" -4 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -6 PRINT: PRINT: PRINT -7 DIM N(6,6),K(18),A(16),X(2),Y(2) -8 DATA 3,102,103,120,130,121,112,111,12 -9 DATA 21,30,1020,1030,1011,1021,1003,1002,1012 -10 FOR M=1 TO 18: READ K(M): NEXT M -13 DATA -1,0,1,0,0,-1,0,1,-1,-1,1,-1,-1,1,1,1 -14 FOR O1= 1 TO 16: READ A(O1): NEXT O1 -20 GOTO 500 -50 FOR J=1 TO 5 -51 FOR K=1 TO 5 -55 IF N(J,K)>99 THEN GOSUB 200 -60 NEXT K -65 NEXT J -90 K=0: M2=0: M3=0 -99 FOR J=0 TO 6: PRINT -100 FOR K=0 TO 6 -101 IF J<>0 THEN IF J<>6 THEN 105 -102 IF K=6 THEN PRINT 0;: GOTO 125 -103 PRINT K;: GOTO 120 -105 IF K<>0 THEN IF K<>6 THEN 110 -106 IF J=6 THEN PRINT 0: GOTO 126 -107 PRINT J;: GOTO 120 -110 GOSUB 300 -120 NEXT K -125 NEXT J -126 RETURN -200 B=1: IF N(J,K)>999 THEN B=10 -220 FOR O1= 1 TO 15 STEP 2 -230 N(J+A(O1),K+A(O1+1))=N(J+A(O1),K+A(O1+1))+B -231 NEXT O1 -239 RETURN -300 IF N(J,K)<3 THEN 399 -305 FOR O1=1 TO 18 -310 IF N(J,K)=K(O1) THEN 350 -315 NEXT O1 -320 GOTO 399 -350 IF O1>9 THEN 360 -351 N(J,K)=100: M2=M2+1: PRINT " * "; -355 RETURN -360 N(J,K)=1000: M3=M3+1: PRINT " # "; -365 RETURN -399 N(J,K)=0: PRINT " ";: RETURN -500 PRINT TAB(10);"U.B. LIFE GAME" -505 M2=0: M3=0 -510 FOR J=1 TO 5 -511 FOR K=1 TO 5 -515 N(J,K)=0 -516 NEXT K -517 NEXT J -519 FOR B=1 TO 2: P1=3: IF B=2 THEN P1=30 -520 PRINT:PRINT "PLAYER";B;" - 3 LIVE PIECES." -535 FOR K1=1 TO 3: GOSUB 700 -540 N(X(B),Y(B))=P1: NEXT K1 -542 NEXT B -559 GOSUB 90 -560 PRINT: GOSUB 50 -570 IF M2=0 THEN IF M3=0 THEN 574 -571 IF M3=0 THEN B=1: GOTO 575 -572 IF M2=0 THEN B=2: GOTO 575 -573 GOTO 580 -574 PRINT: PRINT "A DRAW":GOTO 800 -575 PRINT: PRINT "PLAYER";B;"IS THE WINNER":GOTO 800 -580 FOR B=1 TO 2: PRINT: PRINT: PRINT "PLAYER";B;: GOSUB 700 -581 IF B=99 THEN 560 -582 NEXT B -586 N(X(1),Y(1))=100: N(X(2),Y(2))=1000 -596 GOTO 560 -700 PRINT "X,Y":PRINT"XXXXXX";CHR$(13);"$$$$$$";CHR$(13);"&&&&&&"; -701 PRINT CHR$(13);: INPUT Y(B),X(B) -705 IF X(B)<=5 THEN IF X(B)>0 THEN 708 -706 GOTO 750 -708 IF Y(B)<=5 THEN IF Y(B)>0 THEN 715 -710 GOTO 750 -715 IF N(X(B),Y(B))<>0 THEN 750 -720 IF B=1 THEN RETURN -725 IF X(1)=X(2) THEN IF Y(1)=Y(2) THEN 740 -730 RETURN -740 PRINT "SAME COORD. SET TO 0" -741 N(X(B)+1,Y(B)+1)=0: B=99: RETURN -750 PRINT "ILLEGAL COORDS. RETYPE": GOTO 700 -999 END diff --git a/00_Alternate_Languages/57_Literature_Quiz/MiniScript/README.md b/00_Alternate_Languages/57_Literature_Quiz/MiniScript/README.md deleted file mode 100644 index e3f12eb47..000000000 --- a/00_Alternate_Languages/57_Literature_Quiz/MiniScript/README.md +++ /dev/null @@ -1,22 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -0. Try-It! Page: -Go to https://miniscript.org/tryit/, clear the sample code from the code editor, and paste in the contents of litquiz.ms. Then click the "Run Script" button. Program output (and input) will appear in the green-on-black terminal display to the right of or below the code editor. - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript litquiz.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "litquiz" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/57_Literature_Quiz/MiniScript/litquiz.ms b/00_Alternate_Languages/57_Literature_Quiz/MiniScript/litquiz.ms deleted file mode 100644 index e465cc6bb..000000000 --- a/00_Alternate_Languages/57_Literature_Quiz/MiniScript/litquiz.ms +++ /dev/null @@ -1,66 +0,0 @@ -print " "*24 + "Literature Quiz" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print - -r=0 -print "Test your knowledge of children's literature." -print; print "This is a multiple-choice quiz." -print "Type a 1, 2, 3, or 4 after the question mark." -print; print "Good luck!"; - -print; print -print "In pinocchio, what was the name of the cat?" -print "1)Tigger, 2)Cicero, 3)Figaro, 4)Fuipetto"; -a = input("?").val -if a!=3 then - print "Sorry...Figaro was his name." -else - print "Very good! Here's another." - r += 1 -end if - -print; print -print "From whose garden did Bugs Bunny steal the carrots?" -print "1)Mr. Nixon's, 2)Elmer Fudd's, 3)Clem Judd's, 4)Stromboli's"; -a = input("?").val -if a != 2 then - print "Too bad...it was elmer fudd's garden." -else - print "Pretty good!" - r += 1 -end if - -print; print -print "In the Wizard of Oz, Dorothy's dog was named" -print "1)Cicero, 2)Trixia, 3)King, 4)Toto"; -a = input("?").val -if a != 4 then - print "Back to the books,...Toto was his name." -else - print "Yea! You're a real literature giant." - r += 1 -end if - -print;print -print "Who was the fair maiden who ate the poison apple?" -print "1)Sleeping Beauty, 2)Cinderella, 3)Snow White, 4)Wendy"; -a = input("?").val -if a != 3 then - print "Oh, come on now...it was Snow White." -else - print "Good memory!" - r += 1 -end if - -print;print -if r == 4 then - print "Wow! That's super! You really know your nursery" - print "Your next quiz will be on 2nd century Chinese" - print "literature (ha, ha, ha)" -else if r<2 then - print "Ugh. That was definitely not too swift. Back to" - print "nursery school for you, my friend." -else - print "Not bad, but you might spend a little more time" - print "reading the nursery greats." -end if diff --git a/00_Alternate_Languages/57_Literature_Quiz/README.md b/00_Alternate_Languages/57_Literature_Quiz/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/57_Literature_Quiz/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/57_Literature_Quiz/litquiz.bas b/00_Alternate_Languages/57_Literature_Quiz/litquiz.bas deleted file mode 100644 index fe731b2cb..000000000 --- a/00_Alternate_Languages/57_Literature_Quiz/litquiz.bas +++ /dev/null @@ -1,49 +0,0 @@ -1 PRINT TAB(25);"LITERATURE QUIZ" -2 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -3 PRINT:PRINT:PRINT -5 R=0 -10 PRINT "TEST YOUR KNOWLEDGE OF CHILDREN'S LITERATURE." -12 PRINT: PRINT "THIS IS A MULTIPLE-CHOICE QUIZ." -13 PRINT "TYPE A 1, 2, 3, OR 4 AFTER THE QUESTION MARK." -15 PRINT: PRINT "GOOD LUCK!": PRINT: PRINT -40 PRINT "IN PINOCCHIO, WHAT WAS THE NAME OF THE CAT" -42 PRINT "1)TIGGER, 2)CICERO, 3)FIGARO, 4)GUIPETTO"; -43 INPUT A: IF A=3 THEN 46 -44 PRINT "SORRY...FIGARO WAS HIS NAME.": GOTO 50 -46 PRINT "VERY GOOD! HERE'S ANOTHER." -47 R=R+1 -50 PRINT: PRINT -51 PRINT "FROM WHOSE GARDEN DID BUGS BUNNY STEAL THE CARROTS?" -52 PRINT "1)MR. NIXON'S, 2)ELMER FUDD'S, 3)CLEM JUDD'S, 4)STROMBOLI'S"; -53 INPUT A: IF A=2 THEN 56 -54 PRINT "TOO BAD...IT WAS ELMER FUDD'S GARDEN.": GOTO 60 -56 PRINT "PRETTY GOOD!" -57 R=R+1 -60 PRINT: PRINT -61 PRINT "IN THE WIZARD OF OS, DOROTHY'S DOG WAS NAMED" -62 PRINT "1)CICERO, 2)TRIXIA, 3)KING, 4)TOTO"; -63 INPUT A: IF A=4 THEN 66 -64 PRINT "BACK TO THE BOOKS,...TOTO WAS HIS NAME.": GOTO 70 -66 PRINT "YEA! YOU'RE A REAL LITERATURE GIANT." -67 R=R+1 -70 PRINT:PRINT -71 PRINT "WHO WAS THE FAIR MAIDEN WHO ATE THE POISON APPLE" -72 PRINT "1)SLEEPING BEAUTY, 2)CINDERELLA, 3)SNOW WHITE, 4)WENDY"; -73 INPUT A: IF A=3 THEN 76 -74 PRINT "OH, COME ON NOW...IT WAS SNOW WHITE." -75 GOTO 80 -76 PRINT "GOOD MEMORY!" -77 R=R+1 -80 PRINT:PRINT -85 IF R=4 THEN 100 -90 IF R<2 THEN 200 -92 PRINT "NOT BAD, BUT YOU MIGHT SPEND A LITTLE MORE TIME" -94 PRINT "READING THE NURSERY GREATS." -96 STOP -100 PRINT "WOW! THAT'S SUPER! YOU REALLY KNOW YOUR NURSERY" -110 PRINT "YOUR NEXT QUIZ WILL BE ON 2ND CENTURY CHINESE" -120 PRINT "LITERATURE (HA, HA, HA)" -130 STOP -200 PRINT "UGH. THAT WAS DEFINITELY NOT TOO SWIFT. BACK TO" -205 PRINT "NURSERY SCHOOL FOR YOU, MY FRIEND." -999 END diff --git a/00_Alternate_Languages/58_Love/MiniScript/README.md b/00_Alternate_Languages/58_Love/MiniScript/README.md deleted file mode 100644 index 1186963df..000000000 --- a/00_Alternate_Languages/58_Love/MiniScript/README.md +++ /dev/null @@ -1,22 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -0. Try-It! Page: -Go to https://miniscript.org/tryit/, clear the sample code from the code editor, and paste in the contents of love.ms. Then click the "Run Script" button. Program output (and input) will appear in the green-on-black terminal display to the right of or below the code editor. - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript love.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "love" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/58_Love/MiniScript/love.ms b/00_Alternate_Languages/58_Love/MiniScript/love.ms deleted file mode 100644 index 64693f127..000000000 --- a/00_Alternate_Languages/58_Love/MiniScript/love.ms +++ /dev/null @@ -1,41 +0,0 @@ -print " "*33 + "LOVE" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print - -print "A tribute to the great american artist, Robert Indiana." -print "His greatest work will be reproduced with a message of" -print "your choice up to 60 characters. If you can't think of" -print "a message, simple type the word 'LOVE'"; print -msg = input("Your message, please? ") -for i in range(1, 10); print; end for - -repeatedMsg = msg * ceil(60 / msg.len) - -data = [] -data += [60,1,12,26,9,12,3,8,24,17,8,4,6,23,21,6,4,6,22,12,5,6,5] -data += [4,6,21,11,8,6,4,4,6,21,10,10,5,4,4,6,21,9,11,5,4] -data += [4,6,21,8,11,6,4,4,6,21,7,11,7,4,4,6,21,6,11,8,4] -data += [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] -data += [4,6,17,3,1,7,5,13,4,4,6,15,5,2,23,5,1,29,5,17,8] -data += [1,29,9,9,12,1,13,5,40,1,1,13,5,40,1,4,6,13,3,10,6,12,5,1] -data += [5,6,11,3,11,6,14,3,1,5,6,11,3,11,6,15,2,1] -data += [6,6,9,3,12,6,16,1,1,6,6,9,3,12,6,7,1,10] -data += [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] -data += [8,6,5,3,14,6,7,1,10,9,6,3,3,15,6,16,1,1] -data += [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] -data += [11,8,13,27,1,11,8,13,27,1,60] - -for row in range(0, 35) - s = [] - a1 = 0; p = true - while a1 < 60 - a = data.pull - a1 += a - for i in range(a1-a, a1-1) - s.push repeatedMsg[i] * p + " " * (not p) - end for - p = not p - end while - print s.join("") - wait 0.1 // OPTIONAL; slows printing down so you can see it all -end for diff --git a/00_Alternate_Languages/58_Love/README.md b/00_Alternate_Languages/58_Love/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/58_Love/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/58_Love/love.bas b/00_Alternate_Languages/58_Love/love.bas deleted file mode 100644 index c53d2ae31..000000000 --- a/00_Alternate_Languages/58_Love/love.bas +++ /dev/null @@ -1,34 +0,0 @@ -2 PRINT TAB(33);"LOVE" -4 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -6 PRINT: PRINT: PRINT -20 PRINT "A TRIBUTE TO THE GREAT AMERICAN ARTIST, ROBERT INDIANA." -30 PRINT "HIS GREATEST WORK WILL BE REPRODUCED WITH A MESSAGE OF" -40 PRINT "YOUR CHOICE UP TO 60 CHARACTERS. IF YOU CAN'T THINK OF" -50 PRINT "A MESSAGE, SIMPLE TYPE THE WORD 'LOVE'": PRINT -60 INPUT "YOUR MESSAGE, PLEASE";A$: L=LEN(A$) -70 DIM T$(120): FOR I=1 TO 10: PRINT: NEXT I -100 FOR J=0 TO INT(60/L) -110 FOR I=1 TO L -120 T$(J*L+I)=MID$(A$,I,1) -130 NEXT I: NEXT J -140 C=0 -200 A1=1: P=1: C=C+1: IF C=37 THEN 999 -205 PRINT -210 READ A: A1=A1+A: IF P=1 THEN 300 -240 FOR I=1 TO A: PRINT " ";: NEXT I: P=1: GOTO 400 -300 FOR I=A1-A TO A1-1: PRINT T$(I);: NEXT I: P=0 -400 IF A1>60 THEN 200 -410 GOTO 210 -600 DATA 60,1,12,26,9,12,3,8,24,17,8,4,6,23,21,6,4,6,22,12,5,6,5 -610 DATA 4,6,21,11,8,6,4,4,6,21,10,10,5,4,4,6,21,9,11,5,4 -620 DATA 4,6,21,8,11,6,4,4,6,21,7,11,7,4,4,6,21,6,11,8,4 -630 DATA 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 -640 DATA 4,6,17,3,1,7,5,13,4,4,6,15,5,2,23,5,1,29,5,17,8 -650 DATA 1,29,9,9,12,1,13,5,40,1,1,13,5,40,1,4,6,13,3,10,6,12,5,1 -660 DATA 5,6,11,3,11,6,14,3,1,5,6,11,3,11,6,15,2,1 -670 DATA 6,6,9,3,12,6,16,1,1,6,6,9,3,12,6,7,1,10 -680 DATA 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 -690 DATA 8,6,5,3,14,6,7,1,10,9,6,3,3,15,6,16,1,1 -700 DATA 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 -710 DATA 11,8,13,27,1,11,8,13,27,1,60 -999 FOR I=1 TO 10: PRINT: NEXT I: END diff --git a/00_Alternate_Languages/59_Lunar_LEM_Rocket/MiniScript/README.md b/00_Alternate_Languages/59_Lunar_LEM_Rocket/MiniScript/README.md deleted file mode 100644 index 6ba18136c..000000000 --- a/00_Alternate_Languages/59_Lunar_LEM_Rocket/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). Note that there are three different programs in this folder, all variations on the "land the LEM on the Moon" idea. - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the desired program with a command such as: - -``` - miniscript lem.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "lem" // (or "lunar" or "rocket") - run -``` diff --git a/00_Alternate_Languages/59_Lunar_LEM_Rocket/MiniScript/lem.ms b/00_Alternate_Languages/59_Lunar_LEM_Rocket/MiniScript/lem.ms deleted file mode 100644 index 92a263e26..000000000 --- a/00_Alternate_Languages/59_Lunar_LEM_Rocket/MiniScript/lem.ms +++ /dev/null @@ -1,324 +0,0 @@ -print " "*34 + "LEM" -print " "*15 + "Creative Computing Morristown, New Jersey" -// rockt2 is an interactive game that simulates a lunar -// landing is similar to that of the apollo program. -// There is absolutely no chance involved - - -printIntro = function - print - print " You are on a lunar landing mission. as the pilot of" - print "the lunar excursion module, you will be expected to" - print "give certain commands to the module navigation system." - print "The on-board computer will give a running account" - print "of information needed to navigate the ship." - print - input "(Press Return.)" - print - print "The attitude angle called for is described as follows." - print "+ or -180 degrees is directly away from the moon" - print "-90 degrees is on a tangent in the direction of orbit" - print "+90 degrees is on a tangent from the direction of orbit" - print "0 (zero) degrees is directly toward the moon" - print - print " "*30 + "-180|+180" - print " "*34 + "^" - print " "*27 + "-90 < -+- > +90" - print " "*34 + "!" - print " "*34 + "0" - print " "*21 + "<<<< direction of orbit <<<<" - print - print " "*20 + "------ surface of moon ------" - print - input - print - print "All angles between -180 and +180 degrees are accepted." - print - print "1 fuel unit = 1 sec. at max thrust" - print "Any discrepancies are accounted for in the use of fuel" - print "for an attitude change." - print "Available engine power: 0 (zero) and any value between" - print "10 and 100 percent." - print - print "Negative thrust or time is prohibited." - print - input -end function - -printInOutInfo = function(withExample = true) - print - print "Input: time interval in seconds ------ (T)" - print " percentage of thrust ---------- (P)" - print " attitude angle in degrees ----- (A)" - print - if withExample then - print "For example:" - print "T,P,A? 10,65,-60" - print "To abort the mission at any time, enter 0,0,0" - print - end if - print "Output: total time in elapsed seconds" - print " height in " + ms - print " distance from landing site in " + ms - print " vertical velocity in " + ms + "/second" - print " horizontal velocity in " + ms + "/second" - print " fuel units remaining" - print -end function - -initState = function - globals.m = 17.95 - globals.f1 = 5.25 - globals.n = 7.5 - globals.r0 = 926 - globals.v0 = 1.29 - globals.t = 0 - globals.h0 = 60 - globals.r = r0+h0 - globals.a = -3.425 - globals.r1 = 0 - globals.a1 = 8.84361e-04 - globals.r3 = 0 - globals.a3 = 0 - globals.m1 = 7.45 - globals.m0 = m1 - globals.b = 750 - globals.t1 = 0 - globals.f = 0 - globals.p = 0 - globals.n = 1 - globals.m2 = 0 - globals.s = 0 - globals.c = 0 -end function - -getUnits = function(moreHelp=true) - print - while true - print "Input measurement option number? ", "" - if moreHelp then - print - print "Which system of measurement do you prefer?" - print " 1 = metric 0 = english" - print "Enter the appropriate number? ", "" - end if - k = input.val - if k == 0 then - globals.z = 6080 - globals.ms = "feet" - globals.g3 = .592 - globals.ns = "n.miles" - globals.g5 = z - break - else if k == 1 then - globals.z = 1852.8 - globals.ms="meters" - globals.g3 = 3.6 - globals.ns=" kilometers" - globals.g5 = 1000 - break - end if - moreHelp = true - end while -end function - -startFirstGame = function - initState - print - print "Lunar Landing Simulation" - print - print "Have you flown an Apollo/LEM mission before", "" - while true - qs = input(" (yes or no)? ").lower - if qs and (qs[0] == "y" or qs[0] == "n") then break - print "Just answer the question, please, ", "" - end while - getUnits (qs[0] == "n") - if qs[0] == "n" then printIntro - printInOutInfo -end function - -startSubsequentGame = function - initState - print - print "OK, do you want the complete instructions or the input -" - print "output statements?" - while true - print "1 = complete instructions" - print "2 = input-output statements" - print "3 = neither" - b1 = input.val - if 1 <= b1 <= 3 then break - end while - if b1 == 1 then printIntro - if b1 < 3 then printInOutInfo -end function - -getTurnInputs = function - while true - print - inp = input("T,P,A? ").replace(",", " ").replace(" ", " ").split - if inp.len != 3 then continue - globals.t1 = inp[0].val // NOTE: though we prompt for T, P, A, - globals.f = inp[1].val // internally these are t1, f, and p respectively. - globals.p = inp[2].val - globals.f = f/100 - if t1 < 0 then - print - print "This spacecraft is not able to violate the space-"; - print "time continuum." - continue - else if t1 == 0 then - return // abort mission - end if - if f < 0 or f > 1.05 or abs(f-.05) < .05 then - print - print "Impossible thrust value: ", "" - if f < 0 then - print "negative" - else if f < 0.5 then - print "too small" - else - print "too large" - end if - continue - end if - if abs(p) > 180 then - print - print "If you want to spin around, go outside the module" - print "for an E.V.A." - continue - end if - return - end while -end function - -pad = function(num, width=10) - anum = abs(num) - if anum >= 10000 then - s = round(num) - else if anum >= 10000 then - s = round(num, 1) - else if anum > 100 then - s = round(num, 2) - else - s = round(num, 3) - end if - return (s + " " * width)[:width] -end function - -integrate = function - n = 20 - if t1 >= 400 then n = t1/20 - globals.t1 = t1/n - globals.p = p*3.14159/180 - s = sin(p) - c = cos(p) - globals.m2 = m0*t1*f/b - globals.r3 = -.5*r0*((v0/r)^2)+r*a1*a1 - globals.a3 = -2*r1*a1/r - - for i in range(1, n) - if m1 != 0 then - globals.m1 = m1-m2 - if m1<=0 then - globals.f = f*(1+m1/m2) - globals.m2 = m1+m2 - print "You are out of fuel." - globals.m1 = 0 - end if - else - globals.f = 0 - globals.m2 = 0 - end if - globals.m = m-.5*m2 - globals.r4 = r3 - globals.r3 = -.5*r0*((v0/r)^2)+r*a1*a1 - globals.r2 = (3*r3-r4)/2+.00526*f1*f*c/m - globals.a4 = a3 - globals.a3 = -2*r1*a1/r - globals.a2 = (3*a3-a4)/2+.0056*f1*f*s/(m*r) - globals.x = r1*t1+.5*r2*t1*t1 - globals.r = r+x - globals.h0 = h0+x - globals.r1 = r1+r2*t1 - globals.a = a+a1*t1+.5*a2*t1*t1 - globals.a1 = a1+a2*t1 - globals.m = m-.5*m2 - globals.t = t+t1 - if h0<3.287828e-04 then break - end for - - globals.h = h0*z - globals.h1 = r1*z - globals.d = r0*a*z - globals.d1 = r*a1*z - globals.t2 = m1*b/m0 - - print " " + [pad(t, 10), pad(h, 10), pad(d, 10), pad(h1, 10), pad(d1, 10), pad(t2, 10)].join -end function - -// Do one turn of the game. Return true if game still in progress, -// or false when game is over (aborted, crashed, or landed). -doOneTurn = function - if m1 == 0 then - // out of fuel! - globals.t1 = 20 - globals.f = 0 - globals.p = 0 - else - getTurnInputs - end if - if t1 == 0 then - print "Mission abended" - return false - end if - integrate - - if h0 < 3.287828e-04 then - if r1 < -8.21957e-04 or abs(r*a1) > 4.93174e-04 or h0 < -3.287828e-04 then - print - print "Crash !!!!!!!!!!!!!!!!" - print "Your impact created a crater " + abs(h) + " " + ms + " deep." - x1 = sqr(d1*d1+h1*h1)*g3 - print "At contact you were traveling " + x1 + " " + ns + "/hr" - else if abs(d)>10*z then - print "You are down safely - " - print - print "But missed the landing site by" + abs(d/g5) + " " + ns + "." - else - print - print "Tranquility Base here -- the Eagle has landed." - print "Congratulations -- there was no spacecraft damage." - print "You may now proceed with surface exploration." - end if - return false - end if - - if r0*a>164.474 then - print - print "You have been lost in space with no hope of recovery." - return false - end if - return true -end function - -startFirstGame -while true - t1 = 0; f = 0; p = 0 - integrate - while doOneTurn - end while - print - while true - qs = input("Do you want to try it again (yes/no)? ").lower - if qs and (qs[0] == "y" or qs[0] == "n") then break - end while - if qs[0] == "n" then - print - print "Too bad, the space program hates to lose experienced" - print "astronauts." - break - end if - startSubsequentGame -end while diff --git a/00_Alternate_Languages/59_Lunar_LEM_Rocket/MiniScript/lunar.ms b/00_Alternate_Languages/59_Lunar_LEM_Rocket/MiniScript/lunar.ms deleted file mode 100644 index e8da8d72c..000000000 --- a/00_Alternate_Languages/59_Lunar_LEM_Rocket/MiniScript/lunar.ms +++ /dev/null @@ -1,114 +0,0 @@ -print " "*33 + "Lunar" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print -print "This is a computer simulation of an Apollo lunar" -print "landing capsule."; print; print -print "The on-board computer has failed (it was made by" -print "Xerox) so you have to land the capsule manually." - -printCols = function(fields, delimiter=null) - if delimiter == null then delimiter = text.delimiter - line = "" - for s in fields - line += (s + " "*12)[:12] - end for - print line, delimiter -end function - -doOneGame = function - print; print "Set burn rate of retro rockets to any value between" - print "0 (free fall) and 200 (maximum burn) pounds per second." - print "Set new burn rate every 10 seconds."; print - print "Capsule weight 32,500 lbs; fuel weight 16,500 lbs." - print; print; print; print "Good luck" - l = 0 - - print - printCols ["sec","mi + ft","mph","lb fuel","burn rate"] - print - a=120; v = 1; m=33000; n=16500; g=1e-03; z = 1.8 - - formulaSet1 = function // (subroutine 330) - outer.l += s - outer.t -= s - outer.m -= s * k - outer.a = i - outer.v = j - end function - - formulaSet2 = function // (subroutine 420) - outer.q = s * k / m - outer.j = v + g*s + z*(-q-q*q/2-q^3/3-q^4/4-q^5/5) - outer.i = a - g*s*s/2 - v*s+z*s*(q/2+q^2/6+q^3/12+q^4/20+q^5/30) - end function - - formulaSet3 = function // (loop 340-360) - while s >= 5e-3 - outer.d = v + sqrt(v * v + 2 * a * (g - z * k / m)) - outer.s = 2 * a / d - formulaSet2 - formulaSet1 - end while - end function - - while true - printCols [l, floor(a) + " " + floor(5280*(a-floor(a))), 3600*v, m-n], "" - k = input.val - t=10 - shouldExit = false - - while true - if m-n < 1e-03 then break - if t < 1e-03 then break - s = t; if m < n+s*k then s = (m-n)/k - formulaSet2 - if i <= 0 then - formulaSet3 - shouldExit = true - break - end if - if v > 0 and j < 0 then - while v > 0 and j <= 0 - w = (1 - m*g/(z*k))/2 - s = m*v / (z*k*(w + sqrt(w*w + v/z))) + 0.05 - formulaSet2 - if i <= 0 then - formulaSet3 - shouldExit = true - break - end if - formulaSet1 - end while - if shouldExit then break - continue - end if - formulaSet1 - end while - if shouldExit then break - if m-n < 1e-03 then - print "Fuel out at " + round(l) + " seconds" - s = (-v+sqrt(v*v+2*a*g))/g - v = v+g*s; l = l+s - break - end if - end while - - w = 3600*v - print "On moon at " + l + " seconds - impact velocity " + round(w,1) + " mph" - if w <= 1.2 then - print "Perfect landing!" - else if w <= 10 then - print "Good landing (could be better)" - else if w <= 60 then - print "Craft damage... you're stranded here until a rescue" - print "party arrives. Hope you have enough oxygen!" - else - print "Sorry there were no survivors. You blew it!" - print "In fact, you blasted a new lunar crater " + round(w*.227,1) + " feet deep!" - end if -end function - -while true - doOneGame - print; print; print; print "Try again??" -end while diff --git a/00_Alternate_Languages/59_Lunar_LEM_Rocket/MiniScript/rocket.ms b/00_Alternate_Languages/59_Lunar_LEM_Rocket/MiniScript/rocket.ms deleted file mode 100644 index 4131290b5..000000000 --- a/00_Alternate_Languages/59_Lunar_LEM_Rocket/MiniScript/rocket.ms +++ /dev/null @@ -1,102 +0,0 @@ -if version.hostName == "Mini Micro" then clear -print " "*30 + "Rocket" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print -print "Lunar Landing Simulation" -print "----- ------- ----------"; print -yn = input("Do you want instructions (yes or no)? ").lower -if not yn or yn[0] != "n" then - print - print "You are landing on the moon and and have taken over manual" - print "control 1000 feet above a good landing spot. You have a down-" - print "ward velocity of 50 feet/sec. 150 units of fuel remain." - print - print "Here are the rules that govern your Apollo space-craft" - print "(Press Return after each one):"; print - print "(1) After each second the height, velocity, and remaining fuel" - print " will be reported via Digby your on-board computer." - input - print "(2) After the report a '?' will appear. Enter the number" - print " of units of fuel you wish to burn during the next" - print " second. Each unit of fuel will slow your descent by" - print " 1 foot/sec." - input - print "(3) The maximum thrust of your engine is 30 feet/sec/sec" - print " or 30 units of fuel per second." - input - print "(4) When you contact the lunar surface, your descent engine" - print " will automatically shut down and you will be given a" - print " report of your landing speed and remaining fuel." - input - print "(5) If you run out of fuel the '?' will no longer appear" - print " but your second by second report will continue until" - print " you contact the lunar surface."; print - input -end if - -pad = function(s, width=10) - return (s + " "*width)[:width] -end function - -// Bonus little feature when running in Mini Micro: display a header bar -// always at the top of the screen. -drawHeaders = function - if version.hostName != "Mini Micro" then return - display(2).mode = displayMode.text; td = display(2) - td.color = text.color; td.backColor = color.black - td.row = 25; td.column = 0 - td.print "sec feet speed fuel plot of distance" + " "*21 -end function - -while true - print "Beginning landing procedure.........."; print - print "G O O D L U C K ! ! !" - print; print - print "sec feet speed fuel plot of distance" - drawHeaders - print - t=0; h=1000; v=50; fuel=150 - while true - print pad(t,5) + pad(h,7) + pad(v, 10) + pad(fuel,8) + "|" + " "*floor(h/30) + "*" - if fuel <= 0 then - burn = 0 - wait 0.5 // (slight pause for drama and legibility) - else - burn = input("?").val - if burn < 0 then burn = 0 - if burn > 30 then burn=30 - if burn > fuel then - burn = fuel - print "**** out of fuel ****" - end if - end if - v1 = v - burn + 5 - fuel -= burn - h -= .5*(v+v1) - if h <= 0 then break - t += 1 - v = v1 - end while - print "***** CONTACT *****" - h = h+ .5*(v1+v) - if burn == 5 then - d = h/v - else - d = (-v+sqrt(v*v+h*(10-2*burn)))/(5-burn) - end if - v1 = v + (5-burn)*d - print "Touchdown at " + (t+d) + " seconds." - print "Landing velocity = " + round(v1,1) + " feet/sec." - print fuel + " units of fuel remaining." - if v1 == 0 then - print "Congratulations! a perfect landing!!" - print "Your license will be renewed.......later." - else if abs(v1) >= 2 then - print "***** Sorry, but you blew it!!!!" - print "Appropriate condolences will be sent to your next of kin." - end if - print; print; print - yn = input("Another mission? ").lower - if not yn or yn[0] != "y" then break -end while -print; print "Control out."; print diff --git a/00_Alternate_Languages/59_Lunar_LEM_Rocket/README.md b/00_Alternate_Languages/59_Lunar_LEM_Rocket/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/59_Lunar_LEM_Rocket/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/59_Lunar_LEM_Rocket/lem.bas b/00_Alternate_Languages/59_Lunar_LEM_Rocket/lem.bas deleted file mode 100644 index eece9cc1b..000000000 --- a/00_Alternate_Languages/59_Lunar_LEM_Rocket/lem.bas +++ /dev/null @@ -1,246 +0,0 @@ -2 PRINT TAB(34);"LEM" -4 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -7 REM ROCKT2 IS AN INTERACTIVE GAME THAT SIMULATES A LUNAR -8 REM LANDING IS SIMILAR TO THAT OF THE APOLLO PROGRAM. -9 REM THERE IS ABSOLUTELY NO CHANCE INVOLVED -10 Z$="GO" -15 B1=1 -20 M=17.95 -25 F1=5.25 -30 N=7.5 -35 R0=926 -40 V0=1.29 -45 T=0 -50 H0=60 -55 R=R0+H0 -60 A=-3.425 -65 R1=0 -70 A1=8.84361E-04 -75 R3=0 -80 A3=0 -85 M1=7.45 -90 M0=M1 -95 B=750 -100 T1=0 -105 F=0 -110 P=0 -115 N=1 -120 M2=0 -125 S=0 -130 C=0 -135 IF Z$="YES" THEN 1150 -140 PRINT -145 PRINT "LUNAR LANDING SIMULATION" -150 PRINT -155 PRINT "HAVE YOU FLOWN AN APOLLO/LEM MISSION BEFORE"; -160 PRINT " (YES OR NO)"; -165 INPUT Q$ -170 IF Q$="YES" THEN 190 -175 IF Q$="NO" THEN 205 -180 PRINT "JUST ANSWER THE QUESTION, PLEASE, "; -185 GOTO 160 -190 PRINT -195 PRINT "INPUT MEASUREMENT OPTION NUMBER"; -200 GOTO 225 -205 PRINT -210 PRINT "WHICH SYSTEM OF MEASUREMENT DO YOU PREFER?" -215 PRINT " 1=METRIC 0=ENGLISH" -220 PRINT "ENTER THE APPROPRIATE NUMBER"; -225 INPUT K -230 PRINT -235 IF K=0 THEN 280 -240 IF K=1 THEN 250 -245 GOTO 220 -250 Z=1852.8 -255 M$="METERS" -260 G3=3.6 -265 N$=" KILOMETERS" -270 G5=1000 -275 GOTO 305 -280 Z=6080 -285 M$="FEET" -290 G3=.592 -295 N$="N.MILES" -300 G5=Z -305 IF B1=3 THEN 670 -310 IF Q$="YES" THEN 485 -315 PRINT -320 PRINT " YOU ARE ON A LUNAR LANDING MISSION. AS THE PILOT OF" -325 PRINT "THE LUNAR EXCURSION MODULE, YOU WILL BE EXPECTED TO" -330 PRINT "GIVE CERTAIN COMMANDS TO THE MODULE NAVIGATION SYSTEM." -335 PRINT "THE ON-BOARD COMPUTER WILL GIVE A RUNNING ACCOUNT" -340 PRINT "OF INFORMATION NEEDED TO NAVIGATE THE SHIP." -345 PRINT -350 PRINT -355 PRINT "THE ATTITUDE ANGLE CALLED FOR IS DESCRIBED AS FOLLOWS." -360 PRINT "+ OR -180 DEGREES IS DIRECTLY AWAY FROM THE MOON" -365 PRINT "-90 DEGREES IS ON A TANGENT IN THE DIRECTION OF ORBIT" -370 PRINT "+90 DEGREES IS ON A TANGENT FROM THE DIRECTION OF ORBIT" -375 PRINT "0 (ZERO) DEGREES IS DIRECTLY TOWARD THE MOON" -380 PRINT -385 PRINT TAB(30);"-180|+180" -390 PRINT TAB(34);"^" -395 PRINT TAB(27);"-90 < -+- > +90" -400 PRINT TAB(34);"!" -405 PRINT TAB(34);"0" -410 PRINT TAB(21);"<<<< DIRECTION OF ORBIT <<<<" -415 PRINT -420 PRINT TAB(20);"------ SURFACE OF MOON ------" -425 PRINT -430 PRINT -435 PRINT "ALL ANGLES BETWEEN -180 AND +180 DEGREES ARE ACCEPTED." -440 PRINT -445 PRINT "1 FUEL UNIT = 1 SEC. AT MAX THRUST" -450 PRINT "ANY DISCREPANCIES ARE ACCOUNTED FOR IN THE USE OF FUEL" -455 PRINT "FOR AN ATTITUDE CHANGE." -460 PRINT "AVAILABLE ENGINE POWER: 0 (ZERO) AND ANY VALUE BETWEEN" -465 PRINT "10 AND 100 PERCENT." -470 PRINT -475 PRINT"NEGATIVE THRUST OR TIME IS PROHIBITED." -480 PRINT -485 PRINT -490 PRINT "INPUT: TIME INTERVAL IN SECONDS ------ (T)" -495 PRINT " PERCENTAGE OF THRUST ---------- (P)" -500 PRINT " ATTITUDE ANGLE IN DEGREES ----- (A)" -505 PRINT -510 IF Q$="YES" THEN 535 -515 PRINT "FOR EXAMPLE:" -520 PRINT "T,P,A? 10,65,-60" -525 PRINT "TO ABORT THE MISSION AT ANY TIME, ENTER 0,0,0" -530 PRINT -535 PRINT "OUTPUT: TOTAL TIME IN ELAPSED SECONDS" -540 PRINT " HEIGHT IN ";M$ -545 PRINT " DISTANCE FROM LANDING SITE IN ";M$ -550 PRINT " VERTICAL VELOCITY IN ";M$;"/SECOND" -555 PRINT " HORIZONTAL VELOCITY IN ";M$;"/SECOND" -560 PRINT " FUEL UNITS REMAINING" -565 PRINT -570 GOTO 670 -575 PRINT -580 PRINT "T,P,A"; -585 INPUT T1,F,P -590 F=F/100 -595 IF T1<0 THEN 905 -600 IF T1=0 THEN 1090 -605 IF ABS(F-.05)>1 THEN 945 -610 IF ABS(F-.05)<.05 THEN 945 -615 IF ABS(P)>180 THEN 925 -620 N=20 -625 IF T1<400 THEN 635 -630 N=T1/20 -635 T1=T1/N -640 P=P*3.14159/180 -645 S=SIN(P) -650 C=COS(P) -655 M2=M0*T1*F/B -660 R3=-.5*R0*((V0/R)^2)+R*A1*A1 -665 A3=-2*R1*A1/R -670 FOR I=1 TO N -675 IF M1=0 THEN 715 -680 M1=M1-M2 -685 IF M1>0 THEN 725 -690 F=F*(1+M1/M2) -695 M2=M1+M2 -700 PRINT "YOU ARE OUT OF FUEL." -705 M1=0 -710 GOTO 725 -715 F=0 -720 M2=0 -725 M=M-.5*M2 -730 R4=R3 -735 R3=-.5*R0*((V0/R)^2)+R*A1*A1 -740 R2=(3*R3-R4)/2+.00526*F1*F*C/M -745 A4=A3 -750 A3=-2*R1*A1/R -755 A2=(3*A3-A4)/2+.0056*F1*F*S/(M*R) -760 X=R1*T1+.5*R2*T1*T1 -765 R=R+X -770 H0=H0+X -775 R1=R1+R2*T1 -780 A=A+A1*T1+.5*A2*T1*T1 -785 A1=A1+A2*T1 -790 M=M-.5*M2 -795 T=T+T1 -800 IF H0<3.287828E-04 THEN 810 -805 NEXT I -810 H=H0*Z -815 H1=R1*Z -820 D=R0*A*Z -825 D1=R*A1*Z -830 T2=M1*B/M0 -835 PRINT " ";T;TAB(10);H;TAB(23);D; -840 PRINT TAB(37);H1;TAB(49);D1;TAB(60);T2 -845 IF H0<3.287828E-04 THEN 880 -850 IF R0*A>164.474 THEN 1050 -855 IF M1>0 THEN 580 -860 T1=20 -865 F=0 -870 P=0 -875 GOTO 620 -880 IF R1<-8.21957E-04 THEN 1020 -885 IF ABS(R*A1)>4.93174E-04 THEN 1020 -890 IF H0<-3.287828E-04 THEN 1020 -895 IF ABS(D)>10*Z THEN 1065 -900 GOTO 995 -905 PRINT -910 PRINT "THIS SPACECRAFT IS NOT ABLE TO VIOLATE THE SPACE-"; -915 PRINT "TIME CONTINUUM." -920 GOTO 575 -925 PRINT -930 PRINT "IF YOU WANT TO SPIN AROUND, GO OUTSIDE THE MODULE" -935 PRINT "FOR AN E.V.A." -940 GOTO 575 -945 PRINT -950 PRINT "IMPOSSIBLE THRUST VALUE "; -955 IF F<0 THEN 985 -960 IF F-.05<.05 THEN 975 -965 PRINT "TOO LARGE" -970 GOTO 575 -975 PRINT "TOO SMALL" -980 GOTO 575 -985 PRINT "NEGATIVE" -990 GOTO 575 -995 PRINT -1000 PRINT "TRANQUILITY BASE HERE -- THE EAGLE HAS LANDED." -1005 PRINT "CONGRATULATIONS -- THERE WAS NO SPACECRAFT DAMAGE." -1010 PRINT "YOU MAY NOW PROCEED WITH SURFACE EXPLORATION." -1015 GOTO 1100 -1020 PRINT -1025 PRINT "CRASH !!!!!!!!!!!!!!!!" -1030 PRINT "YOUR IMPACT CREATED A CRATER";ABS(H);M$;" DEEP." -1035 X1=SQR(D1*D1+H1*H1)*G3 -1040 PRINT "AT CONTACT YOU WERE TRAVELING";X1;N$;"/HR" -1045 GOTO 1100 -1050 PRINT -1055 PRINT "YOU HAVE BEEN LOST IN SPACE WITH NO HOPE OF RECOVERY." -1060 GOTO 1100 -1065 PRINT "YOU ARE DOWN SAFELY - " -1075 PRINT -1080 PRINT "BUT MISSED THE LANDING SITE BY";ABS(D/G5);N$;"." -1085 GOTO 1100 -1090 PRINT -1095 PRINT "MISSION ABENDED" -1100 PRINT -1105 PRINT "DO YOU WANT TO TRY IT AGAIN (YES/NO)?" -1110 INPUT Z$ -1115 IF Z$="YES" THEN 20 -1120 IF Z$="NO" THEN 1130 -1125 GOTO 1105 -1130 PRINT -1135 PRINT "TOO BAD, THE SPACE PROGRAM HATES TO LOSE EXPERIENCED" -1140 PRINT "ASTRONAUTS." -1145 STOP -1150 PRINT -1155 PRINT "OK, DO YOU WANT THE COMPLETE INSTRUCTIONS OR THE INPUT -" -1160 PRINT "OUTPUT STATEMENTS?" -1165 PRINT "1=COMPLETE INSTRUCTIONS" -1170 PRINT "2=INPUT-OUTPUT STATEMENTS" -1175 PRINT "3=NEITHER" -1180 INPUT B1 -1185 Q$="NO" -1190 IF B1=1 THEN 205 -1195 Q$="YES" -1200 IF B1=2 THEN 190 -1205 IF B1=3 THEN 190 -1210 GOTO 1165 -1215 END diff --git a/00_Alternate_Languages/59_Lunar_LEM_Rocket/lunar.bas b/00_Alternate_Languages/59_Lunar_LEM_Rocket/lunar.bas deleted file mode 100644 index b12037187..000000000 --- a/00_Alternate_Languages/59_Lunar_LEM_Rocket/lunar.bas +++ /dev/null @@ -1,48 +0,0 @@ -10 PRINT TAB(33);"LUNAR" -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 -50 PRINT "THE ON-BOARD COMPUTER HAS FAILED (IT WAS MADE BY" -60 PRINT "XEROX) SO YOU HAVE TO LAND THE CAPSULE MANUALLY." -70 PRINT: PRINT "SET BURN RATE OF RETRO ROCKETS TO ANY VALUE BETWEEN" -80 PRINT "0 (FREE FALL) AND 200 (MAXIMUM BURN) POUNDS PER SECOND." -90 PRINT "SET NEW BURN RATE EVERY 10 SECONDS.": PRINT -100 PRINT "CAPSULE WEIGHT 32,500 LBS; FUEL WEIGHT 16,500 LBS." -110 PRINT: PRINT: PRINT: PRINT "GOOD LUCK" -120 L=0 -130 PRINT: PRINT "SEC","MI + FT","MPH","LB FUEL","BURN RATE":PRINT -140 A=120:V=1:M=33000:N=16500:G=1E-03:Z=1.8 -150 PRINT L,INT(A);INT(5280*(A-INT(A))),3600*V,M-N,:INPUT K:T=10 -160 IF M-N<1E-03 THEN 240 -170 IF T<1E-03 THEN 150 -180 S=T: IF M>=N+S*K THEN 200 -190 S=(M-N)/K -200 GOSUB 420: IF I<=0 THEN 340 -210 IF V<=0 THEN 230 -220 IF J<0 THEN 370 -230 GOSUB 330: GOTO 160 -240 PRINT "FUEL OUT AT";L;"SECONDS":S=(-V+SQR(V*V+2*A*G))/G -250 V=V+G*S: L=L+S -260 W=3600*V: PRINT "ON MOON AT";L;"SECONDS - IMPACT VELOCITY";W;"MPH" -274 IF W<=1.2 THEN PRINT "PERFECT LANDING!": GOTO 440 -280 IF W<=10 THEN PRINT "GOOD LANDING (COULD BE BETTER)":GOTO 440 -282 IF W>60 THEN 300 -284 PRINT "CRAFT DAMAGE... YOU'RE STRANDED HERE UNTIL A RESCUE" -286 PRINT "PARTY ARRIVES. HOPE YOU HAVE ENOUGH OXYGEN!" -288 GOTO 440 -300 PRINT "SORRY THERE WERE NO SURVIVORS. YOU BLEW IT!" -310 PRINT "IN FACT, YOU BLASTED A NEW LUNAR CRATER";W*.227;"FEET DEEP!" -320 GOTO 440 -330 L=L+S: T=T-S: M=M-S*K: A=I: V=J: RETURN -340 IF S<5E-03 THEN 260 -350 D=V+SQR(V*V+2*A*(G-Z*K/M)):S=2*A/D -360 GOSUB 420: GOSUB 330: GOTO 340 -370 W=(1-M*G/(Z*K))/2: S=M*V/(Z*K*(W+SQR(W*W+V/Z)))+.05:GOSUB 420 -380 IF I<=0 THEN 340 -390 GOSUB 330: IF J>0 THEN 160 -400 IF V>0 THEN 370 -410 GOTO 160 -420 Q=S*K/M: J=V+G*S+Z*(-Q-Q*Q/2-Q^3/3-Q^4/4-Q^5/5) -430 I=A-G*S*S/2-V*S+Z*S*(Q/2+Q^2/6+Q^3/12+Q^4/20+Q^5/30):RETURN -440 PRINT:PRINT:PRINT:PRINT "TRY AGAIN??": GOTO 70 diff --git a/00_Alternate_Languages/59_Lunar_LEM_Rocket/rocket.bas b/00_Alternate_Languages/59_Lunar_LEM_Rocket/rocket.bas deleted file mode 100644 index efcd22fb2..000000000 --- a/00_Alternate_Languages/59_Lunar_LEM_Rocket/rocket.bas +++ /dev/null @@ -1,71 +0,0 @@ -10 PRINT TAB(30); "ROCKET" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT:PRINT:PRINT -70 PRINT "LUNAR LANDING SIMULATION" -80 PRINT "----- ------- ----------": PRINT -100 INPUT "DO YOU WANT INSTRUCTIONS (YES OR NO)";A$ -110 IF A$="NO" THEN 390 -160 PRINT -200 PRINT"YOU ARE LANDING ON THE MOON AND AND HAVE TAKEN OVER MANUAL" -210 PRINT"CONTROL 1000 FEET ABOVE A GOOD LANDING SPOT. YOU HAVE A DOWN-" -220 PRINT"WARD VELOCITY OF 50 FEET/SEC. 150 UNITS OF FUEL REMAIN." -225 PRINT -230 PRINT"HERE ARE THE RULES THAT GOVERN YOUR APOLLO SPACE-CRAFT:": PRINT -240 PRINT"(1) AFTER EACH SECOND THE HEIGHT, VELOCITY, AND REMAINING FUEL" -250 PRINT" WILL BE REPORTED VIA DIGBY YOUR ON-BOARD COMPUTER." -260 PRINT"(2) AFTER THE REPORT A '?' WILL APPEAR. ENTER THE NUMBER" -270 PRINT" OF UNITS OF FUEL YOU WISH TO BURN DURING THE NEXT" -280 PRINT" SECOND. EACH UNIT OF FUEL WILL SLOW YOUR DESCENT BY" -290 PRINT" 1 FOOT/SEC." -310 PRINT"(3) THE MAXIMUM THRUST OF YOUR ENGINE IS 30 FEET/SEC/SEC" -320 PRINT" OR 30 UNITS OF FUEL PER SECOND." -330 PRINT"(4) WHEN YOU CONTACT THE LUNAR SURFACE. YOUR DESCENT ENGINE" -340 PRINT" WILL AUTOMATICALLY SHUT DOWN AND YOU WILL BE GIVEN A" -350 PRINT" REPORT OF YOUR LANDING SPEED AND REMAINING FUEL." -360 PRINT"(5) IF YOU RUN OUT OF FUEL THE '?' WILL NO LONGER APPEAR" -370 PRINT" BUT YOUR SECOND BY SECOND REPORT WILL CONTINUE UNTIL" -380 PRINT" YOU CONTACT THE LUNAR SURFACE.":PRINT -390 PRINT"BEGINNING LANDING PROCEDURE..........":PRINT -400 PRINT"G O O D L U C K ! ! !" -420 PRINT:PRINT -430 PRINT"SEC FEET SPEED FUEL PLOT OF DISTANCE" -450 PRINT -455 T=0:H=1000:V=50:F=150 -490 PRINT T;TAB(6);H;TAB(16);V;TAB(26);F;TAB(35);"I";TAB(H/15);"*" -500 INPUT B -510 IF B<0 THEN 650 -520 IF B>30 THEN B=30 -530 IF B>F THEN B=F -540 V1=V-B+5 -560 F=F-B -570 H=H- .5*(V+V1) -580 IF H<=0 THEN 670 -590 T=T+1 -600 V=V1 -610 IF F>0 THEN 490 -615 IF B=0 THEN 640 -620 PRINT"**** OUT OF FUEL ****" -640 PRINT T;TAB(4);H;TAB(12);V;TAB(20);F;TAB(29);"I";TAB(H/12+29);"*" -650 B=0 -660 GOTO 540 -670 PRINT"***** CONTACT *****" -680 H=H+ .5*(V1+V) -690 IF B=5 THEN 720 -700 D=(-V+SQR(V*V+H*(10-2*B)))/(5-B) -710 GOTO 730 -720 D=H/V -730 V1=V+(5-B)*D -760 PRINT"TOUCHDOWN AT";T+D;"SECONDS." -770 PRINT"LANDING VELOCITY=";V1;"FEET/SEC." -780 PRINT F;"UNITS OF FUEL REMAINING." -790 IF V1<>0 THEN 810 -800 PRINT"CONGRATULATIONS! A PERFECT LANDING!!" -805 PRINT"YOUR LICENSE WILL BE RENEWED.......LATER." -810 IF ABS(V1)<2 THEN 840 -820 PRINT"***** SORRY, BUT YOU BLEW IT!!!!" -830 PRINT"APPROPRIATE CONDOLENCES WILL BE SENT TO YOUR NEXT OF KIN." -840 PRINT:PRINT:PRINT -850 INPUT "ANOTHER MISSION";A$ -860 IF A$="YES" THEN 390 -870 PRINT: PRINT "CONTROL OUT.": PRINT -999 END diff --git a/00_Alternate_Languages/60_Mastermind/MiniScript/README.md b/00_Alternate_Languages/60_Mastermind/MiniScript/README.md deleted file mode 100644 index 088a33011..000000000 --- a/00_Alternate_Languages/60_Mastermind/MiniScript/README.md +++ /dev/null @@ -1,17 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: -``` - miniscript mastermind.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: -``` - load "mastermind" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/60_Mastermind/MiniScript/mastermind.ms b/00_Alternate_Languages/60_Mastermind/MiniScript/mastermind.ms deleted file mode 100644 index 93ea30820..000000000 --- a/00_Alternate_Languages/60_Mastermind/MiniScript/mastermind.ms +++ /dev/null @@ -1,260 +0,0 @@ -// -// MASTERMIND II -// STEVE NORTH -// CREATIVE COMPUTING -// PO BOX 789-M MORRISTOWN NEW JERSEY 07960 -// -// Converted to MiniScript by Joe Strout (Sep 2023) - -// Advance the given combination to the next possible combination. -// Note that (unlike the BASIC program) our values are 0-based, not 1-based. -incrementCombo = function(combo) - idx = 0 - while true - combo[idx] += 1 - if combo[idx] < colorCount then return - combo[idx] = 0 - idx += 1 - end while -end function - -// Convert a numeric combination like [2, 0, 1] into a color string like "RBW". -comboToColorString = function(combo) - result = "" - for q in combo - result += colorCodes[q] - end for - return result -end function - -// Get a random color code like "RBW". -getRandomCode = function - // We do this by starting with a numeric combo of all 0's (first color), - // and then stepping through subsequent combos a random number of times. - combo = [0] * posCount - steps = floor(possibilities * rnd) - while steps - incrementCombo combo - steps -= 1 - end while - return comboToColorString(combo) -end function - -// Return [blackPins, whitePins] for the given guess and actual code. -// blackPins is how many guess entries are the correct color AND position; -// whitePins is how many guess entries have the right color, but wrong position. -// This works with either color strings or numeric combos. -calcResult = function(guess, actual) - if guess isa string then guess = guess.split("") else guess = guess[:] - if actual isa string then actual = actual.split("") else actual = actual[:] - black = 0; white = 0 - for i in guess.indexes - if guess[i] == actual[i] then - black += 1 - actual[i] = null - else - for j in actual.indexes - if guess[i] == actual[j] and guess[j] != actual[j] then - white += 1 - actual[j] = null - break - end if - end for - end if - guess[i] = null - end for - return [black, white] -end function - -// Pad a string with spaces, to the given width. -pad = function(s, width=12) - return (s + " "*width)[:width] -end function - -// Print the history of guesses and results. -printBoard = function - print - print "BOARD" - print "Move Guess Black White" - for i in guessHistory.indexes - print pad(i+1, 9) + pad(guessHistory[i], 15) + - pad(guessResult[i][0], 10) + guessResult[i][1] - end for - print -end function - -// Quit the game (after reporting the computer's secret code). -quit = function(computerCode) - print "Quitter! My combination was: " + computerCode - print - print "Good bye" - exit -end function - -// Prompt the user for a guess (e.g. "RBW"). -// Also handle "BOARD" and "QUIT" commands. -inputGuess = function(guessNum, secretCode) - while true - guess = input("Move #" + guessNum + " Guess? ").upper - if guess == "BOARD" then - printBoard - else if guess == "QUIT" then - quit secretCode - else if guess.len != posCount then - print "Bad number of positions." - else - ok = true - for c in guess - if colorCodes.indexOf(c) == null then - print "'" + c + "' is unrecognized." - ok = false - break - end if - end for - if ok then return guess - end if - end while -end function - -// Play one half-round where the computer picks a code, -// and the human tries to guess it. -doHumanGuesses = function - print "Guess my combination." - print - secretCode = getRandomCode - //print "My secret combo is: " + secretCode // (for debugging purposes) - - globals.guessHistory = [] // list of guesses, e.g. "RBW" - globals.guessResult = [] // result of each guess, as [BlackPins, WhitePins] - - for guessNum in range(1, 10) - guess = inputGuess(guessNum, secretCode) - result = calcResult(guess, secretCode) - if result[0] == posCount then - print "You guessed it in " + guessNum + " moves!" - break - end if - // Tell human results - print "You have " + result[0] + " blacks and " + result[1] + " whites." - // Save all this stuff for board printout later - guessHistory.push guess - guessResult.push result - end for - if guess != secretCode then - print "You ran out of moves! That's all you get!" - print "The actual combination was: " + secretCode - end if - globals.humanScore += guessNum -end function - -// Play one half-round where the human picks a code, -// and the computer tries to guess it. -// Return true if this goes OK, and false if we need a do-over. -doComputerGuesses = function - print "Now I guess. Think of a combination." - input "Hit Return when ready:" - - // Make a list of possible combination *numbers*, from 0 to possibilities-1. - // We'll remove entries from this list as we eliminate them with our guesses. - possible = range(0, possibilities-1) - - gotIt = false - for guessNum in range(1, 10) - if not possible then - print "You have given me inconsistent information." - print "Try again, and this time please be more careful." - return false - end if - guessIdx = possible[rnd * possible.len] - guessCombo = [0] * posCount - if guessIdx > 0 then - for x in range(0, guessIdx-1) - incrementCombo guessCombo - end for - end if - - print "My guess is: " + comboToColorString(guessCombo) - - while true - s = input(" Blacks, Whites? ").replace(",", " ").replace(" ", " ").split - if s.len == 2 then break - end while - actualResult = [s[0].val, s[1].val] - - if actualResult[0] == posCount then - print "I got it in " + guessNum + " moves!" - gotIt = true - break - end if - - // Now zip through all possibilities, and if it's still in our - // possible list but doesn't match the given result, remove it. - combo = [0] * posCount - for x in range(0, possibilities-1) - if x > 0 then incrementCombo combo - idx = possible.indexOf(x) - if idx == null then continue // (already eliminated) - result = calcResult(combo, guessCombo) - if result != actualResult then - //print "Eliminating #" + x + ", " + comboToColorString(combo) - possible.remove idx - end if - end for - end for - - if not gotIt then - print "I used up all my moves!" - print "I guess my CPU is just having an off day." - end if - globals.computerScore += guessNum - return true -end function - -// Show the score (with the given header). -showScore = function(header="Score") - print header + ":" - print " COMPUTER " + computerScore - print " HUMAN " + humanScore - print -end function - -// Initialization of global variables -colorCodes = "BWRGOYPT" -colorNames = "Black,White,Red,Green,Orange,Yellow,Purple,Tan".split(",") -computerScore = 0 -humanScore = 0 - -// Main program -print " "*30 + "Mastermind" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print -while true - colorCount = input("Number of colors? ").val - if 0 < colorCount <= 8 then break - print "No more than 8, please!" -end while -posCount = input("Number of positions? ").val -roundCount = input("Number of rounds? ").val -possibilities = colorCount ^ posCount -print "Total possibilities = " + possibilities - -print; print -print "Color Letter" -print "===== ======" -for x in range(0, colorCount-1) - print pad(colorNames[x], 9) + colorCodes[x] -end for -print - -for round in range(1, roundCount) - print - print "Round number " + round + " ----" - print - doHumanGuesses - showScore - while not doComputerGuesses; end while - showScore -end for - -print "GAME OVER" -showScore "Final score" diff --git a/00_Alternate_Languages/60_Mastermind/README.md b/00_Alternate_Languages/60_Mastermind/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/60_Mastermind/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/60_Mastermind/mastermind.bas b/00_Alternate_Languages/60_Mastermind/mastermind.bas deleted file mode 100644 index 215cdd186..000000000 --- a/00_Alternate_Languages/60_Mastermind/mastermind.bas +++ /dev/null @@ -1,232 +0,0 @@ -2 PRINT TAB(30);"MASTERMIND" -4 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -6 PRINT: PRINT: PRINT -10 REM -20 REM MASTERMIND II -30 REM STEVE NORTH -40 REM CREATIVE COMPUTING -50 REM PO BOX 789-M MORRISTOWN NEW JERSEY 07960 -60 REM -70 REM -80 INPUT "NUMBER OF COLORS";C9 -90 IF C9>8 THEN PRINT "NO MORE THAN 8, PLEASE!":GOTO 80 -100 INPUT "NUMBER OF POSITIONS";P9 -110 INPUT "NUMBER OF ROUNDS";R9 -120 P=C9^P9 -130 PRINT "TOTAL POSSIBILITIES =";P -140 H=0:C=0 -150 DIM Q(P9),S(10,2),S$(10),A$(P9),G$(P9),I(P),H$(P9) -160 L$="BWRGOYPT" -170 PRINT -180 PRINT -190 PRINT "COLOR LETTER" -200 PRINT "===== ======" -210 FOR X=1 TO C9 -220 READ X$ -230 PRINT X$;TAB(13);MID$(L$,X,1) -240 NEXT X -250 PRINT -260 FOR R=1 TO R9 -270 PRINT -280 PRINT "ROUND NUMBER";R;"----" -290 PRINT -300 PRINT "GUESS MY COMBINATION.":PRINT -310 REM GET A COMBINATION -320 A=INT(P*RND(1)+1) -330 GOSUB 3000 -340 FOR X=1 TO A -350 GOSUB 3500 -360 NEXT X -370 FOR M=1 TO 10 -380 PRINT "MOVE # ";M;" GUESS ";:INPUT X$ -390 IF X$="BOARD" THEN 2000 -400 IF X$="QUIT" THEN 2500 -410 IF LEN(X$)<>P9 THEN PRINT "BAD NUMBER OF POSITIONS.":GOTO 380 -420 REM UNPACK X$ INTO G$(1-P9) -430 FOR X=1 TO P9 -440 FOR Y=1 TO C9 -450 IF MID$(X$,X,1)=MID$(L$,Y,1) THEN 480 -460 NEXT Y -470 PRINT "'"; MID$(X$,X,1); "' IS UNRECOGNIZED.":GOTO 380 -480 G$(X)=MID$(X$,X,1) -490 NEXT X -500 REM NOW WE CONVERT Q(1-P9) INTO A$(1-P9) [ACTUAL GUESS] -510 GOSUB 4000 -520 REM AND GET NUMBER OF BLACKS AND WHITES -530 GOSUB 4500 -540 IF B=P9 THEN 630 -550 REM TELL HUMAN RESULTS -560 PRINT "YOU HAVE ";B;" BLACKS AND ";W;" WHITES." -570 REM SAVE ALL THIS STUFF FOR BOARD PRINTOUT LATER -580 S$(M)=X$ -590 S(M,1)=B -600 S(M,2)=W -610 NEXT M -620 PRINT "YOU RAN OUT OF MOVES! THAT'S ALL YOU GET!":GOTO 640 -622 GOSUB 4000 -623 PRINT "THE ACTUAL COMBINATION WAS: "; -624 FOR X=1 TO P9 -625 PRINT A$(X); -626 NEXT X -627 PRINT -630 PRINT "YOU GUESSED IT IN ";M;" MOVES!" -640 H=H+M -650 GOSUB 5000 -660 REM -670 REM NOW COMPUTER GUESSES -680 REM -690 FOR X=1 TO P -700 I(X)=1 -710 NEXT X -720 PRINT "NOW I GUESS. THINK OF A COMBINATION." -730 INPUT "HIT RETURN WHEN READY:";X$ -740 FOR M=1 TO 10 -750 GOSUB 3000 -760 REM FIND A GUESS -770 G=INT(P*RND(1)+1) -780 IF I(G)=1 THEN 890 -790 FOR X=G TO P -800 IF I(X)=1 THEN 880 -810 NEXT X -820 FOR X=1 TO G -830 IF I(X)=1 THEN 880 -840 NEXT X -850 PRINT "YOU HAVE GIVEN ME INCONSISTENT INFORMATION." -860 PRINT "TRY AGAIN, AND THIS TIME PLEASE BE MORE CAREFUL." -870 GOTO 660 -880 G=X -890 REM NOW WE CONVERT GUESS #G INTO G$ -900 FOR X=1 TO G -910 GOSUB 3500 -920 NEXT X -930 GOSUB 6000 -940 PRINT "MY GUESS IS: "; -950 FOR X=1 TO P9 -960 PRINT H$(X); -970 NEXT X -980 INPUT " BLACKS, WHITES ";B1,W1 -990 IF B1=P9 THEN 1120 -1000 GOSUB 3000 -1010 FOR X=1 TO P -1020 GOSUB 3500 -1030 IF I(X)=0 THEN 1070 -1035 GOSUB 6500 -1040 GOSUB 4000 -1050 GOSUB 4500 -1060 IF B1>B OR W1>W THEN I(X)=0 -1070 NEXT X -1080 NEXT M -1090 PRINT "I USED UP ALL MY MOVES!" -1100 PRINT "I GUESS MY CPU IS JUST HAVING AN OFF DAY." -1110 GOTO 1130 -1120 PRINT "I GOT IT IN ";M;" MOVES!" -1130 C=C+M -1140 GOSUB 5000 -1150 NEXT R -1160 PRINT "GAME OVER" -1170 PRINT "FINAL SCORE:" -1180 GOSUB 5040 -1190 STOP -2000 REM -2010 REM BOARD PRINTOUT ROUTINE -2020 REM -2025 PRINT -2030 PRINT "BOARD" -2040 PRINT "MOVE GUESS BLACK WHITE" -2050 FOR Z=1 TO M-1 -2060 PRINT Z;TAB(9);S$(Z);TAB(25);S(Z,1);TAB(35);S(Z,2) -2070 NEXT Z -2075 PRINT -2080 GOTO 380 -2500 REM -2510 REM QUIT ROUTINE -2520 REM -2530 PRINT "QUITTER! MY COMBINATION WAS: "; -2535 GOSUB 4000 -2540 FOR X=1 TO P9 -2550 PRINT A$(X); -2560 NEXT X -2565 PRINT -2570 PRINT "GOOD BYE" -2580 STOP -3000 REM -3010 REM INITIALIZE Q(1-P9) TO ZEROS -3020 REM -3030 FOR S=1 TO P9 -3040 Q(S)=0 -3050 NEXT S -3060 RETURN -3500 REM -3510 REM INCREMENT Q(1-P9) -3520 REM -3522 IF Q(1)>0 THEN 3530 -3524 REM IF ZERO, THIS IS OUR FIRST INCREMENT: MAKE ALL ONES -3526 FOR S=1 TO P9 -3527 Q(S)=1 -3528 NEXT S -3529 RETURN -3530 Q=1 -3540 Q(Q)=Q(Q)+1 -3550 IF Q(Q)<=C9 THEN RETURN -3560 Q(Q)=1 -3570 Q=Q+1 -3580 GOTO 3540 -4000 REM -4010 REM CONVERT Q(1-P9) TO A$(1-P9) -4020 REM -4030 FOR S=1 TO P9 -4040 A$(S)=MID$(L$,Q(S),1) -4050 NEXT S -4060 RETURN -4500 REM -4510 REM GET NUMBER OF BLACKS (B) AND WHITES (W) -4520 REM MASHES G$ AND A$ IN THE PROCESS -4530 REM -4540 B=0:W=0:F=0 -4550 FOR S=1 TO P9 -4560 IF G$(S)<>A$(S) THEN 4620 -4570 B=B+1 -4580 G$(S)=CHR$(F) -4590 A$(S)=CHR$(F+1) -4600 F=F+2 -4610 GOTO 4660 -4620 FOR T=1 TO P9 -4630 IF G$(S)<>A$(T) THEN 4650 -4640 IF G$(T)=A$(T) THEN 4650 -4645 W=W+1:A$(T)=CHR$(F):G$(S)=CHR$(F+1):F=F+2:GOTO 4660 -4650 NEXT T -4660 NEXT S -4670 RETURN -5000 REM -5010 REM PRINT SCORE -5020 REM -5030 PRINT "SCORE:" -5040 PRINT " COMPUTER ";C -5050 PRINT " HUMAN ";H -5060 PRINT -5070 RETURN -5500 REM -5510 REM CONVERT Q(1-P9) INTO G$(1-P9) -5520 REM -5530 FOR S=1 TO P9 -5540 G$(S)=MID$(L$,Q(S),1) -5550 NEXT S -5560 RETURN -6000 REM -6010 REM CONVERT Q(1-P9) TO H$(1-P9) -6020 REM -6030 FOR S=1 TO P9 -6040 H$(S)=MID$(L$,Q(S),1) -6050 NEXT S -6060 RETURN -6500 REM -6510 REM COPY H$ INTO G$ -6520 REM -6530 FOR S=1 TO P9 -6540 G$(S)=H$(S) -6550 NEXT S -6560 RETURN -8000 REM PROGRAM DATA FOR COLOR NAMES -8010 DATA BLACK,WHITE,RED,GREEN,ORANGE,YELLOW,PURPLE,TAN -9998 REM ...WE'RE SORRY BUT IT'S TIME TO GO... -9999 END diff --git a/00_Alternate_Languages/61_Math_Dice/MiniScript/README.md b/00_Alternate_Languages/61_Math_Dice/MiniScript/README.md deleted file mode 100644 index ac7b913c2..000000000 --- a/00_Alternate_Languages/61_Math_Dice/MiniScript/README.md +++ /dev/null @@ -1,21 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -0. Try-It! Page: -Go to https://miniscript.org/tryit/, clear the sample code from the code editor, and paste in the contents of mathdice.ms. Then click the "Run Script" button. Program output (and input) will appear in the green-on-black terminal display to the right of or below the code editor. - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: -``` - miniscript mathdice.ms -``` - -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: -``` - load "mathdice" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/61_Math_Dice/MiniScript/mathdice.ms b/00_Alternate_Languages/61_Math_Dice/MiniScript/mathdice.ms deleted file mode 100644 index 74ed63496..000000000 --- a/00_Alternate_Languages/61_Math_Dice/MiniScript/mathdice.ms +++ /dev/null @@ -1,58 +0,0 @@ -print " "*31 + "Math Dice" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print -print "This program generates successive pictures of two dice." -print "When two dice and an equal sign followed by a question" -print "mark have been printed, type your answer and the return key." -print "To conclude the lesson, type Control-C as your answer." -print - -printDie = function(d) - print - print " -----" - if d == 1 then - print "| |" - else if d == 2 or d == 3 then - print "| * |" - else - print "| * * |" - end if - if d == 2 or d == 4 then - print "| |" - else if d == 6 then - print "| * * |" - else - print "| * |" - end if - if d == 1 then - print "| |" - else if d == 2 or d == 3 then - print "| * |" - else - print "| * * |" - end if - print " -----" - print -end function - -while true - d1 = floor(6 * rnd + 1) - printDie d1 - print " +" - d2 = floor(6 * rnd + 1) - printDie d2 - total = d1 + d2 - answer = input(" =? ").val - if answer != total then - print "No, count the spots and give another answer." - answer = input(" =? ").val - end if - if answer == total then - print "Right!" - else - print "No, the answer is " + total - end if - print - print "The dice roll again..." -end while - diff --git a/00_Alternate_Languages/61_Math_Dice/README.md b/00_Alternate_Languages/61_Math_Dice/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/61_Math_Dice/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/61_Math_Dice/mathdice.bas b/00_Alternate_Languages/61_Math_Dice/mathdice.bas deleted file mode 100644 index a62a7d8c7..000000000 --- a/00_Alternate_Languages/61_Math_Dice/mathdice.bas +++ /dev/null @@ -1,60 +0,0 @@ -10 PRINT TAB(31);"MATH DICE" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT:PRINT:PRINT -40 PRINT "THIS PROGRAM GENERATES SUCCESSIVE PICTURES OF TWO DICE." -50 PRINT "WHEN TWO DICE AND AN EQUAL SIGN FOLLOWED BY A QUESTION" -60 PRINT "MARK HAVE BEEN PRINTED, TYPE YOUR ANSWER AND THE RETURN KEY." -70 PRINT "TO CONCLUDE THE LESSON, TYPE CONTROL-C AS YOUR ANSWER." -80 PRINT -90 PRINT -100 N=N+1 -110 D=INT(6*RND(1)+1) -120 PRINT" ----- " -130 IF D=1 THEN 200 -140 IF D=2 THEN 180 -150 IF D=3 THEN 180 -160 PRINT "I * * I" -170 GOTO 210 -180 PRINT "I * I" -190 GOTO 210 -200 PRINT "I I" -210 IF D=2 THEN 260 -220 IF D=4 THEN 260 -230 IF D=6 THEN 270 -240 PRINT "I * I" -250 GOTO 280 -260 PRINT "I I" -265 GOTO 280 -270 PRINT "I * * I" -280 IF D=1 THEN 350 -290 IF D=2 THEN 330 -300 IF D=3 THEN 330 -310 PRINT "I * * I" -320 GOTO 360 -330 PRINT "I * I" -340 GOTO 360 -350 PRINT "I I" -360 PRINT " ----- " -370 PRINT -375 IF N=2 THEN 500 -380 PRINT " +" -381 PRINT -400 A=D -410 GOTO 100 -500 T=D+A -510 PRINT " ="; -520 INPUT T1 -530 IF T1=T THEN 590 -540 PRINT "NO, COUNT THE SPOTS AND GIVE ANOTHER ANSWER." -541 PRINT " ="; -550 INPUT T2 -560 IF T2=T THEN 590 -570 PRINT "NO, THE ANSWER IS";T -580 GOTO 600 -590 PRINT "RIGHT!" -600 PRINT -601 PRINT "THE DICE ROLL AGAIN..." -610 PRINT -615 N=0 -620 GOTO 100 -999 END diff --git a/00_Alternate_Languages/61_Math_Dice/pascal/README.md b/00_Alternate_Languages/61_Math_Dice/pascal/README.md deleted file mode 100644 index 1bdf62cdb..000000000 --- a/00_Alternate_Languages/61_Math_Dice/pascal/README.md +++ /dev/null @@ -1,14 +0,0 @@ -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) - -Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language)) - -##### Translator Notes: -I tried to preserve as much of the original layout and flow of the code -as possible. I added a procedure for the printing of the die-face; and -another to read an integer from the player, as I was unhappy with the runtime -error message spat out when a non-number is given to readln(). - -I was torn between using the correct singular term "die" instead of "dice". -In the end I used a (poor?) combination of both. - -krt@krt.com.au 2020-10-12 diff --git a/00_Alternate_Languages/62_Mugwump/MiniScript/README.md b/00_Alternate_Languages/62_Mugwump/MiniScript/README.md deleted file mode 100644 index ac7b913c2..000000000 --- a/00_Alternate_Languages/62_Mugwump/MiniScript/README.md +++ /dev/null @@ -1,21 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -0. Try-It! Page: -Go to https://miniscript.org/tryit/, clear the sample code from the code editor, and paste in the contents of mathdice.ms. Then click the "Run Script" button. Program output (and input) will appear in the green-on-black terminal display to the right of or below the code editor. - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: -``` - miniscript mathdice.ms -``` - -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: -``` - load "mathdice" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/62_Mugwump/MiniScript/mugwump.ms b/00_Alternate_Languages/62_Mugwump/MiniScript/mugwump.ms deleted file mode 100644 index 8ba5f7fb2..000000000 --- a/00_Alternate_Languages/62_Mugwump/MiniScript/mugwump.ms +++ /dev/null @@ -1,65 +0,0 @@ -print " "*33 + "Mugwump" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print -// Courtesy People's Computer Company -print "The object of this game is to find four mugwumps" -print "hidden on a 10 by 10 grid. Homebase is position 0,0." -print "Any guess you make must be two numbers with each" -print "number between 0 and 9, inclusive. First number" -print "is distance to right of homebase and second number" -print "is distance above homebase." -print -print "You get 10 tries. After each try, I will tell" -print "you how far you are from each mugwump." -print - -playOneGame = function - mugwump = {} // key: number 1-4; value: [x,y] position - for i in range(1, 4) - mugwump[i] = [floor(10*rnd), floor(10*rnd)] - end for - - found = 0 - for turn in range(1, 10) - print - print - while true - inp = input("Turn no. " + turn + " -- what is your guess? ") - inp = inp.replace(",", " ").replace(" ", " ").split - if inp.len == 2 then break - end while - x = inp[0].val; y = inp[1].val - for i in range(1, 4) - pos = mugwump[i] - if pos == null then continue // (already found) - if pos == [x,y] then - print "You have found mugwump " + i - mugwump[i] = null - found += 1 - else - d = sqrt( (pos[0] - x)^2 + (pos[1] - y)^2 ) - print "You are " + round(d, 1) + " units from mugwump " + i - end if - end for - if found == 4 then - print - print "You got them all in " + turn + " turns!" - return - end if - end for - print - print "Sorry, that's 10 tries. Here is where they're hiding:" - for i in range(1, 4) - pos = mugwump[i] - if pos == null then continue - print "Mugwump " + i + " is at (" + pos[0] + "," + pos[1] + ")" - end for -end function - -// Main loop -while true - playOneGame - print - print "That was fun! Let's play again......." - print "Four more mugwumps are now in hiding." -end while diff --git a/00_Alternate_Languages/62_Mugwump/README.md b/00_Alternate_Languages/62_Mugwump/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/62_Mugwump/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/62_Mugwump/mugwump.bas b/00_Alternate_Languages/62_Mugwump/mugwump.bas deleted file mode 100644 index e238486d3..000000000 --- a/00_Alternate_Languages/62_Mugwump/mugwump.bas +++ /dev/null @@ -1,56 +0,0 @@ -1 PRINT TAB(33);"MUGWUMP" -2 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -3 PRINT:PRINT:PRINT -4 REM COURTESY PEOPLE'S COMPUTER COMPANY -10 DIM P(4,2) -20 PRINT "THE OBJECT OF THIS GAME IS TO FIND FOUR MUGWUMPS" -30 PRINT "HIDDEN ON A 10 BY 10 GRID. HOMEBASE IS POSITION 0,0." -40 PRINT "ANY GUESS YOU MAKE MUST BE TWO NUMBERS WITH EACH" -50 PRINT "NUMBER BETWEEN 0 AND 9, INCLUSIVE. FIRST NUMBER" -60 PRINT "IS DISTANCE TO RIGHT OF HOMEBASE AND SECOND NUMBER" -70 PRINT "IS DISTANCE ABOVE HOMEBASE." -80 PRINT -90 PRINT "YOU GET 10 TRIES. AFTER EACH TRY, I WILL TELL" -100 PRINT "YOU HOW FAR YOU ARE FROM EACH MUGWUMP." -110 PRINT -240 GOSUB 1000 -250 T=0 -260 T=T+1 -270 PRINT -275 PRINT -290 PRINT "TURN NO.";T;"-- WHAT IS YOUR GUESS"; -300 INPUT M,N -310 FOR I=1 TO 4 -320 IF P(I,1)=-1 THEN 400 -330 IF P(I,1)<>M THEN 380 -340 IF P(I,2)<>N THEN 380 -350 P(I,1)=-1 -360 PRINT "YOU HAVE FOUND MUGWUMP";I -370 GOTO 400 -380 D=SQR((P(I,1)-M)^2+(P(I,2)-N)^2) -390 PRINT "YOU ARE";(INT(D*10))/10;"UNITS FROM MUGWUMP";I -400 NEXT I -410 FOR J=1 TO 4 -420 IF P(J,1)<>-1 THEN 470 -430 NEXT J -440 PRINT -450 PRINT "YOU GOT THEM ALL IN";T;"TURNS!" -460 GOTO 580 -470 IF T<10 THEN 260 -480 PRINT -490 PRINT "SORRY, THAT'S 10 TRIES. HERE IS WHERE THEY'RE HIDING:" -540 FOR I=1 TO 4 -550 IF P(I,1)=-1 THEN 570 -560 PRINT "MUGWUMP";I;"IS AT (";P(I,1);",";P(I,2);")" -570 NEXT I -580 PRINT -600 PRINT "THAT WAS FUN! LET'S PLAY AGAIN......." -610 PRINT "FOUR MORE MUGWUMPS ARE NOW IN HIDING." -630 GOTO 240 -1000 FOR J=1 TO 2 -1010 FOR I=1 TO 4 -1020 P(I,J)=INT(10*RND(1)) -1030 NEXT I -1040 NEXT J -1050 RETURN -1099 END diff --git a/00_Alternate_Languages/63_Name/MiniScript/README.md b/00_Alternate_Languages/63_Name/MiniScript/README.md deleted file mode 100644 index 819ecf501..000000000 --- a/00_Alternate_Languages/63_Name/MiniScript/README.md +++ /dev/null @@ -1,21 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -0. Try-It! Page: -Go to https://miniscript.org/tryit/, clear the sample code from the code editor, and paste in the contents of name.ms. Then click the "Run Script" button. Program output (and input) will appear in the green-on-black terminal display to the right of or below the code editor. - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: -``` - miniscript name.ms -``` - -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: -``` - load "name" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/63_Name/MiniScript/name.ms b/00_Alternate_Languages/63_Name/MiniScript/name.ms deleted file mode 100644 index bb3d2da23..000000000 --- a/00_Alternate_Languages/63_Name/MiniScript/name.ms +++ /dev/null @@ -1,25 +0,0 @@ -print " "*34 + "Name" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print -print "Hello."; print "My name is Creative Computer." -name = input("What's your name (first and last)? ") - -s = "" -for i in range(name.len - 1) - s += name[i] -end for -print; print "Thank you, " + s + "." -print "Oops! I guess I got it backwards. A smart" -print "computer like me shouldn't make a mistake like that!"; print -print "But i just noticed your letters are out of order." -s = name.split("").sort.join("") -print "Let's put them in order like this: " + s -yn = input("Don't you like that better? ").lower -print -if yn and yn[0] == "y" then - print "I knew you'd agree!!" -else - print "I'm sorry you don't like it that way." -end if -print; print "I really enjoyed meeting you " + name + "." -print "Have a nice day!" diff --git a/00_Alternate_Languages/63_Name/README.md b/00_Alternate_Languages/63_Name/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/63_Name/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/63_Name/name.bas b/00_Alternate_Languages/63_Name/name.bas deleted file mode 100644 index 6cdf3f91f..000000000 --- a/00_Alternate_Languages/63_Name/name.bas +++ /dev/null @@ -1,25 +0,0 @@ -1 PRINT TAB(34);"NAME" -2 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -3 PRINT: PRINT: PRINT -5 DIM B$(40) -10 PRINT "HELLO.": PRINT "MY NAME IS CREATIVE COMPUTER." -20 PRINT "WHAT'S YOUR NAME (FIRST AND LAST";: INPUT A$: L=LEN(A$) -30 PRINT: PRINT "THANK YOU, "; -40 FOR I=1 TO L: B$(I)=MID$(A$,I,1): NEXT I -50 FOR I=L TO 1 STEP -1: PRINT B$(I);: NEXT I -60 PRINT ".": PRINT "OOPS! I GUESS I GOT IT BACKWARDS. A SMART" -70 PRINT "COMPUTER LIKE ME SHOULDN'T MAKE A MISTAKE LIKE THAT!": PRINT -80 PRINT "BUT I JUST NOTICED YOUR LETTERS ARE OUT OF ORDER." -90 PRINT "LET'S PUT THEM IN ORDER LIKE THIS: "; -100 FOR J=2 TO L: I=J-1: T$=B$(J) -110 IF T$>B$(I) THEN 130 -120 B$(I+1)=B$(I): I=I-1: IF I>0 THEN 110 -130 B$(I+1)=T$: NEXT J -140 FOR I=1 TO L: PRINT B$(I);: NEXT I: PRINT: PRINT -150 PRINT "DON'T YOU LIKE THAT BETTER";: INPUT D$ -160 IF D$="YES" THEN 180 -170 PRINT: PRINT "I'M SORRY YOU DON'T LIKE IT THAT WAY.": GOTO 200 -180 PRINT: PRINT "I KNEW YOU'D AGREE!!" -200 PRINT: PRINT "I REALLY ENJOYED MEETING YOU ";A$;"." -210 PRINT "HAVE A NICE DAY!" -999 END diff --git a/00_Alternate_Languages/64_Nicomachus/MiniScript/README.md b/00_Alternate_Languages/64_Nicomachus/MiniScript/README.md deleted file mode 100644 index 5ea2cf130..000000000 --- a/00_Alternate_Languages/64_Nicomachus/MiniScript/README.md +++ /dev/null @@ -1,21 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript nicomachus.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "nicomachus" - run -``` -3. "Try-It!" page on the web: -Go to https://miniscript.org/tryit/, clear the default program from the source code editor, paste in the contents of nicomachus.ms, and click the "Run Script" button. diff --git a/00_Alternate_Languages/64_Nicomachus/MiniScript/nicomachus.ms b/00_Alternate_Languages/64_Nicomachus/MiniScript/nicomachus.ms deleted file mode 100644 index ebbc394b7..000000000 --- a/00_Alternate_Languages/64_Nicomachus/MiniScript/nicomachus.ms +++ /dev/null @@ -1,45 +0,0 @@ -// Nicomachus -// originally by David Ahl -// Ported from BASIC to MiniScript by Joe Strout, 2023 - -print " "*33 + "NICOMA" -print " "*15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -print; print; print -print "Boomerang puzzle from Arithmetica of Nicomachus -- A.D. 90!" - -// Get a yes/no (or at least y/n) response from the user. -askYesNo = function(prompt) - while true - answer = input(prompt) - a1 = answer.lower[:1] - if a1 == "y" or a1 == "n" then return a1 - print "Eh? I don't understand '" + answer + "' Try 'yes' or 'no'." - end while -end function - -doOne = function - print - print "Please think of a number between 1 and 100." - A = input("Your number divided by 3 has a remainder of: ").val - B = input("Your number divided by 5 has a remainder of: ").val - C = input("Your number divided by 7 has a remainder of: ").val - print - print "Let me think a moment..." - print - wait 1.5 - D = 70*A + 21*B + 15*C - D = D % 105 // gets the remainder after dividing by 105 - yesNo = askYesNo("Your number was " + D + ", right? ") - if yesNo == "y" then - print "How about that!" - else - print "I feel your arithmetic is in error." - end if -end function - -// Main loop -- press Control-C to break -while true - doOne - print - print "Let's try another." -end while diff --git a/00_Alternate_Languages/64_Nicomachus/README.md b/00_Alternate_Languages/64_Nicomachus/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/64_Nicomachus/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/64_Nicomachus/nicomachus.bas b/00_Alternate_Languages/64_Nicomachus/nicomachus.bas deleted file mode 100644 index d478bc3c0..000000000 --- a/00_Alternate_Languages/64_Nicomachus/nicomachus.bas +++ /dev/null @@ -1,34 +0,0 @@ -2 PRINT TAB(33);"NICOMA" -4 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -6 PRINT: PRINT: PRINT -10 PRINT "BOOMERANG PUZZLE FROM ARITHMETICA OF NICOMACHUS -- A.D. 90!" -20 PRINT -30 PRINT "PLEASE THINK OF A NUMBER BETWEEN 1 AND 100." -40 PRINT "YOUR NUMBER DIVIDED BY 3 HAS A REMAINDER OF"; -45 INPUT A -50 PRINT "YOUR NUMBER DIVIDED BY 5 HAS A REMAINDER OF"; -55 INPUT B -60 PRINT "YOUR NUMBER DIVIDED BY 7 HAS A REMAINDER OF"; -65 INPUT C -70 PRINT -80 PRINT "LET ME THINK A MOMENT..." -85 PRINT -90 FOR I=1 TO 1500: NEXT I -100 D=70*A+21*B+15*C -110 IF D<=105 THEN 140 -120 D=D-105 -130 GOTO 110 -140 PRINT "YOUR NUMBER WAS";D;", RIGHT"; -160 INPUT A$ -165 PRINT -170 IF A$="YES" THEN 220 -180 IF A$="NO" THEN 240 -190 PRINT "EH? I DON'T UNDERSTAND '";A$;"' TRY 'YES' OR 'NO'." -200 GOTO 160 -220 PRINT "HOW ABOUT THAT!!" -230 GOTO 250 -240 PRINT "I FEEL YOUR ARITHMETIC IS IN ERROR." -250 PRINT -260 PRINT "LET'S TRY ANOTHER." -270 GOTO 20 -999 END diff --git a/00_Alternate_Languages/65_Nim/MiniScript/README.md b/00_Alternate_Languages/65_Nim/MiniScript/README.md deleted file mode 100644 index 0265ff51f..000000000 --- a/00_Alternate_Languages/65_Nim/MiniScript/README.md +++ /dev/null @@ -1,18 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: -``` - miniscript nim.ms -``` - -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: -``` - load "nim" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/65_Nim/MiniScript/nim.ms b/00_Alternate_Languages/65_Nim/MiniScript/nim.ms deleted file mode 100644 index f241c6964..000000000 --- a/00_Alternate_Languages/65_Nim/MiniScript/nim.ms +++ /dev/null @@ -1,194 +0,0 @@ -print " "*33 + "Nim" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print - -askYesNo = function(prompt) - while true - answer = input(prompt + "? ").lower - if answer and answer[0] == "y" then return "yes" - if answer and answer[0] == "n" then return "no" - print "Please answer yes or no." - end while -end function - -print "This is the game of Nim." -if askYesNo("Do you want instructions") == "yes" then - print "The game is played with a number of piles of objects." - print "Any number of objects are removed from one pile by you and" - print "the machine alternately. On your turn, you may take" - print "all the objects that remain in any pile, but you must" - print "take at least one object, and you may take objects from" - print "only one pile on a single turn. You must specify whether" - print "winning is defined as taking or not taking the last object," - print "the number of piles in the game, and how many objects are" - print "originally in each pile. Each pile may contain a" - print "different number of objects." - print "The machine will show its move by listing each pile and the" - print "number of objects remaining in the piles after each of its" - print "moves." -end if - -allEmpty = function(piles) - for i in range(1, piles.len-1) - if piles[i] then return false - end for - return true -end function - -// Do the computer's turn; return true if game over, false otherwise. -doComputerTurn = function(pile, winCondition) - n = pile.len - 1 - d = [0,0,0] - b = [null] - for i in range(1, n) - b.push [0]*11 - end for - - if winCondition == 2 then - c = 0 - broke = false - for i in range(1, n) - if pile[i] == 0 then continue - c += 1 - if c == 3 then; broke = true; break; end if - d[c] = i - end for - if not broke then - if c == 2 and (pile[d[1]] == 1 or pile[d[2]] == 1) then - print "Machine wins" - return true - end if - if pile[d[1]] > 1 then - print "Machine wins" - return true - end if - print "Machine loses" - return true - end if - c = 0 - broke = false - for i in range(1, n) - if pile[i] > 1 then; broke = true; break; end if - if pile[i] == 0 then continue - c += 1 - end for - if not broke and c/2 != floor(c/2) then - print "Machine loses" - return true - end if - end if - - for i in range(1, n) - e = pile[i] - for j in range(0, 10) - f = e/2 - b[i][j] = 2*(f-floor(f)) - e = floor(f) - end for - end for - broke = false - for j in range(10, 0) - c = 0 - h = 0 - for i in range(1, n) - if b[i][j] == 0 then continue - c += 1 - if pile[i] <= h then continue - h = pile[i] - g = i - end for - if c/2 != floor(c/2) then; broke = true; break; end if - end for - if not broke then - while true - e = floor(n*rnd+1) - if pile[e] != 0 then break - end while - f = floor(pile[e]*rnd+1) - pile[e] -= f - else - pile[g] = 0 - for j in range(0, 10) - b[g][j] = 0 - c=0 - for i in range(1,n) - if b[i][j] == 0 then continue - c += 1 - end for - pile[g] += 2*(c/2-floor(c/2))*2^j - end for - if winCondition != 1 then - c = 0 - broke = false - for i in range(1, n) - if pile[i]>1 then; broke = true; break; end if - if pile[i] == 0 then continue - c += 1 - end for - if not broke and c/2 == floor(c/2) then pile[g]= 1 - pile[g] - end if - end if - - print "Pile Size" - for i in range(1, n) - print i + " " + pile[i] - end for - if winCondition == 1 and allEmpty(pile) then - print "Machine wins" - return true - end if - return false -end function - -// Do the human player's turn; return true if game over, false otherwise. -doPlayerTurn = function(pile, winCondition) - n = pile.len - 1 - while true - inp = input("Your move - pile, number to be removed? ") - inp = inp.replace(",", " ").replace(" ", " ").split - if inp.len != 2 then continue - x = inp[0].val; y = inp[1].val - if x == floor(x) and y == floor(y) and 1 <= x <= n and 1 <= y <= pile[x] then break - end while - - pile[x] -= y - if allEmpty(pile) then - if winCondition == 1 then print "Machine loses" else print "Machine wins" - return true - end if - return false -end function - -playOneGame = function - print - while true - w = input("Enter win option - 1 to take last, 2 to avoid last? ").val - if w == 1 or w == 2 then break - end while - while true - n = input("Enter number of piles? ").val - if n == floor(n) and 1 <= n <= 100 then break - end while - - print "Enter pile sizes" - pile = [null] + [0]*n // (null at element 0 to make our array 1-based) - for i in range(1, n) - while true - pile[i] = input(i + "? ").val - if pile[i] == floor(pile[i]) and 1 <= pile[i] <= 2000 then break - end while - end for - - if askYesNo("Do you want to move first") == "yes" then - if doPlayerTurn(pile, w) then return - end if - while true - if doComputerTurn(pile, w) then return - if doPlayerTurn(pile, w) then return - end while -end function - -while true - playOneGame - if askYesNo("Do you want to play another game") == "no" then break -end while diff --git a/00_Alternate_Languages/65_Nim/README.md b/00_Alternate_Languages/65_Nim/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/65_Nim/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/65_Nim/nim.bas b/00_Alternate_Languages/65_Nim/nim.bas deleted file mode 100644 index d078a0c6a..000000000 --- a/00_Alternate_Languages/65_Nim/nim.bas +++ /dev/null @@ -1,156 +0,0 @@ -100 PRINT TAB(33);"NIM" -110 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -120 PRINT:PRINT:PRINT -210 DIM A(100),B(100,10),D(2) -220 PRINT "THIS IS THE GAME OF NIM." -230 PRINT "DO YOU WANT INSTRUCTIONS"; -240 INPUT Z$ -250 IF Z$="NO" THEN 440 -260 IF Z$="no" THEN 440 -270 IF Z$="YES" THEN 310 -280 IF Z$="yes" THEN 310 -290 PRINT "PLEASE ANSWER YES OR NO" -300 GOTO 240 -310 PRINT "THE GAME IS PLAYED WITH A NUMBER OF PILES OF OBJECTS." -320 PRINT "ANY NUMBER OF OBJECTS ARE REMOVED FROM ONE PILE BY YOU AND" -330 PRINT "THE MACHINE ALTERNATELY. ON YOUR TURN, YOU MAY TAKE" -340 PRINT "ALL THE OBJECTS THAT REMAIN IN ANY PILE, BUT YOU MUST" -350 PRINT "TAKE AT LEAST ONE OBJECT, AND YOU MAY TAKE OBJECTS FROM" -360 PRINT "ONLY ONE PILE ON A SINGLE TURN. YOU MUST SPECIFY WHETHER" -370 PRINT "WINNING IS DEFINED AS TAKING OR NOT TAKING THE LAST OBJECT," -380 PRINT "THE NUMBER OF PILES IN THE GAME, AND HOW MANY OBJECTS ARE" -390 PRINT "ORIGINALLY IN EACH PILE. EACH PILE MAY CONTAIN A" -400 PRINT "DIFFERENT NUMBER OF OBJECTS." -410 PRINT "THE MACHINE WILL SHOW ITS MOVE BY LISTING EACH PILE AND THE" -420 PRINT "NUMBER OF OBJECTS REMAINING IN THE PILES AFTER EACH OF ITS" -430 PRINT "MOVES." -440 PRINT -450 PRINT "ENTER WIN OPTION - 1 TO TAKE LAST, 2 TO AVOID LAST"; -460 INPUT W -470 IF W=1 THEN 490 -480 IF W<>2 THEN 450 -490 PRINT "ENTER NUMBER OF PILES"; -500 INPUT N -510 IF N>100 THEN 490 -520 IF N<1 THEN 490 -530 IF N<>INT(N) THEN 490 -540 PRINT "ENTER PILE SIZES" -550 FOR I=1 TO N -560 PRINT I; -570 INPUT A(I) -580 IF A(I)>2000 THEN 560 -590 IF A(I)<1 THEN 560 -600 IF A(I)<>INT(A(I)) THEN 560 -610 NEXT I -620 PRINT "DO YOU WANT TO MOVE FIRST"; -630 INPUT Q9$ -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 -700 IF W=1 THEN 940 -710 LET C=0 -720 FOR I=1 TO N -730 IF A(I)=0 THEN 770 -740 LET C=C+1 -750 IF C=3 THEN 840 -760 LET D(C)=I -770 NEXT I -780 IF C=2 THEN 920 -790 IF A(D(1))>1 THEN 820 -800 PRINT "MACHINE LOSES" -810 GOTO 1640 -820 PRINT "MACHINE WINS" -830 GOTO 1640 -840 LET C=0 -850 FOR I=1 TO N -860 IF A(I)>1 THEN 940 -870 IF A(I)=0 THEN 890 -880 LET C=C+1 -890 NEXT I -900 IF C/2<>INT(C/2) THEN 800 -910 GOTO 940 -920 IF A(D(1))=1 THEN 820 -930 IF A(D(2))=1 THEN 820 -940 FOR I=1 TO N -950 LET E=A(I) -960 FOR J=0 TO 10 -970 LET F=E/2 -980 LET B(I,J)=2*(F-INT(F)) -990 LET E=INT(F) -1000 NEXT J -1010 NEXT I -1020 FOR J=10 TO 0 STEP -1 -1030 LET C=0 -1040 LET H=0 -1050 FOR I=1 TO N -1060 IF B(I,J)=0 THEN 1110 -1070 LET C=C+1 -1080 IF A(I)<=H THEN 1110 -1090 LET H=A(I) -1100 LET G=I -1110 NEXT I -1120 IF C/2<>INT(C/2) THEN 1190 -1130 NEXT J -1140 LET E=INT(N*RND(1)+1) -1150 IF A(E)=0 THEN 1140 -1160 LET F=INT(A(E)*RND(1)+1) -1170 LET A(E)=A(E)-F -1180 GOTO 1380 -1190 LET A(G)=0 -1200 FOR J=0 TO 10 -1210 LET B(G,J)=0 -1220 LET C=0 -1230 FOR I=1 TO N -1240 IF B(I,J)=0 THEN 1260 -1250 LET C=C+1 -1260 NEXT I -1270 LET A(G)=A(G)+2*(C/2-INT(C/2))*2^J -1280 NEXT J -1290 IF W=1 THEN 1380 -1300 LET C=0 -1310 FOR I=1 TO N -1320 IF A(I)>1 THEN 1380 -1330 IF A(I)=0 THEN 1350 -1340 LET C=C+1 -1350 NEXT I -1360 IF C/2<>INT(C/2) THEN 1380 -1370 LET A(G)=1-A(G) -1380 PRINT "PILE SIZE" -1390 FOR I=1 TO N -1400 PRINT I;A(I) -1410 NEXT I -1420 IF W=2 THEN 1450 -1430 GOSUB 1570 -1440 IF Z=1 THEN 820 -1450 PRINT "YOUR MOVE - PILE, NUMBER TO BE REMOVED"; -1460 INPUT X,Y -1470 IF X>N THEN 1450 -1480 IF X<1 THEN 1450 -1490 IF X<>INT(X) THEN 1450 -1500 IF Y>A(X) THEN 1450 -1510 IF Y<1 THEN 1450 -1520 IF Y<>INT(Y) THEN 1450 -1530 LET A(X)=A(X)-Y -1540 GOSUB 1570 -1550 IF Z=1 THEN 800 -1560 GOTO 700 -1570 LET Z=0 -1580 FOR I=1 TO N -1590 IF A(I)=0 THEN 1610 -1600 RETURN -1610 NEXT I -1620 LET Z=1 -1630 RETURN -1640 PRINT "do you want to play another game"; -1650 INPUT Q9$ -1660 IF Q9$="YES" THEN 1720 -1670 IF Q9$="yes" THEN 1720 -1680 IF Q9$="NO" THEN 1730 -1690 IF Q9$="no" THEN 1730 -1700 PRINT "PLEASE. YES OR NO." -1710 GOTO 1650 -1720 GOTO 440 -1730 END diff --git a/00_Alternate_Languages/66_Number/MiniScript/README.md b/00_Alternate_Languages/66_Number/MiniScript/README.md deleted file mode 100644 index e3c8143ac..000000000 --- a/00_Alternate_Languages/66_Number/MiniScript/README.md +++ /dev/null @@ -1,21 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript number.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "number" - run -``` -3. "Try-It!" page on the web: -Go to https://miniscript.org/tryit/, clear the default program from the source code editor, paste in the contents of number.ms, and click the "Run Script" button. diff --git a/00_Alternate_Languages/66_Number/MiniScript/number.ms b/00_Alternate_Languages/66_Number/MiniScript/number.ms deleted file mode 100644 index 0f242d682..000000000 --- a/00_Alternate_Languages/66_Number/MiniScript/number.ms +++ /dev/null @@ -1,44 +0,0 @@ -// Number Game -// originally by Tom Adametx -// Ported from BASIC to MiniScript by Joe Strout, 2023 - -print " "*33 + "NUMBER" -print " "*15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -print; print; print - -print "You have 100 points. By guessing numbers from 1 to 5, you" -print "can gain or lose points depending on how close you get to" -print "a random number selected by the computer."; print -print "You occasionally will get a jackpot which will double(!)" -print "your point count. You win when you get to 500 points." -print - -P = 100 -fnr = function; return ceil(5*rnd); end function -while true - guess = input("Guess a number from 1 to 5: ").val - R = fnr - S = fnr - T = fnr - U = fnr - V = fnr - if guess == R then - P = P - 5 - else if guess == S then - P = P + 5 - else if guess == T then - P = P+P - print "You hit the jackpot!!!" - else if guess == U then - P = P + 1 - else if guess == V then - P = P - floor(P*0.5) - else if guess > 5 then - continue - end if - if P > 500 then - print "!!!!You win!!!! with " + P + " points." - break - end if - print "You have " + P + " points."; print -end while diff --git a/00_Alternate_Languages/66_Number/README.md b/00_Alternate_Languages/66_Number/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/66_Number/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/66_Number/number.bas b/00_Alternate_Languages/66_Number/number.bas deleted file mode 100644 index c5b9ff7c1..000000000 --- a/00_Alternate_Languages/66_Number/number.bas +++ /dev/null @@ -1,37 +0,0 @@ -1 PRINT TAB(33);"NUMBER" -2 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -3 PRINT:PRINT:PRINT -4 PRINT "YOU HAVE 100 POINTS. BY GUESSING NUMBERS FROM 1 TO 5, YOU" -5 PRINT "CAN GAIN OR LOSE POINTS DEPENDING UPON HOW CLOSE YOU GET TO" -6 PRINT "A RANDOM NUMBER SELECTED BY THE COMPUTER.": PRINT -7 PRINT "YOU OCCASIONALLY WILL GET A JACKPOT WHICH WILL DOUBLE(!)" -8 PRINT "YOUR POINT COUNT. YOU WIN WHEN YOU GET 500 POINTS." -9 PRINT: P=100 -10 DEF FNR(X)=INT(5*RND(1)+1) -12 INPUT "GUESS A NUMBER FROM 1 TO 5";G -15 R=FNR(1) -16 S=FNR(1) -17 T=FNR(1) -18 U=FNR(1) -19 V=FNR(1) -20 IF G=R THEN 30 -21 IF G=S THEN 40 -22 IF G=T THEN 50 -23 IF G=U THEN 60 -24 IF G=V THEN 70 -25 IF G>5 THEN 12 -30 P=P-5 -35 GOTO 80 -40 P=P+5 -45 GOTO 80 -50 P=P+P -53 PRINT "YOU HIT THE JACKPOT!!!" -55 GOTO 80 -60 P=P+1 -65 GOTO 80 -70 P=P-(P*.5) -80 IF P>500 THEN 90 -82 PRINT "YOU HAVE";P;"POINTS.":PRINT -85 GOTO 12 -90 PRINT "!!!!YOU WIN!!!! WITH ";P;"POINTS." -99 END diff --git a/00_Alternate_Languages/67_One_Check/MiniScript/README.md b/00_Alternate_Languages/67_One_Check/MiniScript/README.md deleted file mode 100644 index d79b401fb..000000000 --- a/00_Alternate_Languages/67_One_Check/MiniScript/README.md +++ /dev/null @@ -1,18 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: -``` - miniscript onecheck.ms -``` - -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: -``` - load "onecheck" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/67_One_Check/MiniScript/onecheck.ms b/00_Alternate_Languages/67_One_Check/MiniScript/onecheck.ms deleted file mode 100644 index fee41c8c4..000000000 --- a/00_Alternate_Languages/67_One_Check/MiniScript/onecheck.ms +++ /dev/null @@ -1,101 +0,0 @@ -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 -input "(Press Return.)" -print - -pad4 = function(n) - return (" " + n)[-4:] -end function - -printBoard = function - // Idea: This program could be greatly improved by printing the board - // as the index numbers (1-64), indicating which of those positions - // contain checkers via color or punctuation, e.g. "(42)" vs " 42 ". - // This would make it much easier for the user to figure out what - // numbers correspond to the positions they have in mind. - print - for j in range(1, 57, 8) - print " " + board[j:j+8].join(" ") - end for -end function - -initBoard = function - globals.board = [null] + [1] * 64 // treat this as 1-based array - for j in range(19, 43, 8) - for i in range(j, j+3) - board[i] = 0 - end for - end for -end function - -isLegal = function(from, to) - if board[from] == 0 then return false - if board[to] == 1 then return false - if board[(to+from)/2] == 0 then return false - fromRow = floor((from-1) / 8) // row in range 0-7 - fromCol = from - fromRow*8 // column in range 1-8 - toRow = floor((to-1) / 8) - toCol = to - toRow*8 - if fromRow > 7 or toRow > 7 or fromCol > 8 or toCol > 8 then return false - if abs(fromRow-toRow) != 2 or abs(fromCol-toCol) != 2 then return false - return true -end function - -askYesNo = function(prompt) - while true - answer = input(prompt + "? ").lower - if answer and answer[0] == "y" then return "yes" - if answer and answer[0] == "n" then return "no" - print "Please answer 'yes' or 'no'." - end while -end function - -print "Here is the numerical board:" -print -for j in range(1, 57, 8) - print pad4(j) + pad4(j+1) + pad4(j+2) + pad4(j+3) + - pad4(j+4) + pad4(j+5) + pad4(j+6) + pad4(j+7) -end for - -while true - initBoard - print - print "And here is the opening position of the checkers." - printBoard - jumps = 0 - while true - fromPos = input("Jump from? ").val - if fromPos == 0 then break - toPos = input("To? ").val - print - if not isLegal(fromPos, toPos) then - print "Illegal move. Try again..." - continue - end if - board[fromPos] = 0 - board[toPos] = 1 - board[(toPos+fromPos)/2] = 0 - jumps += 1 - printBoard - end while - // End game summary - sum = board[1:].sum - print "You made " + jumps + " jumps and had " + sum + " pieces" - print "remaining on the board." - print - if askYesNo("Try again") == "no" then break -end while -print -print "O.K. Hope you had fun!!" - - \ No newline at end of file diff --git a/00_Alternate_Languages/67_One_Check/README.md b/00_Alternate_Languages/67_One_Check/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/67_One_Check/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/67_One_Check/onecheck.bas b/00_Alternate_Languages/67_One_Check/onecheck.bas deleted file mode 100644 index 2161a7433..000000000 --- a/00_Alternate_Languages/67_One_Check/onecheck.bas +++ /dev/null @@ -1,86 +0,0 @@ -2 PRINT TAB(30);"ONE CHECK" -4 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -6 PRINT: PRINT: PRINT -8 DIM A(64) -10 PRINT "SOLITAIRE CHECKER PUZZLE BY DAVID AHL" -15 PRINT -20 PRINT "48 CHECKERS ARE PLACED ON THE 2 OUTSIDE SPACES OF A" -25 PRINT "STANDARD 64-SQUARE CHECKERBOARD. THE OBJECT IS TO" -30 PRINT "REMOVE AS MANY CHECKERS AS POSSIBLE BY DIAGONAL JUMPS" -35 PRINT "(AS IN STANDARD CHECKERS). USE THE NUMBERED BOARD TO" -40 PRINT "INDICATE THE SQUARE YOU WISH TO JUMP FROM AND TO. ON" -45 PRINT "THE BOARD PRINTED OUT ON EACH TURN '1' INDICATES A" -50 PRINT "CHECKER AND '0' AN EMPTY SQUARE. WHEN YOU HAVE NO" -55 PRINT "POSSIBLE JUMPS REMAINING, INPUT A '0' IN RESPONSE TO" -60 PRINT "QUESTION 'JUMP FROM ?'" -62 PRINT -63 PRINT "HERE IS THE NUMERICAL BOARD:" -66 PRINT -70 FOR J=1 TO 57 STEP 8 -74 PRINT J;TAB(4);J+1;TAB(8);J+2;TAB(12);J+3;TAB(16);J+4;TAB(20);J+5; -75 PRINT TAB(24);J+6;TAB(28);J+7 -76 NEXT J -77 PRINT -78 PRINT "AND HERE IS THE OPENING POSITION OF THE CHECKERS." -79 PRINT -80 FOR J=1 TO 64 -82 A(J)=1 -84 NEXT J -86 FOR J=19 TO 43 STEP 8 -88 FOR I=J TO J+3 -90 A(I)=0 -92 NEXT I -94 NEXT J -96 M=0 -98 GOTO 340 -100 INPUT "JUMP FROM";F -105 IF F=0 THEN 500 -110 INPUT "TO";T -112 PRINT -118 REM *** CHECK LEGALITY OF MOVE -120 F1=INT((F-1)/8) -130 F2=F-8*F1 -140 T1=INT((T-1)/8) -150 T2=T-8*T1 -160 IF F1>7 THEN 230 -170 IF T1>7 THEN 230 -180 IF F2>8 THEN 230 -190 IF T2>8 THEN 230 -200 IF ABS(F1-T1)<>2 THEN 230 -210 IF ABS(F2-T2)<>2 THEN 230 -212 IF A((T+F)/2)=0 THEN 230 -215 IF A(F)=0 THEN 230 -220 IF A(T)=1 THEN 230 -225 GOTO 250 -230 PRINT "ILLEGAL MOVE. TRY AGAIN..." -240 GOTO 100 -245 REM *** UPDATE BOARD -250 A(T)=1 -260 A(F)=0 -270 A((T+F)/2)=0 -290 M=M+1 -310 REM *** PRINT BOARD -340 FOR J=1 TO 57 STEP 8 -350 FOR I=J TO J+7 -360 PRINT A(I); -370 NEXT I -380 PRINT -390 NEXT J -400 PRINT -410 GOTO 100 -490 REM *** END GAME SUMMARY -500 S=0 -510 FOR I=1 TO 64 -520 S=S+A(I) -530 NEXT I -540 PRINT:PRINT "YOU MADE";M;"JUMPS AND HAD";S;"PIECES" -550 PRINT "REMAINING ON THE BOARD." -560 PRINT -562 INPUT "TRY AGAIN";A$ -570 IF A$="YES" THEN 70 -575 IF A$="NO" THEN 600 -580 PRINT "PLEASE ANSWER 'YES' OR 'NO'." -590 GOTO 562 -600 PRINT -610 PRINT "O.K. HOPE YOU HAD FUN!!" -999 END diff --git a/00_Alternate_Languages/68_Orbit/MiniScript/README.md b/00_Alternate_Languages/68_Orbit/MiniScript/README.md deleted file mode 100644 index cc0c29669..000000000 --- a/00_Alternate_Languages/68_Orbit/MiniScript/README.md +++ /dev/null @@ -1,18 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: -``` - miniscript orbit.ms -``` - -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: -``` - load "orbit" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/68_Orbit/MiniScript/orbit.ms b/00_Alternate_Languages/68_Orbit/MiniScript/orbit.ms deleted file mode 100644 index 5c624c42b..000000000 --- a/00_Alternate_Languages/68_Orbit/MiniScript/orbit.ms +++ /dev/null @@ -1,95 +0,0 @@ -print " "*33 + "Orbit" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print -print "Somewhere above your planet is a Romulan ship." -print -print "The ship is in a constant polar orbit. Its" -print "distance from the center of your planet is from" -print "10,000 to 30,000 miles and at its present velocity can" -print "circle your planet once every 12 to 36 hours." -print -print "Unfortunately, they are using a cloaking device so" -print "you are unable to see them, but with a special" -print "instrument you can tell how near their ship your" -print "photon bomb exploded. You have seven hours until they" -print "have built up sufficient power in order to escape" -print "your planet's gravity." -print -print "Your planet has enough power to fire one bomb an hour." -print -print "At the beginning of each hour you will be asked to give an" -print "angle (between 0 and 360) and a distance in units of" -print "100 miles (between 100 and 300), after which your bomb's" -print "distance from the enemy ship will be given." -print -print "An explosion within 5,000 miles of the romulan ship" -print "will destroy it." -print; input "(Press Return.)" -print -print "Below is a diagram to help you visualize your plight." -print -print -print " 90" -print " 0000000000000" -print " 0000000000000000000" -print " 000000 000000" -print " 00000 00000" -print " 00000 xxxxxxxxxxx 00000" -print " 00000 xxxxxxxxxxxxx 00000" -print " 0000 xxxxxxxxxxxxxxx 0000" -print " 0000 xxxxxxxxxxxxxxxxx 0000" -print " 0000 xxxxxxxxxxxxxxxxxxx 0000" -print "180<== 00000 xxxxxxxxxxxxxxxxxxx 00000 ==>0" -print " 0000 xxxxxxxxxxxxxxxxxxx 0000" -print " 0000 xxxxxxxxxxxxxxxxx 0000" -print " 0000 xxxxxxxxxxxxxxx 0000" -print " 00000 xxxxxxxxxxxxx 00000" -print " 00000 xxxxxxxxxxx 00000" -print " 00000 00000" -print " 000000 000000" -print " 0000000000000000000" -print " 0000000000000" -print " 270" -print -print "x - your planet" -print "o - the orbit of the romulan ship" -print; input "(Press Return.)" -print -print "On the above diagram, the romulan ship is circling" -print "counterclockwise around your planet. Don't forget that" -print "without sufficient power the romulan ship's altitude" -print "and orbital rate will remain constant." -print -print "Good luck. The federation is counting on you." - -while true - a=floor(360*rnd) - d=floor(200*rnd + 200) - r=floor(20*rnd + 10) - for h in range(1,7) - print - print - print "This is hour " + h + ", at what angle do you wish to send" - a1 = input("your photon bomb? ").val - d1 = input("How far out do you wish to detonate it? ").val - print - print - a += r - if a >= 360 then a -= 360 - t = abs(a-a1) - if t >= 180 then t = 360 - t - c = sqrt(d*d + d1*d1 - 2*d*d1*cos(t*pi/180)) - print "Your photon bomb exploded " + round(c) + " * 10^2 miles from the" - print "Romulan ship." - if c<=50 then break - end for - if c <= 50 then - print "You have succesfully completed your mission." - else - print "You have allowed the Romulans to escape." - end if - print "Another romulan ship has gone into orbit." - yn = input("Do you wish to try to destroy it? ").lower + " " - if yn[0] != "y" then break -end while -print "good bye." diff --git a/00_Alternate_Languages/68_Orbit/README.md b/00_Alternate_Languages/68_Orbit/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/68_Orbit/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/68_Orbit/orbit.bas b/00_Alternate_Languages/68_Orbit/orbit.bas deleted file mode 100644 index f290eee47..000000000 --- a/00_Alternate_Languages/68_Orbit/orbit.bas +++ /dev/null @@ -1,96 +0,0 @@ -2 PRINT TAB(33);"ORBIT" -4 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -6 PRINT:PRINT:PRINT -10 PRINT "SOMEWHERE ABOVE YOUR PLANET IS A ROMULAN SHIP." -15 PRINT -20 PRINT "THE SHIP IS IN A CONSTANT POLAR ORBIT. ITS" -25 PRINT "DISTANCE FROM THE CENTER OF YOUR PLANET IS FROM" -30 PRINT "10,000 TO 30,000 MILES AND AT ITS PRESENT VELOCITY CAN" -31 PRINT "CIRCLE YOUR PLANET ONCE EVERY 12 TO 36 HOURS." -35 PRINT -40 PRINT "UNFORTUNATELY, THEY ARE USING A CLOAKING DEVICE SO" -45 PRINT "YOU ARE UNABLE TO SEE THEM, BUT WITH A SPECIAL" -50 PRINT "INSTRUMENT YOU CAN TELL HOW NEAR THEIR SHIP YOUR" -55 PRINT "PHOTON BOMB EXPLODED. YOU HAVE SEVEN HOURS UNTIL THEY" -60 PRINT "HAVE BUILT UP SUFFICIENT POWER IN ORDER TO ESCAPE" -65 PRINT "YOUR PLANET'S GRAVITY." -70 PRINT -75 PRINT "YOUR PLANET HAS ENOUGH POWER TO FIRE ONE BOMB AN HOUR." -80 PRINT -85 PRINT "AT THE BEGINNING OF EACH HOUR YOU WILL BE ASKED TO GIVE AN" -90 PRINT "ANGLE (BETWEEN 0 AND 360) AND A DISTANCE IN UNITS OF" -95 PRINT "100 MILES (BETWEEN 100 AND 300), AFTER WHICH YOUR BOMB'S" -100 PRINT "DISTANCE FROM THE ENEMY SHIP WILL BE GIVEN." -105 PRINT -110 PRINT "AN EXPLOSION WITHIN 5,000 MILES OF THE ROMULAN SHIP" -111 PRINT "WILL DESTROY IT." -114 PRINT -115 PRINT "BELOW IS A DIAGRAM TO HELP YOU VISUALIZE YOUR PLIGHT." -116 PRINT -117 PRINT -168 PRINT " 90" -170 PRINT " 0000000000000" -171 PRINT " 0000000000000000000" -172 PRINT " 000000 000000" -173 PRINT " 00000 00000" -174 PRINT " 00000 XXXXXXXXXXX 00000" -175 PRINT " 00000 XXXXXXXXXXXXX 00000" -176 PRINT " 0000 XXXXXXXXXXXXXXX 0000" -177 PRINT " 0000 XXXXXXXXXXXXXXXXX 0000" -178 PRINT " 0000 XXXXXXXXXXXXXXXXXXX 0000" -179 PRINT "180<== 00000 XXXXXXXXXXXXXXXXXXX 00000 ==>0" -180 PRINT " 0000 XXXXXXXXXXXXXXXXXXX 0000" -181 PRINT " 0000 XXXXXXXXXXXXXXXXX 0000" -182 PRINT " 0000 XXXXXXXXXXXXXXX 0000" -183 PRINT " 00000 XXXXXXXXXXXXX 00000" -184 PRINT " 00000 XXXXXXXXXXX 00000" -185 PRINT " 00000 00000" -186 PRINT " 000000 000000" -187 PRINT " 0000000000000000000" -188 PRINT " 0000000000000" -190 PRINT " 270" -192 PRINT -195 PRINT "X - YOUR PLANET" -196 PRINT "O - THE ORBIT OF THE ROMULAN SHIP" -197 PRINT -198 PRINT "ON THE ABOVE DIAGRAM, THE ROMULAN SHIP IS CIRCLING" -199 PRINT "COUNTERCLOCKWISE AROUND YOUR PLANET. DON'T FORGET THAT" -200 PRINT "WITHOUT SUFFICIENT POWER THE ROMULAN SHIP'S ALTITUDE" -210 PRINT "AND ORBITAL RATE WILL REMAIN CONSTANT." -220 PRINT -230 PRINT "GOOD LUCK. THE FEDERATION IS COUNTING ON YOU." -270 A=INT(360*RND(1)) -280 D=INT(200*RND(1)+200) -290 R=INT(20*RND(1)+10) -300 H=0 -310 IF H=7 THEN 490 -320 H=H+1 -325 PRINT -326 PRINT -330 PRINT "THIS IS HOUR";H;", AT WHAT ANGLE DO YOU WISH TO SEND" -335 PRINT "YOUR PHOTON BOMB"; -340 INPUT A1 -350 PRINT "HOW FAR OUT DO YOU WISH TO DETONATE IT"; -360 INPUT D1 -365 PRINT -366 PRINT -370 A=A+R -380 IF A<360 THEN 400 -390 A=A-360 -400 T=ABS(A-A1) -410 IF T<180 THEN 430 -420 T=360-T -430 C=SQR(D*D+D1*D1-2*D*D1*COS(T*3.14159/180)) -440 PRINT "YOUR PHOTON BOMB EXPLODED";C;"*10^2 MILES FROM THE" -445 PRINT "ROMULAN SHIP." -450 IF C<=50 THEN 470 -460 GOTO 310 -470 PRINT "YOU HAVE SUCCESFULLY COMPLETED YOUR MISSION." -480 GOTO 500 -490 PRINT "YOU HAVE ALLOWED THE ROMULANS TO ESCAPE." -500 PRINT "ANOTHER ROMULAN SHIP HAS GONE INTO ORBIT." -510 PRINT "DO YOU WISH TO TRY TO DESTROY IT"; -520 INPUT C$ -530 IF C$="YES" THEN 270 -540 PRINT "GOOD BYE." -999 END diff --git a/00_Alternate_Languages/69_Pizza/MiniScript/README.md b/00_Alternate_Languages/69_Pizza/MiniScript/README.md deleted file mode 100644 index 993c4056c..000000000 --- a/00_Alternate_Languages/69_Pizza/MiniScript/README.md +++ /dev/null @@ -1,18 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: -``` - miniscript pizza.ms -``` - -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: -``` - load "pizza" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/69_Pizza/MiniScript/pizza.ms b/00_Alternate_Languages/69_Pizza/MiniScript/pizza.ms deleted file mode 100644 index 84c33bb63..000000000 --- a/00_Alternate_Languages/69_Pizza/MiniScript/pizza.ms +++ /dev/null @@ -1,98 +0,0 @@ -print " "*33 + "Pizza" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print -print "Pizza Delivery Game"; print -name = input("What is your first name? "); print -print "Hi, " + name + ". In this game you are to take orders" -print "for pizzas. Then you are to tell a delivery boy" -print "where to deliver the ordered pizzas."; print; print - -// Convert a house name like "G" into coordinates like [3,2]. -nameToCoords = function(name) - idx = name.code - "A".code - row = floor(idx / 4) - col = idx % 4 - return [col+1, row+1] -end function - -// Convert house coordinates like [3,2] into a house name like "G". -coordsToName = function(coords) - idx = (coords[1]-1)*4 + (coords[0]-1) - return char("A".code + idx) -end function - -askYesNo = function(prompt) - while true - yn = input(prompt + "? ").lower + " " - if yn[0] == "y" then return "yes" - if yn[0] == "n" then return "no" - print "'Yes' or 'no' please, now then," - end while -end function - -input "(Press Return.)"; print - -print "Map of the city of Hyattsville"; print -print " -----1-----2-----3-----4-----" -for row in range(4, 1) - print "-"; print "-"; print "-" - s = row + " " - for col in range(1, 4) - s += coordsToName([col, row]) + " " - end for - s += row - print s -end for -print "-"; print "-"; print "-" -print " -----1-----2-----3-----4-----" - -input -print "The output is a map of the homes where" -print "you are to send pizzas."; print -print "Your job is to give a truck driver" -print "the location or coordinates of the" -print "home ordering the pizza."; print -if askYesNo("Do you need more directions") == "yes" then - print; print "Somebody will ask for a pizza to be" - print "delivered. Then a delivery boy will" - print "ask you for the location."; - print " Example:" - print "This is J. Please send a pizza." - print "Driver to " + name + ". Where does j live?" - print "Your answer would be 2,3"; print - if askYesNo("Understand") == "no" then - print "This job is definitely too difficult for you. Thanks anyway" - exit - end if - print "Good. you are now ready to start taking orders."; print - print "Good luck!!"; print -end if - -while true - for turn in range(1,5) - coords = [floor(rnd*4+1), floor(rnd*4+1)] - buyer = coordsToName(coords) - print "Hello " + name + "'s Pizza. This is " + buyer + - ". Please send a pizza." - while true - while true - inp = input(" Driver to " + name + ": Where does " + buyer + " live? ") - inp = inp.replace(",", " ").replace(" ", " ") - inp = inp.split + ["0","0"] - guess = [inp[0].val, inp[1].val] - if 1 <= guess[0] <= 4 and 1 <= guess[1] <= 4 then break - end while - if guess == coords then - print "Hello " + name + ". This is " + buyer + ", thanks for the pizza." - break - else - print "This is " + coordsToName(guess) + ". I did not order a pizza." - print "I live at " + guess.join(",") - end if - end while - print - end for - if askYesNo("Do you want to deliver more pizzas") == "no" then break -end while - -print; print "O.K. " + name + ", see you later!"; print diff --git a/00_Alternate_Languages/69_Pizza/README.md b/00_Alternate_Languages/69_Pizza/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/69_Pizza/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/69_Pizza/pizza.bas b/00_Alternate_Languages/69_Pizza/pizza.bas deleted file mode 100644 index a3d4e4f15..000000000 --- a/00_Alternate_Languages/69_Pizza/pizza.bas +++ /dev/null @@ -1,68 +0,0 @@ -5 PRINT TAB(33);"PIZZA" -10 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -15 PRINT: PRINT: PRINT -20 DIM S$(16),M$(4) -30 PRINT "PIZZA DELIVERY GAME": PRINT -50 INPUT "WHAT IS YOUR FIRST NAME";N$: PRINT -80 PRINT "HI, ";N$;". IN THIS GAME YOU ARE TO TAKE ORDERS" -90 PRINT "FOR PIZZAS. THEN YOU ARE TO TELL A DELIVERY BOY" -100 PRINT "WHERE TO DELIVER THE ORDERED PIZZAS.": PRINT: PRINT -140 FOR I=1 TO 16 -150 READ S$(I) -160 NEXT I -170 FOR I=1 TO 4 -180 READ M$(I) -190 NEXT I -200 DATA "A","B","C","D","E","F","G","H","I","J","K","L","M","N","O" -210 DATA "P","1","2","3","4" -230 PRINT "MAP OF THE CITY OF HYATTSVILLE": PRINT -250 PRINT " -----1-----2-----3-----4-----" -260 K=4 -270 FOR I=1 TO 4 -280 PRINT "-": PRINT "-": PRINT"-": PRINT "-" -320 PRINT M$(K); -330 S1=16-4*I+1 -340 PRINT " ";S$(S1);" ";S$(S1+1);" ";S$(S1+2);" "; -350 PRINT S$(S1+3);" ";M$(K) -380 K=K-1 -390 NEXT I -400 PRINT "-": PRINT "-": PRINT "-": PRINT "-" -440 PRINT " -----1-----2-----3-----4-----": PRINT -460 PRINT "THE OUTPUT IS A MAP OF THE HOMES WHERE" -470 PRINT "YOU ARE TO SEND PIZZAS.": PRINT -490 PRINT "YOUR JOB IS TO GIVE A TRUCK DRIVER" -500 PRINT "THE LOCATION OR COORDINATES OF THE" -510 PRINT "HOME ORDERING THE PIZZA.": PRINT -520 INPUT "DO YOU NEED MORE DIRECTIONS";A$ -530 IF A$="YES" THEN 590 -540 IF A$="NO" THEN 750 -550 PRINT "'YES' OR 'NO' PLEASE, NOW THEN,": GOTO 520 -590 PRINT: PRINT "SOMEBODY WILL ASK FOR A PIZZA TO BE" -600 PRINT "DELIVERED. THEN A DELIVERY BOY WILL" -610 PRINT "ASK YOU FOR THE LOCATION.":PRINT " EXAMPLE:" -620 PRINT "THIS IS J. PLEASE SEND A PIZZA." -640 PRINT "DRIVER TO ";N$;". WHERE DOES J LIVE?" -650 PRINT "YOUR ANSWER WOULD BE 2,3": PRINT -660 INPUT "UNDERSTAND";A$ -670 IF A$="YES" THEN 690 -680 PRINT "THIS JOB IS DEFINITELY TOO DIFFICULT FOR YOU. THANKS ANYWAY" -685 GOTO 999 -690 PRINT "GOOD. YOU ARE NOW READY TO START TAKING ORDERS.": PRINT -700 PRINT "GOOD LUCK!!": PRINT -750 FOR I=1 TO 5 -760 S=INT(RND(1)*16+1): PRINT -770 PRINT "HELLO ";N$;"'S PIZZA. THIS IS ";S$(S);"."; -775 PRINT " PLEASE SEND A PIZZA." -780 PRINT " DRIVER TO ";N$;": WHERE DOES ";S$(S);" LIVE"; -790 INPUT A(1),A(2) -870 T=A(1)+(A(2)-1)*4 -880 IF T=S THEN 920 -890 PRINT "THIS IS ";S$(T);". I DID NOT ORDER A PIZZA." -900 PRINT "I LIVE AT ";A(1);",";A(2) -910 GOTO 780 -920 PRINT "HELLO "N$;". THIS IS ";S$(S);", THANKS FOR THE PIZZA." -930 NEXT I -940 PRINT: INPUT "DO YOU WANT TO DELIVER MORE PIZZAS";A$ -960 IF A$="YES" THEN 750 -970 PRINT: PRINT "O.K. ";N$;", SEE YOU LATER!":PRINT -999 END diff --git a/00_Alternate_Languages/70_Poetry/MiniScript/README.md b/00_Alternate_Languages/70_Poetry/MiniScript/README.md deleted file mode 100644 index 52effbcc2..000000000 --- a/00_Alternate_Languages/70_Poetry/MiniScript/README.md +++ /dev/null @@ -1,18 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: -``` - miniscript poetry.ms -``` - -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: -``` - load "poetry" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/70_Poetry/MiniScript/poetry.ms b/00_Alternate_Languages/70_Poetry/MiniScript/poetry.ms deleted file mode 100644 index f55d32901..000000000 --- a/00_Alternate_Languages/70_Poetry/MiniScript/poetry.ms +++ /dev/null @@ -1,51 +0,0 @@ -print " "*30 + "POETRY" -print " "*15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -print; print; print - -I = 0; J = 0; K = 0; U = 0 - -// Note: infinite loop. Press control-C to break. -while true - if J == 1 then - print ["MIDNIGHT DREARY", "FIERY EYES", - "BIRD OR FIEND", "THING OF EVIL", "PROPHET"][I-1], "" - else if J == 2 then - if I == 1 or I == 4 then U = 2 - if I == 3 then U = 0 - print ["BEGUILING ME", "THRILLED ME", - "STILL SITTING....", "NEVER FLITTING", "BURNED"][I-1], "" - else if J == 3 then - if U != 0 or I < 5 then - print ["AND MY SOUL", "DARKNESS THERE", - "SHALL BE LIFTED", "QUOTH THE RAVEN", "SIGN OF PARTING"][I-1], "" - end if - else if J == 4 then - print ["NOTHING MORE", "YET AGAIN", - "SLOWLY CREEPING", "...EVERMORE", "NEVERMORE"][I-1], "" - end if - if U != 0 and rnd <= 0.19 then - print ",", "" - U = 2 - end if - if rnd <= 0.65 then - print " ", "" - U += 1 - else - print - U = 0 - end if - while true - I =floor(floor(10*rnd)/2)+1 - J += 1 - K += 1 - if U == 0 and floor(J/2) == J/2 then print " ", "" - if J <= 5 then break - J = 0 - print - if K <= 20 then continue - print - U = 0 - K = 0 - break - end while -end while diff --git a/00_Alternate_Languages/70_Poetry/README.md b/00_Alternate_Languages/70_Poetry/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/70_Poetry/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/70_Poetry/poetry.bas b/00_Alternate_Languages/70_Poetry/poetry.bas deleted file mode 100644 index 3661287de..000000000 --- a/00_Alternate_Languages/70_Poetry/poetry.bas +++ /dev/null @@ -1,42 +0,0 @@ -10 PRINT TAB(30);"POETRY" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT:PRINT:PRINT -90 ON I GOTO 100,101,102,103,104 -100 PRINT "MIDNIGHT DREARY";:GOTO 210 -101 PRINT "FIERY EYES";:GOTO 210 -102 PRINT "BIRD OR FIEND";:GOTO 210 -103 PRINT "THING OF EVIL";:GOTO 210 -104 PRINT "PROPHET";:GOTO 210 -110 ON I GOTO 111,112,113,114,115 -111 PRINT "BEGUILING ME";:U=2:GOTO 210 -112 PRINT "THRILLED ME";:GOTO 210 -113 PRINT "STILL SITTING....";:GOTO 212 -114 PRINT "NEVER FLITTING";:U=2:GOTO 210 -115 PRINT "BURNED";:GOTO 210 -120 ON I GOTO 121,122,123,124,125 -121 PRINT "AND MY SOUL";:GOTO 210 -122 PRINT "DARKNESS THERE";:GOTO 210 -123 PRINT "SHALL BE LIFTED";:GOTO 210 -124 PRINT "QUOTH THE RAVEN";:GOTO 210 -125 IF U=0 THEN 210 -126 PRINT "SIGN OF PARTING";:GOTO 210 -130 ON I GOTO 131,132,133,134,135 -131 PRINT "NOTHING MORE";:GOTO 210 -132 PRINT "YET AGAIN";:GOTO 210 -133 PRINT "SLOWLY CREEPING";:GOTO 210 -134 PRINT "...EVERMORE";:GOTO 210 -135 PRINT "NEVERMORE"; -210 IF U=0 OR RND(1)>.19 THEN 212 -211 PRINT ",";:U=2 -212 IF RND(1)>.65 THEN 214 -213 PRINT " ";:U=U+1:GOTO 215 -214 PRINT : U=0 -215 I=INT(INT(10*RND(1))/2)+1 -220 J=J+1 : K=K+1 -230 IF U>0 OR INT(J/2)<>J/2 THEN 240 -235 PRINT " "; -240 ON J GOTO 90,110,120,130,250 -250 J=0 : PRINT : IF K>20 THEN 270 -260 GOTO 215 -270 PRINT : U=0 : K=0 : GOTO 110 -999 END diff --git a/00_Alternate_Languages/70_Poetry/poetry.pl b/00_Alternate_Languages/70_Poetry/poetry.pl deleted file mode 100644 index 585915c49..000000000 --- a/00_Alternate_Languages/70_Poetry/poetry.pl +++ /dev/null @@ -1,79 +0,0 @@ -#!/usr/bin/perl -#use strict; -# Automatic converted by bas2perl.pl -# Too much spaguetti code to be properly converted. - - -print ' 'x 30 . "POETRY\n"; -print ' 'x 15 . "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n"; -print "\n"; print "\n"; print "\n"; -Line90: -if ($I==1) { goto Line100; } elsif ($I==2) { goto Line101; } elsif ($I==3) { goto Line102; } elsif ($I==4) { goto Line103; } elsif ($I==5) { goto Line104; } ; -Line100: -print "MIDNIGHT DREARY"; goto Line210; -Line101: -print "FIERY EYES"; goto Line210; -Line102: -print "BIRD OR FIEND"; goto Line210; -Line103: -print "THING OF EVIL"; goto Line210; -Line104: -print "PROPHET"; goto Line210; -Line110: -if ($I==1) { goto Line111; } elsif ($I==2) { goto Line112; } elsif ($I==3) { goto Line113; } elsif ($I==4) { goto Line114; } elsif ($I==5) { goto Line115; } ; -Line111: -print "BEGUILING ME"; $U=2; goto Line210; -Line112: -print "THRILLED ME"; goto Line210; -Line113: -print "STILL SITTING...."; goto Line212; -Line114: -print "NEVER FLITTING"; $U=2; goto Line210; -Line115: -print "BURNED"; goto Line210; -Line120: -if ($I==1) { goto Line121; } elsif ($I==2) { goto Line122; } elsif ($I==3) { goto Line123; } elsif ($I==4) { goto Line124; } elsif ($I==5) { goto Line125; } ; -Line121: -print "AND MY SOUL"; goto Line210; -Line122: -print "DARKNESS THERE"; goto Line210; -Line123: -print "SHALL BE LIFTED"; goto Line210; -Line124: -print "QUOTH THE RAVEN"; goto Line210; -Line125: -if ($U==0) { goto Line210; } -print "SIGN OF PARTING"; goto Line210; -Line130: -if ($I==1) { goto Line131; } elsif ($I==2) { goto Line132; } elsif ($I==3) { goto Line133; } elsif ($I==4) { goto Line134; } elsif ($I==5) { goto Line135; } ; -Line131: -print "NOTHING MORE"; goto Line210; -Line132: -print "YET AGAIN"; goto Line210; -Line133: -print "SLOWLY CREEPING"; goto Line210; -Line134: -print "...EVERMORE"; goto Line210; -Line135: -print "NEVERMORE"; -Line210: -if ($U==0 || rand(1)>.19) { goto Line212; } -print ","; $U=2; -Line212: -if (rand(1)>.65) { goto Line214; } -print " "; $U=$U+1; goto Line215; -Line214: -print "\n"; $U=0; -Line215: -$I=int(int(10*rand(1))/2)+1; -$J=$J+1; $K=$K+1; -if ($U>0 || int($J/2)!=$J/2) { goto Line240; } -print " "; -Line240: -if ($J==1) { goto Line90; } elsif ($J==2) { goto Line110; } elsif ($J==3) { goto Line120; } elsif ($J==4) { goto Line130; } elsif ($J==5) { goto Line250; } ; -Line250: -$J=0; print "\n"; if ($K>20) { goto Line270; } -goto Line215; -Line270: -print "\n"; $U=0; $K=0; goto Line110; -exit; diff --git a/00_Alternate_Languages/71_Poker/MiniScript/README.md b/00_Alternate_Languages/71_Poker/MiniScript/README.md deleted file mode 100644 index 95144dcfd..000000000 --- a/00_Alternate_Languages/71_Poker/MiniScript/README.md +++ /dev/null @@ -1,18 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: -``` - miniscript poker.ms -``` - -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: -``` - load "poker" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/71_Poker/MiniScript/poker.ms b/00_Alternate_Languages/71_Poker/MiniScript/poker.ms deleted file mode 100644 index b367db031..000000000 --- a/00_Alternate_Languages/71_Poker/MiniScript/poker.ms +++ /dev/null @@ -1,557 +0,0 @@ -print " "*33 + "POKER" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print - -print "Welcome to the casino. We each have $200." -print "I will open the betting before the draw; you open after." -print "To fold bet 0; to check bet .5." -print "Enough talk -- let's get down to business." -print - -askYesNo = function(prompt) - while true - yn = input(prompt + "? ").lower + " " - if yn[0] == "y" then return "yes" - if yn[0] == "n" then return "no" - print "Answer yes or no, please." - end while -end function -askNumber = function(prompt, maxQty=3, minQty=1, maxErr=null, minErr=null) - while true - value = input(prompt + "? ").val - if minQty <= value <= maxQty then return value - if value < minQty and minErr != null then - print minErr - else if maxErr != null then - print maxErr - else - print "Enter a value between " + minQty + " and " + maxQty + ", please." - end if - end while -end function -random = function(n) - return floor(n * rnd) -end function -rand10 = function - return floor(10 * rnd) -end function -pad = function(s, width) - return s + " " * (width - s.len) -end function - -// Bonus little feature when running in Mini Micro: display a header bar -// always at the top of the screen, showing current balances. Does nothing -// on other platforms. -drawHeaders = function - if version.hostName != "Mini Micro" then return - display(2).mode = displayMode.text; td = display(2) - td.color = color.black; td.backColor = text.color - td.row = 25; td.column = 0 - td.print pad("Computer: $" + computer.balance, 25) + - pad("Table: $" + Table.pot, 25) + - pad("Player: $" + human.balance, 18) -end function - - -// Card class: represents a single playing card -Card = {} -Card.rank = 0 // from 2 to 14 (Ace) -Card.suit = "Clubs" -Card.keep = false // temp flag, used to note which cards to keep vs. discard -Card.make = function(rank, suit) - result = new Card - result.rank = rank - result.suit = suit - return result -end function -Card.rankStr = function(plural=false) - if self.rank > 10 then - return ["Jack", "Queen", "King", "Ace"][self.rank-11] + "s"*plural - else - return str(self.rank) + "'s" * plural - end if -end function -Card.str = function - return self.rankStr + " of " + self.suit -end function - -// Prepare a standard deck of 52 cards, and functions to draw and discard -deck = [] -for suit in ["Clubs", "Diamonds", "Hearts", "Spades"] - for rank in range(2, 14) - deck.push Card.make(rank, suit) - end for -end for -deck.shuffle -discardPile = [] -drawCard = function - if not deck then - globals.deck = discardPile - deck.shuffle - globals.discardPile = [] - end if - return deck.pop -end function -discard = function(cardOrCards) - if cardOrCards isa Hand then - globals.discardPile += cardOrCards.cards - else if cardOrCards isa list then - globals.discardPile += cardOrCards - else - discardPile.push cardOrCards - end if -end function - -// Hand ranks: how we compare Poker hands -HandRank = {} -HandRank.value = 0 -HandRank.str = function(highCard); return ""; end function -HandRank.make = function(value) - result = new HandRank - result.value = value - return result -end function - -HandRank.None = new HandRank -HandRank.Schmaltz = HandRank.make(1) -HandRank.Schmaltz.str = function(c); return "schmaltz, " + c.rankStr + " high"; end function -HandRank.PartialStraight = HandRank.make(2) -HandRank.PartialStraight.str = function(c); return ""; end function // (no display string; this is used only internally) -HandRank.Pair = HandRank.make(3) -HandRank.Pair.str = function(c); return "a pair of " + c.rankStr(true); end function -HandRank.TwoPair = HandRank.make(4) -HandRank.TwoPair.str = function(c); return "two pair, " + c.rankStr(true); end function -HandRank.Three = HandRank.make(5) -HandRank.Three.str = function(c); return "three " + c.rankStr(true); end function -HandRank.Straight = HandRank.make(6) -HandRank.Straight.str = function(c); return "straight, " + c.rankStr + " high"; end function -HandRank.Flush = HandRank.make(7) -HandRank.Flush.str = function(c); return "a flush in " + c.suit; end function -HandRank.FullHouse = HandRank.make(8) -HandRank.FullHouse.str = function(c); return "full house, " + c.rankStr(true); end function -HandRank.Four = HandRank.make(9) -HandRank.Four.str = function(c); return "four " + c.rankStr(true); end function -// Note: original code does not detect a straight flush or royal flush. - -// Hand: represents a set of cards in the hand of one player. -Hand = {} -Hand.cards = null // list of Card -Hand.rank = null // HandRank instance -Hand.highCard = null // reference to which (of self.cards) determines relative value -Hand.afterDraw = false // true if we've already had a chance to draw cards -Hand.make = function(cards) - result = new Hand - result.cards = cards - result.analyze - return result -end function -Hand.deal = function - return Hand.make([drawCard, drawCard, drawCard, drawCard, drawCard]) -end function -Hand.replaceCard = function(index) - discard self.cards[index] - self.cards[index] = drawCard -end function -Hand.rankStr = function - return self.rank.str(self.highCard) -end function -Hand.isWeak = function - return self.rank.value < HandRank.PartialStraight.value or - (self.rank.value == HandRank.PartialStraight.value and self.afterDraw) or - (self.rank <= HandRank.TwoPair.value and self.highCard.rank <= 6) -end function -Hand.beats = function(other) - if self.rank.value > other.rank.value then return true - if self.rank.value < other.rank.value then return false - return self.highCard.rank > other.highCard.rank -end function -Hand.print = function(startingNumber=1) - num = startingNumber - for c in self.cards - s = " " * (num < 10) + num + " -- " + c.str - print " " + s, "" - if num % 2 == 0 then - print - else - print " " * (28-s.len), "" - end if - num += 1 - end for - if num % 2 == 0 then print -end function -Hand.analyze = function - allSameSuit = true - for i in range(1, self.cards.len-1) - if self.cards[i].suit != self.cards[0].suit then allSameSuit = false - end for - if allSameSuit then - self.rank = HandRank.Flush - self.highCard = self.cards[0] - return - end if - - sortedCards = self.cards[:] - sortedCards.sort "rank" - self.rank = HandRank.Schmaltz - for c in sortedCards; c.keep = false; end for - keepAny = false - - for i in range(0, sortedCards.len-2) - matchesNextCard = (sortedCards[i].rank == sortedCards[i+1].rank) - if matchesNextCard then - self.highCard = sortedCards[i] - matchesPrevCard = (i > 0 and sortedCards[i].rank == sortedCards[i-1].rank) - sortedCards[i].keep = true - sortedCards[i+1].keep = true - keepAny = true - if self.rank.value < HandRank.Pair.value then - self.rank = HandRank.Pair - else if matchesPrevCard and self.rank == HandRank.Pair then - self.rank = HandRank.Three - else if self.rank == HandRank.Pair then - self.rank = HandRank.TwoPair - else if self.rank == HandRank.TwoPair then - self.rank = HandRank.FullHouse - else if matchesPrevCard then - self.rank = HandRank.Four - else - self.rank = HandRank.FullHouse - end if - end if - end for - if not keepAny then - if sortedCards[3].rank - sortedCards[0].rank == 3 then - for i in range(0,3); sortedCards[i].keep = true; end for - self.rank = HandRank.PartialStraight - end if - if sortedCards[4].rank - sortedCards[1].rank == 3 then - if self.rank == HandRank.PartialStraight then - self.rank = HandRank.Straight - sortedCards[4].keep = true - self.highCard = sortedCards[4] - else - self.rank = HandRank.PartialStraight - for i in range(1,4); sortedCards[i].keep = true; end for - end if - end if - end if - if self.rank == HandRank.Schmaltz then - self.highCard = sortedCards[4] - sortedCards[4].keep = true - sortedCards[3].keep = true - end if - -end function - -// Some global constants, just to make the code more understandable -Ante = 5 - -// Player -- base class for computer and human -Player = {} -Player.balance = 200 -Player.hand = null -Player.totalBet = 0 -Player.anteUp = function - self.balance -= Ante - return Ante -end function -Player.newHand = function - if self.hand then discard self.hand - self.hand = Hand.deal - self.totalBet = 0 -end function -Player.addToPot = function(amount) - self.balance -= amount - Table.pot += amount - drawHeaders -end function -Player.win = function - self.balance += Table.pot - Table.pot = 0 - drawHeaders -end function - -// strategies the computer player might employ -Strategy = {} -Strategy.make = function(name, value=2, drawCount=null) - result = new Strategy - result.name = name - result.value = value - result.drawCount = drawCount - return result -end function -Strategy.fold = Strategy.make("FOLD") -Strategy.check = Strategy.make("CHECK") -Strategy.raise = Strategy.make("RAISE", 2) -Strategy.bluff = function(value, drawCount); return Strategy.make("BLUFF", value, drawCount); end function -Strategy.bet = function(value); return Strategy.make("BET", value); end function - -// computer player -computer = new Player -computer.strategy = null -computer.newHand = function - super.newHand - if self.hand.isWeak then - if rand10 < 2 then - self.strategy = Strategy.bluff(23, 2) - else if rand10 < 2 then - self.strategy = Strategy.bluff(23, 1) - else if rand10 < 1 then - self.strategy = Strategy.bluff(23, 0) - else - self.strategy = Strategy.fold - end if - else if self.hand.rank.value < HandRank.Three.value then - if rand10 < 2 then self.strategy = Strategy.bluff(23, null) else self.strategy = Strategy.check - else if self.hand.rank.value < HandRank.FullHouse.value then - self.strategy = Strategy.bet(35) - else - if rand10 < 1 then self.strategy = Strategy.bet(35) else self.strategy = Strategy.raise - end if -end function -computer.bet = function(minBet=1, openingBet=false) - //print "My hand: "; self.hand.print; print "Strategy: " + self.strategy - if self.balance < minBet then - print "I fold." - return 0 - end if - if openingBet and (self.strategy == Strategy.check or self.strategy == Strategy.fold) then - print "I check." - return 0.5 - else if self.strategy == Strategy.fold and human.totalBet > 5 then - print "I fold." - return 0 - else if self.strategy == Strategy.check then - print "I'll see you." - return minBet - else if openingBet then - result = self.strategy.value + rand10 - if result > self.balance then result = self.balance - if result == 0 then - print "I check." - return 0.5 - end if - print "I'll open with $" + result - return result - else - bet = self.strategy.value + rand10 - if self.strategy == Strategy.raise then bet += minBet - if bet > self.balance then bet = self.balance - raise = bet - minBet - if raise <= 0 then - print "I'll see you." - return minBet - else - print "I'll see you, and raise you " + raise - return bet - end if - end if -end function -computer.drawCards = function - //print "My hand:"; self.hand.print - drawCount = 0 - for c in self.hand.cards; if not c.keep then drawCount += 1; end for - print "I am taking " + drawCount + " card" + "s" * (drawCount != 1) - for i in self.hand.cards.indexes - if not self.hand.cards[i].keep then self.hand.replaceCard i - end for - self.hand.analyze - //print "My new hand: "; self.hand.print - if self.strategy.name == "BLUFF" then - self.strategy = Strategy.bluff(28) - else if self.hand.isWeak then - self.strategy = Strategy.fold - else if self.hand.rank.value < HandRank.Three.value then - if rand10 == 0 then self.strategy = Strategy.bet(19) else self.strategy = Strategy.raise - else if self.hand.rank.value < HandRank.FullHouse.value then - if rand10 == 0 then self.strategy = Strategy.bet(11) else self.strategy = Strategy.bet(19) - else - self.strategy = Strategy.raise - end if -end function -computer.win = function - print; print "I win." - super.win -end function -computer.checkFunds = function - if self.balance >= Ante then return - if human.balance < 50 then return // BUGFIX - if human.hasWatch or askYesNo("Would you like to buy back your watch for $50") == "no" then - print "I'm busted. Conglatulations!" - exit - end if - self.balance += 50 - // Note: original BASIC code does not take money from the player, but let's fix that: - human.balance -= 50 // BUGFIX - human.hasWatch = true - drawHeaders -end function - - -human = new Player -human.hasWatch = true -human.bet = function(minBet=1, openingBet=false) - while true - betStr = input("What is your bet? ") - bet = betStr.val - if bet == 0 and betStr != "0" then - print "Enter 0 to fold, 0.5 to check, or a value of 1 or more to bet." - continue - else if bet == 0.5 and openingBet then - return bet // (check) - else if 0 < bet < 1 then - print "No small change, please." - continue - else if bet < minBet then - print "If you can't see my bet, then fold." - continue - else if bet > self.balance then - print "You can't bet with what you haven't got." - self.trySellWatch - continue - end if - return bet - end while -end function -human.drawCards = function - qty = askNumber("How many cards do you want", 3, 0, "You can't draw more than three cards.") - if qty == 0 then return - print "What are their numbers: " - for i in range(1, qty) - num = askNumber("", 5, 1) - self.hand.replaceCard num - 1 - end for - print "Your new hand:" - self.hand.print - self.hand.analyze -end function -human.win = function - print; print "You win." - super.win -end function -human.checkFunds = function - if self.balance < Ante then self.trySellWatch - if self.balance < Ante then - print "Your wad is shot. So long, sucker!" - exit - end if -end function -human.trySellWatch = function - if not self.hasWatch then return - if rand10 < 7 then - value = 75 - msg = "I'll give you $" + value + " for it." - else - value = 25 - msg = "That's a pretty crummy watch - I'll give you $" + value + "." - end if - if computer.balance < value then return // BUGFIX - if askYesNo("Would you like to sell your watch") == "no" then return - print msg - self.balance += value - self.hasWatch = false - // Note: the original BASIC program does not actually take any money from the computer. - // But let's do it right here: - computer.balance -= value // BUGFIX - drawHeaders -end function - -Table = {} -Table.pot = 0 - - -deal = function - Table.pot += computer.anteUp + human.anteUp - drawHeaders - computer.newHand - human.newHand -end function - -// Do a round of betting. Return true to continue, or false -// if either player folds (ending the hand). -takeBets = function(computerFirst) - if computerFirst then - bet = computer.bet(1, true) - if bet == 0 then - human.win - return false - end if - if bet == 0.5 then bet = 0 // "check" (no bet, but stay in the hand) - computer.addToPot bet - else - bet = 0 - end if - raise = bet - canCheck = (bet == 0) - while true - bet = human.bet(raise, canCheck) - if bet == 0 then - computer.win - return false - end if - if bet == 0.5 then // (checked) - if computerFirst then return true - bet = 0 - else - human.addToPot bet - raise = bet - raise - if raise == 0 then return true - end if - if computerFirst or bet > 0 then canCheck = false - - bet = computer.bet(raise, canCheck) - if bet == 0 then - human.win - return false - end if - if bet == 0.5 then return true // (checked) - canCheck = false - computer.addToPot bet - raise = bet - raise - if raise == 0 then return true - end while -end function - -playHand = function - print - computer.checkFunds - human.checkFunds - print "The ante is " + Ante + ". I will deal:" - print - - deal - - print "Your hand:" - human.hand.print - - print - if not takeBets(true) then return - - print; print "Now we draw -- ", "" - human.drawCards - computer.drawCards - - if not takeBets(false) then return - - print; print "Now we compare hands:" - print "My hand:" - computer.hand.print 6 - print - print "You have " + human.hand.rankStr - print "I have " + computer.hand.rankStr - if computer.hand.beats(human.hand) then - computer.win - else if human.hand.beats(computer.hand) then - human.win - else - print "The hand is drawn." - print "All $" + Table.pot + " remains in the pot." - end if -end function - -drawHeaders -while true - playHand - print "Now I have $" + computer.balance + " and you have $" + human.balance - if askYesNo("Do you wish to continue") == "no" then break -end while \ No newline at end of file diff --git a/00_Alternate_Languages/71_Poker/README.md b/00_Alternate_Languages/71_Poker/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/71_Poker/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/71_Poker/poker.bas b/00_Alternate_Languages/71_Poker/poker.bas deleted file mode 100644 index 82bfe8625..000000000 --- a/00_Alternate_Languages/71_Poker/poker.bas +++ /dev/null @@ -1,416 +0,0 @@ -2 PRINT TAB(33);"POKER" -4 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -6 PRINT: PRINT: PRINT -10 DIM A(50),B(15) -20 DEF FNA(X)=INT(10*RND(1)) -30 DEF FNB(X)=X-100*INT(X/100) -40 PRINT "WELCOME TO THE CASINO. WE EACH HAVE $200." -50 PRINT "I WILL OPEN THE BETTING BEFORE THE DRAW; YOU OPEN AFTER." -60 PRINT "TO FOLD BET 0; TO CHECK BET .5." -70 PRINT "ENOUGH TALK -- LET'S GET DOWN TO BUSINESS." -80 PRINT -90 LET O=1 -100 LET C=200 -110 LET S=200 -120 LET P=0 -130 REM -140 PRINT -150 IF C<=5 THEN 3670 -160 PRINT "THE ANTE IS $5. I WILL DEAL:" -170 PRINT -180 IF S>5 THEN 200 -190 GOSUB 3830 -200 LET P=P+10 -210 LET S=S-5 -220 LET C=C-5 -230 FOR Z=1 TO 10 -240 GOSUB 1740 -250 NEXT Z -260 PRINT "YOUR HAND:" -270 N=1 -280 GOSUB 1850 -290 N=6 -300 I=2 -310 GOSUB 2170 -320 PRINT -330 IF I<>6 THEN 470 -340 IF FNA(0)<=7 THEN 370 -350 LET X=11100 -360 GOTO 420 -370 IF FNA(0)<=7 THEN 400 -380 LET X=11110 -390 GOTO 420 -400 IF FNA(0)>=1 THEN 450 -410 X=11111 -420 I=7 -430 Z=23 -440 GOTO 580 -450 Z=1 -460 GOTO 510 -470 IF U>=13 THEN 540 -480 IF FNA(0)>=2 THEN 500 -490 GOTO 420 -500 Z=0 -510 K=0 -520 PRINT "I CHECK." -530 GOTO 620 -540 IF U<=16 THEN 570 -550 Z=2 -560 IF FNA(0)>=1 THEN 580 -570 Z=35 -580 V=Z+FNA(0) -590 GOSUB 3480 -600 PRINT "I'LL OPEN WITH $"V -610 K=V -620 GOSUB 3050 -630 GOSUB 650 -640 GOTO 820 -650 IF I<>3 THEN 760 -660 PRINT -670 PRINT "I WIN." -680 C=C+P -690 PRINT "NOW I HAVE $"C"AND YOU HAVE $"S -700 PRINT "DO YOU WISH TO CONTINUE"; -710 INPUT H$ -720 IF H$="YES" THEN 120 -730 IF H$="NO" THEN 4100 -740 PRINT "ANSWER YES OR NO, PLEASE." -750 GOTO 700 -760 IF I<>4 THEN 810 -770 PRINT -780 PRINT "YOU WIN." -790 S=S+P -800 GOTO 690 -810 RETURN -820 PRINT -830 PRINT "NOW WE DRAW -- HOW MANY CARDS DO YOU WANT"; -840 INPUT T -850 IF T=0 THEN 980 -860 Z=10 -870 IF T<4 THEN 900 -880 PRINT "YOU CAN'T DRAW MORE THAN THREE CARDS." -890 GOTO 840 -900 PRINT "WHAT ARE THEIR NUMBERS:" -910 FOR Q=1 TO T -920 INPUT U -930 GOSUB 1730 -940 NEXT Q -950 PRINT "YOUR NEW HAND:" -960 N=1 -970 GOSUB 1850 -980 Z=10+T -990 FOR U=6 TO 10 -1000 IF INT(X/10^(U-6))<>10*INT(X/10^(U-5)) THEN 1020 -1010 GOSUB 1730 -1020 NEXT U -1030 PRINT -1040 PRINT "I AM TAKING"Z-10-T"CARD"; -1050 IF Z=11+T THEN 1090 -1060 PRINT "S" -1070 PRINT -1080 GOTO 1100 -1090 PRINT -1100 N=6 -1110 V=I -1120 I=1 -1130 GOSUB 2170 -1140 B=U -1150 M=D -1160 IF V<>7 THEN 1190 -1170 Z=28 -1180 GOTO 1330 -1190 IF I<>6 THEN 1220 -1200 Z=1 -1210 GOTO 1330 -1220 IF U>=13 THEN 1270 -1230 Z=2 -1240 IF FNA(0)<>6 THEN 1260 -1250 Z=19 -1260 GOTO 1330 -1270 IF U>=16 THEN 1320 -1280 Z=19 -1290 IF FNA(0)<>8 THEN 1310 -1300 Z=11 -1310 GOTO 1330 -1320 Z=2 -1330 K=0 -1340 GOSUB 3050 -1350 IF T<>.5 THEN 1450 -1360 IF V=7 THEN 1400 -1370 IF I<>6 THEN 1400 -1380 PRINT "I'LL CHECK" -1390 GOTO 1460 -1400 V=Z+FNA(0) -1410 GOSUB 3480 -1420 PRINT "I'LL BET $"V -1430 K=V -1440 GOSUB 3060 -1450 GOSUB 650 -1460 PRINT -1470 PRINT "NOW WE COMPARE HANDS:" -1480 J$=H$ -1490 K$=I$ -1500 PRINT "MY HAND:" -1510 N=6 -1520 GOSUB 1850 -1530 N=1 -1540 GOSUB 2170 -1550 PRINT -1560 PRINT "YOU HAVE "; -1570 K=D -1580 GOSUB 3690 -1590 H$=J$ -1600 I$=K$ -1610 K=M -1620 PRINT "AND I HAVE "; -1630 GOSUB 3690 -1640 IF B>U THEN 670 -1650 IF U>B THEN 780 -1660 IF H$="A FLUS" THEN 1700 -1662 IF FNB(M)FNB(D) THEN 670 -1670 PRINT "THE HAND IS DRAWN." -1680 PRINT "ALL $"P"REMAINS IN THE POT." -1690 GOTO 140 -1700 IF FNB(M)>FNB(D) THEN 670 -1710 IF FNB(D)>FNB(M) THEN 780 -1720 GOTO 1670 -1730 Z=Z+1 -1740 A(Z)=100*INT(4*RND(1))+INT(100*RND(1)) -1750 IF INT(A(Z)/100)>3 THEN 1740 -1760 IF A(Z)-100*INT(A(Z)/100)>12 THEN 1740 -1765 IF Z=1 THEN 1840 -1770 FOR K=1 TO Z-1 -1780 IF A(Z)=A(K) THEN 1740 -1790 NEXT K -1800 IF Z<=10 THEN 1840 -1810 N=A(U) -1820 A(U)=A(Z) -1830 A(Z)=N -1840 RETURN -1850 FOR Z=N TO N+4 -1860 PRINT Z"-- "; -1870 GOSUB 1950 -1880 PRINT " OF"; -1890 GOSUB 2070 -1900 IF Z/2<>INT(Z/2) THEN 1920 -1910 PRINT -1920 NEXT Z -1930 PRINT -1940 RETURN -1950 K=FNB(A(Z)) -1960 IF K<>9 THEN 1980 -1970 PRINT "JACK"; -1980 IF K<>10 THEN 2000 -1990 PRINT "QUEEN"; -2000 IF K<>11 THEN 2020 -2010 PRINT "KING"; -2020 IF K<>12 THEN 2040 -2030 PRINT "ACE"; -2040 IF K>=9 THEN 2060 -2050 PRINT K+2; -2060 RETURN -2070 K=INT(A(Z)/100) -2080 IF K<>0 THEN 2100 -2090 PRINT " CLUBS", -2100 IF K<>1 THEN 2120 -2110 PRINT " DIAMONDS", -2120 IF K<>2 THEN 2140 -2130 PRINT " HEARTS", -2140 IF K<>3 THEN 2160 -2150 PRINT " SPADES", -2160 RETURN -2170 U=0 -2180 FOR Z=N TO N+4 -2190 B(Z)=FNB(A(Z)) -2200 IF Z=N+4 THEN 2230 -2210 IF INT(A(Z)/100)<>INT(A(Z+1)/100) THEN 2230 -2220 U=U+1 -2230 NEXT Z -2240 IF U<>4 THEN 2310 -2250 X=11111 -2260 D=A(N) -2270 H$="A FLUS" -2280 I$="H IN" -2290 U=15 -2300 RETURN -2310 FOR Z=N TO N+3 -2320 FOR K=Z+1 TO N+4 -2330 IF B(Z)<=B(K) THEN 2390 -2340 X=A(Z) -2350 A(Z)=A(K) -2360 B(Z)=B(K) -2370 A(K)=X -2380 B(K)=A(K)-100*INT(A(K)/100) -2390 NEXT K -2400 NEXT Z -2410 X=0 -2420 FOR Z=N TO N+3 -2430 IF B(Z)<>B(Z+1) THEN 2470 -2440 X=X+11*10^(Z-N) -2450 D=A(Z) -2460 GOSUB 2760 -2470 NEXT Z -2480 IF X<>0 THEN 2620 -2490 IF B(N)+3<>B(N+3) THEN 2520 -2500 X=1111 -2510 U=10 -2520 IF B(N+1)+3<>B(N+4) THEN 2620 -2530 IF U<>10 THEN 2600 -2540 U=14 -2550 H$="STRAIG" -2560 I$="HT" -2570 X=11111 -2580 D=A(N+4) -2590 RETURN -2600 U=10 -2610 X=11110 -2620 IF U>=10 THEN 2690 -2630 D=A(N+4) -2640 H$="SCHMAL" -2650 I$="TZ, " -2660 U=9 -2670 X=11000 -2680 GOTO 2740 -2690 IF U<>10 THEN 2720 -2700 IF I=1 THEN 2740 -2710 GOTO 2750 -2720 IF U>12 THEN 2750 -2730 IF FNB(D)>6 THEN 2750 -2740 I=6 -2750 RETURN -2760 IF U>=11 THEN 2810 -2770 U=11 -2780 H$="A PAIR" -2790 I$=" OF " -2800 RETURN -2810 IF U<>11 THEN 2910 -2820 IF B(Z)<>B(Z-1) THEN 2870 -2830 H$="THREE" -2840 I$=" " -2850 U=13 -2860 RETURN -2870 H$="TWO P" -2880 I$="AIR, " -2890 U=12 -2900 RETURN -2910 IF U>12 THEN 2960 -2920 U=16 -2930 H$="FULL H" -2940 I$="OUSE, " -2950 RETURN -2960 IF B(Z)<>B(Z-1) THEN 3010 -2970 U=17 -2980 H$="FOUR" -2990 I$=" " -3000 RETURN -3010 U=16 -3020 H$="FULL H" -3030 I$="OUSE, " -3040 RETURN -3050 G=0 -3060 PRINT:PRINT "WHAT IS YOUR BET"; -3070 INPUT T -3080 IF T-INT(T)=0 THEN 3140 -3090 IF K<>0 THEN 3120 -3100 IF G<>0 THEN 3120 -3110 IF T=.5 THEN 3410 -3120 PRINT "NO SMALL CHANGE, PLEASE." -3130 GOTO 3060 -3140 IF S-G-T>=0 THEN 3170 -3150 GOSUB 3830 -3160 GOTO 3060 -3170 IF T<>0 THEN 3200 -3180 I=3 -3190 GOTO 3380 -3200 IF G+T>=K THEN 3230 -3210 PRINT "IF YOU CAN'T SEE MY BET, THEN FOLD." -3220 GOTO 3060 -3230 G=G+T -3240 IF G=K THEN 3380 -3250 IF Z<>1 THEN 3420 -3260 IF G>5 THEN 3300 -3270 IF Z>=2 THEN 3350 -3280 V=5 -3290 GOTO 3420 -3300 IF Z=1 THEN 3320 -3310 IF T<=25 THEN 3350 -3320 I=4 -3330 PRINT "I FOLD." -3340 RETURN -3350 IF Z=2 THEN 3430 -3360 PRINT "I'LL SEE YOU." -3370 K=G -3380 S=S-G -3390 C=C-K -3400 P=P+G+K -3410 RETURN -3420 IF G>3*Z THEN 3350 -3430 V=G-K+FNA(0) -3440 GOSUB 3480 -3450 PRINT "I'LL SEE YOU, AND RAISE YOU"V -3460 K=G+V -3470 GOTO 3060 -3480 IF C-G-V>=0 THEN 3660 -3490 IF G<>0 THEN 3520 -3500 V=C -3510 RETURN -3520 IF C-G>=0 THEN 3360 -3530 IF (O/2)<>INT(O/2) THEN 3600 -3540 PRINT "WOULD YOU LIKE TO BUY BACK YOUR WATCH FOR $50"; -3550 INPUT J$ -3560 IF LEFT$(J$,1)="N" THEN 3600 -3570 C=C+50 -3580 O=O/2 -3590 RETURN -3600 IF O/3<>INT(O/3) THEN 3670 -3610 PRINT "WOULD YOU LIKE TO BUY BACK YOUR TIE TACK FOR $50"; -3620 INPUT J$ -3630 IF LEFT$(J$,1)="N" THEN 3670 -3640 C=C+50 -3650 O=O/3 -3660 RETURN -3670 PRINT "I'M BUSTED. CONGRATULATIONS!" -3680 STOP -3690 PRINT H$;I$; -3700 IF H$<>"A FLUS" THEN 3750 -3710 K=INT(K/100) -3720 GOSUB 2080 -3730 PRINT -3740 RETURN -3750 K=FNB(K) -3760 GOSUB 1960 -3770 IF H$="SCHMAL" THEN 3790 -3780 IF H$<>"STRAIG" THEN 3810 -3790 PRINT " HIGH" -3800 RETURN -3810 PRINT "'S" -3820 RETURN -3830 PRINT -3840 PRINT "YOU CAN'T BET WITH WHAT YOU HAVEN'T GOT." -3850 IF O/2=INT(O/2) THEN 3970 -3860 PRINT "WOULD YOU LIKE TO SELL YOUR WATCH"; -3870 INPUT J$ -3880 IF LEFT$(J$,1)="N" THEN 3970 -3890 IF FNA(0)>=7 THEN 3930 -3900 PRINT "I'LL GIVE YOU $75 FOR IT." -3910 S=S+75 -3920 GOTO 3950 -3930 PRINT "THAT'S A PRETTY CRUMMY WATCH - I'LL GIVE YOU $25." -3940 S=S+25 -3950 O=O*2 -3960 RETURN -3970 IF O/3<>INT(O/3) THEN 4090 -3980 PRINT "WILL YOU PART WITH THAT DIAMOND TIE TACK": -3990 INPUT J$ -4000 IF LEFT$(J$,1)="N" THEN 4080 -4010 IF FNA(0)>=6 THEN 4050 -4020 PRINT "YOU ARE NOW $100 RICHER." -4030 S=S+100 -4040 GOTO 4070 -4050 PRINT "IT'S PASTE. $25." -4060 S=S+25 -4070 O=O*3 -4080 RETURN -4090 PRINT "YOUR WAD IS SHOT. SO LONG, SUCKER!" -4100 END diff --git a/00_Alternate_Languages/72_Queen/MiniScript/README.md b/00_Alternate_Languages/72_Queen/MiniScript/README.md deleted file mode 100644 index cf8463343..000000000 --- a/00_Alternate_Languages/72_Queen/MiniScript/README.md +++ /dev/null @@ -1,18 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: -``` - miniscript queen.ms -``` - -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: -``` - load "queen" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/72_Queen/MiniScript/queen.ms b/00_Alternate_Languages/72_Queen/MiniScript/queen.ms deleted file mode 100644 index d3e882b91..000000000 --- a/00_Alternate_Languages/72_Queen/MiniScript/queen.ms +++ /dev/null @@ -1,151 +0,0 @@ -print " "*33 + "QUEEN" -print " "*15 + "Creative Computing Morristown New Jersey" -print; print; print - -getYesNo = function(prompt) - while true - inp = input(prompt + "? ").lower + " " - if inp[0] == "y" then return "yes" - if inp[0] == "n" then return "no" - print "Please answer 'yes' or 'no'." - end while -end function - -printDirections = function - print "We are going to play a game based on one of the chess" - print "moves. Our queen will be able to move only to the left " - print "down or diagonally down and to the left." - print - print "The object of the game is to place the queen in the lower" - print "left hand square by alternating moves between you and the" - print "computer. The first one to place the queen there wins." - print - print "You go first and place the queen in any one of the squares" - print "on the top row or right hand column." - print "That will be your first move." - print "We alternate moves." - print "You may forfeit by typing '0' as your move." - print "Be sure to press the return key after each response." - print - input "(Press Return to continue.)" - print -end function - -printCoordinates = function - // Porting note: I cannot imagine what possessed the original author to - // use such a crazy numbering scheme, which is not easy for the human - // player OR the code. But assumptions about it are scattered throughout - // the whole program, so we're stuck with it. - print - print " 81 71 61 51 41 31 21 11" - print " 92 82 72 62 52 42 32 22" - print " 103 93 83 73 63 53 43 33" - print " 114 104 94 84 74 64 54 44" - print " 125 115 105 95 85 75 65 55" - print " 136 126 116 106 96 86 76 66" - print " 147 137 127 117 107 97 87 77" - print " 158 148 138 128 118 108 98 88" - print -end function - -getStartPos = function - while true - m1 = input("Where would you like to start? ").val - tens = floor(m1/10) - ones = m1 % 10 - if ones == 1 or tens == ones or m1 == 0 then return m1 - print "Please read the directions again." - print "You have begun illegally." - print - end while -end function - -isGoodMove = function(ones, tens) - pos = 10 * tens + ones - return [158, 127, 126, 75, 73].indexOf(pos) != null -end function - -getRandomMove = function(queenPos) - tens = floor(queenPos/10) - ones = queenPos % 10 - z = rnd - if z > 0.6 then - return 10 * (tens+1) + ones - else if z > 0.3 then - return 10 * (tens+2) + (ones+1) - else - return 10 * (tens+1) + ones - end if -end function - -getComputerMove = function(queenPos) - tens = floor(queenPos/10) - ones = queenPos % 10 - if [41, 44, 73, 75, 126, 127].indexOf(queenPos) != null then return getRandomMove(queenPos) - for k in range(7, 1) - if isGoodMove(ones, tens+k) then return 10 * (tens+k) + ones // left - if isGoodMove(ones+k, tens+k) then return 10 * (tens+k) + (ones+k) // down - if isGoodMove(ones+k, tens+k*2) then return 10 * (tens+k*2) + (ones+k) // down-left - end for - return getRandomMove(queenPos) -end function - -getHumanMove = function(queenPos) - tens = floor(queenPos/10) - ones = queenPos % 10 - while true - pos = input("What is your move? ").val - if pos == 0 then return 0 - dTens = floor(pos/10) - tens - dOnes = pos % 10 - ones - ok = false - if dOnes == 0 and dTens > 0 then ok = true // moving left - if dOnes == dTens and dOnes > 0 then ok = true // moving down - if dTens == dOnes*2 and dOnes > 0 then ok = true // moving down-left - if ok then return pos - print - print "Y O U C H E A T . . . Try again"; - end while -end function - -playGame = function - queenPos = getStartPos - while true - if queenPos == 0 then - print "It looks like I have won by forfeit." - return - end if - - // computer move - queenPos = getComputerMove(queenPos) - print "Computer moves to square " + queenPos - if queenPos == 158 then - print - print "Nice try, but it looks like I have won." - return - end if - - // human move - queenPos = getHumanMove(queenPos) - if queenPos == 158 then - print - print "C O N G R A T U L A T I O N S . . ." - print - print "You have won--very well played." - print "It looks like I have met my match." - print "Thanks for playing---I can't win all the time." - return - end if - end while -end function - -// Main program -if getYesNo("Do you want instructions") == "yes" then printDirections -while true - printCoordinates - playGame - print - if getYesNo("Anyone else care to try") == "no" then break -end while -print -print "OK --- Thanks again." diff --git a/00_Alternate_Languages/72_Queen/README.md b/00_Alternate_Languages/72_Queen/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/72_Queen/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/72_Queen/queen.bas b/00_Alternate_Languages/72_Queen/queen.bas deleted file mode 100644 index e7b808105..000000000 --- a/00_Alternate_Languages/72_Queen/queen.bas +++ /dev/null @@ -1,168 +0,0 @@ -1 PRINT TAB(33);"QUEEN" -2 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -3 PRINT:PRINT:PRINT -10 DIM S(64) -11 FOR I=1 TO 64 -12 READ S(I) -13 NEXT I -14 DATA 81, 71, 61, 51, 41, 31, 21, 11 -15 DATA 92, 82, 72, 62, 52, 42, 32, 22 -16 DATA 103, 93, 83, 73, 63, 53, 43, 33 -17 DATA 114, 104, 94, 84, 74, 64, 54, 44 -18 DATA 125, 115, 105, 95, 85, 75, 65, 55 -19 DATA 136, 126, 116, 106, 96, 86, 76, 66 -20 DATA 147, 137, 127, 117, 107, 97, 87, 77 -21 DATA 158, 148, 138, 128, 118, 108, 98, 88 -22 INPUT "DO YOU WANT INSTRUCTIONS";W$ -23 IF W$="NO" THEN 30 -24 IF W$="YES" THEN 28 -25 PRINT "PLEASE ANSWER 'YES' OR 'NO'." -26 GOTO 22 -28 GOSUB 5000 -29 GOTO 100 -30 GOSUB 5160 -90 REM ERROR CHECKS -100 PRINT "WHERE WOULD YOU LIKE TO START"; -110 INPUT M1 -115 IF M1=0 THEN 232 -120 T1=INT(M1/10) -130 U1=M1-10*T1 -140 IF U1=1 THEN 200 -150 IF U1=T1 THEN 200 -160 PRINT "PLEASE READ THE DIRECTIONS AGAIN." -170 PRINT "YOU HAVE BEGUN ILLEGALLY." -175 PRINT -180 GOTO 100 -200 GOSUB 2000 -210 PRINT "COMPUTER MOVES TO SQUARE";M -215 IF M=158 THEN 3400 -220 PRINT "WHAT IS YOUR MOVE"; -230 INPUT M1 -231 IF M1<>0 THEN 239 -232 PRINT -233 PRINT "IT LOOKS LIKE I HAVE WON BY FORFEIT." -234 PRINT -235 GOTO 4000 -239 IF M1<=M THEN 3200 -240 T1=INT(M1/10) -250 U1=M1-10*T1 -260 P=U1-U -270 IF P<>0 THEN 300 -280 L=T1-T -290 IF L<=0 THEN 3200 -295 GOTO 200 -300 IF T1-T <>P THEN 320 -310 GOTO 200 -320 IF T1-T <>2*P THEN 3200 -330 GOTO 200 -1990 REM LOCATE MOVE FOR COMPUTER -2000 IF M1=41 THEN 2180 -2010 IF M1=44 THEN 2180 -2020 IF M1=73 THEN 2180 -2030 IF M1=75 THEN 2180 -2040 IF M1=126 THEN 2180 -2050 IF M1=127 THEN 2180 -2060 IF M1=158 THEN 3300 -2065 C=0 -2070 FOR K=7 TO 1 STEP -1 -2080 U=U1 -2090 T=T1+K -2100 GOSUB 3500 -2105 IF C=1 THEN 2160 -2110 U=U+K -2120 GOSUB 3500 -2125 IF C=1 THEN 2160 -2130 T=T+K -2140 GOSUB 3500 -2145 IF C=1 THEN 2160 -2150 NEXT K -2155 GOTO 2180 -2160 C=0 -2170 RETURN -2180 GOSUB 3000 -2190 RETURN -2990 REM RANDOM MOVE -3000 Z=RND(1) -3010 IF Z>.6 THEN 3110 -3020 IF Z>.3 THEN 3070 -3030 U=U1 -3040 T=T1+1 -3050 M=10*T+U -3060 RETURN -3070 U=U1+1 -3080 T=T1+2 -3090 M=10*T+U -3100 RETURN -3110 U=U1+1 -3120 T=T1+1 -3130 M=10*T+U -3140 RETURN -3190 REM ILLEGAL MOVE MESSAGE -3200 PRINT -3210 PRINT "Y O U C H E A T . . . TRY AGAIN"; -3220 GOTO 230 -3290 REM PLAYER WINS -3300 PRINT -3310 PRINT "C O N G R A T U L A T I O N S . . ." -3320 PRINT -3330 PRINT "YOU HAVE WON--VERY WELL PLAYED." -3340 PRINT "IT LOOKS LIKE I HAVE MET MY MATCH." -3350 PRINT "THANKS FOR PLAYING---I CAN'T WIN ALL THE TIME." -3360 PRINT -3370 GOTO 4000 -3390 REM COMPUTER WINS -3400 PRINT -3410 PRINT "NICE TRY, BUT IT LOOKS LIKE I HAVE WON." -3420 PRINT "THANKS FOR PLAYING." -3430 PRINT -3440 GOTO 4000 -3490 REM TEST FOR COMPUTER MOVE -3500 M=10*T+U -3510 IF M=158 THEN 3570 -3520 IF M=127 THEN 3570 -3530 IF M=126 THEN 3570 -3540 IF M=75 THEN 3570 -3550 IF M=73 THEN 3570 -3560 RETURN -3570 C=1 -3580 GOTO 3560 -3990 REM ANOTHER GAME??? -4000 PRINT "ANYONE ELSE CARE TO TRY"; -4010 INPUT Q$ -4020 PRINT -4030 IF Q$="YES" THEN 30 -4040 IF Q$="NO" THEN 4050 -4042 PRINT "PLEASE ANSWER 'YES' OR 'NO'." -4045 GOTO 4000 -4050 PRINT:PRINT "OK --- THANKS AGAIN." -4060 STOP -4990 REM DIRECTIONS -5000 PRINT "WE ARE GOING TO PLAY A GAME BASED ON ONE OF THE CHESS" -5010 PRINT "MOVES. OUR QUEEN WILL BE ABLE TO MOVE ONLY TO THE LEFT," -5020 PRINT "DOWN, OR DIAGONALLY DOWN AND TO THE LEFT." -5030 PRINT -5040 PRINT "THE OBJECT OF THE GAME IS TO PLACE THE QUEEN IN THE LOWER" -5050 PRINT "LEFT HAND SQUARE BY ALTERNATING MOVES BETWEEN YOU AND THE" -5060 PRINT "COMPUTER. THE FIRST ONE TO PLACE THE QUEEN THERE WINS." -5070 PRINT -5080 PRINT "YOU GO FIRST AND PLACE THE QUEEN IN ANY ONE OF THE SQUARES" -5090 PRINT "ON THE TOP ROW OR RIGHT HAND COLUMN." -5100 PRINT "THAT WILL BE YOUR FIRST MOVE." -5110 PRINT "WE ALTERNATE MOVES." -5120 PRINT "YOU MAY FORFEIT BY TYPING '0' AS YOUR MOVE." -5130 PRINT "BE SURE TO PRESS THE RETURN KEY AFTER EACH RESPONSE." -5140 PRINT -5150 PRINT -5160 PRINT -5170 FOR A=0 TO 7 -5180 FOR B=1 TO 8 -5185 I=8*A+B -5190 PRINT S(I); -5200 NEXT B -5210 PRINT -5220 PRINT -5230 PRINT -5240 NEXT A -5250 PRINT -5260 RETURN -9999 END diff --git a/00_Alternate_Languages/73_Reverse/MiniScript/README.md b/00_Alternate_Languages/73_Reverse/MiniScript/README.md deleted file mode 100644 index 18812f302..000000000 --- a/00_Alternate_Languages/73_Reverse/MiniScript/README.md +++ /dev/null @@ -1,16 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - - miniscript reverse.ms - -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - - load "reverse" - run diff --git a/00_Alternate_Languages/73_Reverse/MiniScript/reverse.ms b/00_Alternate_Languages/73_Reverse/MiniScript/reverse.ms deleted file mode 100644 index 9d7396cf3..000000000 --- a/00_Alternate_Languages/73_Reverse/MiniScript/reverse.ms +++ /dev/null @@ -1,71 +0,0 @@ -num = 9 - -reverse = function(i) - if i == null then return i - ret = [] - for item in i - ret.insert(0,item) - end for - return ret -end function - -showRules = function - print - print "This is the game of 'Reverse'. To win, all you have" - print "to do is arrange a list of numbers (1 through " + num + ")" - print "in numerical order from left to right. To move, you" - print "tell me how many numbers (counting from the left) to" - print "reverse. For example, if the current list is:" - print; print "2 3 4 5 1 6 7 8 9" - print; print "and you reverse 4, the result will be:" - print; print "5 4 3 2 1 6 7 8 9" - print; print "Now if reverse 5, you win!" - print; print "1 2 3 4 5 6 7 8 9" - print - print "No doubt you will like this game, but" - print "if you want to quit, reverse 0 (zero)." - print - return -end function - -printState = function - print;print digits.join(" "); print -end function - -print " " * 32 + "Reverse" -print " " * 15 + "Creative Computing Morristown, New Jersey" -print; print; print -print "Reverse -- a game of skill" -print - -ans = input("Do you want the rules? ") + " " -if ans != null and ans[0].lower == "y" then showRules - -while true - turns = 0 - digits = range(1, num) - digits.shuffle - print;print "Here we go ... the list is:" - while true - printState - amt = input("How many shall I reverse? ").val - if amt == null or amt == 0 then break - - if amt > num then - print "OOPS! Too many! I can reverse at most " + num - else - turns += 1 - digits = reverse(digits[:amt]) + digits[amt:] - end if - if digits == range(1,num) then - printState - print "You won it in " + turns + " moves!!" - break - end if - end while - print - ans = input("Try again (YES or NO)? ") + " " - print - if ans == null or ans[0].lower != "y" then break -end while -print "O.K. Hope you had fun!!" diff --git a/00_Alternate_Languages/73_Reverse/README.md b/00_Alternate_Languages/73_Reverse/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/73_Reverse/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/73_Reverse/reverse.bas b/00_Alternate_Languages/73_Reverse/reverse.bas deleted file mode 100644 index 37d486767..000000000 --- a/00_Alternate_Languages/73_Reverse/reverse.bas +++ /dev/null @@ -1,62 +0,0 @@ -10 PRINT TAB(32);"REVERSE" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT:PRINT:PRINT -100 PRINT "REVERSE -- A GAME OF SKILL": PRINT -130 DIM A(20) -140 REM *** N=NUMBER OF NUMBERS -150 N=9 -160 PRINT "DO YOU WANT THE RULES"; -170 INPUT A$ -180 IF A$="NO" THEN 210 -190 GOSUB 710 -200 REM *** MAKE A RANDOM LIST A(1) TO A(N) -210 A(1)=INT((N-1)*RND(1)+2) -220 FOR K=2 TO N -230 A(K)=INT(N*RND(1)+1) -240 FOR J=1 TO K-1 -250 IF A(K)=A(J) THEN 230 -260 NEXT J:NEXT K -280 REM *** PRINT ORIGINAL LIST AND START GAME -290 PRINT: PRINT "HERE WE GO ... THE LIST IS:" -310 T=0 -320 GOSUB 610 -330 PRINT "HOW MANY SHALL I REVERSE"; -340 INPUT R -350 IF R=0 THEN 520 -360 IF R<=N THEN 390 -370 PRINT "OOPS! TOO MANY! I CAN REVERSE AT MOST";N:GOTO 330 -390 T=T+1 -400 REM *** REVERSE R NUMBERS AND PRINT NEW LIST -410 FOR K=1 TO INT(R/2) -420 Z=A(K) -430 A(K)=A(R-K+1) -440 A(R-K+1)=Z -450 NEXT K -460 GOSUB 610 -470 REM *** CHECK FOR A WIN -480 FOR K=1 TO N -490 IF A(K)<>K THEN 330 -500 NEXT K -510 PRINT "YOU WON IT IN";T;"MOVES!!!":PRINT -520 PRINT -530 PRINT "TRY AGAIN (YES OR NO)"; -540 INPUT A$ -550 IF A$="YES" THEN 210 -560 PRINT: PRINT "O.K. HOPE YOU HAD FUN!!":GOTO 999 -600 REM *** SUBROUTINE TO PRINT LIST -610 PRINT:FOR K=1 TO N:PRINT A(K);:NEXT K -650 PRINT:PRINT:RETURN -700 REM *** SUBROUTINE TO PRINT THE RULES -710 PRINT:PRINT "THIS IS THE GAME OF 'REVERSE'. TO WIN, ALL YOU HAVE" -720 PRINT "TO DO IS ARRANGE A LIST OF NUMBERS (1 THROUGH";N;")" -730 PRINT "IN NUMERICAL ORDER FROM LEFT TO RIGHT. TO MOVE, YOU" -740 PRINT "TELL ME HOW MANY NUMBERS (COUNTING FROM THE LEFT) TO" -750 PRINT "REVERSE. FOR EXAMPLE, IF THE CURRENT LIST IS:" -760 PRINT:PRINT "2 3 4 5 1 6 7 8 9" -770 PRINT:PRINT "AND YOU REVERSE 4, THE RESULT WILL BE:" -780 PRINT:PRINT "5 4 3 2 1 6 7 8 9" -790 PRINT:PRINT "NOW IF YOU REVERSE 5, YOU WIN!" -800 PRINT:PRINT "1 2 3 4 5 6 7 8 9":PRINT -810 PRINT "NO DOUBT YOU WILL LIKE THIS GAME, BUT" -820 PRINT "IF YOU WANT TO QUIT, REVERSE 0 (ZERO).":PRINT: RETURN -999 END diff --git a/00_Alternate_Languages/74_Rock_Scissors_Paper/MiniScript/README.md b/00_Alternate_Languages/74_Rock_Scissors_Paper/MiniScript/README.md deleted file mode 100644 index bfec2da94..000000000 --- a/00_Alternate_Languages/74_Rock_Scissors_Paper/MiniScript/README.md +++ /dev/null @@ -1,21 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -0. Try-It! Page: -Go to https://miniscript.org/tryit/, clear the sample code from the code editor, and paste in the contents of rockscissors.ms. Then click the "Run Script" button. Program output (and input) will appear in the green-on-black terminal display to the right of or below the code editor. - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: -``` - miniscript rockscissors.ms -``` - -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: -``` - load "rockscissors" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/74_Rock_Scissors_Paper/MiniScript/rockscissors.ms b/00_Alternate_Languages/74_Rock_Scissors_Paper/MiniScript/rockscissors.ms deleted file mode 100644 index 322e354b6..000000000 --- a/00_Alternate_Languages/74_Rock_Scissors_Paper/MiniScript/rockscissors.ms +++ /dev/null @@ -1,40 +0,0 @@ -print " "*21 + "Game of Rock, Scissors, Paper" -print " "*15 + "Creative Computing Morristown New Jersey" -print; print; print - -while true - numGames = input("How many games? ").val - if 0 < numGames < 11 then break - print "Sorry, but we aren't allowed to play that many." -end while - -computerWins = 0 -playerWins = 0 -for game in range(1, numGames) - print; print "Game number " + game - myChoice = floor(rnd*3 + 1) - while true - print "3=Rock...2=Scissors...1=Paper" - playerChoice = input("1...2...3...What's your choice? ").val - if [1,2,3].indexOf(playerChoice) != null then break - print "Invalid." - end while - print "This is my choice..." - print ["...Paper", "...Scissors", "...Rock"][myChoice-1] - diff = myChoice - playerChoice - if diff == 0 then - print "Tie game. No winner." - else if diff == 1 or diff == -2 then - print "Wow! I win!!!" - computerWins += 1 - else - print "You win!!!" - playerWins += 1 - end if -end for - -print; print "Here is the final game score:" -print "I have won " + computerWins + " game(s)." -print "You have won " + playerWins + " game(s)." -print "And " + (numGames - computerWins - playerWins) + " game(s) ended in a tie." -print; print "Thanks for playing!!" diff --git a/00_Alternate_Languages/74_Rock_Scissors_Paper/README.md b/00_Alternate_Languages/74_Rock_Scissors_Paper/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/74_Rock_Scissors_Paper/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/74_Rock_Scissors_Paper/bash/rockscissors.sh b/00_Alternate_Languages/74_Rock_Scissors_Paper/bash/rockscissors.sh deleted file mode 100644 index e91b1bb85..000000000 --- a/00_Alternate_Languages/74_Rock_Scissors_Paper/bash/rockscissors.sh +++ /dev/null @@ -1,100 +0,0 @@ -#!/bin/bash - -#10 PRINT TAB(21);"GAME OF ROCK, SCISSORS, PAPER" -#20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -#25 PRINT:PRINT:PRINT -printf "%*s GAME OF ROCK, SCISSORS, PAPER\n" 21 -printf "%*s CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n" 15 -echo ; echo - -#30 INPUT "HOW MANY GAMES";Q -#40 IF Q<11 THEN 60 -#50 PRINT "SORRY, BUT WE AREN'T ALLOWED TO PLAY THAT MANY.": GOTO 30 -while true; do - printf "HOW MANY GAMES " - read NUMBER_OF_GAMES - [ $NUMBER_OF_GAMES -ge 11 ] || break; - echo "SORRY, BUT WE AREN'T ALLOWED TO PLAY THAT MANY." -done - -COMPUTER_WINS=0 -HUMAN_WINS=0 -TIES=0 - -#60 FOR G=1 TO Q -for GAME_NUMBER in $( seq 1 $NUMBER_OF_GAMES ) -do - #70 PRINT: PRINT "GAME NUMBER";G - echo - printf "GAME NUMBER %s\n" $GAME_NUMBER - - #80 X=INT(RND(1)*3+1) - COMPUTER_PICK=$((RANDOM%3+1)) - - #90 PRINT "3=ROCK...2=SCISSORS...1=PAPER" - #100 INPUT "1...2...3...WHAT'S YOUR CHOICE";K - #110 IF (K-1)*(K-2)*(K-3)<>0 THEN PRINT "INVALID.": GOTO 90 - while true; do - echo "3=ROCK...2=SCISSORS...1=PAPER" - printf "1...2...3...WHAT'S YOUR CHOICE " - read HUMAN_PICK - [ $(( (HUMAN_PICK-1)*(HUMAN_PICK-2)*(HUMAN_PICK-3) )) -eq 0 ] && break; - echo "INVALID." - done - - - #120 PRINT "THIS IS MY CHOICE..." - #130 ON X GOTO 140,150,160 - #140 PRINT "...PAPER": GOTO 170 - #150 PRINT "...SCISSORS": GOTO 170 - #160 PRINT "...ROCK" - printf "THIS IS MY CHOICE..." - if [ $COMPUTER_PICK -eq 1 ]; then - echo "...PAPER" - elif [ $COMPUTER_PICK -eq 2 ]; then - echo "...SCISSORS" - else - echo "...ROCK" - fi - - #170 IF X=K THEN 250 - #180 IF X>K THEN 230 - #190 IF X=1 THEN 210 - #200 PRINT "YOU WIN!!!":H=H+1: GOTO 260 - #210 IF K<>3 THEN 200 - #220 PRINT "WOW! I WIN!!!":C=C+1:GOTO 260 - #230 IF K<>1 OR X<>3 THEN 220 - #240 GOTO 200 - #250 PRINT "TIE GAME. NO WINNER." - #260 NEXT G - if [ $COMPUTER_PICK -eq $HUMAN_PICK ]; then - echo "TIE GAME. NO WINNER." - ((TIES+=1)) - continue - elif ([ $COMPUTER_PICK -gt $HUMAN_PICK ] && ([ $COMPUTER_PICK -ne 3 ] || [ $HUMAN_PICK -ne 1 ])) \ - || ([ $COMPUTER_PICK -eq 1 ] && [ $HUMAN_PICK -eq 3 ]); then - echo "WOW! I WIN!!!" - ((COMPUTER_WINS+=1)) - continue - else - echo "YOU WIN!!!" - ((HUMAN_WINS+=1)) - continue - fi -done - - -#270 PRINT: PRINT "HERE IS THE FINAL GAME SCORE:" -#280 PRINT "I HAVE WON";C;"GAME(S)." -#290 PRINT "YOU HAVE WON";H;"GAME(S)." -#300 PRINT "AND";Q-(C+H);"GAME(S) ENDED IN A TIE." -#310 PRINT: PRINT "THANKS FOR PLAYING!!" -echo -echo "HERE IS THE FINAL GAME SCORE:" -printf "I HAVE WON %d GAME(S).\n" $COMPUTER_WINS -printf "YOU HAVE WON %d GAME(S).\n" $HUMAN_WINS -printf "AND %d GAME(S) ENDED IN A TIE.\n" $TIES -echo -echo "THANKS FOR PLAYING!!" - -#320 END diff --git a/00_Alternate_Languages/74_Rock_Scissors_Paper/nim/rockscissors.nim b/00_Alternate_Languages/74_Rock_Scissors_Paper/nim/rockscissors.nim deleted file mode 100644 index 3c0cda0c5..000000000 --- a/00_Alternate_Languages/74_Rock_Scissors_Paper/nim/rockscissors.nim +++ /dev/null @@ -1,68 +0,0 @@ -import std/[random,strformat,strutils] - -type - symbol = enum - PAPER = 1, SCISSORS = 2, ROCK = 3 - -var - cpuChoice, playerChoice, turns: int - cpuWins, playerWins, ties: int = 0 - -randomize() - -# Function: player makes a choice -proc choose(): int = - echo "3=ROCK...2=SCISSORS...1=PAPER...WHAT'S YOUR CHOICE?" - result = readLine(stdin).parseInt() - -# Function: determine the outcome -proc outcome(p: symbol, c: symbol): string = - if p == c: - ties += 1 - result = "TIE GAME. NO WINNER." - else: - const - winTable = [ - PAPER: (ROCK, "COVERS"), - SCISSORS: (PAPER, "CUTS"), - ROCK: (SCISSORS, "CRUSHES") - ] - let (winCond, winVerb) = winTable[p] - if winCond == c: - playerWins += 1 - result = fmt"{p} {winVerb} {c}. YOU WIN." - else: - let (_, winVerb) = winTable[c] - cpuWins += 1 - result = fmt"{c} {winVerb} {p}. I WIN." - -# Start the game -echo spaces(21), "GAME OF ROCK, SCISSORS, PAPER" -echo spaces(15), "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -echo "\n" -echo "HOW MANY GAMES?" -turns = readLine(stdin).parseInt() -while turns > 10: - echo "SORRY, BUT WE AREN'T ALLOWED TO PLAY THAT MANY." - turns = readLine(stdin).parseInt() - -# Play the game -for i in 1..turns: - echo "" - echo "GAME NUMBER ", i - playerChoice = choose() - while playerChoice != 1 and playerChoice != 2 and playerChoice != 3: - echo "INVALID" - playerChoice = choose() - cpuChoice = rand(1..3) # match against range in symbol - echo "THIS IS MY CHOICE... ", symbol(cpuChoice) - echo outcome(symbol(playerChoice), symbol(cpuChoice)) - -# Results -echo "" -echo "HERE IS THE FINAL GAME SCORE:" -echo "I HAVE WON ", cpuWins," GAME(S)." -echo "YOU HAVE WON ", playerWins," GAME(S)." -echo "AND ", ties," GAME(S) ENDED IN A TIE." -echo "" -echo "THANKS FOR PLAYING!!" diff --git a/00_Alternate_Languages/74_Rock_Scissors_Paper/rockscissors.bas b/00_Alternate_Languages/74_Rock_Scissors_Paper/rockscissors.bas deleted file mode 100644 index 8c364b63d..000000000 --- a/00_Alternate_Languages/74_Rock_Scissors_Paper/rockscissors.bas +++ /dev/null @@ -1,33 +0,0 @@ -10 PRINT TAB(21);"GAME OF ROCK, SCISSORS, PAPER" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -25 PRINT:PRINT:PRINT -30 INPUT "HOW MANY GAMES";Q -40 IF Q<11 THEN 60 -50 PRINT "SORRY, BUT WE AREN'T ALLOWED TO PLAY THAT MANY.": GOTO 30 -60 FOR G=1 TO Q -70 PRINT: PRINT "GAME NUMBER";G -80 X=INT(RND(1)*3+1) -90 PRINT "3=ROCK...2=SCISSORS...1=PAPER" -100 INPUT "1...2...3...WHAT'S YOUR CHOICE";K -110 IF (K-1)*(K-2)*(K-3)<>0 THEN PRINT "INVALID.": GOTO 90 -120 PRINT "THIS IS MY CHOICE..." -130 ON X GOTO 140,150,160 -140 PRINT "...PAPER": GOTO 170 -150 PRINT "...SCISSORS": GOTO 170 -160 PRINT "...ROCK" -170 IF X=K THEN 250 -180 IF X>K THEN 230 -190 IF X=1 THEN 210 -200 PRINT "YOU WIN!!!":H=H+1: GOTO 260 -210 IF K<>3 THEN 200 -220 PRINT "WOW! I WIN!!!":C=C+1:GOTO 260 -230 IF K<>1 OR X<>3 THEN 220 -240 GOTO 200 -250 PRINT "TIE GAME. NO WINNER." -260 NEXT G -270 PRINT: PRINT "HERE IS THE FINAL GAME SCORE:" -280 PRINT "I HAVE WON";C;"GAME(S)." -290 PRINT "YOU HAVE WON";H;"GAME(S)." -300 PRINT "AND";Q-(C+H);"GAME(S) ENDED IN A TIE." -310 PRINT: PRINT "THANKS FOR PLAYING!!" -320 END diff --git a/00_Alternate_Languages/75_Roulette/MiniScript/README.md b/00_Alternate_Languages/75_Roulette/MiniScript/README.md deleted file mode 100644 index 4a2e49289..000000000 --- a/00_Alternate_Languages/75_Roulette/MiniScript/README.md +++ /dev/null @@ -1,18 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: -``` - miniscript roulette.ms -``` - -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: -``` - load "roulette" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/75_Roulette/MiniScript/roulette.ms b/00_Alternate_Languages/75_Roulette/MiniScript/roulette.ms deleted file mode 100644 index 60e7087bc..000000000 --- a/00_Alternate_Languages/75_Roulette/MiniScript/roulette.ms +++ /dev/null @@ -1,200 +0,0 @@ -print " "*32 + "Roulette" -print " "*15 + "Creative Computing Morristown New Jersey" -print; print; print - -if version.hostName == "Mini Micro" then - import "dateTime" - globals.date = dateTime.str(dateTime.now, "MMM d, yyyy") -else - globals.date = input("Enter the current date (as in 'Jan 23, 1979') - ") -end if - -yn = input("Do you want instructions? ").lower + " " -if yn[0] != "n" then - print - print "This is the betting layout" - print " (*=Red)" - print - print " 1* 2 3*" - print " 4 5* 6 " - print " 7* 8 9*" - print "10 11 12*" - print "---------------" - print "13 14* 15 " - print "16* 17 18*" - print "19* 20 21*" - print "22 23* 24 " - print "---------------" - print "25* 26 27*" - print "28 29 30*" - print "31 32* 33 " - print "34* 35 36*" - print "---------------" - print " 00 0 " - print - input "(Press Return at each pause.)" - print - print "Types of Bets" - print - print "The numbers 1 to 36 signify a straight bet" - print "on that number." - print "These pay off 35:1" - print - print "The 2:1 bets are:" - print " 37) 1-12 40) first column" - print " 38) 13-24 41) second column" - print " 39) 25-36 42) third column" - print - print "The even money bets are:" - print " 43) 1-18 46) odd" - print " 44) 19-36 47) red" - print " 45) even 48) black" - print - print " 49)0 and 50)00 pay off 35:1" - print " NOTE: 0 and 00 do not count under any" - print " bets except their own." - input - print "When I ask for each bet, type the number" - print "and the amount, separated by a comma." - print "For example: to bet $500 on black, type 48,500" - print "when I ask for a bet." - print - print "The minimum bet is $5, the maximum is $500." - print -end if - -redNumbers = [1,3,5,7,9,12,14,16,18,19,21,23,25,27,30,32,34,36] - -// function to convert a number 1-38 to a number/description, like "00" -// or "7 RED" -numDesc = function(number) - if number == 37 then return "0" - if number == 38 then return "00" - s = str(number) - if redNumbers.indexOf(number) == null then - return s + " BLACK" - else - return s + " RED" - end if -end function - -// function to calculate the payout factor (positive if player wins, -// or -1 if player loses) for the given bet and actual spin. -payoutFactor = function(bet, spin) - if bet <= 36 then // straight bet, pays 35:1 - if bet == spin then return 35 else return -1 - else if bet == 49 then // 0, pays 35:1 - if spin == 37 then return 35 else return -1 - else if bet == 50 then // 00, pays 35:1 - if spin == 38 then return 35 else return -1 - else if bet == 37 then // 1-12, pays 2:1 - if 1 <= spin <= 12 then return 2 else return -1 - else if bet == 38 then // 13-24, pays 2:1 - if 13 <= spin <= 24 then return 2 else return -1 - else if bet == 39 then // 25-36, pays 2:1 - if 25 <= spin <= 36 then return 2 else return -1 - else if bet == 40 then // first column, pays 2:1 - if spin % 3 == 1 then return 2 else return -1 - else if bet == 41 then // second column, pays 2:1 - if spin % 3 == 2 then return 2 else return -1 - else if bet == 42 then // third column, pays 2:1 - if spin % 3 == 0 then return 2 else return -1 - else if bet == 43 then // 1-18, even money - if 1 <= spin <= 18 then return 1 else return -1 - else if bet == 44 then // 19-36, even money - if 19 <= spin <= 36 then return 1 else return -1 - else if bet == 45 then // even number, even money - if spin % 2 == 0 then return 1 else return -1 - else if bet == 46 then // odd number, even money - if spin % 2 == 1 then return 1 else return -1 - else if bet == 47 then // red, even money - if redNumbers.indexOf(spin) != null then return 1 else return -1 - else if bet == 48 then // black, even money - if redNumbers.indexOf(spin) == null then return 1 else return -1 - end if - print "Invalid bet " + bet + " in payoutFactor" -end function - -playerCash = 1000 -houseCash = 100000 -x = [0] * 38 // (keeps track of how often each number comes up) -while playerCash > 0 - // Get the player's bets - numBets = input("How many bets? ").val - if numBets < 1 then continue - bets = []; amounts = [] - for i in range(1, numBets) - while true - s = input("Number " + i + "? ").replace(",", " ").replace(" ", " ").split - if s.len != 2 then continue - bet = s[0].val; amount = s[1].val - if bets.indexOf(bet) != null then - print "You made that bet once already,dum-dum" - continue - end if - if 1 <= bet <= 50 and 5 <= amount <= 500 then - bets.push bet - amounts.push amount - break - end if - end while - end for - - // Spin the wheel! - print "Spinning" - print - print - spin = floor(38 * rnd + 1) - x[spin] += 1 - print numDesc(spin) - print - - // Now, pay out the bets - for i in bets.indexes - f = payoutFactor(bets[i], spin) - if f > 0 then - print "You win " + f*amounts[i] + " on bet " + i - else - print "You lose " + (-f)*amounts[i] + " on bet " + i - end if - playerCash += f * amounts[i] - houseCash -= f * amounts[i] - end for - print - print "Totals: ME YOU" - print " " + (houseCash+" "*12)[:12] + playerCash - if playerCash > 0 and houseCash > 0 then - yn = input("Again? ").lower + " " - if yn[0] != "y" then break - end if -end while - -if houseCash < 1 then - print "You broke the house!" - playerCash = 101000 -end if -if playerCash < 1 then - print "Oops! You just spent your last dollar!" - print "Thanks for your money." - print "I'll use it to buy a solid gold roulette wheel" - print -else - name = input("To whom shall I make the check? ") - print - print "-"*68 - print " "*55 + "Check No. " + floor(rnd*100) - print - print " "*(67 - date.len) + date - print - print - print "Pay to the order of-----" + name + "-----$ " + playerCash - print - print - print " "*10 + "The Memory Bank of New York" - print - print " "*35 + "The Computer" - print " "*35 + "----------X-----" - print - print "-"*68 - print "Come back soon!" -end if diff --git a/00_Alternate_Languages/75_Roulette/README.md b/00_Alternate_Languages/75_Roulette/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/75_Roulette/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/75_Roulette/roulette.bas b/00_Alternate_Languages/75_Roulette/roulette.bas deleted file mode 100644 index 461231c0b..000000000 --- a/00_Alternate_Languages/75_Roulette/roulette.bas +++ /dev/null @@ -1,239 +0,0 @@ -10 PRINT TAB(32);"ROULETTE" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT:PRINT:PRINT -40 PRINT "ENTER THE CURRENT DATE (AS IN 'JANUARY 23, 1979') -"; -50 INPUT D$,E$ -1000 REM-ROULETTE -1010 REM-DAVID JOSLIN -1020 PRINT "WELCOME TO THE ROULETTE TABLE" -1030 PRINT -1040 PRINT "DO YOU WANT INSTRUCTIONS"; -1050 INPUT Y$ -1060 IF LEFT$(Y$,1)="N" THEN 1550 -1070 PRINT -1080 PRINT "THIS IS THE BETTING LAYOUT" -1090 PRINT " (*=RED)" -1100 PRINT -1110 PRINT " 1* 2 3*" -1120 PRINT " 4 5* 6 " -1130 PRINT " 7* 8 9*" -1140 PRINT "10 11 12*" -1150 PRINT "---------------" -1160 PRINT "13 14* 15 " -1170 PRINT "16* 17 18*" -1180 PRINT "19* 20 21*" -1190 PRINT "22 23* 24 " -1200 PRINT "---------------" -1210 PRINT "25* 26 27*" -1220 PRINT "28 29 30*" -1230 PRINT "31 32* 33 " -1240 PRINT "34* 35 36*" -1250 PRINT "---------------" -1260 PRINT " 00 0 " -1270 PRINT -1280 PRINT "TYPES OF BETS" -1290 PRINT -1300 PRINT "THE NUMBERS 1 TO 36 SIGNIFY A STRAIGHT BET" -1310 PRINT "ON THAT NUMBER." -1320 PRINT "THESE PAY OFF 35:1" -1330 PRINT -1340 PRINT "THE 2:1 BETS ARE:" -1350 PRINT " 37) 1-12 40) FIRST COLUMN" -1360 PRINT " 38) 13-24 41) SECOND COLUMN" -1370 PRINT " 39) 25-36 42) THIRD COLUMN" -1380 PRINT -1390 PRINT "THE EVEN MONEY BETS ARE:" -1400 PRINT " 43) 1-18 46) ODD" -1410 PRINT " 44) 19-36 47) RED" -1420 PRINT " 45) EVEN 48) BLACK" -1430 PRINT -1440 PRINT " 49)0 AND 50)00 PAY OFF 35:1" -1450 PRINT " NOTE: 0 AND 00 DO NOT COUNT UNDER ANY" -1460 PRINT " BETS EXCEPT THEIR OWN." -1470 PRINT -1480 PRINT "WHEN I ASK FOR EACH BET, TYPE THE NUMBER" -1490 PRINT "AND THE AMOUNT, SEPARATED BY A COMMA." -1500 PRINT "FOR EXAMPLE: TO BET $500 ON BLACK, TYPE 48,500" -1510 PRINT "WHEN I ASK FOR A BET." -1520 PRINT -1530 PRINT "THE MINIMUM BET IS $5, THE MAXIMUM IS $500." -1540 PRINT -1550 REM-PROGRAM BEGINS HERE -1560 REM-TYPE OF BET(NUMBER) ODDS -1570 REM DON'T NEED TO DIMENSION STRINGS -1580 DIM B(100),C(100),T(100),X(38) -1590 DIM A(50) -1600 FOR I=1 TO 38: X(I)=0: NEXT I: REM MAT X=ZER -1610 P=1000 -1620 D=100000. -1630 PRINT "HOW MANY BETS"; -1640 INPUT Y -1650 IF Y<1 OR Y<>INT(Y) THEN 1630 -1660 FOR I=1 TO 50: A(I)=0: NEXT I: REM MAT A=ZER -1670 FOR C=1 TO Y -1680 PRINT "NUMBER";C; -1690 INPUT X,Z -1700 B(C)=Z -1710 T(C)=X -1720 IF X<1 OR X>50 OR X<>INT(X) THEN 1680 -1730 IF Z<1 OR Z<>INT(Z) THEN 1680 -1740 IF Z<5 OR Z>500 THEN 1680 -1750 IF A(X)=0 THEN 1780 -1760 PRINT "YOU MADE THAT BET ONCE ALREADY,DUM-DUM" -1770 GOTO 1680 -1780 A(X)=1 -1790 NEXT C -1800 PRINT "SPINNING" -1810 PRINT -1820 PRINT -1830 S=INT(RND(1)*100) -1840 IF S=0 OR S>38 THEN 1830 -1850 X(S)=X(S)+1 -1860 IF S<37 THEN 1920 -1870 IF S=37 THEN 1900 -1880 PRINT "00" -1890 GOTO 2020 -1900 PRINT "0" -1910 GOTO 2020 -1920 RESTORE -1930 FOR I1=1 TO 18 -1940 READ R -1950 IF R=S THEN 2000 -1960 NEXT I1 -1970 A$="BLACK" -1980 PRINT S;A$ -1990 GOTO 2020 -2000 A$="RED" -2010 GOTO 1980 -2020 PRINT -2030 FOR C=1 TO Y -2040 IF T(C)<37 THEN 2710 -2050 ON T(C)-36 GOTO 2090,2190,2220,2250,2300,2350,2400,2470,2500 -2060 ON T(C)-45 GOTO 2530,2560,2630 -2070 GOTO 2710 -2080 STOP -2090 REM 1-12(37) 2:1 -2100 IF S <= 12 THEN 2150 -2110 PRINT "YOU LOSE";B(C);"DOLLARS ON BET";C -2120 D=D+B(C) -2130 P=P-B(C) -2140 GOTO 2180 -2150 PRINT "YOU WIN";B(C)*2;"DOLLARS ON BET"C -2160 D=D-B(C)*2 -2170 P=P+B(C)*2 -2180 GOTO 2810 -2190 REM 13-24(38) 2:1 -2200 IF S>12 AND S<25 THEN 2150 -2210 GOTO 2110 -2220 REM 25-36(39) 2:1 -2230 IF S>24 AND S<37 THEN 2150 -2240 GOTO 2110 -2250 REM FIRST COLUMN(40) 2:1 -2260 FOR I=1 TO 34 STEP 3 -2270 IF S=I THEN 2150 -2280 NEXT I -2290 GOTO 2110 -2300 REM SECOND COLUMN(41) 2:1 -2310 FOR I=2 TO 35 STEP 3 -2320 IF S=I THEN 2150 -2330 NEXT I -2340 GOTO 2110 -2350 REM THIRD COLUMN(42) 2:1 -2360 FOR I=3 TO 36 STEP 3 -2370 IF S=I THEN 2150 -2380 NEXT I -2390 GOTO 2110 -2400 REM 1-18(43) 1:1 -2410 IF S<19 THEN 2430 -2420 GOTO 2110 -2430 PRINT "YOU WIN";B(C);"DOLLARS ON BET";C -2440 D=D-B(C) -2450 P=P+B(C) -2460 GOTO 2810 -2470 REM 19-36(44) 1:1 -2480 IF S<37 AND S>18 THEN 2430 -2490 GOTO 2110 -2500 REM EVEN(45) 1:1 -2510 IF S/2=INT(S/2) AND S<37 THEN 2430 -2520 GOTO 2110 -2530 REM ODD(46) 1:1 -2540 IF S/2<>INT(S/2) AND S<37 THEN 2430 -2550 GOTO 2110 -2560 REM RED(47) 1:1 -2570 RESTORE -2580 FOR I=1 TO 18 -2590 READ R -2600 IF S=R THEN 2430 -2610 NEXT I -2620 GOTO 2110 -2630 REM BLACK(48) 1:1 -2640 RESTORE -2650 FOR I=1 TO 18 -2660 READ R -2670 IF S=R THEN 2110 -2680 NEXT I -2690 IF S>36 THEN 2110 -2700 GOTO 2430 -2710 REM--1TO36,0,00(1-36,49,50)35:1 -2720 IF T(C)<49 THEN 2760 -2730 IF T(C)=49 AND S=37 THEN 2780 -2740 IF T(C)=50 AND S=38 THEN 2780 -2750 GOTO 2110 -2760 IF T(C)=S THEN 2780 -2770 GOTO 2110 -2780 PRINT "YOU WIN";B(C)*35;"DOLLARS ON BET";C -2790 D=D-B(C)*35 -2800 P=P+B(C)*35 -2810 NEXT C -2820 PRINT -2830 PRINT "TOTALS:","ME","YOU" -2840 PRINT " ",D,P -2850 IF P>0 THEN 2880 -2860 PRINT "OOPS! YOU JUST SPENT YOUR LAST DOLLAR!" -2870 GOTO 3190 -2880 IF D>0 THEN 2920 -2890 PRINT "YOU BROKE THE HOUSE!" -2900 P=101000. -2910 GOTO 2960 -2920 PRINT "AGAIN"; -2930 INPUT Y$ -2940 IF LEFT$(Y$,1)="Y" THEN 1630 -2950 DATA 1,3,5,7,9,12,14,16,18,19,21,23,25,27,30,32,34,36 -2960 IF P<1 THEN 3190 -2970 PRINT "TO WHOM SHALL I MAKE THE CHECK"; -2980 INPUT B$ -2990 PRINT -3000 FOR I=1 TO 72: PRINT "-";: NEXT I: REM PRINT 72 DASHES -3010 PRINT TAB(50);"CHECK NO. ";INT(RND(1)*100) -3020 PRINT -3030 GOSUB 3230 -3040 PRINT TAB(40);M$ -3050 PRINT -3060 PRINT -3070 PRINT "PAY TO THE ORDER OF-----";B$;"-----$ "; -3080 PRINT P -3090 PRINT -3100 PRINT -3110 PRINT TAB(10),"THE MEMORY BANK OF NEW YORK" -3120 PRINT -3130 PRINT TAB(40),"THE COMPUTER" -3140 PRINT TAB(40)"----------X-----" -3150 PRINT -3160 FOR I=1 TO 62: PRINT "-";: NEXT I -3170 PRINT "COME BACK SOON!" -3180 GOTO 3210 -3190 PRINT "THANKS FOR YOUR MONEY." -3200 PRINT "I'LL USE IT TO BUY A SOLID GOLD ROULETTE WHEEL" -3210 PRINT -3220 GOTO 3420 -3230 REM -3240 REM THIS ROUTINE RETURNS THE CURRENT DATE IN M$ -3250 REM IF YOU HAVE SYSTEM FUNCTIONS TO HANDLE THIS -3260 REM THEY CAN BE USED HERE. HOWEVER IN THIS -3270 REM PROGRAM, WE JUST INPUT THE DATE AT THE START -3280 REM THE GAME -3290 REM -3300 REM THE DATE IS RETURNED IN VARIABLE M$ -3310 M$=D$+", "+E$ -3320 RETURN -3420 END diff --git a/00_Alternate_Languages/76_Russian_Roulette/MiniScript/README.md b/00_Alternate_Languages/76_Russian_Roulette/MiniScript/README.md deleted file mode 100644 index 79d028a92..000000000 --- a/00_Alternate_Languages/76_Russian_Roulette/MiniScript/README.md +++ /dev/null @@ -1,21 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -0. Try-It! Page: -Go to https://miniscript.org/tryit/, clear the sample code from the code editor, and paste in the contents of russianroulette.ms. Then click the "Run Script" button. Program output (and input) will appear in the green-on-black terminal display to the right of or below the code editor. - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: -``` - miniscript russianroulette.ms -``` - -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: -``` - load "russianroulette" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/76_Russian_Roulette/MiniScript/russianroulette.ms b/00_Alternate_Languages/76_Russian_Roulette/MiniScript/russianroulette.ms deleted file mode 100644 index 3eb896f94..000000000 --- a/00_Alternate_Languages/76_Russian_Roulette/MiniScript/russianroulette.ms +++ /dev/null @@ -1,37 +0,0 @@ -print " "*28 + "Russian Roulette" -print " "*15 + "Creative Computing Morristown New Jersey" -print; print; print - -print "This is a game of >>>>>>>>>>Russian Roulette." - -while true - print; print "Here is a revolver." - print "Type '1' to spin chamber and pull trigger." - print "Type '2' to give up." - print "GO" - - n = 0 - while n < 10 - inp = input("? ").val - if inp == 2 then - print " CHICKEN!!!!!" - break - else if rnd > 0.833333 then - print " BANG!!!!! You're dead!" - print "Condolences will be sent to your relatives." - break - else - n += 1 - print "- CLICK -" - print - end if - end while - - if n >= 10 then - print "You win!!!!!" - print "Let someone else blow his brains out." - else - print; print; print - print "...Next victim..." - end if -end while diff --git a/00_Alternate_Languages/76_Russian_Roulette/README.md b/00_Alternate_Languages/76_Russian_Roulette/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/76_Russian_Roulette/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/76_Russian_Roulette/russianroulette.bas b/00_Alternate_Languages/76_Russian_Roulette/russianroulette.bas deleted file mode 100644 index 437e53c11..000000000 --- a/00_Alternate_Languages/76_Russian_Roulette/russianroulette.bas +++ /dev/null @@ -1,26 +0,0 @@ -1 PRINT TAB(28);"RUSSIAN ROULETTE" -2 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -3 PRINT:PRINT:PRINT -5 PRINT "THIS IS A GAME OF >>>>>>>>>>RUSSIAN ROULETTE." -10 PRINT:PRINT "HERE IS A REVOLVER." -20 PRINT "TYPE '1' TO SPIN CHAMBER AND PULL TRIGGER." -22 PRINT "TYPE '2' TO GIVE UP." -23 PRINT "GO"; -25 N=0 -30 INPUT I -31 IF I<>2 THEN 35 -32 PRINT " CHICKEN!!!!!" -33 GOTO 72 -35 N=N+1 -40 IF RND(1)>.833333 THEN 70 -45 IF N>10 THEN 80 -50 PRINT "- CLICK -" -60 PRINT: GOTO 30 -70 PRINT " BANG!!!!! YOU'RE DEAD!" -71 PRINT "CONDOLENCES WILL BE SENT TO YOUR RELATIVES." -72 PRINT:PRINT:PRINT -75 PRINT "...NEXT VICTIM...":GOTO 20 -80 PRINT "YOU WIN!!!!!" -85 PRINT "LET SOMEONE ELSE BLOW HIS BRAINS OUT." -90 GOTO 10 -99 END diff --git a/00_Alternate_Languages/77_Salvo/MiniScript/README.md b/00_Alternate_Languages/77_Salvo/MiniScript/README.md deleted file mode 100644 index d31694466..000000000 --- a/00_Alternate_Languages/77_Salvo/MiniScript/README.md +++ /dev/null @@ -1,18 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: -``` - miniscript salvo.ms -``` - -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: -``` - load "salvo" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/77_Salvo/MiniScript/salvo.ms b/00_Alternate_Languages/77_Salvo/MiniScript/salvo.ms deleted file mode 100644 index e7c2796e7..000000000 --- a/00_Alternate_Languages/77_Salvo/MiniScript/salvo.ms +++ /dev/null @@ -1,240 +0,0 @@ -print " "*33 + "Salvo" -print " "*15 + "Creative Computing Morristown New Jersey" -print; print; print - -import "listUtil" - -Ship = {} -Ship.name = "Ship" -Ship.positions = null // list of [x,y] coordinates for this ship -Ship.shots = 1 // how many shots this ship provides -Ship.hitPoints = 1 // how many hits this ship can take before sinking -Ship.make = function(name, shots=1, size=2) - result = new Ship - result.name = name - result.shots = shots - result.positions = [] - result.hitPoints = size - return result -end function - -Board = {} -Board.ships = null // list of Ship instances -Board.splash = null // 2D array of: none, or turn on which it was hit -Board.shipAt = function(xy) - for ship in self.ships - if ship.positions.contains(xy) then return ship - end for -end function -Board.isEmptySpot = function(xy) - return 0 < xy[0] < 11 and 0 < xy[1] < 11 and self.shipAt(xy) == null -end function -Board.make = function - result = new Board - result.ships = [] - result.splash = list.init2d(11, 11) - return result -end function -Board.totalShots = function - sum = 0 - for ship in self.ships - sum += ship.shots - end for - return sum -end function - -computerBoard = Board.make -playerBoard = Board.make - -directions = [[-1,-1], [-1,0], [-1,1], [0,-1], [0,1], [1,-1], [1,0], [1,1]] - -randomPosition = function - return [1 + floor(rnd*10), 1 + floor(rnd*10)] -end function - -inputCoords = function(prompt="?") - while true - inp = input(prompt + "? ").replace(",", " ").replace(" ", " ").split - if inp.len != 2 then - print "Please enter coordinates such as: 5,3" - else - x = inp[0].val - y = inp[1].val - if 0 < x < 11 and 0 < y < 11 then return [x,y] - print "X and Y coordinates must be in the range 1-10." - end if - end while -end function - -inBounds = function(pos) - return 0 < pos[0] < 11 and 0 < pos[1] < 11 -end function - -placeComputerShips = function - placeOne = function(ship) - while true - pos = randomPosition - dir = directions.any - ok = true - p = pos[:] - for i in range(0, ship.hitPoints - 1) - if not computerBoard.isEmptySpot(p) then ok = false - p.add dir - end for - if ok then break - end while - for i in range(0, ship.hitPoints - 1) - ship.positions.push pos[:] - pos.add dir - end for - computerBoard.ships.push ship - end function - placeOne Ship.make("Battleship", 3, 5) - placeOne Ship.make("Cruiser", 2, 3) - placeOne Ship.make("Destroyer", 1, 2) - placeOne Ship.make("Destroyer", 1, 2) -end function - -placePlayerShips = function - placeOne = function(ship) - print ship.name - playerBoard.ships.push ship - // Note: like the original BASIC program, we do no validation on - // the input other than making sure it is in range. So you can - // have a ship scattered all over the map, have ships overlap, etc. - for i in range(1, ship.hitPoints) - ship.positions.push inputCoords - end for - end function - print "Enter coordinates for..." - placeOne Ship.make("Battleship", 3, 5) - placeOne Ship.make("Cruiser", 2, 3) - placeOne Ship.make("Destroyer", 1, 2) - placeOne Ship.make("Destroyer", 1, 2) -end function - -printComputerShips = function - for ship in computerBoard.ships - print ship.name - for pos in ship.positions - print " " + pos.join(" ") - end for - end for -end function - -doPlayerTurn = function(turnNum = 1) - shots = playerBoard.totalShots - print "You have " + shots + " shot" + "s"*(shots!=1) + "." - if shots < 1 then - print "I have won." - exit - end if - hits = [] - for i in range(1, shots) - while true - pos = inputCoords - prevHitOnTurn = computerBoard.splash[pos[0]][pos[1]] - if prevHitOnTurn == null then break - print "You shot there before on turn " + prevHitOnTurn - end while - computerBoard.splash[pos[0]][pos[1]] = turnNum - hit = computerBoard.shipAt(pos) - if hit then hits.push hit - end for - for hit in hits - print "You hit my " + hit.name + "." - hit.hitPoints -= 1 - if hit.hitPoints == 0 then - print "...and sank it!" // (not in original BASIC program) - computerBoard.ships.removeVal hit - end if - end for -end function - -pickShot = function - // Pick a spot for the computer to shoot at. We'll do this by - // computing a "neighbor score" for each spot: the number of - // neighboring spots that (1) we have previously hit, and (2) - // contain an enemy ship. Then we'll pick randomly from the - // set of spots with the highest neighbor score. - bestScore = 0 - spots = [] - for i in range(1,10) - for j in range(1,10) - pos = [i,j] - if playerBoard.splash[pos[0]][pos[1]] then continue - score = 0 - for dir in directions - n = pos.plus(dir) - if inBounds(n) and playerBoard.splash[n[0]][n[1]] and playerBoard.shipAt(n) then - score += 1 - end if - end for - if score > bestScore then - bestScore = score - spots = [pos] - else if score == bestScore then - spots.push pos - end if - end for - end for - return spots.any -end function - -doComputerTurn = function(turnNum = 1) - shots = computerBoard.totalShots - print "I have " + shots + " shot" + "s"*(shots!=1) + "." - if shots < 1 then - print "You have won." - exit - end if - hits = [] - for i in range(1, shots) - pos = pickShot - playerBoard.splash[pos[0]][pos[1]] = turnNum - hit = playerBoard.shipAt(pos) - if hit then hits.push hit - if seeComputerShots then print " " + pos.join(" ") - end for - for hit in hits - print "I hit your " + hit.name + "." - hit.hitPoints -= 1 - if hit.hitPoints == 0 then - print "...and sank it!" // (not in original BASIC program) - playerBoard.ships.removeVal hit - end if - end for -end function - -// Main Program - -placeComputerShips -placePlayerShips -while true - yn = input("Do you want to start? ").lower - if yn == "where are your ships?" then - printComputerShips - else if yn and (yn[0] == "y" or yn[0] == "n") then - break - end if -end while -startWithPlayer = (yn[0] == "y") -while true - yn = input("Do you want to see my shots? ").lower - if yn and (yn[0] == "y" or yn[0] == "n") then break -end while -seeComputerShots = (yn[0] == "y") - -turnNumber = 1 -while true - print - print "Turn " + turnNumber - if startWithPlayer then - doPlayerTurn turnNumber - doComputerTurn turnNumber - else - doComputerTurn turnNumber - doPlayerTurn turnNumber - end if - turnNumber += 1 -end while \ No newline at end of file diff --git a/00_Alternate_Languages/77_Salvo/README.md b/00_Alternate_Languages/77_Salvo/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/77_Salvo/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/77_Salvo/salvo.bas b/00_Alternate_Languages/77_Salvo/salvo.bas deleted file mode 100644 index 6a85d715e..000000000 --- a/00_Alternate_Languages/77_Salvo/salvo.bas +++ /dev/null @@ -1,329 +0,0 @@ -1000 PRINT TAB(33);"SALVO" -1010 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -1020 PRINT:PRINT:PRINT -1030 REM -1040 DIM A(10,10),B(10,10),C(7),D(7),E(12),F(12),G(12),H(12),K(10,10) -1050 Z8=0 -1060 FOR W=1 TO 12 -1070 E(W)=-1 -1080 H(W)=-1 -1090 NEXT W -1100 FOR X=1 TO 10 -1110 FOR Y=1 TO 10 -1120 B(X,Y)=0 -1130 NEXT Y -1140 NEXT X -1150 FOR X=1 TO 12 -1160 F(X)=0 -1170 G(X)=0 -1180 NEXT X -1190 FOR X=1 TO 10 -1200 FOR Y=1 TO 10 -1210 A(X,Y)=0 -1220 NEXT Y -1230 NEXT X -1240 FOR K=4 TO 1 STEP -1 -1250 U6=0 -1260 GOSUB 2910 -1270 DEF FNA(K)=(5-K)*3-2*INT(K/4)+SGN(K-1)-1 -1280 DEF FNB(K)=K+INT(K/4)-SGN(K-1) -1290 IF V+V2+V*V2=0 THEN 1260 -1300 IF Y+V*FNB(K)>10 THEN 1260 -1310 IF Y+V*FNB(K)<1 THEN 1260 -1320 IF X+V2*FNB(K)>10 THEN 1260 -1330 IF X+V2*FNB(K)<1 THEN 1260 -1340 U6=U6+1 -1350 IF U6>25 THEN 1190 -1360 FOR Z=0 TO FNB(K) -1370 F(Z+FNA(K))=X+V2*Z -1380 G(Z+FNA(K))=Y+V*Z -1390 NEXT Z -1400 U8=FNA(K) -1405 IF U8>U8+FNB(K) THEN 1460 -1410 FOR Z2= U8 TO U8+FNB(K) -1415 IF U8<2 THEN 1450 -1420 FOR Z3=1 TO U8-1 -1430 IF SQR((F(Z3)-F(Z2))^2 + (G(Z3)-G(Z2))^2) < 3.59 THEN 1260 -1440 NEXT Z3 -1450 NEXT Z2 -1460 FOR Z=0 TO FNB(K) -1470 A(F(Z+U8),G(Z+U8))=.5+SGN(K-1)*(K-1.5) -1480 NEXT Z -1490 NEXT K -1500 PRINT "ENTER COORDINATES FOR..." -1510 PRINT "BATTLESHIP" -1520 FOR X=1 TO 5 -1530 INPUT Y,Z -1540 B(Y,Z)=3 -1550 NEXT X -1560 PRINT "CRUISER" -1570 FOR X=1 TO 3 -1580 INPUT Y,Z -1590 B(Y,Z)=2 -1600 NEXT X -1610 PRINT "DESTROYER" -1620 FOR X=1 TO 2 -1630 INPUT Y,Z -1640 B(Y,Z)=1 -1650 NEXT X -1660 PRINT "DESTROYER" -1670 FOR X=1 TO 2 -1680 INPUT Y,Z -1690 B(Y,Z)=.5 -1700 NEXT X -1710 PRINT "DO YOU WANT TO START"; -1720 INPUT J$ -1730 IF J$<>"WHERE ARE YOUR SHIPS?" THEN 1890 -1740 PRINT "BATTLESHIP" -1750 FOR Z=1 TO 5 -1760 PRINT F(Z);G(Z) -1770 NEXT Z -1780 PRINT "CRUISER" -1790 PRINT F(6);G(6) -1800 PRINT F(7);G(7) -1810 PRINT F(8);G(8) -1820 PRINT "DESTROYER" -1830 PRINT F(9);G(9) -1840 PRINT F(10);G(10) -1850 PRINT "DESTROYER" -1860 PRINT F(11);G(11) -1870 PRINT F(12);G(12) -1880 GOTO 1710 -1890 C=0 -1900 PRINT "DO YOU WANT TO SEE MY SHOTS"; -1910 INPUT K$ -1920 PRINT -1930 IF J$<>"YES" THEN 2620 -1940 REM*******************START -1950 IF J$<>"YES" THEN 1990 -1960 C=C+1 -1970 PRINT -1980 PRINT "TURN";C -1990 A=0 -2000 FOR W=.5 TO 3 STEP .5 -2010 FOR X=1 TO 10 -2020 FOR Y=1 TO 10 -2030 IF B(X,Y)=W THEN 2070 -2040 NEXT Y -2050 NEXT X -2060 GOTO 2080 -2070 A=A+INT(W+.5) -2080 NEXT W -2090 FOR W=1 TO 7 -2100 C(W)=0 -2110 D(W)=0 -2120 F(W)=0 -2130 G(W)=0 -2140 NEXT W -2150 P3=0 -2160 FOR X=1 TO 10 -2170 FOR Y=1 TO 10 -2180 IF A(X,Y)>10 THEN 2200 -2190 P3=P3+1 -2200 NEXT Y -2210 NEXT X -2220 PRINT "YOU HAVE";A;"SHOTS." -2230 IF P3>=A THEN 2260 -2240 PRINT "YOU HAVE MORE SHOTS THAN THERE ARE BLANK SQUARES." -2250 GOTO 2890 -2260 IF A<>0 THEN 2290 -2270 PRINT "I HAVE WON." -2280 STOP -2290 FOR W=1 TO A -2300 INPUT X,Y -2310 IF X<>INT(X) THEN 2370 -2320 IF X>10 THEN 2370 -2330 IF X<1 THEN 2370 -2340 IF Y<>INT(Y) THEN 2370 -2350 IF Y>10 THEN 2370 -2360 IF Y>=1 THEN 2390 -2370 PRINT "ILLEGAL, ENTER AGAIN." -2380 GOTO 2300 -2390 IF A(X,Y)>10 THEN 2440 -2400 C(W)=X -2410 D(W)=Y -2420 NEXT W -2430 GOTO 2460 -2440 PRINT "YOU SHOT THERE BEFORE ON TURN";A(X,Y)-10 -2450 GOTO 2300 -2460 FOR W=1 TO A -2470 IF A(C(W),D(W))=3 THEN 2540 -2480 IF A(C(W),D(W))=2 THEN 2560 -2490 IF A(C(W),D(W))=1 THEN 2580 -2500 IF A(C(W),D(W))=.5 THEN 2600 -2510 A(C(W),D(W))=10+C -2520 NEXT W -2530 GOTO 2620 -2540 PRINT "YOU HIT MY BATTLESHIP." -2550 GOTO 2510 -2560 PRINT "YOU HIT MY CRUISER." -2570 GOTO 2510 -2580 PRINT "YOU HIT MY DESTROYER." -2590 GOTO 2510 -2600 PRINT "YOU HIT MY DESTROYER." -2610 GOTO 2510 -2620 A=0 -2630 IF J$="YES" THEN 2670 -2640 C=C+1 -2650 PRINT -2660 PRINT "TURN";C -2670 A=0 -2680 FOR W=.5 TO 3 STEP .5 -2690 FOR X=1 TO 10 -2700 FOR Y=1 TO 10 -2710 IF A(X,Y)=W THEN 2750 -2720 NEXT Y -2730 NEXT X -2740 GOTO 2760 -2750 A=A+INT(W+.5) -2760 NEXT W -2770 P3=0 -2780 FOR X=1 TO 10 -2790 FOR Y=1 TO 10 -2800 IF A(X,Y)>10 THEN 2820 -2810 P3=P3+1 -2820 NEXT Y -2830 NEXT X -2840 PRINT "I HAVE";A;"SHOTS." -2850 IF P3>A THEN 2880 -2860 PRINT "I HAVE MORE SHOTS THAN BLANK SQUARES." -2870 GOTO 2270 -2880 IF A<>0 THEN 2960 -2890 PRINT "YOU HAVE WON." -2900 STOP -2910 X=INT(RND(1)*10+1) -2920 Y=INT(RND(1)*10+1) -2930 V=INT(3*RND(1)-1) -2940 V2=INT(3*RND(1)-1) -2950 RETURN -2960 FOR W=1 TO 12 -2970 IF H(W)>0 THEN 3800 -2980 NEXT W -2990 REM*******************RANDOM -3000 W=0 -3010 R3=0 -3020 GOSUB 2910 -3030 RESTORE -3040 R2=0 -3050 R3=R3+1 -3060 IF R3>100 THEN 3010 -3070 IF X>10 THEN 3110 -3080 IF X>0 THEN 3120 -3090 X=1+INT(RND(1)*2.5) -3100 GOTO 3120 -3110 X=10-INT(RND(1)*2.5) -3120 IF Y>10 THEN 3160 -3130 IF Y>0 THEN 3270 -3140 Y=1+INT(RND(1)*2.5) -3150 GOTO 3270 -3160 Y=10-INT(RND(1)*2.5) -3170 GOTO 3270 -3180 F(W)=X -3190 G(W)=Y -3200 IF W=A THEN 3380 -3210 IF R2=6 THEN 3030 -3220 READ X1,Y1 -3230 R2=R2+1 -3240 DATA 1,1,-1,1,1,-3,1,1,0,2,-1,1 -3250 X=X+X1 -3260 Y=Y+Y1 -3270 IF X>10 THEN 3210 -3280 IF X<1 THEN 3210 -3290 IF Y>10 THEN 3210 -3300 IF Y<1 THEN 3210 -3310 IF B(X,Y)>10 THEN 3210 -3320 FOR Q9=1 TO W -3330 IF F(Q9)<>X THEN 3350 -3340 IF G(Q9)=Y THEN 3210 -3350 NEXT Q9 -3360 W=W+1 -3370 GOTO 3180 -3380 IF K$<>"YES" THEN 3420 -3390 FOR Z5=1 TO A -3400 PRINT F(Z5);G(Z5) -3410 NEXT Z5 -3420 FOR W=1 TO A -3430 IF B(F(W),G(W))=3 THEN 3500 -3440 IF B(F(W),G(W))=2 THEN 3520 -3450 IF B(F(W),G(W))=1 THEN 3560 -3460 IF B(F(W),G(W))=.5 THEN 3540 -3470 B(F(W),G(W))=10+C -3480 NEXT W -3490 GOTO 1950 -3500 PRINT "I HIT YOUR BATTLESHIP" -3510 GOTO 3570 -3520 PRINT "I HIT YOUR CRUISER" -3530 GOTO 3570 -3540 PRINT "I HIT YOUR DESTROYER" -3550 GOTO 3570 -3560 PRINT "I HIT YOUR DESTROYER" -3570 FOR Q=1 TO 12 -3580 IF E(Q)<>-1 THEN 3730 -3590 E(Q)=10+C -3600 H(Q)=B(F(W),G(W)) -3610 M3=0 -3620 FOR M2=1 TO 12 -3630 IF H(M2)<>H(Q) THEN 3650 -3640 M3=M3+1 -3650 NEXT M2 -3660 IF M3<>INT(H(Q)+.5)+1+INT(INT(H(Q)+.5)/3) THEN 3470 -3670 FOR M2=1 TO 12 -3680 IF H(M2)<>H(Q) THEN 3710 -3690 E(M2)=-1 -3700 H(M2)=-1 -3710 NEXT M2 -3720 GOTO 3470 -3730 NEXT Q -3740 PRINT "PROGRAM ABORT:" -3750 FOR Q=1 TO 12 -3760 PRINT "E(";Q;") =";E(Q) -3770 PRINT "H(";Q;") =";H(Q) -3780 NEXT Q -3790 STOP -3800 REM************************USINGEARRAY -3810 FOR R=1 TO 10 -3820 FOR S=1 TO 10 -3830 K(R,S)=0 -3840 NEXT S -3850 NEXT R -3860 FOR U=1 TO 12 -3870 IF E(U)<10 THEN 4020 -3880 FOR R=1 TO 10 -3890 FOR S=1 TO 10 -3900 IF B(R,S)<10 THEN 3930 -3910 K(R,S)=-10000000 -3920 GOTO 4000 -3930 FOR M=SGN(1-R) TO SGN(10-R) -3940 FOR N=SGN(1-S) TO SGN(10-S) -3950 IF N+M+N*M=0 THEN 3980 -3960 IF B(R+M,S+N)<>E(U) THEN 3980 -3970 K(R,S)=K(R,S)+E(U)-S*INT(H(U)+.5) -3980 NEXT N -3990 NEXT M -4000 NEXT S -4010 NEXT R -4020 NEXT U -4030 FOR R=1 TO A -4040 F(R)=R -4050 G(R)=R -4060 NEXT R -4070 FOR R=1 TO 10 -4080 FOR S=1 TO 10 -4090 Q9=1 -4100 FOR M=1 TO A -4110 IF K(F(M),G(M))>=K(F(Q9),G(Q9)) THEN 4130 -4120 Q9=M -4130 NEXT M -4131 IF R>A THEN 4140 -4132 IF R=S THEN 4210 -4140 IF K(R,S)R THEN 4190 -4170 IF G(M)=S THEN 4210 -4180 NEXT M -4190 F(Q9)=R -4200 G(Q9)=S -4210 NEXT S -4220 NEXT R -4230 GOTO 3380 -4240 END diff --git a/00_Alternate_Languages/78_Sine_Wave/C++/README.md b/00_Alternate_Languages/78_Sine_Wave/C++/README.md deleted file mode 100644 index b62763ffe..000000000 --- a/00_Alternate_Languages/78_Sine_Wave/C++/README.md +++ /dev/null @@ -1,3 +0,0 @@ -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) - -Conversion to [C++17](https://en.wikipedia.org/wiki/C%2B%2B17) \ No newline at end of file diff --git a/00_Alternate_Languages/78_Sine_Wave/C++/sinewave.cpp b/00_Alternate_Languages/78_Sine_Wave/C++/sinewave.cpp deleted file mode 100644 index 9d274e566..000000000 --- a/00_Alternate_Languages/78_Sine_Wave/C++/sinewave.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include // std::cout, std::endl -#include // std::string(size_t n, char c) -#include // std::sin(double x) - -int main() -{ - std::cout << std::string(30, ' ') << "SINE WAVE" << std::endl; - std::cout << std::string(15, ' ') << "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" << std::endl; - std::cout << std::string(5, '\n'); - - bool b = true; - - for (double t = 0.0; t <= 40.0; t += 0.25) - { - int a = int(26 + 25 * std::sin(t)); - std::cout << std::string(a, ' ') << (b ? "CREATIVE" : "COMPUTING") << std::endl; - b = !b; - } - - return 0; -} diff --git a/00_Alternate_Languages/78_Sine_Wave/MiniScript/README.md b/00_Alternate_Languages/78_Sine_Wave/MiniScript/README.md deleted file mode 100644 index a17e5cf14..000000000 --- a/00_Alternate_Languages/78_Sine_Wave/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript sinewave.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "sinewave" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/78_Sine_Wave/MiniScript/sinewave.ms b/00_Alternate_Languages/78_Sine_Wave/MiniScript/sinewave.ms deleted file mode 100644 index da3e99a77..000000000 --- a/00_Alternate_Languages/78_Sine_Wave/MiniScript/sinewave.ms +++ /dev/null @@ -1,15 +0,0 @@ -print " "*30 + "SINE WAVE" -print " "*15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -print; print; print; print; print -// Remarkable program by David Ahl, ported -// from BASIC to MiniScript by Joe Strout - -B = 0 -// start long loop -for t in range(0, 40, 0.25) - A = floor(26 + 25*sin(t)) - print " "*A, "" - if not B then print "CREATIVE" else print "COMPUTING" - B = not B - wait 0.01 -end for diff --git a/00_Alternate_Languages/78_Sine_Wave/README.md b/00_Alternate_Languages/78_Sine_Wave/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/78_Sine_Wave/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/78_Sine_Wave/pascal/sinewave.pas b/00_Alternate_Languages/78_Sine_Wave/pascal/sinewave.pas deleted file mode 100644 index db82189f2..000000000 --- a/00_Alternate_Languages/78_Sine_Wave/pascal/sinewave.pas +++ /dev/null @@ -1,35 +0,0 @@ -program sinewave; - -procedure tabWriteLn(text: string; indent: integer); -begin - Writeln(text:length(text)+indent); -end; - -var - a, t, b: integer; -begin - tabWriteLn('SINE WAVE', 30); - tabWriteLn('CREATIVE COMPUTING MORRISTOWN, NEW JERSEY', 15); - Writeln(); - Writeln(); - Writeln(); - Writeln(); - Writeln(); - // REMARKABLE PROGRAM BY DAVID AHL - b := 0; - // START LONG LOOP - for t := 0 to 40*4 do - begin - a := Trunc(26+25*Sin(t/4)); - if (b = 0) then - begin - tabWriteLn('CREATIVE', a); - b := 1; - end - else - begin - tabWriteLn('COMPUTING', a); - b := 0; - end; - end; -end. diff --git a/00_Alternate_Languages/78_Sine_Wave/sinewave.bas b/00_Alternate_Languages/78_Sine_Wave/sinewave.bas deleted file mode 100644 index 0e362acd4..000000000 --- a/00_Alternate_Languages/78_Sine_Wave/sinewave.bas +++ /dev/null @@ -1,17 +0,0 @@ -10 PRINT TAB(30);"SINE WAVE" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT: PRINT: PRINT: PRINT: PRINT -40 REMARKABLE PROGRAM BY DAVID AHL -50 B=0 -100 REM START LONG LOOP -110 FOR T=0 TO 40 STEP .25 -120 A=INT(26+25*SIN(T)) -130 PRINT TAB(A); -140 IF B=1 THEN 180 -150 PRINT "CREATIVE" -160 B=1 -170 GOTO 200 -180 PRINT "COMPUTING" -190 B=0 -200 NEXT T -999 END diff --git a/00_Alternate_Languages/79_Slalom/MiniScript/README.md b/00_Alternate_Languages/79_Slalom/MiniScript/README.md deleted file mode 100644 index c954f090c..000000000 --- a/00_Alternate_Languages/79_Slalom/MiniScript/README.md +++ /dev/null @@ -1,18 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: -``` - miniscript slalom.ms -``` - -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: -``` - load "slalom" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/79_Slalom/MiniScript/slalom.ms b/00_Alternate_Languages/79_Slalom/MiniScript/slalom.ms deleted file mode 100644 index 41bb0b829..000000000 --- a/00_Alternate_Languages/79_Slalom/MiniScript/slalom.ms +++ /dev/null @@ -1,170 +0,0 @@ -print " "*33 + "Slalom" -print " "*15 + "Creative Computing Morristown New Jersey" -print; print; print - -gateSpeeds = [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] - -medals = {} -medals.gold = 0 -medals.silver = 0 -medals.bronze = 0 - -while true - qtyGates = input("How many gates does this course have (1 to 25)? ").val - if qtyGates > 25 then - print "25 is the limit." - qtyGates = 25 - end if - if qtyGates >= 1 then break - print "Try again," -end while - -print "Type ""ins"" for instructions" -print "Type ""max"" for approximate maximum speeds" -print "Type ""run"" for the beginning of the race" -while true - cmd = input("Command--").lower - if cmd == "ins" then - print - print "*** Slalom: This is the 1976 Winter Olympic Giant Slalom. You are" - print " the American team's only hope of a gold medal." - print - 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." - print - print " The place to use these options is when the computer asks:" - print - print "Option?" - print - print " Good luck!" - print - else if cmd == "max" then - print "GATE MAX" - print " # M.P.H." - print "-----------" - for i in range(1, qtyGates) - print " " + i + " "*(i<10) + " " + gateSpeeds[i-1] - end for - else if cmd == "run" then - break - end if -end while - -while true - skill = input("Rate yourself as a skier, (1=worst, 3=best)? ").val - if 1 <= skill <= 3 then break - print "The bounds are 1-3" -end while - -doOneRace = function - print "The starter counts down...5...4...3...2...1..GO!" - time = 0 - speed = floor(rnd * 9 + 9) - print - print "You're off!" - gate = 0 - while gate+1 <= qtyGates - gate += 1 - gateSpeed = gateSpeeds[(gate-1) % gateSpeeds.len] - print - print "Here comes gate #" + gate + ":" - print speed + " M.P.H." - prevSpeed = speed - while true - opt = input("Option? ").val - if opt == 0 then - print "You've taken " + time + " seconds." - else if opt < 1 or opt > 8 then - print "What?" - else - break - end if - end while - if opt == 1 then - speed += floor(rnd*(10-5)+5) - else if opt == 2 then - speed += floor(rnd*(5-3)+3) - else if opt == 3 then - speed += floor(rnd*(4-1)+1) - else if opt == 4 then - // (no change) - else if opt == 5 then - speed -= floor(rnd*(4-1)+1) - else if opt == 6 then - speed -= floor(rnd*(5-3)+3) - else if opt == 7 then - speed -= floor(rnd*(10-5)+5) - else if opt == 8 then - print "***CHEAT" - if rnd < 0.7 then - print "An official caught you!" - print "You took " + round(time+rnd, 3) + " seconds." - break - else - print "You made it!" + char(7) - time += 1.5 - continue - end if - end if - print speed + " M.P.H." - if speed > gateSpeed then - if rnd < (speed - gateSpeed)*0.1 + 0.2 then - msg = "You went over the maximum speed and " - if rnd < 0.5 then msg += "snagged a flag!" else msg += "wiped out!" - print msg - print "You took " + round(time+rnd, 3) + " seconds." - else - print "You went over the maximum speed and made it!" - end if - else if speed > gateSpeed - 1 then - print "Close one!" - end if - if speed < 7 then - print "Let's be realistic, OK? Let's go back and try again..." - speed = prevSpeed - gate -= 1 - continue - end if - time += gateSpeed - speed + 1 - if speed > gateSpeed then time += 0.5 - end while - - print - print "You took " + round(time+rnd, 3) + " seconds." - avg = time / qtyGates - if avg < 1.5 - (skill * 0.1) then - print "You won a gold medal!" - medals.gold += 1 - else if avg < 2.9 - (skill * 0.1) then - print "You won a silver medal" - medals.silver += 1 - else if avg < 4.4 - (skill * 0.01) then - print "You won a bronze medal" - medals.bronze += 1 - end if -end function - -while true - doOneRace - while true - yesno = input("Do you want to race again? ").lower + " " - if yesno[0] == "y" or yesno[0] == "n" then break - print "Please type 'yes' or 'no'" - end while - if yesno[0] == "n" then break - print -end while - -print -print "Thanks for the race" -if medals.gold then print "Gold medals: " + medals.gold -if medals.silver then print "Silver medals: " + medals.silver -if medals.bronze then print "Bronze medals: " + medals.bronze diff --git a/00_Alternate_Languages/79_Slalom/README.md b/00_Alternate_Languages/79_Slalom/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/79_Slalom/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/79_Slalom/slalom.bas b/00_Alternate_Languages/79_Slalom/slalom.bas deleted file mode 100644 index 47c6d8010..000000000 --- a/00_Alternate_Languages/79_Slalom/slalom.bas +++ /dev/null @@ -1,165 +0,0 @@ -10 PRINT TAB(33);"SLALOM" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT:PRINT:PRINT -310 PRINT "HOW MANY GATES DOES THIS COURSE HAVE (1 TO 25)"; -320 INPUT V -330 IF V>25 THEN 360 -340 IF V<1 THEN 390 -350 GOTO 1440 -360 PRINT "25 IS THE LIMIT." -370 LET V=25 -380 GOTO 1440 -390 PRINT "TRY AGAIN," -400 GOTO 310 -410 PRINT "RATE YOURSELF AS A SKIER, (1=WORST, 3=BEST)"; -420 INPUT A -430 IF A<1 THEN 460 -440 IF A>3 THEN 460 -450 GOTO 480 -460 PRINT "THE BOUNDS ARE 1-3" -470 GOTO 410 -480 PRINT"THE STARTER COUNTS DOWN...5...4...3...2...1...GO!"; -490 REM -500 LET T=0 -510 LET S=INT(RND(1)*(18-9)+9) -520 PRINT -525 PRINT "YOU'RE OFF!" -530 FOR O=1 TO V -540 READ Q -550 PRINT -555 PRINT "HERE COMES GATE #";STR$(O);":" -560 PRINT S;"M.P.H." -570 LET S1=S -580 PRINT "OPTION"; -590 INPUT O1 -600 IF O1=0 THEN 970 -610 IF O1>8 THEN 1420 -620 IF O1<1 THEN 1420 -630 GOSUB 990 -640 IF S<7 THEN 1390 -650 LET T=T+(Q-S+1) -660 IF S>Q THEN 1630 -670 NEXT O -680 PRINT:PRINT "YOU TOOK";(T+RND(1));"SECONDS." -690 LET M=T -700 LET M=M/V -710 IF M<1.5-(A*.1) THEN 1650 -720 IF M<2.9-(A*.1) THEN 1680 -730 IF M<4.4-(A*.01) THEN 1710 -740 PRINT:PRINT "DO YOU WANT TO RACE AGAIN"; -750 INPUT B$ -760 REM -770 IF B$="NO" THEN 1740 -780 IF B$="YES" THEN 480 -790 PRINT "PLEASE TYPE 'YES' OR 'NO'" -800 GOTO 740 -810 STOP -820 PRINT -825 PRINT "*** SLALOM: THIS IS THE 1976 WINTER OLYMPIC GIANT SLALOM. YOU ARE" -830 PRINT " THE AMERICAN TEAM'S ONLY HOPE OF A GOLD MEDAL." -840 PRINT -845 PRINT " 0 -- TYPE THIS IF YOU WANT TO SEE HOW LONG YOU'VE TAKEN." -850 PRINT " 1 -- TYPE THIS IF YOU WANT TO SPEED UP A LOT." -860 PRINT " 2 -- TYPE THIS IF YOU WANT TO SPEED UP A LITTLE." -870 PRINT " 3 -- TYPE THIS IF YOU WANT TO SPEED UP A TEENSY." -880 PRINT " 4 -- TYPE THIS IF YOU WANT TO KEEP GOING THE SAME SPEED." -890 PRINT " 5 -- TYPE THIS IF YOU WANT TO CHECK A TEENSY." -900 PRINT " 6 -- TYPE THIS IF YOU WANT TO CHECK A LITTLE." -910 PRINT " 7 -- TYPE THIS IF YOU WANT TO CHECK A LOT." -920 PRINT " 8 -- TYPE THIS IF YOU WANT TO CHEAT AND TRY TO SKIP A GATE." -930 PRINT -935 PRINT " THE PLACE TO USE THESE OPTIONS IS WHEN THE COMPUTER ASKS:" -940 PRINT -945 PRINT "OPTION?" -950 PRINT -955 PRINT " GOOD LUCK!" -957 PRINT -960 GOTO 1470 -970 PRINT "YOU'VE TAKEN";(T+RND(1));"SECONDS." -980 GOTO 580 -990 ON O1 GOTO 1130,1010,1170,1080,1190,1100,1150,1210 -1000 STOP -1010 LET S=S+INT(RND(1)*(5-3)+3) -1020 PRINT S;"M.P.H." -1030 IF S>Q THEN 1290 -1040 IF S>Q-1 THEN 1060 -1050 RETURN -1060 PRINT "CLOSE ONE!" -1070 RETURN -1080 PRINT S;"M.P.H." -1090 GOTO 1030 -1100 LET S=S-INT(RND(1)*(5-3)+3) -1110 PRINT S;"M.P.H." -1120 GOTO 1030 -1130 LET S=S+INT(RND(1)*(10-5)+5) -1140 GOTO 1080 -1150 LET S=S-INT(RND(1)*(10-5)+5) -1160 GOTO 1110 -1170 LET S=S+INT(RND(1)*(4-1)+1) -1180 GOTO 1110 -1190 LET S=S-INT(RND(1)*(4-1)+1) -1200 GOTO 1110 -1210 PRINT "***CHEAT" -1220 IF RND(1)<.7 THEN 1260 -1230 PRINT "YOU MADE IT!" -1240 LET T=T+1.5 -1250 RETURN -1260 PRINT "AN OFFICIAL CAUGHT YOU!" -1270 PRINT "YOU TOOK";(T+RND(1));"SECONDS." -1280 GOTO 740 -1290 IF RND(1)<((S-Q)*.1)+.2 THEN 1320 -1300 PRINT "YOU WENT OVER THE NAXIMUM SPEED AND MADE IT!" -1310 RETURN -1320 PRINT "YOU WENT OVER THE MAXIMUM SPEED AND "; -1330 IF RND(1)<.5 THEN 1370 -1340 PRINT "WIPED OUT!" -1350 PRINT "YOU TOOK";(T+RND(1));"SECONDS" -1360 GOTO 740 -1370 PRINT "SNAGGED A FLAG!" -1380 GOTO 1350 -1390 PRINT "LET'S BE REALISTIC, OK? LET'S GO BACK AND TRY AGAIN..." -1400 LET S=S1 -1410 GOTO 550 -1420 PRINT "WHAT?" -1430 GOTO 580 -1440 PRINT -1445 PRINT "TYPE ";CHR$(34);"INS";CHR$(34);" FOR INSTRUCTIONS" -1450 PRINT "TYPE ";CHR$(34);"MAX";CHR$(34);" FOR APPROXIMATE MAXIMUM SPEEDS" -1460 PRINT "TYPE ";CHR$(34);"RUN";CHR$(34);" FOR THE BEGINNING OF THE RACE" -1470 PRINT "COMMAND--"; -1480 INPUT A$ -1490 REM -1500 IF A$="INS" THEN 820 -1510 IF A$="MAX" THEN 1550 -1520 IF A$="RUN" THEN 410 -1530 PRINT CHR$(34);A$;CHR$(34);" IS AN ILLEGAL COMMAND--RETRY"; -1540 GOTO 1480 -1550 PRINT "GATE MAX" -1560 PRINT " # M.P.H." -1570 PRINT"----------" -1580 FOR B=1 TO V -1590 READ Q -1600 PRINT B;" ";Q -1610 NEXT B -1620 GOTO 1470 -1630 LET T=T+.5 -1640 GOTO 670 -1650 PRINT "YOU WON A GOLD MEDAL!" -1660 LET G(1)=G(1)+1 -1670 GOTO 1730 -1680 PRINT "YOU WON A SILVER MEDAL" -1690 LET S(1)=S(1)+1 -1700 GOTO 1730 -1710 PRINT "YOU WON A BRONZE MEDAL" -1720 LET B(1)=B(1)+1 -1730 GOTO 740 -1740 PRINT "THANKS FOR THE RACE" -1750 IF G(1)<1 THEN 1770 -1760 PRINT "GOLD MEDALS:";G(1) -1770 IF S(1)<1 THEN 1790 -1780 PRINT "SILVER MEDALS:";S(1) -1790 IF B(1)<1 THEN 1830 -1800 PRINT "BRONZE MEDALS:";B(1) -1810 DATA 14,18,26,29,18,25,28,32,29,20,29,29,25,21,26,29,20,21,20 -1820 DATA 18,26,25,33,31,22 -1830 END diff --git a/00_Alternate_Languages/80_Slots/MiniScript/README.md b/00_Alternate_Languages/80_Slots/MiniScript/README.md deleted file mode 100644 index a8b56b3d6..000000000 --- a/00_Alternate_Languages/80_Slots/MiniScript/README.md +++ /dev/null @@ -1,18 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: -``` - miniscript slots.ms -``` - -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: -``` - load "slots" - run -``` diff --git a/00_Alternate_Languages/80_Slots/MiniScript/slots.ms b/00_Alternate_Languages/80_Slots/MiniScript/slots.ms deleted file mode 100644 index 310ff95e7..000000000 --- a/00_Alternate_Languages/80_Slots/MiniScript/slots.ms +++ /dev/null @@ -1,108 +0,0 @@ -print " "*30 + "Slots" -print " "*15 + "Creative Computing Morristown New Jersey" -print; print; print - -// PRODUCED BY FRED MIRABELLE AND BOB HARPER ON JAN 29, 1973 -// IT SIMULATES THE SLOT MACHINE. -// (Ported to MiniScript by Joe Strout on Oct 04, 2023) - -print "You are in the H&M casino,in front of one of our" -print "one-arm bandits. Bet from $1 to $100." -print "To pull the arm, punch the return key after making your bet." - -symbols = ["BAR", "BELL", "ORANGE", "LEMON", "PLUM", "CHERRY"] - - -winTriple = function(symbol, bet) - if symbol == "BAR" then - print "***JACKPOT***" - globals.profit += 101 * bet - else - print "**TOP DOLLAR**" - globals.profit += 11 * bet - end if - print "You won!" -end function - -winDouble = function(symbol, bet) - if symbol == "BAR" then - print "*DOUBLE BAR*" - globals.profit += 6 * bet - else - print "Double!" - globals.profit += 3 * bet - end if - print "You won!" -end function - -lose = function(bet) - print "You lost." - globals.profit -= bet -end function - -calcWinLoss = function(spun, bet) - if spun[0] == spun[1] then - if spun[0] == spun[2] then - winTriple spun[0], bet - else - winDouble spun[0], bet - end if - else if spun[0] == spun[2] then - winDouble spun[0], bet - else if spun[1] == spun[2] then - winDouble spun[1], bet - else - lose bet - end if -end function - -ringBells = function(qty=5) - // I believe all the obnoxious beeping was to slow down the game - // and build suspense as each "wheel" appears. Our version: - wait 0.1 - for i in range(1, qty) - print char(7), "" - wait 0.05 - end for -end function - -// Main program -profit = 0 -while true - print - - // Get bet - while true - bet = input("Your bet? ").val - if 1 <= bet <= 100 then break - if bet < 1 then print "Minimum bet is $1" else print "House limits are $100" - end while - - // Spin 3 wheels (randomly picking a symbol for each one) - spun = [] - spun.push symbols[rnd * symbols.len] - spun.push symbols[rnd * symbols.len] - spun.push symbols[rnd * symbols.len] - print - ringBells 10; print spun[0], " " - ringBells 5; print spun[1], " " - ringBells 5; print spun[2] - print - - // Calculate and display win/loss - wait 0.5 - calcWinLoss spun, bet - - // Show new state, and maybe play again - print "Your standings are $ " + profit - yn = input("Again? ").lower + " " - if yn[0] != "y" then break -end while - -if profit == 0 then - print "Hey, you broke even." -else if profit > 0 then - print "Collect your winnings from the H&M cashier." -else - print "Pay up! Please leave your money on the terminal." -end if diff --git a/00_Alternate_Languages/80_Slots/README.md b/00_Alternate_Languages/80_Slots/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/80_Slots/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/80_Slots/slots.bas b/00_Alternate_Languages/80_Slots/slots.bas deleted file mode 100644 index ef7ed841d..000000000 --- a/00_Alternate_Languages/80_Slots/slots.bas +++ /dev/null @@ -1,134 +0,0 @@ -10 PRINT TAB(30);"SLOTS" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT: PRINT: PRINT -100 REM PRODUCED BY FRED MIRABELLE AND BOB HARPER ON JAN 29, 1973 -110 REM IT SIMULATES THE SLOT MACHINE. -120 PRINT "YOU ARE IN THE H&M CASINO,IN FRONT OF ONE OF OUR" -130 PRINT "ONE-ARM BANDITS. BET FROM $1 TO $100." -140 PRINT "TO PULL THE ARM, PUNCH THE RETURN KEY AFTER MAKING YOUR BET." -150 LET P=0 -160 PRINT: PRINT"YOUR BET"; -170 INPUT M -180 IF M>100 THEN 860 -190 IF M<1 THEN 880 -200 M=INT(M) -210 GOSUB 1270 -220 PRINT -230 LET X=INT(6*RND(1)+1) -240 LET Y=INT(6*RND(1)+1) -250 LET Z=INT(6*RND(1)+1) -260 PRINT -270 IF X=1 THEN 910 -280 IF X=2 THEN 930 -290 IF X=3 THEN 950 -300 IF X=4 THEN 970 -310 IF X=5 THEN 990 -320 IF X=6 THEN 1010 -330 IF Y=1 THEN 1030 -340 IF Y=2 THEN 1050 -350 IF Y=3 THEN 1070 -360 IF Y=4 THEN 1090 -370 IF Y=5 THEN 1110 -380 IF Y=6 THEN 1130 -390 IF Z=1 THEN 1150 -400 IF Z=2 THEN 1170 -410 IF Z=3 THEN 1190 -420 IF Z=4 THEN 1210 -430 IF Z=5 THEN 1230 -440 IF Z=6 THEN 1250 -450 IF X=Y THEN 600 -460 IF X=Z THEN 630 -470 IF Y=Z THEN 650 -480 PRINT -490 PRINT "YOU LOST." -500 LET P=P-M -510 PRINT "YOUR STANDINGS ARE $"P -520 PRINT "AGAIN"; -530 INPUT A$ -540 IF A$="Y" THEN 160 -550 PRINT -560 IF P<0 THEN 670 -570 IF P=0 THEN 690 -580 IF P>0 THEN 710 -590 GOTO 1350 -600 IF Y=Z THEN 730 -610 IF Y=1 THEN 820 -620 GOTO 1341 -630 IF Z=1 THEN 820 -640 GOTO 470 -650 IF Z=1 THEN 820 -660 GOTO 1341 -670 PRINT "PAY UP! PLEASE LEAVE YOUR MONEY ON THE TERMINAL." -680 GOTO 1350 -690 PRINT"HEY, YOU BROKE EVEN." -700 GOTO 1350 -710 PRINT "COLLECT YOUR WINNINGS FROM THE H&M CASHIER." -720 GOTO 1350 -730 IF Z=1 THEN 780 -740 PRINT: PRINT"**TOP DOLLAR**" -750 PRINT "YOU WON!" -760 P=(((10*M)+M)+P) -770 GOTO 510 -780 PRINT:PRINT"***JACKPOT***" -790 PRINT "YOU WON!" -800 P=(((100*M)+M)+P) -810 GOTO 510 -820 PRINT:PRINT"*DOUBLE BAR*" -830 PRINT"YOU WON!" -840 P=(((5*M)+M)+P) -850 GOTO 510 -860 PRINT"HOUSE LIMITS ARE $100" -870 GOTO 160 -880 PRINT"MINIMUM BET IS $1" -890 GOTO 160 -900 GOTO 220 -910 PRINT"BAR";:GOSUB 1310 -920 GOTO 330 -930 PRINT"BELL";:GOSUB 1310 -940 GOTO 330 -950 PRINT"ORANGE";:GOSUB 1310 -960 GOTO 330 -970 PRINT"LEMON";:GOSUB 1310 -980 GOTO 330 -990 PRINT"PLUM";:GOSUB 1310 -1000 GOTO 330 -1010 PRINT"CHERRY";:GOSUB 1310 -1020 GOTO 330 -1030 PRINT" BAR";:GOSUB 1310 -1040 GOTO 390 -1050 PRINT" BELL";:GOSUB 1310 -1060 GOTO 390 -1070 PRINT" ORANGE";:GOSUB 1310 -1080 GOTO 390 -1090 PRINT" LEMON";:GOSUB 1310 -1100 GOTO 390 -1110 PRINT" PLUM";:GOSUB 1310 -1120 GOTO 390 -1130 PRINT" CHERRY";:GOSUB 1310 -1140 GOTO 390 -1150 PRINT" BAR" -1160 GOTO 450 -1170 PRINT" BELL" -1180 GOTO 450 -1190 PRINT" ORANGE" -1200 GOTO 450 -1210 PRINT" LEMON" -1220 GOTO 450 -1230 PRINT" PLUM" -1240 GOTO 450 -1250 PRINT" CHERRY" -1260 GOTO 450 -1270 FOR Q4=1 TO 10 -1280 PRINT CHR$(7); -1290 NEXT Q4 -1300 RETURN -1310 FOR T8=1 TO 5 -1320 PRINT CHR$(7); -1330 NEXT T8 -1340 RETURN -1341 PRINT: PRINT "DOUBLE!!" -1342 PRINT"YOU WON!" -1343 P=(((2*M)+M)+P) -1344 GOTO 510 -1350 STOP -9999 END diff --git a/00_Alternate_Languages/81_Splat/MiniScript/README.md b/00_Alternate_Languages/81_Splat/MiniScript/README.md deleted file mode 100644 index 2d133f871..000000000 --- a/00_Alternate_Languages/81_Splat/MiniScript/README.md +++ /dev/null @@ -1,18 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: -``` - miniscript splat.ms -``` - -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: -``` - load "splat" - run -``` diff --git a/00_Alternate_Languages/81_Splat/MiniScript/splat.ms b/00_Alternate_Languages/81_Splat/MiniScript/splat.ms deleted file mode 100644 index d38ddd237..000000000 --- a/00_Alternate_Languages/81_Splat/MiniScript/splat.ms +++ /dev/null @@ -1,133 +0,0 @@ -within5pct = function(n) - return n * (1 + rnd / 20 - rnd / 20) -end function - -splatMsg = ["Requiescat in pace.", "May the Angel of Heaven lead you into Paradise.", - "Rest in piece.", "Son-Of-A-Gun.", "#$%&&%!$", - "A kick in the pants is a boost if you're headed right.", - "Hmm. Should have picked a shorter time.", "Mutter. Mutter. Mutter.", - "Pushing up daisies.", "Easy come, easy go."] - -history = [] -//clear // (works on Mini Micro only) -print " " * 33 + "Splat" -print " " * 15 + "Creative Computing Morristown, New Jersey" -print;print;print -print "Welcome to 'Splat' -- the game that simulates a parachute" -print "jump. Try to open your chute at the last possible" -print "moment without going splat." -ans = "y" -while ans == "y" - print;print - - distance = floor(9001 * rnd) + 1000 - - ans = input("Select your own terminal velocity (Yes or No)? ") + " " - if ans[0].lower == "y" then - terminalVel = input("What terminal velocity (mi/hr)? ").val - else - terminalVel = floor(1000 * rnd) - print "Ok. Terminal velocity = " + terminalVel + "mi/hr" - end if - - terminalVel = terminalVel * 5280/3600 - velocity = within5pct(terminalVel) - - ans = input("Want to select acceleration due to gravity (Yes or No)? ") + " " - if ans[0].lower == "y" then - acceleration = input("What acceleration (ft/sec/sec)? ").val - acceleration = within5pct(acceleration) - else - bodies = ["Mercury", "Venus", "Earth", "the moon", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "the Sun"] - gravity = [12.2, 28.3,32.16,5.15,12.5,85.2,37.6,33.8,39.6,896] - - initialStmt = ["Fine. You're on ", "All right. You're on ", "Then you're on "] - - i = floor(rnd * 10) - acceleration = gravity[i] - stmt = initialStmt[i%3] + bodies[i] + ". Acceleration=" + acceleration + " ft/sec/sec." - print stmt - end if - - actAccel = within5pct(acceleration) - print - print " Altitude = " + distance + " ft" - print " Term. Velocity = " + terminalVel + " ft/sec +/-5%" - print " Acceleration = " + acceleration + " ft/sec/sec +/-5%" - print "Set the timer for your freefall." - sec = input("How many seconds? ").val - - print "Here we go."; print - - print "Time (sec)" + char(9) + "Dist to Fall (ft)" - print "==========" + char(9) + "=================" - termVelHit = false - for i in range(0, sec, sec/8) - sec = velocity/actAccel - if i <= sec and termVelHit == false then - dist = distance - ((actAccel/2)*i^2) - else if termVelHit == false then - termVelHit = true - print "Terminal velocity reached a T plus " + velocity/actAccel + " seconds." - end if - if termVelHit then - dist = distance - ((velocity^2/(2*actAccel))+(velocity*(i-sec))) - end if - - if dist <= 0 then break - print (" " + i + " " * 9)[:9] + char(9) + " " + dist - end for - - if dist > 0 then - print "Chute open" - history.push(dist) - numJumps = history.len - numLowerJumps = 0 - for d in history - numLowerJumps += (dist <= d) - end for - - jumpDiff = numJumps - numLowerJumps - if numJumps < 4 then - ordinal = ["1st", "2nd", "3rd"] - print "Amazing!! Not bad for your " + ordinal[numJumps-1] + " successful jump!!!" - else if jumpDiff <= numJumps * 0.10 then - print "Wow! That's some jumping. Of the " + numJumps + " successful jumps" - print "before yours, only " + jumpDiff + " opened their chutes lower than" - print "you did." - else if jumpDiff <= numJumps * 0.25 then - print "Pretty good! " + numJumps + " successful jumps preceded yours and only" - print jumpDiff + " of them got lower than you did before their chute" - print "opened." - else if jumpDiff <= numJumps * 0.50 then - print "Not bad. There have been " + numJumps + " successful jumps before yours." - print "You were beaten out by " + jumpDiff + " of them." - else if jumpDiff <= numJumps * 0.75 then - print "Conservative, aren't you? You ranked only " + jumpDiff + " in the" - print numJumps + " successful jumps before yours." - else if jumpDiff <= numJumps * 0.90 then - print "Humph! Don't you have any sporting blood? There were" - print numJumps + " successful jumps before yours and you came in " + numLowerJumps + " jumps" - print "better than the worst. Shape up!!!" - else - print "Hey! You pulled the rip code much too soon. " + numJumps + " successful" - print "jumps before yours and you came in number " + jumpDiff + "! Get with it." - end if - else if dist <= 0 and not termVelHit then - print (2 * distance / actAccel) ^ .5 + " " * 5 + "Splat" - else if dist <= 0 and termVelHit then - print velocity/actAccel + ((distance - (velocity^2/(2*actAccel)))/velocity) + " " *5 + "Splat" - end if - - if dist <=0 then - splatMsg.shuffle - print splatMsg[0] - print "I'll give you another chance." - end if - - ans = input("Do you want to play again? ") + " " - ans = ans[0].lower -end while - -print "S" * 10 -print \ No newline at end of file diff --git a/00_Alternate_Languages/81_Splat/README.md b/00_Alternate_Languages/81_Splat/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/81_Splat/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/81_Splat/splat.bas b/00_Alternate_Languages/81_Splat/splat.bas deleted file mode 100644 index 8561f6345..000000000 --- a/00_Alternate_Languages/81_Splat/splat.bas +++ /dev/null @@ -1,128 +0,0 @@ -10 PRINT TAB(33);"SPLAT" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -40 PRINT:PRINT:PRINT -50 DIM A(42) -95 PRINT "WELCOME TO 'SPLAT' -- THE GAME THAT SIMULATES A PARACHUTE" -96 PRINT "JUMP. TRY TO OPEN YOUR CHUTE AT THE LAST POSSIBLE" -97 PRINT "MOMENT WITHOUT GOING SPLAT." -118 PRINT:PRINT:D1=0:V=0:A=0:N=0:M=0:D1=INT(9001*RND(1)+1000) -119 PRINT "SELECT YOUR OWN TERMINAL VELOCITY (YES OR NO)";:INPUT A1$ -120 IF A1$="NO" THEN 128 -121 IF A1$<>"YES" THEN PRINT "YES OR NO";:INPUT A1$:GOTO 120 -123 PRINT "WHAT TERMINAL VELOCITY (MI/HR)";:INPUT V1 -125 V1=V1*(5280/3600):V=V1+((V1*RND(1))/20)-((V1*RND(1))/20):GOTO 135 -128 V1=INT(1000*RND(1)) -130 PRINT "OK. TERMINAL VELOCITY ="V1"MI/HR" -131 V1=V1*(5280/3600):V=V1+((V1*RND(1))/20)-((V1*RND(1))/20) -135 PRINT "WANT TO SELECT ACCELERATION DUE TO GRAVITY (YES OR NO)"; -136 INPUT B1$ -140 IF B1$="NO" THEN 150 -141 IF B1$<>"YES" THEN PRINT "YES OR NO";:INPUT B1$:GOTO 140 -143 PRINT "WHAT ACCELERATION (FT/SEC/SEC)";:INPUT A2 -145 A=A2+((A2*RND(1))/20)-((A2*RND(1))/20):GOTO 205 -150 ON INT(1+(10*RND(1)))GOTO 151,152,153,154,155,156,157,158,159,160 -151 PRINT"FINE. YOU'RE ON MERCURY. ACCELERATION=12.2 FT/SEC/SEC.":GOTO 161 -152 PRINT"ALL RIGHT. YOU'RE ON VENUS. ACCELERATION=28.3 FT/SEC/SEC.":GOTO 162 -153 PRINT "THEN YOU'RE ON EARTH. ACCELERATION=32.16 FT/SEC/SEC.":GOTO 163 -154 PRINT"FINE. YOU'RE ON THE MOON. ACCELERATION=5.15 FT/SEC/SEC.":GOTO 164 -155 PRINT"ALL RIGHT. YOU'RE ON MARS. ACCELERATION=12.5 FT/SEC/SEC.":GOTO 165 -156 PRINT"THEN YOU'RE ON JUPITER. ACCELERATION=85.2 FT/SEC/SEC.":GOTO 166 -157 PRINT"FINE. YOU'RE ON SATURN. ACCELERATION=37.6 FT/SEC/SEC.":GOTO 167 -158 PRINT"ALL RIGHT. YOU'RE ON URANUS. ACCELERATION=33.8 FT/SEC/SEC.":GOTO 168 -159 PRINT"THEN YOU'RE ON NEPTUNE. ACCELERATION=39.6 FT/SEC/SEC.":GOTO 169 -160 PRINT"FINE. YOU'RE ON THE SUN. ACCELERATION=896 FT/SEC/SEC.":GOTO 170 -161 A2=12.2:GOTO 145 -162 A2=28.3:GOTO 145 -163 A2=32.16:GOTO 145 -164 A2=5.15:GOTO 145 -165 A2=12.5:GOTO 145 -166 A2=85.2:GOTO 145 -167 A2=37.6:GOTO 145 -168 A2=33.8 :GOTO 145 -169 A2=39.6:GOTO 145 -170 A2=896:GOTO 145 -205 PRINT -206 PRINT " ALTITUDE ="D1"FT" -207 PRINT " TERM. VELOCITY ="V1"FT/SEC +/-5%" -208 PRINT " ACCELERATION ="A2"FT/SEC/SEC +/-5%" -210 PRINT "SET THE TIMER FOR YOUR FREEFALL." -211 PRINT "HOW MANY SECONDS";:INPUT T -215 PRINT "HERE WE GO." -217 PRINT -218 PRINT "TIME (SEC)","DIST TO FALL (FT)" -219 PRINT "==========","=================" -300 FOR I=0 TO T STEP (T/8) -310 IF I>V/A THEN 400 -320 D=D1-((A/2)*I^2) -330 IF D<=0 THEN 1000 -340 PRINT I,D -350 NEXT I -360 GOTO 500 -400 PRINT "TERMINAL VELOCITY REACHED AT T PLUS"V/A"SECONDS." -405 FOR I=I TO T STEP (T/8) -410 D=D1-((V^2/(2*A))+(V*(I-(V/A)))) -420 IF D<=0 THEN 1010 -430 PRINT I,D -440 NEXT I -500 PRINT "CHUTE OPEN" -510 K=0:K1=0 -550 FOR J=0 TO 42 -555 IF A(J)=0 THEN 620 -560 K=K+1 -570 IF D>=A(J) THEN 600 -580 K1=K1+1 -600 NEXT J -610 GOTO 540 -620 A(J)=D -630 IF J>2 THEN 650 -635 PRINT "AMAZING!!! NOT BAD FOR YOUR "; -636 IF J=0 THEN PRINT "1ST "; -637 IF J=1 THEN PRINT "2ND "; -638 IF J=2 THEN PRINT "3RD "; -639 PRINT "SUCCESSFUL JUMP!!!":GOTO 2000 -650 IF K-K1<=.1*K THEN 700 -660 IF K-K1<=.25*K THEN 710 -670 IF K-K1<=.5*K THEN 720 -680 IF K-K1<=.75*K THEN 730 -690 IF K-K1<=.9*K THEN 740 -695 GOTO 750 -700 PRINT "WOW! THAT'S SOME JUMPING. OF THE"K"SUCCESSFUL JUMPS" -701 PRINT "BEFORE YOURS, ONLY"K-K1"OPENED THEIR CHUTES LOWER THAN" -702 PRINT "YOU DID." -703 GOTO 2000 -710 PRINT "PRETTY GOOD! " K"SUCCESSFUL JUMPS PRECEDED YOURS AND ONLY" -711 PRINT K-K1" OF THEM GOT LOWER THAN YOU DID BEFORE THEIR CHUTES" -712 PRINT "OPENED." :GOTO 2000 -720 PRINT "NOT BAD. THERE HAVE BEEN"K"SUCCESSFUL JUMPS BEFORE YOURS." -721 PRINT"YOU WERE BEATEN OUT BY"K-K1"OF THEM.":GOTO 2000 -730 PRINT "CONSERVATIVE, AREN'T YOU? YOU RANKED ONLY"K-K1"IN THE" -731 PRINT K"SUCCESSFUL JUMPS BEFORE YOURS.":GOTO 2000 -740 PRINT "HUMPH! DON'T YOU HAVE ANY SPORTING BLOOD? THERE WERE" -741 PRINT K"SUCCESSFUL JUMPS BEFORE YOURS AND YOU CAME IN"K1"JUMPS" -742 PRINT "BETTER THAN THE WORST. SHAPE UP!!!":GOTO 2000 -750 PRINT "HEY! YOU PULLED THE RIP CORD MUCH TOO SOON. "K"SUCCESSFUL" -751 PRINT "JUMPS BEFORE YOURS AND YOU CAME IN NUMBER"K-K1"! GET WITH IT!" -752 GOTO 2000 -800 PRINT "REQUIESCAT IN PACE.":GOTO 1950 -801 PRINT "MAY THE ANGEL OF HEAVEN LEAD YOU INTO PARADISE.":GOTO 1950 -802 PRINT "REST IN PEACE.":GOTO 1950 -803 PRINT "SON-OF-A-GUN.":GOTO 1950 -804 PRINT "#$%&&%!$":GOTO 1950 -805 PRINT "A KICK IN THE PANTS IS A BOOST IF YOU'RE HEADED RIGHT.":GOTO 1950 -806 PRINT "HMMM. SHOULD HAVE PICKED A SHORTER TIME.":GOTO 1950 -807 PRINT "MUTTER. MUTTER. MUTTER.":GOTO 1950 -808 PRINT "PUSHING UP DAISIES.":GOTO 1950 -809 PRINT "EASY COME, EASY GO.":GOTO 1950 -1000 PRINT SQR(2*D1/A),"SPLAT" -1005 ON INT(1+(10*RND(1)))GOTO 800,801,802,803,804,805,806,807,808,809 -1010 PRINT (V/A)+((D1-(V^2/(2*A)))/V),"SPLAT" -1020 GOTO 1005 -1950 PRINT "I'LL GIVE YOU ANOTHER CHANCE.":GOTO 2000 -2000 PRINT "DO YOU WANT TO PLAY AGAIN";:INPUT Z$ -2001 IF Z$="YES" THEN 118 -2002 IF Z$="NO" THEN 2005 -2003 PRINT "YES OR NO":GOTO 2000 -2005 PRINT "PLEASE";:INPUT Z$:IF Z$="YES" THEN 118 -2006 IF Z$<>"NO" THEN PRINT "YES OR NO ";:GOTO 2005 -2007 PRINT "SSSSSSSSSS.":PRINT:GOTO 2046 -2046 END diff --git a/00_Alternate_Languages/82_Stars/MiniScript/README.md b/00_Alternate_Languages/82_Stars/MiniScript/README.md deleted file mode 100644 index 2e4b6d024..000000000 --- a/00_Alternate_Languages/82_Stars/MiniScript/README.md +++ /dev/null @@ -1,18 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: -``` - miniscript stars.ms -``` - -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: -``` - load "stars" - run -``` diff --git a/00_Alternate_Languages/82_Stars/MiniScript/stars.ms b/00_Alternate_Languages/82_Stars/MiniScript/stars.ms deleted file mode 100644 index d83d75b74..000000000 --- a/00_Alternate_Languages/82_Stars/MiniScript/stars.ms +++ /dev/null @@ -1,48 +0,0 @@ -kMaxNum = 100 -kTries = 7 - -instructions = function - print "I am thinking of a whole number from 1 to " + kMaxNum - print "Try to guess my number. After you guess, I" - print "will output one or more stars (*). The more" - print "stars I type, the closer you are to my number." - print "One star (*) means far away, seven stars (*******)" - print "means really close! You get " + kTries + " guesses." - print -end function - -print " " * 34 + "Stars" -print " " * 15 + "Creative Computing Morristown, New Jersey" -print; print; print - -ans = input("Do you want instructions? ").lower + " " -if ans[0] == "y" then - instructions -end if - -while true - print - print "OK, I am thinking of a number, start guessing." - starNum = floor(rnd * kMaxNum) + 1 - try = 0 - while try < kTries - print - guess = input("Your guess: ").val - - if guess == starNum then - break - else - d = abs(guess - starNum) - print "*" * (7 - floor(log(d,2))) - end if - try += 1 - end while - - if try < kTries then - print "*" * 59 - print "You got it in " + (try + 1) + " guesses! Let's play again." - else - print "Sorry, that's " + try + " guesses. The number was " + starNum - end if - print -end while diff --git a/00_Alternate_Languages/82_Stars/README.md b/00_Alternate_Languages/82_Stars/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/82_Stars/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/82_Stars/stars.bas b/00_Alternate_Languages/82_Stars/stars.bas deleted file mode 100644 index 0536ed3a7..000000000 --- a/00_Alternate_Languages/82_Stars/stars.bas +++ /dev/null @@ -1,54 +0,0 @@ -10 PRINT TAB(34);"STARS" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT:PRINT:PRINT -100 REM *** STARS - PEOPLE'S COMPUTER CENTER, MENLO PARK, CA -140 REM *** A IS LIMIT ON NUMBER, M IS NUMBER OF GUESSES -150 A=100:M=7 -170 INPUT "DO YOU WANT INSTRUCTIONS";A$ -190 IF LEFT$(A$,1)="N" THEN 280 -200 REM *** INSTRUCTIONS ON HOW TO PLAY -210 PRINT "I AM THINKING OF A WHOLE NUMBER FROM 1 TO";A -220 PRINT "TRY TO GUESS MY NUMBER. AFTER YOU GUESS, I" -230 PRINT "WILL TYPE ONE OR MORE STARS (*). THE MORE" -240 PRINT "STARS I TYPE, THE CLOSER YOU ARE TO MY NUMBER." -250 PRINT "ONE STAR (*) MEANS FAR AWAY, SEVEN STARS (*******)" -260 PRINT "MEANS REALLY CLOSE! YOU GET";M;"GUESSES." -270 REM *** COMPUTER THINKS OF A NUMBER -280 PRINT -290 PRINT -300 X=INT(A*RND(1)+1) -310 PRINT "OK, I AM THINKING OF A NUMBER, START GUESSING." -320 REM *** GUESSING BEGINS, HUMAN GETS M GUESSES -330 FOR K=1 TO M -340 PRINT -350 PRINT "YOUR GUESS"; -360 INPUT G -370 IF G=X THEN 600 -380 D=ABS(G-X) -390 IF D>=64 THEN 510 -400 IF D>=32 THEN 500 -410 IF D>=16 THEN 490 -420 IF D>=8 THEN 480 -430 IF D>=4 THEN 470 -440 IF D>=2 THEN 460 -450 PRINT "*"; -460 PRINT "*"; -470 PRINT "*"; -480 PRINT "*"; -490 PRINT "*"; -500 PRINT "*"; -510 PRINT "*"; -520 PRINT -530 NEXT K -540 REM *** DID NOT GUESS IN M GUESSES -550 PRINT -560 PRINT "SORRY, THAT'S";M;"GUESSES. THE NUMBER WAS";X -580 GOTO 650 -590 REM *** WE HAVE A WINNER -600 PRINT:FOR N=1 TO 79 -610 PRINT "*"; -620 NEXT N -630 PRINT:PRINT -640 PRINT "YOU GOT IT IN";K;"GUESSES!!! LET'S PLAY AGAIN..." -650 GOTO 280 -660 END diff --git a/00_Alternate_Languages/83_Stock_Market/MiniScript/README.md b/00_Alternate_Languages/83_Stock_Market/MiniScript/README.md deleted file mode 100644 index ac3893185..000000000 --- a/00_Alternate_Languages/83_Stock_Market/MiniScript/README.md +++ /dev/null @@ -1,18 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: -``` - miniscript stockmarket.ms -``` - -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: -``` - load "stockmarket" - run -``` diff --git a/00_Alternate_Languages/83_Stock_Market/MiniScript/stockmarket.ms b/00_Alternate_Languages/83_Stock_Market/MiniScript/stockmarket.ms deleted file mode 100644 index 850cb725f..000000000 --- a/00_Alternate_Languages/83_Stock_Market/MiniScript/stockmarket.ms +++ /dev/null @@ -1,199 +0,0 @@ -print " "*30 + "Stock Market" -print " "*15 + "Creative Computing Morristown New Jersey" -print; print; print - -// Stock Market Simulation -STOCK- -// Revised 8/18/70 (D. Pessel, L. Braun, C. Losik) -// Ported to MiniScript 10/07/23 (J. Strout) - - -// Ask a yes/no question; return true if yes, false if no -yes = function(prompt) - while true - response = input(prompt + " (YES-Type 1, NO-Type 0)? ") - if not response then continue - if response == "1" or response[0].lower == "y" then return true - if response == "0" or response[0].lower == "n" then return false - end while -end function - -printInstructions = function - print; print - print "This program plays the stock market. You will be given" - print "$10,000 and may buy or sell stocks. The stock prices will" - print "be generated randomly and therefore this model does not" - print "represent exactly what happens on the exchange. A table" - print "of available stocks, their prices, and the number of shares" - print "in your portfolio will be printed. Following this, the" - print "initials of each stock will be printed with a question" - print "mark. Here you indicate a transaction. To buy a stock" - print "type +NNN, to sell a stock type -NNN, where NNN is the" - print "number of shares. A brokerage fee of 1% will be charged" - print "on all transactions. Note that if a stock's value drops" - print "to zero it may rebound to a positive value again. You" - print "have $10,000 to invest. Use integers for all your inputs." - print "(Note: To get a 'feel' for the market run for at least" - print "10 days)" - print "-----Good luck!-----" - print - input "(Press Return to continue.)" -end function - -randomIndex = function; return floor(rnd * stockPrices.len); end function - -// Randomly produce new stock values based on previous day's values. -// N1,N2 are random numbers of days which respectively determine -// when a stock will increase or decrease 10 points. -adjustStockPrices = function - for i in changePerShare.indexes - changePerShare[i] = 0 - end for - // if N1 days have passed, increase a random stock by 10 - if N1 < 1 then - changePerShare[randomIndex] = 10 - globals.N1 = floor(4.99 * rnd + 1) - end if - // if N2 days have passed, decrease a random stock by 10 - if N2 < 1 then - changePerShare[randomIndex] = -10 - globals.N2 = floor(4.99 * rnd + 1) - end if - // Deduct one day from N1 and N2 - globals.N1 -= 1 - globals.N2 -= 1 - // update all stocks - for i in stockPrices.indexes - smallChange = rnd - if smallChange < 0.25 then smallChange = 0.25 - if smallChange > 0.5 then smallChange = 0.5 - changePerShare[i] += marketTrendSlope * stockPrices[i] + smallChange + floor(3 - 6*rnd + 0.5) - changePerShare[i] = round(changePerShare[i], 2) - stockPrices[i] += changePerShare[i] - if stockPrices[i] < 0 then - changePerShare[i] = 0 - stockPrices[i] = 0 - end if - stockPrices[i] = round(stockPrices[i], 2) - end for - // After trendDaysLeft, randomly change trend sign and slope - globals.trendDaysLeft -= 1 - if trendDaysLeft < 1 then - globals.trendDaysLeft = floor(4.99 * rnd + 1) - globals.marketTrendSlope = floor(rnd*10 + 0.5)/100 - if rnd < 0.5 then globals.marketTrendSlope = -marketTrendSlope - end if -end function - -pad = function(s, width=20) - s = str(s) - return s + " "*(width - s.len) -end function - -printInitialPortfolio = function - print pad("Stock", 30) + pad("Initials", 12) + "Price/Share" - for i in stockSymbols.indexes - print pad(stockNames[i], 32) + pad(stockSymbols[i], 14) + stockPrices[i] - end for -end function - -printMarketResults = function - print - print "********** END OF DAY'S TRADING **********" - print - print - print pad("Stock", 8) + pad("Price/Share", 14) + pad("Holdings", 12) + - pad("Value", 10) + "Net Price Change" - for i in stockSymbols.indexes - value = round(stockPrices[i] + sharesOwned[i], 2) - print pad(stockSymbols[i], 9) + pad(stockPrices[i], 14) + - pad(sharesOwned[i], 12) + pad(value, 10) + changePerShare[i] - end for - print -end function - -printStatus = function - average = stockPrices.sum / stockPrices.len - print - print "New York Stock Exchange Average: " + round(average, 2), "" - if prevAverage != null then - print " Net Change " + round(average - prevAverage, 2) - else - print - end if - globals.prevAverage = average - print - stockValue = 0 - for i in stockPrices.indexes - stockValue += stockPrices[i] * sharesOwned[i] - end for - print "Total stock assets are $ " + round(stockValue, 2) - print "Total cash assets are $ " + round(cash, 2) - print "Total assets are $ " + round(stockValue + cash, 2) - print - // Uncomment the following line to cheat/debug: - //print "marketTrendSlope: " + marketTrendSlope + "; trendDaysLeft: " + trendDaysLeft -end function - -// Calculate total cost, including brokerage fee, to buy the given -// stock (or if qtyToBuy < 0, negative cash gains minus the fee). -totalCost = function(stockIndex, qtyToBuy) - baseVal = stockPrices[stockIndex] * qtyToBuy - fee = round(abs(baseVal) * 0.01, 2) - return baseVal + fee -end function - -buySell = function - print "What is your transaction in" - i = 0 - while i < stockSymbols.len - while true - qty = input(stockSymbols[i] + "? ") - if qty == "" or qty == "0" or qty.val != 0 then break - print "Enter quantity to buy/sell like +10 or -2." - end while - qty = qty.val - if qty < 0 and -qty > sharesOwned[i] then - print "You have only " + sharesOwned[i] + " of " + stockSymbols[i] + "; try again." - continue - end if - if totalCost(i, qty) > cash then - print "This would cost " + (totalCost(i, qty) - cash) + " more than you have." - continue - end if - sharesOwned[i] += qty - globals.cash -= totalCost(i, qty) - i += 1 - end while -end function - -// Introduction -if yes("Do you want the instructions") then printInstructions -print; print - -// Initial stock values and trends -stockSymbols = ["IBM", "RCA", "LBJ", "ABC", "CBS"] -stockNames = ["Int. Ballistic Missiles", "Red Cross of America", - "Lichtenstein, Bumrap & Joke", "American Bankrupt Co.", "Censured Books Store"] -sharesOwned = [0] * stockSymbols.len -cash = 10000 -stockPrices = [100, 85, 150, 140, 110] -changePerShare = [0] * stockSymbols.len -trendDaysLeft = floor(4.99 * rnd + 1) -marketTrendSlope = floor(rnd*10 + 0.5)/100 -if rnd > 0.5 then marketTrendSlope = -marketTrendSlope -N1 = 0 // days until a big positive jump in a random price -N2 = 0 // days until a big negative jump in a random price -adjustStockPrices -prevAverage = null - -printInitialPortfolio -printStatus -while true - buySell - adjustStockPrices - printMarketResults - printStatus - if not yes("Do you wish to continue") then break -end while -print "Hope you had fun!!" - diff --git a/00_Alternate_Languages/83_Stock_Market/README.md b/00_Alternate_Languages/83_Stock_Market/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/83_Stock_Market/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/83_Stock_Market/stockmarket.bas b/00_Alternate_Languages/83_Stock_Market/stockmarket.bas deleted file mode 100644 index 402b6360b..000000000 --- a/00_Alternate_Languages/83_Stock_Market/stockmarket.bas +++ /dev/null @@ -1,232 +0,0 @@ -10 PRINT TAB(30);"STOCK MARKET" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT: PRINT: PRINT -100 REM STOCK MARKET SIMULATION -STOCK- -101 REM REVISED 8/18/70 (D. PESSEL, L. BRAUN, C. LOSIK) -102 REM IMP VRBLS: A-MRKT TRND SLP; B5-BRKRGE FEE; C-TTL CSH ASSTS; -103 REM C5-TTL CSH ASSTS (TEMP); C(I)-CHNG IN STK VAL; D-TTL ASSTS; -104 REM E1,E2-LRG CHNG MISC; I-STCK #; I1,I2-STCKS W LRG CHNG; -105 REM N1,N2-LRG CHNG DAY CNTS; P5-TTL DAYS PRCHSS; P(I)-PRTFL CNTNTS; -106 REM Q9-NEW CYCL?; S4-SGN OF A; S5-TTL DYS SLS; S(I)-VALUE/SHR; -107 REM T-TTL STCK ASSTS; T5-TTL VAL OF TRNSCTNS; -108 REM W3-LRG CHNG; X1-SMLL CHNG(<$1); Z4,Z5,Z6-NYSE AVE.; Z(I)-TRNSCT -110 DIM S(5),P(5),Z(5),C(5) -112 REM SLOPE OF MARKET TREND:A (SAME FOR ALL STOCKS) -113 LET X=1 -114 LET A=INT((RND(X)/10)*100+.5)/100 -115 LET T5=0 -116 LET X9=0 -117 LET N1=0 -118 LET N2=0 -119 LET E1=0 -120 LET E2=0 -121 REM INTRODUCTION -122 PRINT "DO YOU WANT THE INSTRUCTIONS (YES-TYPE 1, NO-TYPE 0)"; -123 INPUT Z9 -124 PRINT -125 PRINT -126 IF Z9<1 THEN 200 -130 PRINT "THIS PROGRAM PLAYS THE STOCK MARKET. YOU WILL BE GIVEN" -132 PRINT "$10,000 AND MAY BUY OR SELL STOCKS. THE STOCK PRICES WILL" -134 PRINT "BE GENERATED RANDOMLY AND THEREFORE THIS MODEL DOES NOT" -135 PRINT "REPRESENT EXACTLY WHAT HAPPENS ON THE EXCHANGE. A TABLE" -136 PRINT "OF AVAILABLE STOCKS, THEIR PRICES, AND THE NUMBER OF SHARES" -137 PRINT "IN YOUR PORTFOLIO WILL BE PRINTED. FOLLOWING THIS, THE" -138 PRINT "INITIALS OF EACH STOCK WILL BE PRINTED WITH A QUESTION" -139 PRINT "MARK. HERE YOU INDICATE A TRANSACTION. TO BUY A STOCK" -140 PRINT "TYPE +NNN, TO SELL A STOCK TYPE -NNN, WHERE NNN IS THE" -141 PRINT "NUMBER OF SHARES. A BROKERAGE FEE OF 1% WILL BE CHARGED" -142 PRINT "ON ALL TRANSACTIONS. NOTE THAT IF A STOCK'S VALUE DROPS" -143 PRINT "TO ZERO IT MAY REBOUND TO A POSITIVE VALUE AGAIN. YOU" -144 PRINT "HAVE $10,000 TO INVEST. USE INTEGERS FOR ALL YOUR INPUTS." -145 PRINT "(NOTE: TO GET A 'FEEL' FOR THE MARKET RUN FOR AT LEAST" -146 PRINT "10 DAYS)" -147 PRINT "-----GOOD LUCK!-----" -200 REM GENERATION OF STOCK TABLE; INPUT REQUESTS -210 REM INITIAL STOCK VALUES -220 LET S(1)=100 -230 LET S(2)=85 -240 LET S(3)=150 -250 LET S(4)=140 -260 LET S(5)=110 -265 REM INITIAL T8 - # DAYS FOR FIRST TREND SLOPE (A) -266 LET T8=INT(4.99*RND(X)+1) -267 REM RANDOMIZE SIGN OF FIRST TREND SLOPE (A) -268 IF RND(X)>.5 THEN 270 -269 LET A=-A -270 REM RANDOMIZE INITIAL VALUES -280 GOSUB 830 -285 REM INITIAL PORTFOLIO CONTENTS -290 FOR I=1 TO 5 -300 LET P(I)=0 -305 LET Z(I)=0 -310 NEXT I -320 PRINT -330 PRINT -333 REM INITIALIZE CASH ASSETS:C -335 LET C=10000 -338 REM PRINT INITIAL PORTFOLIO -340 PRINT "STOCK"," ","INITIALS","PRICE/SHARE" -350 PRINT "INT. BALLISTIC MISSILES"," IBM",S(1) -352 PRINT "RED CROSS OF AMERICA"," RCA",S(2) -354 PRINT "LICHTENSTEIN, BUMRAP & JOKE"," LBJ",S(3) -356 PRINT "AMERICAN BANKRUPT CO."," ABC",S(4) -358 PRINT "CENSURED BOOKS STORE"," CBS",S(5) -360 PRINT -361 REM NYSE AVERAGE:Z5; TEMP. VALUE:Z4; NET CHANGE:Z6 -363 LET Z4=Z5 -364 LET Z5=0 -365 LET T=0 -370 FOR I=1 TO 5 -375 LET Z5=Z5+S(I) -380 LET T=T+S(I)*P(I) -390 NEXT I -391 LET Z5=INT(100*(Z5/5)+.5)/100 -392 LET Z6=INT((Z5-Z4)*100+.5)/100 -393 REM TOTAL ASSETS:D -394 LET D=T+C -395 IF X9>0 THEN 398 -396 PRINT "NEW YORK STOCK EXCHANGE AVERAGE: "Z5 -397 GOTO 399 -398 PRINT "NEW YORK STOCK EXCHANGE AVERAGE: "Z5"NET CHANGE"Z6 -399 PRINT -400 LET T=INT(100*T+.5)/100 -401 PRINT "TOTAL STOCK ASSETS ARE $";T -403 LET C=INT(100*C+.5)/100 -405 PRINT "TOTAL CASH ASSETS ARE $";C -407 LET D=INT(100*D+.5)/100 -408 PRINT "TOTAL ASSETS ARE $";D -410 PRINT -411 IF X9=0 THEN 416 -412 PRINT "DO YOU WISH TO CONTINUE (YES-TYPE 1, NO-TYPE 0)"; -413 INPUT Q9 -414 IF Q9<1 THEN 998 -416 REM INPUT TRANSACTIONS -420 PRINT "WHAT IS YOUR TRANSACTION IN" -430 PRINT "IBM"; -440 INPUT Z(1) -450 PRINT "RCA"; -460 INPUT Z(2) -470 PRINT "LBJ"; -480 INPUT Z(3) -490 PRINT "ABC"; -500 INPUT Z(4) -510 PRINT "CBS"; -520 INPUT Z(5) -525 PRINT -530 REM TOTAL DAY'S PURCHASES IN $:P5 -540 LET P5=0 -550 REM TOTAL DAY'S SALES IN $:S5 -560 LET S5=0 -570 FOR I=1 TO 5 -575 LET Z(I)=INT(Z(I)+.5) -580 IF Z(I)<=0 THEN 610 -590 LET P5=P5+Z(I)*S(I) -600 GOTO 620 -610 LET S5=S5-Z(I)*S(I) -612 IF -Z(I)<=P(I) THEN 620 -614 PRINT "YOU HAVE OVERSOLD A STOCK; TRY AGAIN." -616 GOTO 420 -620 NEXT I -622 REM TOTAL VALUE OF TRANSACTIONS:T5 -625 LET T5=P5+S5 -630 REM BROKERAGE FEE:B5 -640 LET B5=INT(.01*T5*100+.5)/100 -650 REM CASH ASSETS=OLD CASH ASSETS-TOTAL PURCHASES -652 REM -BROKERAGE FEES+TOTAL SALES:C5 -654 LET C5=C-P5-B5+S5 -656 IF C5>=0 THEN 674 -658 PRINT "YOU HAVE USED $"-C5" MORE THAN YOU HAVE." -660 GOTO 420 -674 LET C=C5 -675 REM CALCULATE NEW PORTFOLIO -680 FOR I=1 TO 5 -690 LET P(I)=P(I)+Z(I) -700 NEXT I -710 REM CALCULATE NEW STOCK VALUES -720 GOSUB 830 -750 REM PRINT PORTFOLIO -751 REM BELL RINGING-DIFFERENT ON MANY COMPUTERS -755 PRINT -756 PRINT "********** END OF DAY'S TRADING **********" -757 PRINT -758 PRINT -759 IF X9<1 THEN 769 -769 PRINT "STOCK","PRICE/SHARE","HOLDINGS", "VALUE", "NET PRICE CHANGE" -770 PRINT "IBM", S(1), P(1), S(1)*P(1), C(1) -771 PRINT "RCA", S(2), P(2), S(2)*P(2), C(2) -772 PRINT "LBJ", S(3), P(3), S(3)*P(3), C(3) -773 PRINT "ABC", S(4), P(4), S(4)*P(4), C(4) -774 PRINT "CBS", S(5), P(5), S(5)*P(5), C(5) -775 LET X9=1 -780 PRINT -790 PRINT -810 GOTO 360 -829 REM NEW STOCK VALUES - SUBROUTINE -830 REM RANDOMLY PRODUCE NEW STOCK VALUES BASED ON PREVIOUS -831 REM DAY'S VALUES -832 REM N1,N2 ARE RANDOM NUMBERS OF DAYS WHICH RESPECTIVELY -833 REM DETERMINE WHEN STOCK I1 WILL INCREASE 10 PTS. AND STOCK -834 REM I2 WILL DECREASE 10 PTS. -840 REM IF N1 DAYS HAVE PASSED, PICK AN I1, SET E1, DETERMINE NEW N1 -841 IF N1>0 THEN 850 -845 LET I1=INT(4.99*RND(X)+1) -846 LET N1=INT(4.99*RND(X)+1) -847 LET E1=1 -850 REM IF N2 DAYS HAVE PASSED, PICK AN I2, SET E2, DETERMINE NEW N2 -851 IF N2>0 THEN 860 -855 LET I2=INT(4.99*RND(X)+1) -856 LET N2=INT(4.99*RND(X)+1) -857 LET E2=1 -860 REM DEDUCT ONE DAY FROM N1 AND N2 -861 LET N1=N1-1 -862 LET N2=N2-1 -890 REM LOOP THROUGH ALL STOCKS -900 FOR I=1 TO 5 -910 LET X1=RND(X) -915 IF X1>.25 THEN 920 -916 LET X1=.25 -917 GOTO 935 -920 IF X1>.5 THEN 925 -921 LET X1=.5 -922 GOTO 935 -925 IF X1>.75 THEN 930 -926 LET X1=.75 -927 GOTO 935 -930 LET X1=0.0 -931 REM BIG CHANGE CONSTANT:W3 (SET TO ZERO INITIALLY) -935 LET W3=0 -936 IF E1<1 THEN 945 -937 IF INT(I1+.5)<>INT(I+.5) THEN 945 -938 REM ADD 10 PTS. TO THIS STOCK; RESET E1 -939 LET W3=10 -943 LET E1=0 -945 IF E2<1 THEN 955 -947 IF INT(I2+.5)<>INT(I+.5) THEN 955 -948 REM SUBTRACT 10 PTS. FROM THIS STOCK; RESET E2 -949 LET W3=W3-10 -953 LET E2=0 -954 REM C(I) IS CHANGE IN STOCK VALUE -955 LET C(I)=INT(A*S(I))+X1+INT(3-6*RND(X)+.5)+W3 -956 LET C(I)=INT(100*C(I)+.5)/100 -957 LET S(I)=S(I)+C(I) -960 IF S(I)>0 THEN 967 -964 LET C(I)=0 -965 LET S(I)=0 -966 GOTO 970 -967 LET S(I)=INT(100*S(I)+.5)/100 -970 NEXT I -972 REM AFTER T8 DAYS RANDOMLY CHANGE TREND SIGN AND SLOPE -973 LET T8=T8-1 -974 IF T8<1 THEN 985 -980 RETURN -985 REM RANDOMLY CHANGE TREND SIGN AND SLOPE (A), AND DURATION -986 REM OF TREND (T8) -990 LET T8=INT(4.99*RND(X)+1) -992 LET A=INT((RND(X)/10)*100+.5)/100 -993 LET S4=RND(X) -994 IF S4<=.5 THEN 997 -995 LET A=-A -997 RETURN -998 PRINT "HOPE YOU HAD FUN!!" -999 END diff --git a/00_Alternate_Languages/84_Super_Star_Trek/MiniScript/README.md b/00_Alternate_Languages/84_Super_Star_Trek/MiniScript/README.md deleted file mode 100644 index 0b383f4b5..000000000 --- a/00_Alternate_Languages/84_Super_Star_Trek/MiniScript/README.md +++ /dev/null @@ -1,18 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). Note that while the original game separated the instructions into a separate BASIC program (probably due to memory limitations), we have chosen here to combine them into one MiniScript program with both instructions and gameplay. The instructions are available at the start of the game, and later at any time via the HLP command. - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: -``` - miniscript superstartrek.ms -``` - -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: -``` - load "superstartrek" - run -``` diff --git a/00_Alternate_Languages/84_Super_Star_Trek/MiniScript/superstartrek.ms b/00_Alternate_Languages/84_Super_Star_Trek/MiniScript/superstartrek.ms deleted file mode 100644 index 7b7a247c9..000000000 --- a/00_Alternate_Languages/84_Super_Star_Trek/MiniScript/superstartrek.ms +++ /dev/null @@ -1,1267 +0,0 @@ -// SUPER STARTREK - MAY 16,1978 - REQUIRES 24K MEMORY -// -// **** **** STAR TREK **** **** -// **** SIMULATION OF A MISSION OF THE STARSHIP ENTERPRISE, -// **** AS SEEN ON THE STAR TREK TV SHOW. -// **** ORIGIONAL 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 . . . -// *** COMMENTS, EPITHETS, AND SUGGESTIONS SOLICITED -- -// *** SEND TO; R. C. LEEDOM -// *** WESTINGHOUSE DEFENSE & ELECTRONICS SYSTEMS CNTR. -// *** BOX 746, M.S. 338 -// *** BALTIMORE, MD 21203 -// *** -// *** CONVERTED TO MICROSOFT 8 K BASIC 3/16/78 BY JOHN GORDERS -// *** Convertod te MiniScript 10/10/23 by Joe Strout -// *** (based heavily on the Python port by @jkboyce) - -import "listUtil" -import "stringUtil" -import "mathUtil" - -//================================================================= -// Instructions -// (This was originally in a separate program, superstartreckins.bas, -// for memory reasons. I've chosen to incorporate it into the main -// program, as that's more convenient for everybody.) -//================================================================= -Instructions = {} -Instructions.print = function - print - print "At each pause, press Return to continue." - input - - 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), that 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." - input - - 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 quadrant. Therefore, to get" - print " from quadrant 6,5 to 5,5, you would" - print " use course 3, warp factor 1." - input - - 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." - input - - 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 the 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." - input - - 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)." - input - - 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 " that 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." - input - - 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." - input - print -end function - -//================================================================= -// Constants (tweak these to make the game easier or harder!) -//================================================================= -Constant = {} -Constant.klingonShieldStrength = 200 -Constant.maxEnergy = 3000 -Constant.maxTorpedos = 10 -Constant.minDays = 25 -Constant.maxDays = 34 - -// Directions. NOTE: this game has an unusual coordinate -// system, where x is the row (higher X values are further -// down on the screen), and y is the column (higher Y values -// are further to the right). -dirs = [ // (down, right) - [0, 1], // 1: go right (same as #9) - [-1, 1], // 2: go up-right - [-1, 0], // 3: go up (lower x-coordines; north) - [-1, -1], // 4: go up-left (north-west) - [0, -1], // 5: go left (west) - [1, -1], // 6: go down-left (south-west) - [1, 0], // 7: go down (higher x-coordines; south) - [1, 1], // 8: go down-right - [0, 1]] // 9: go right (east) - - - -//================================================================= -// Global Utility Functions -//================================================================= - -// Generate a random integer from 0 to 7 inclusive. -fnr = function - return floor(rnd * 8) -end function - -// Generate a random integer between any two limits (inclusive). -randInt = function(minVal, maxVal) - return floor(rnd * (maxVal - minVal + 1)) + minVal -end function - -// Print distance and direction between two points on a grid. -printDirection = function(source, dest) - delta1 = -(dest.x - source.x) - delta2 = dest.y - source.y - - if delta2 > 0 then - if delta1 < 0 then - base = 7 - else - base = 1 - temp = delta1; delta1 = delta2; delta2 = temp - end if - else - if delta1 > 0 then - base = 3 - else - base = 5 - temp = delta1; delta1 = delta2; delta2 = temp - end if - end if - - delta1 = abs(delta1) - delta2 = abs(delta2) - if delta1 or delta2 then // bug in original: failed when source == dest - if delta1 >= delta2 then - print "Direction = " + round(base + delta2 / delta1, 6) - else - print "Direction = " + round(base + 2 - delta1 / delta2, 6) - end if - end if - print "Distance = " + round(sqrt(delta1 ^ 2 + delta2 ^ 2), 6) -end function - -getYesNo = function(prompt) - while true - ans = input(prompt + "? ").lower + " " - if ans[0] == "y" then return "yes" - if ans[0] == "n" then return "no" - print "Please answer Yes or No." - end while -end function - -getXY = function(prompt) - while true - ans = input(prompt + "? ").split(",") - if ans.len == 2 then return {"x":ans[0].val, "y":ans[1].val} - print "Please enter two numbers separated by a comma. Example: 5,2" - end while -end function - -string.padBoth = function(length, padChar=" ") - // Pad a string on BOTH sides, so that it ends up centered. - if self.len > length then return self.len[:length] - extra = length - self.len - leftExtra = floor(extra/2) - rightExtra = extra - leftExtra - return padChar * leftExtra + self + padChar * rightExtra -end function - -//================================================================= -// Entity: map of strings used both as unique identifiers for -// things that can be at any position in a quadrant, AND also used -// as display strings in the short-range scan. -//================================================================= -Entity = {} -Entity.klingon = "+K+" -Entity.ship = "<*>" -Entity.empty = " " -Entity.starbase = ">!<" -Entity.star = " * " - -//================================================================= -// Point class: represents an X,Y position. Note that because -// the original game used 1-based coordinates, we have a conversion -// to string method that adds 1 to X and Y. But internally, these -// are assumed to be 0-based. -//================================================================= -Point = {} -Point.make = function(x,y) - p = new Point - p.x = x - p.y = y - return p -end function -Point.random = function - return Point.make(fnr, fnr) -end function -Point.oneBasedStr = function - return (self.x + 1) + " , " + (self.y + 1) -end function - -//================================================================= -// Position: combination of quadrant and sector -//================================================================= -Position = {} -Position.make = function(quadX, quadY, secX, secY) - pos = new Position - pos.quadrant = Point.make(quadX, quadY) - pos.sector = Point.make(secX, secY) - return pos -end function -Position.random = function - return Position.make(fnr, fnr, fnr, fnr) -end function - -//================================================================= -// Quadrant: represents one area of the map -//================================================================= -Quadrant = {} -Quadrant.make = function(quadrantX, quadrantY, klingons, bases, stars) - q = new Quadrant - q.point = Point.make(quadrantX, quadrantY) - q.klingons = klingons - q.bases = bases - q.stars = stars - q.extraRepairTime = rnd * 0.5 - q.klingonShips = [] // (list of KlingonShip) - q.starbase = null // (Point of starbase, if any) - q.charted = false - q.data = null - return q -end function - -// Get the name of the region of this quadrant (e.g. "Rigel"). -Quadrant.name = function - region1 = [ - "Antares", - "Rigel", - "Procyon", - "Vega", - "Canopus", - "Altair", - "Sagittarius", - "Pollux"] - region2 = [ - "Sirius", - "Deneb", - "Capella", - "Betelgeuse", - "Aldebaran", - "Regulus", - "Arcturus", - "Spica"] - if self.point.y < 4 then return region1[self.point.x] - return region2[self.point.x] -end function - -// Get the full name of this quadrant (e.g. "Rigel IV") -Quadrant.fullName = function - return self.name + " " + ["I", "II", "III", "IV"][self.point.y % 4] -end function - -// Store the given entity for the given cell in this quadrant -// (rounding to the nearest integer coordinates). -Quadrant.setValue = function(x, y, entity) - self.data[round(x)][round(y)] = entity -end function - -// Get the entity in the given cell of this quadrant -// (again rounding to the nearest integers). -Quadrant.value = function(x, y) - return self.data[round(x)][round(y)] -end function - -// Find an empty position within this quadrant. -Quadrant.findEmptyPoint = function - while true - p = Point.random - if self.value(p.x, p.y) == Entity.empty then return p - end while -end function - -Quadrant.addStarbase = function - pos = self.findEmptyPoint - self.setValue pos.x, pos.y, Entity.starbase - self.starbase = pos // (note: assumes 0 or 1 starbases) -end function - -// Fill out the contents of this quadrant, given the position of -// the ship and our number of klingons, bases, and stars. -Quadrant.populate = function(shipPos) - self.data = list.init2d(8, 8, Entity.empty) - if shipPos != null then self.setValue shipPos.x, shipPos.y, Entity.ship - for i in range(0, self.klingons-1, 1) - pos = self.findEmptyPoint - self.setValue pos.x, pos.y, Entity.klingon - self.klingonShips.push KlingonShip.make(pos.x, pos.y) - end for - if self.bases > 0 then self.addStarbase - for i in range(0, self.stars-1, 1) - pos = self.findEmptyPoint - self.setValue pos.x, pos.y, Entity.star - end for -end function - -// Return the three-digit number that represents the contents of -// this quadrant in a long-range scan: -Quadrant.lrsValue = function - return str(self.klingons) + str(self.bases) + str(self.stars) -end function - -// Return a list of lines representing the short-range scan -// of this quadrant (i.e., a representation of what entities -// it contains). -Quadrant.scanLines = function - result = [] - for row in self.data - result.push row.join - end for - return result -end function - -//================================================================= -// KlingonShip: represents an enemy ship. These are very simple; -// they need only their position (sector) within the quadrant, -// and their current shield level. -//================================================================= -KlingonShip = {} -KlingonShip.make = function(x, y) - k = new KlingonShip - k.sector = Point.make(x,y) - k.shield = Constant.klingonShieldStrength * (rnd + 0.5) - return k -end function -KlingonShip.distance = function(ship) - // Find distance, in sector units, between this ship and the given - // (player) ship. Assumes both are in the same quadrant. - return mathUtil.distance(self.sector, ship.position.sector) -end function - -//================================================================= -// Ship: represents the starship Enterprise and all its systems. -//================================================================= -Ship = {} -Ship.maxEnergy = Constant.maxEnergy -Ship.maxTorpedos = Constant.maxTorpedos -Ship.init = function - self.position = Position.random - self.devices = [ - "Warp Engines", - "Short Range Sensors", - "Long Range Sensors", - "Phaser Control", - "Photon Tubes", - "Damage Control", - "Shield Control", - "Library-Computer", - ] - self.deviceStatus = [0] * self.devices.len // > 0 means working; < 0 means broken - self.docked = false - self.shields = 0 - self.refill -end function - -Ship.useWarpEnergy = function(warpRounds) - // Note: movement costs 10 energy per sub-step (sector change). - self.energy -= warpRounds * 10 - if self.energy < 0 then - print "Shield control supplies energy to complete the maneuver." - self.shields += self.energy - self.energy = 0 - if self.shields < 0 then self.shields = 0 - end if -end function - -Ship.refill = function - self.energy = self.maxEnergy - self.torpedos = self.maxTorpedos -end function - -Ship.stranded = function - return self.shields + self.energy <= 10 or - (self.energy <= 10 and self.deviceStatus[6] < 0) -end function - -//================================================================= -// Galaxy: all 64 quadrants, plus global information about how many -// klingons there are, the current game time, etc. Basically -// represents the state of the game (but not the flow; that happens -// in the Game class). -//================================================================= -Galaxy = {} -Galaxy.init = function(minDuration=20) - self.qtyKlingons = 0 - self.qtyBases = 0 - self.startDate = 100 * randInt(20, 39) - self.endDate = self.startDate + randInt(Constant.minDays, Constant.maxDays) - self.stardate = self.startDate - self.ship = new Ship - self.ship.init - self.quadrants = list.init2d(8, 8) - for x in range(0, 7) - for y in range(0, 7) - klingons = 0 - r1 = rnd - if r1 > 0.80 then klingons = 1 - if r1 > 0.95 then klingons = 2 - if r1 > 0.98 then klingons = 3 - bases = (rnd > 0.96) - self.quadrants[x][y] = Quadrant.make(x, y, klingons, bases, fnr+1) - self.qtyKlingons += klingons - self.qtyBases += bases - end for - end for - self.missionDuration = minDuration - if self.qtyKlingons > self.missionDuration then - self.missionDuration = self.qtyKlingons + 1 - end if - here = self.localQuadrant - if self.qtyBases == 0 then self.qtyBases = 1 - self.ship.position.sector = Point.random -end function - -Galaxy.daysElapsed = function; return self.stardate - self.startDate; end function -Galaxy.daysLeft = function; return self.endDate - self.stardate; end function -Galaxy.missionOver = function; return self.stardate > self.endDate; end function - -Galaxy.localQuadrant = function - qp = self.ship.position.quadrant - return self.quadrants[qp.x][qp.y] -end function - -Galaxy.printLongRangeScan = function(point) - sep = "-" * 19 - for x in range(point.x - 1, point.x + 1) - print sep - entries = [] - for y in range(point.y - 1, point.y + 1) - if not (0 <= x <= 7 and 0 <= y <= 7) then - entries.push "***" - else - q = self.quadrants[x][y] - entries.push q.lrsValue - q.charted = true - end if - end for - print ": " + entries.join(" : ") + " :" - end for - print sep -end function - -//================================================================= -// Game: represents the flow of the game, and handles user actions. -//================================================================= -Game = {} -Game.init = function - self.galaxy = new Galaxy - self.galaxy.init - self.gameOver = false -end function - -Game.printIntro = function - print;print;print;print;print;print;print;print;print;print;print - print " ,------*------," - print " ,------------- '--- ------'" - print " '-------- --' / /" - print " ,---' '-------/ /--," - print " '----------------'";print - print " THE USS ENTERPRISE --- NCC-1701" - print;print;print;print;print - k = self.galaxy.qtyKlingons - sb = self.galaxy.qtyBases - if sb == 1 then isAre = "is" else isAre = "are" - days = self.galaxy.endDate - self.galaxy.startDate - orders = ["Your orders are as follows:"] - orders.push " Destroy the " + k + " Klingon warships which have invaded" - orders.push " the galaxy before they can attack federation headquarters" - orders.push " on stardate " + self.galaxy.endDate + ". This gives you " + - days + " days. There " + isAre - orders.push " " + sb + " starbase" + "s"*(sb!=1) + " in the galaxy for resupplying your ship." - for line in orders - print line // for extra drama, add a `wait 0.5` line here! - end for - print - input "Press Return when ready to accept command" - print - self.enterQuadrant -end function - -Game.enterQuadrant = function - // Populate the local quadrant and print a short-range scan. - ship = self.galaxy.ship - here = self.galaxy.localQuadrant - here.charted = true - here.populate ship.position.sector - - if self.galaxy.daysElapsed == 0 then - print "Your mission begins with your ship located" - print "in the galactic quadrant, '" + here.fullName + "'" - else - print "Now entering " + here.fullName + " quadrant . . ." - end if - print - - if here.klingons > 0 then - print "COMBAT AREA CONDITION RED" - if ship.shields <= 200 then print " SHIELDS DANGEROUSLY LOW" - end if - self.shortRangeScan -end function - -Game.shortRangeScan = function - ship = self.galaxy.ship - ship.docked = false - quad = self.galaxy.localQuadrant - cs = null - for x in range(ship.position.sector.x - 1, ship.position.sector.x + 1) - for y in range(ship.position.sector.y - 1, ship.position.sector.y + 1) - if 0 <= x <= 7 and 0 <= y <= 7 and quad.value(x, y) == Entity.starbase then - ship.docked = true - cs = "DOCKED" - ship.refill - print "Shields dropped for docking purposes" - ship.shields = 0 - end if - end for - end for - if not cs then - if quad.klingons then - cs = "*RED*" - else if ship.energy < ship.maxEnergy * 0.1 then - cs = "*YELLOW*" - else - cs = "GREEN" - end if - end if - if ship.deviceStatus[1] < 0 then - print - print "*** Short range sensors are out ***" - return - end if - print "-"*33 - for x in range(0, 7) - line = quad.data[x].join - if x == 0 then - line += " STARDATE " + round(self.galaxy.stardate, 1) - else if x == 1 then - line += " CONDITION " + cs - else if x == 2 then - line += " QUADRANT " + ship.position.quadrant.oneBasedStr - else if x == 3 then - line += " SECTOR " + ship.position.sector.oneBasedStr - else if x == 4 then - line += " PHOTON TORPEDOES " + ship.torpedos - else if x == 5 then - line += " TOTAL ENERGY " + floor(ship.energy + ship.shields) - else if x == 6 then - line += " SHIELDS " + floor(ship.shields) - else if x == 7 then - line += " KLINGONS REMAINING " + self.galaxy.qtyKlingons - end if - print line - end for - print "-"*33 -end function - -Game.longRangeScan = function - ship = self.galaxy.ship - if ship.deviceStatus[2] < 0 then - print "Long range sensors are inoperable" - return - end if - print "Long range scan for quadrant " + ship.position.quadrant.oneBasedStr - self.galaxy.printLongRangeScan ship.position.quadrant -end function - -Game.updateKlingons = function - // Move klingons around randomly within the sector - here = self.galaxy.localQuadrant - if not here.klingonShips then return - - for klingonShip in here.klingonShips - if klingonShip.shield <= 0 then continue // (already disabled/destroyed) - here.setValue klingonShip.sector.x, klingonShip.sector.y, Entity.empty - klingonShip.sector = here.findEmptyPoint - here.setValue klingonShip.sector.x, klingonShip.sector.y, Entity.klingon - end for - - self.klingonsFire -end function - -Game.klingonsFire = function - // Nearby klingons fire on the player ship. - here = self.galaxy.localQuadrant - if here.klingons <= 0 then return - ship = self.galaxy.ship - if ship.docked then - print "Starbase shields protect the Enterprise" - return - end if - for klingonShip in here.klingonShips - if klingonShip.shield <= 0 then continue // (already disabled/destroyed) - hit = floor((klingonShip.shield / klingonShip.distance(ship)) * (rnd + 2)) - ship.shields -= hit - print " " + hit + " unit hit on Enterprise from sector " + klingonShip.sector.oneBasedStr - if ship.shields <= 0 then - self.endGame false, false, true - return - end if - print " " - if hit >= 20 and rnd < 0.60 and hit / ship.shields > 0.02 then - deviceNum = floor(rnd * ship.devices.len) - ship.deviceStatus[deviceNum] -= hit / ship.shields + 0.5 * rnd - print "Damage control reports '" + ship.devices[deviceNum] + " damaged by the hit'" - end if - end for -end function - -Game.damControlWhileUnderway = function(improvement=1) - // Work on repairing damaged devices, and 20% of the time, do additional work on - // some random device (which may make it better or worse). - ship = self.galaxy.ship - first = true - for i in range(0, ship.devices.len-1) - if ship.deviceStatus[i] >= 0 then continue - ship.deviceStatus[i] += improvement - if -0.1 < ship.deviceStatus[i] < 0 then ship.deviceStatus[i] = -0.1 - if ship.deviceStatus[i] >= 0 then - if first then s = "Damage control report:" else s = "" - s += " " + ship.devices[i] + " repair completed" - print s - first = false - end if - end for - - if rnd > 0.2 then return - deviceNum = floor(rnd * ship.devices.len) - if rnd < 0.6 then - ship.deviceStatus[deviceNum] -= rnd * 5 + 1 - print "Damage control report: " + ship.devices[deviceNum] + " damaged" - else - ship.deviceStatus[deviceNum] += rnd * 3 + 1 - print "Damage control report: " + ship.devices[deviceNum] + " state of repair improved" - end if -end function - -Game.navigate = function - galaxy = self.galaxy - ship = galaxy.ship - cd = input("Course (1-9)? ").val - 1 // (convert input to 0-8) - if cd == dirs.len - 1 then cd == 0 - if cd < 0 or cd >= dirs.len then - print " Lt. Sulu reports, 'Incorrect course data, sir!'" - return - end if - - if ship.deviceStatus[0] < 0 then maxWarp = 0.2 else maxWarp = 8 - warp = input("Warp factor (0-" + maxWarp + ")? ").val - if warp > maxWarp and maxWarp < 1 then - print "Warp engines are damaged. Maximum speed = warp " + maxWarp - return - end if - if warp == 0 then return - if warp < 0 or warp > 8 then - print " Chief engineer Scott reports 'The engines won't take warp " + warp + "!'" - return - end if - - warpRounds = round(warp * 8) - // Note that we check for sufficient energy based on 1/10th of what it - // will actually cost. This is apparently intentional. - if ship.energy < warpRounds then - print "Engineering reports 'Insufficient energy available" - print " for maneuvering at warp " + warp + "!'" - if ship.shields >= warpRounds - ship.energy and ship.deviceStatus[6] >= 0 then - print "Deflector control room acknowledges " + ship.shields + " units of energy" - print " presently deployed to shields." - end if - return - end if - - self.updateKlingons - self.damControlWhileUnderway - - here = galaxy.localQuadrant - here.setValue ship.position.sector.x, ship.position.sector.y, Entity.empty - startQuad = Point.make(here.point.x, here.point.y) -// print "DEBUG set value at " + ship.position.sector.x + "," + ship.position.sector.y + " to Entity.empty" - // interpolate the direction - cdi = floor(cd) - dx = mathUtil.lerp(dirs[cdi][0], dirs[cdi+1][0], cd - cdi) - dy = mathUtil.lerp(dirs[cdi][1], dirs[cdi+1][1], cd - cdi) - finalGlobalX = ship.position.quadrant.x * 8 + ship.position.sector.x + dx * warpRounds - finalGlobalY = ship.position.quadrant.y * 8 + ship.position.sector.y + dy * warpRounds - for i in range(1, warpRounds) - ship.position.sector.x += dx - ship.position.sector.y += dy - if not (0 <= ship.position.sector.x <= 7 and 0 <= ship.position.sector.y <= 7) then - // Exceeded quadrant limits; calculate final position. - // Note that we randomly re-generate all the stuff in a quadrant every - // time we enter it. So we can jump right to the final position now; - // We only check for collisions when moving *within* your starting sector. - // your starting sector. - ship.position.quadrant.x = floor(finalGlobalX / 8) - ship.position.quadrant.y = floor(finalGlobalY / 8) - ship.position.sector.x = finalGlobalX - ship.position.quadrant.x * 8 - ship.position.sector.y = finalGlobalY - ship.position.quadrant.y * 8 - hitEdge = false - if ship.position.quadrant.x < 0 then - hitEdge = true - ship.position.quadrant.x = 0 - ship.position.sector.x = 0 - else if ship.position.quadrant.x > 7 then - hitEdge = true - ship.position.quadrant.x = 7 - ship.position.sector.x = 7 - end if - if ship.position.quadrant.y < 0 then - hitEdge = true - ship.position.quadrant.y = 0 - ship.position.sector.y = 0 - else if ship.position.quadrant.y > 7 then - hitEdge = true - ship.position.quadrant.y = 7 - ship.position.sector.y = 7 - end if - if hitEdge then - print "Lt. Uhura reports message from Starfleet Command:" - print " 'Permission to attempt crossing of galactic perimeter" - print " is hereby *denied*. Shut down your engines.'" - print "Chief Engineer Scott reports 'Warp engines shut down" - print " at sector " + ship.position.sector.oneBasedStr + - " of quadrant " + ship.position.quadrant.oneBasedStr + ".'" - end if - break - end if - x = floor(ship.position.sector.x) - y = floor(ship.position.sector.y) - if here.value(x, y) != Entity.empty then - ship.position.sector.x = floor(x - dx) - ship.position.sector.y = floor(y - dy) - print "Warp engines shut down at sector " + ship.position.sector.oneBasedStr + - " due to bad navigation" - break - end if - end for - ship.position.sector.x = floor(ship.position.sector.x) - ship.position.sector.y = floor(ship.position.sector.y) - doScan = true - if ship.position.quadrant != startQuad then - self.enterQuadrant - doScan = false - else - here.setValue ship.position.sector.x, ship.position.sector.y, Entity.ship -// print "DEBUG set value at " + ship.position.sector.x + "," + ship.position.sector.y + " to Entity.ship" - end if - ship.useWarpEnergy warpRounds - if warp < 1 then galaxy.stardate += round(warp, 1) else galaxy.stardate += 1 - if galaxy.missionOver then - self.endGame false, false, false - else if doScan then - self.shortRangeScan - end if -end function - -Game.damageControl = function - ship = self.galaxy.ship - if ship.deviceStatus[5] < 0 then - print "Damage control report not available." - else - print - print "DEVICE STATE OF REPAIR" - for i in range(0, ship.devices.len-1) - print ship.devices[i].pad(26) + round(ship.deviceStatus[i], 2) - end for - print - end if - - if not ship.docked then return - - repairTime = 0 - for status in ship.deviceStatus - if status < 0 then repairTime += 0.1 - end for - if repairTime == 0 then return - - repairTime += self.galaxy.localQuadrant.extraRepairTime - if repairTime >= 1 then repairTime = 0.9 - print - print "Technicians standing by to effect repairs to your ship;" - print "estimated time to repair: " + round(repairTime, 2) + " stardates" - if getYesNo("Will you authorize the repair order (Y/N)") == "no" then return - - for i in range(0, ship.devices.len-1) - if ship.deviceStatus[i] < 0 then ship.deviceStatus[i] = 0 - end for - self.galaxy.stardate += repairTime + 0.1 -end function - -Game.shieldControl = function - ship = self.galaxy.ship - if ship.deviceStatus[6] < 0 then - print "Shield control inoperable" - return - end if - totalEnergy = ship.energy + ship.shields - shieldEnergy = input("Energy available = " + totalEnergy + " Number of units to shields? ") - if shieldEnergy == "" then shieldEnergy = ship.shields else shieldEnergy = shieldEnergy.val - if shieldEnergy > totalEnergy then - print "Shield control reports 'This is not the federation treasury.'" - print - shieldEnergy = -1 - end if - if shieldEnergy < 0 or shieldEnergy == ship.shields then - print "" - return - end if - ship.energy += ship.shields - shieldEnergy - ship.shields = shieldEnergy - print "Deflector control room report:" - print " 'Shields now at " + ship.shields + " units per your command.'" -end function - -Game.computer = function - galaxy = self.galaxy - ship = galaxy.ship - if ship.deviceStatus[7] < 0 then - print "Computer disabled" - return - end if - - while true - command = input("Computer active and awaiting command? ") - print - if command == "0" then // Cumulative Galactic Record - print - print " COMPUTER RECORD OF GALAXY FOR QUADRANT " + - ship.position.quadrant.oneBasedStr - print " 1 2 3 4 5 6 7 8" - sep = " ----- ----- ----- ----- ----- ----- ----- -----" - print sep - for i in range(0,7) - line = " " + (i+1) + " " - for j in range(0, 7) - line += " " - if galaxy.quadrants[i][j].charted then - line += galaxy.quadrants[i][j].lrsValue - else - line += "***" - end if - end for - print line - print sep - end for - else if command == "1" then // Status Report - print " STATUS REPORT:" - print "Klingon" + "s" * (galaxy.qtyKlingons != 1) + " left: " + galaxy.qtyKlingons - print "Mission must be completed in " + round(galaxy.daysLeft, 1) + " stardates" - - if galaxy.qtyBases == 0 then - print "Your stupidity has left you on your own in" - print " the galaxy -- you have no starbases left!" - else - print "The Federation is maintaining " + galaxy.qtyBases + - " starbase" + "s" * (galaxy.qtyBases != 1) + " in the galaxy" - end if - - self.damageControl - else if command == "2" then // Photon Torpedo Data - here = galaxy.localQuadrant - if here.klingons <= 0 then - print "Science officer Spock reports 'Sensors show no enemy ships" - print " in this quadrant'" - else - print "FROM ENTERPRISE TO KLINGON BATTLE CRUISER" + "S" * (here.klingons != 1) - for klingonShip in here.klingonShips - if klingonShip.shield <= 0 then continue - printDirection ship.position.sector, klingonShip.sector - end for - end if - else if command == "3" then // Starbase Nav Data - here = galaxy.localQuadrant - if not here.starbase then - print "Science officer Spock reports, 'Sensors show no starbases" - print " in this quadrant.'" - else - print "FROM ENTERPRISE TO STARBASE:" - printDirection ship.position.sector, here.starbase - end if - else if command == "4" then // Direction/Distance Calculator - print "DIRECTION/DISTANCE CALCULATOR:" - print "You are at quadrant " + ship.position.quadrant.oneBasedStr + - " SECTOR " + ship.position.sector.oneBasedStr - print "Please enter" - fromXY = getXY(" Initial coordinates (X,Y)") - toXY = getXY(" Final coordinates (X,Y)") - printDirection fromXY, toXY - else if command == "5" then // Galaxy 'Region Name' Map - print - print " THE GALAXY" - print " 1 2 3 4 5 6 7 8" - sep = " ----- ----- ----- ----- ----- ----- ----- -----" - print sep - for i in range(0,7) - line = " " + (i+1) + " " - line += galaxy.quadrants[i][0].name.padBoth(25) - line += galaxy.quadrants[i][4].name.padBoth(25) - print line - print sep - end for - else - print "Functions available from Library-Computer:" - print " 0 = Cumulative Galactic Record" - print " 1 = Status Report" - print " 2 = Photon Torpedo Data" - print " 3 = Starbase Nav Data" - print " 4 = Direction/Distance Calculator" - print " 5 = Galaxy 'Region Name' Map" - continue - end if - print - break // break out after any valid command - end while -end function - -Game.destroyKlingon = function(x, y) - // Destroy the Klingon in the local quadrant at sector x,y. - // Return true if the game is now won (last klingon destroyed), - // or false otherwise. - galaxy = self.galaxy - here = galaxy.localQuadrant - print "*** KLINGON DESTROYED ***" - galaxy.qtyKlingons -= 1 - here.klingons -= 1 - here.setValue x, y, Entity.empty - for i in here.klingonShips.indexes - ks = here.klingonShips[i] - if ks.sector.x == x and ks.sector.y == y then - ks.shield = 0 - here.klingonShips.remove i - break - end if - end for - - if galaxy.qtyKlingons <= 0 then - self.endGame true, false, false - return true - end if - return false -end function - - -Game.phasers = function - galaxy = self.galaxy - ship = galaxy.ship - here = galaxy.localQuadrant - klingonShips = here.klingonShips - - if ship.deviceStatus[3] < 0 then - print "Phasers inoperative" - return - end if - - if here.klingons <= 0 then - print "Science officer Spock reports 'Sensors show no enemy ships" - print " in this quadrant'" - return - end if - - if ship.deviceStatus[7] < 0 then - print "Computer failure hampers accuracy" - end if - - print "Phasers locked on target; energy available = " + ship.energy + " units" - while true - phaserPower = input("Number of units to fire? ").val - if phaserPower <= 0 then return - if phaserPower <= ship.energy then break - print "Energy available = " + ship.energy + " units" - end while - - ship.energy -= phaserPower - if ship.deviceStatus[7] < 0 then // (bug in original; was d(6) - phaserPower *= rnd - end if - - phaserPerKlingon = floor(phaserPower / here.klingons) - for i in range(klingonShips.len - 1) - ks = klingonShips[i] - if ks.shield <= 0 then continue - distance = mathUtil.distance(ks.sector, ship.position.sector) - hit = floor((phaserPerKlingon / distance) * (rnd + 2)) - if hit <= 0.15 * ks.shield then - print "Sensors show no damage to enemy at " + ks.sector.oneBasedStr - else - ks.shield -= hit - print " " + hit + " unit hit on Klingon at sector " + ks.sector.oneBasedStr - if ks.shield <= 0 then - if self.destroyKlingon(ks.sector.x, ks.sector.y) then return - else - print " (Sensors show " + round(ks.shield, 6) + " units remaining)" - end if - end if - end for - - self.klingonsFire -end function - -Game.torpedos = function - galaxy = self.galaxy - ship = galaxy.ship - here = galaxy.localQuadrant - klingonShips = here.klingonShips - - if ship.torpedos <= 0 then - print "All photon torpedos expended" - return - else if ship.deviceStatus[4] < 0 then - print "Photon tubes are not operational" - return - end if - - cd = input("Course (1-9)? ").val - 1 // (convert input to 0-8) - if cd == dirs.len - 1 then cd == 0 - if cd < 0 or cd >= dirs.len then - print " Lt. Sulu reports, 'Incorrect course data, sir!'" - return - end if - - cdi = floor(cd) - dx = mathUtil.lerp(dirs[cdi][0], dirs[cdi+1][0], cd - cdi) - dy = mathUtil.lerp(dirs[cdi][1], dirs[cdi+1][1], cd - cdi) - - ship.energy -= 2 - ship.torpedos -= 1 - - x = ship.position.sector.x - y = ship.position.sector.y - print "Torpedo track:" - while true - x += dx - y += dy - roundX = round(x); roundY = round(y) - if not (0 <= roundX <= 7) or not (0 <= roundY <= 7) then - print "Torpedo missed" - self.klingonsFire - return - end if - print " " + (roundX+1) + " , " + (roundY+1) - wait 0.5 // (added for dramatic effect) - entityHit = here.value(roundX, roundY) - if entityHit != Entity.empty then break - end while - - if entityHit == Entity.klingon then - if self.destroyKlingon(roundX, roundY) then return - else if entityHit == Entity.star then - print "Star at " + (roundX+1) + " , " + (roundY+1) + " absorbed torpedo energy." - else if entityHit == Entity.starbase then - print "*** STARBASE DESTROYED ***" - here.bases -= 1 - here.setValue roundX, roundY, Entity.empty - galaxy.qtyBases -= 1 - if galaxy.qtyBases == 0 and galaxy.qtyKlingons <= galaxy.daysLeft then - // (Note: bug in original code, compared qtyKlingons to - // quantity daysLeft - missionDuration, which would always be a negative - // number. So this hard-labor message could never appear. I've chosen - // a different comparison which at least can be true sometimes.) - print "That does it, captain!! You are hereby relieved of command" - print "and sentenced to 99 stardates at hard labor on Cygnus 12!!" - self.endGame false, false, false - return - end if - print "Starfleet Command reviewing your record to consider" - print "court martial!" - ship.docked = false - end if - - self.klingonsFire -end function - -Game.endGame = function(won=false, quit=true, shipDestroyed=false) - if won then - print "Congratulations, captain! The last klingon battle cruiser" - print "menacing the federation has been destroyed." - efficiency = round(1000 * self.galaxy.qtyKlingons / self.galaxy.daysElapsed^2, 4) - print "Your efficiency rating is " + efficiency - print - else - if not quit then - if shipDestroyed then - print - print "The enterprise has been destroyed. The Federation " - print "will be conquered." - end if - print "It is stardate " + round(self.galaxy.stardate, 1) - end if - - print "There were " + self.galaxy.qtyKlingons + " klingon battle cruisers left at" - print "the end of your mission." - print - end if - if self.galaxy.qtyBases == 0 then exit - print "The Federation is in need of a new starship commander" - print "for a similar mission -- if there is a volunteer," - if input("let him step forward and enter 'aye'? ").lower().trim != "aye" then exit - self.gameOver = true -end function - -notImplemented = function - print - print "Not implemented yet." - print -end function - -Game.commands = [] // each entry is [command, summary, function] -Game.addCommand = function(command, summary, func) - self.commands.push [command, summary, @func] -end function - -Game.addCommand "NAV", "to set course", @Game.navigate -Game.addCommand "SRS", "for short range sensor scan", @Game.shortRangeScan -Game.addCommand "LRS", "for long range sensor scan", @Game.longRangeScan -Game.addCommand "PHA", "to fire phasers", @Game.phasers -Game.addCommand "TOR", "to fire photon torpedos", @Game.torpedos -Game.addCommand "SHE", "to raise or lower shields", @Game.shieldControl -Game.addCommand "DAM", "for damage control reports", @Game.damageControl -Game.addCommand "COM", "to call on library-computer", @Game.computer -Game.addCommand "HLP", "for help, i.e. instructions", @Instructions.print // (not in original game) -Game.addCommand "XXX", "to resign your command", @Game.endGame - - -Game.doOneCommand = function - cmd = input("Command? ").upper - for entry in self.commands - if cmd == entry[0] then - self.curCmdFunc = entry[2] - self.curCmdFunc - return - end if - end for - print "Enter one of the following:" - for entry in self.commands - print " " + entry[0] + " (" + entry[1] + ")" - end for - print -end function - -Game.mainLoop = function - while not self.gameOver - self.doOneCommand - if self.galaxy.ship.stranded then - print - print "** FATAL ERROR ** You've just stranded your ship in space." - print "You have insufficient maneuvering energy, and shield control" - print "is presently incapable of cross-circuiting to engine room!!" - end if - end while -end function - -for i in range(1,12); print; end for -print " "*10 + "*************************************" -print " "*10 + "* *" -print " "*10 + "* *" -print " "*10 + "* * * SUPER STAR TREK * * *" -print " "*10 + "* *" -print " "*10 + "* *" -print " "*10 + "*************************************" -for i in range(1,8); print; end for -if getYesNo("Do you need instructions (y/n)") == "yes" then - Instructions.print -end if - -while true - game = new Game - game.init - game.printIntro - game.mainLoop -end while \ No newline at end of file diff --git a/00_Alternate_Languages/84_Super_Star_Trek/README.md b/00_Alternate_Languages/84_Super_Star_Trek/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/84_Super_Star_Trek/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/84_Super_Star_Trek/instructions.txt b/00_Alternate_Languages/84_Super_Star_Trek/instructions.txt deleted file mode 100644 index 837558347..000000000 --- a/00_Alternate_Languages/84_Super_Star_Trek/instructions.txt +++ /dev/null @@ -1,130 +0,0 @@ - - - - - - - - - - -************************************* -* * -* * -* * * SUPER STAR TREK * * * -* * -* * -************************************* - - - - - - - - - INSTRUCTIONS FOR 'SUPER STAR TREK' - -1. WHEN YOU SEE \COMMAND ?\ PRINTED, ENTER ONE OF THE LEGAL - COMMANDS (NAV,SRS,LRS,PHA,TOR,SHE,DAM,COM, OR XXX). -2. IF YOU SHOULD TYPE IN AN ILLEGAL COMMAND, YOU'LL GET A SHORT - LIST OF THE LEGAL COMMANDS PRINTED OUT. -3. SOME COMMANDS REQUIRE YOU TO ENTER DATA (FOR EXAMPLE, THE - 'NAV' COMMAND COMES BACK WITH 'COURSE (1-9) ?'.) IF YOU - TYPE IN ILLEGAL DATA (LIKE NEGATIVE NUMBERS), THAN COMMAND - WILL BE ABORTED - - THE GALAXY IS DIVIDED INTO AN 8 X 8 QUADRANT GRID, -AND EACH QUADRANT IS FURTHER DIVIDED INTO AN 8 X 8 SECTOR GRID. - - YOU WILL BE ASSIGNED A STARTING POINT SOMEWHERE IN THE -GALAXY TO BEGIN A TOUR OF DUTY AS COMANDER OF THE STARSHIP -\ENTERPRISE\; YOUR MISSION: TO SEEK AND DESTROY THE FLEET OF -KLINGON WARWHIPS WHICH ARE MENACING THE UNITED FEDERATION OF -PLANETS. - - YOU HAVE THE FOLLOWING COMMANDS AVAILABLE TO YOU AS CAPTAIN -OF THE STARSHIP ENTERPRISE: - -\NAV\ COMMAND = WARP ENGINE CONTROL -- - COURSE IS IN A CIRCULAR NUMERICAL 4 3 2 - VECTOR ARRANGEMENT AS SHOWN . . . - INTEGER AND REAL VALUES MAY BE ... - USED. (THUS COURSE 1.5 IS HALF- 5 ---*--- 1 - WAY BETWEEN 1 AND 2 ... - . . . - VALUES MAY APPROACH 9.0, WHICH 6 7 8 - ITSELF IS EQUIVALENT TO 1.0" - COURSE - ONE WARP FACTOR IS THE SIZE OF - ONE QUADRANT. THEREFORE, TO GET - FROM QUADRANT 6,5 TO 5,5, YOU WOULD - USE COURSE 3, WARP FACTOR 1. - -\SRS\ COMMAND = SHORT RANGE SENSOR SCAN - SHOWS YOU A SCAN OF YOUR PRESENT QUADRANT. - - SYMBOLOGY ON YOUR SENSOR SCREEN IS AS FOLLOWS: - <*> = YOUR STARSHIP'S POSITION - +K+ = KLINGON BATTLE CRUISER - >!< = FEDERATION STARBASE (REFUEL/REPAIR/RE-ARM HERE!) - * = STAR - - A CONDENSED 'STATUS REPORT' WILL ALSO BE PRESENTED. - -\LRS\ COMMAND = LONG RANGE SENSOR SCAN - SHOWS CONDITIONS IN SPACE FOR ONE QUADRANT ON EACH SIDE - OF THE ENTERPRISE (WHICH IS IN THE MIDDLE OF THE SCAN) - THE SCAN IS CODED IN THE FORM \###\, WHERE TH UNITS DIGIT - IS THE NUMBER OF STARS, THE TENS DIGIT IS THE NUMBER OF - STARBASES, AND THE HUNDREDS DIGIT IS THE NUMBER OF - KLINGONS. - - EXAMPLE - 207 = 2 KLINGONS, NO STARBASES, & 7 STARS. - -\PHA\ COMMAND = PHASER CONTROL. - ALLOWS YOU TO DESTROY THE KLINGON BATTLE CRUISERS BY - ZAPPING THEM WITH SUITABLY LARGE UNITS OF ENERGY TO - DEPLETE THEIR SHIELD POWER. (REMEMBER, KLINGONS HAVE - PHASERS TOO!) - -\TOR\ COMMAND = PHOTON TORPEDO CONTROL - TORPEDO COURSE IS THE SAME AS USED IN WARP ENGINE CONTROL - IF YOU HIT THE KLINGON VESSEL, HE IS DESTROYED AND - CANNOT FIRE BACK AT YOU. IF YOU MISS, YOU ARE SUBJECT TO - HIS PHASER FIRE. IN EITHER CASE, YOU ARE ALSO SUBJECT TO - THE PHASER FIRE OF ALL OTHER KLINGONS IN THE QUADRANT. - - THE LIBRARY-COMPUTER (\COM\ COMMAND) HAS AN OPTION TO - COMPUTE TORPEDO TRAJECTORY FOR YOU (OPTION 2) - -\SHE\ COMMAND = SHIELD CONTROL - DEFINES THE NUMBER OF ENERGY UNITS TO BE ASSIGNED TO THE - SHIELDS. ENERGY IS TAKEN FROM TOTAL SHIP'S ENERGY. NOTE - THAN THE STATUS DISPLAY TOTAL ENERGY INCLUDES SHIELD ENERGY - -\DAM\ COMMAND = DAMMAGE CONTROL REPORT - GIVES THE STATE OF REPAIR OF ALL DEVICES. WHERE A NEGATIVE - 'STATE OF REPAIR' SHOWS THAT THE DEVICE IS TEMPORARILY - DAMAGED. - -\COM\ COMMAND = LIBRARY-COMPUTER - THE LIBRARY-COMPUTER CONTAINS SIX OPTIONS: - OPTION 0 = CUMULATIVE GALACTIC RECORD - THIS OPTION SHOWES COMPUTER MEMORY OF THE RESULTS OF ALL - PREVIOUS SHORT AND LONG RANGE SENSOR SCANS - OPTION 1 = STATUS REPORT - THIS OPTION SHOWS THE NUMBER OF KLINGONS, STARDATES, - AND STARBASES REMAINING IN THE GAME. - OPTION 2 = PHOTON TORPEDO DATA - WHICH GIVES DIRECTIONS AND DISTANCE FROM THE ENTERPRISE - TO ALL KLINGONS IN YOUR QUADRANT - OPTION 3 = STARBASE NAV DATA - THIS OPTION GIVES DIRECTION AND DISTANCE TO ANY - STARBASE WITHIN YOUR QUADRANT - OPTION 4 = DIRECTION/DISTANCE CALCULATOR - THIS OPTION ALLOWS YOU TO ENTER COORDINATES FOR - DIRECTION/DISTANCE CALCULATIONS - OPTION 5 = GALACTIC /REGION NAME/ MAP - THIS OPTION PRINTS THE NAMES OF THE SIXTEEN MAJOR - GALACTIC REGIONS REFERRED TO IN THE GAME. diff --git a/00_Alternate_Languages/84_Super_Star_Trek/superstartrek.bas b/00_Alternate_Languages/84_Super_Star_Trek/superstartrek.bas deleted file mode 100644 index efd74cb0d..000000000 --- a/00_Alternate_Languages/84_Super_Star_Trek/superstartrek.bas +++ /dev/null @@ -1,425 +0,0 @@ -10 REM SUPER STARTREK - MAY 16,1978 - REQUIRES 24K MEMORY -30 REM -40 REM **** **** STAR TREK **** **** -50 REM **** SIMULATION OF A MISSION OF THE STARSHIP ENTERPRISE, -60 REM **** AS SEEN ON THE STAR TREK TV SHOW. -70 REM **** ORIGIONAL PROGRAM BY MIKE MAYFIELD, MODIFIED VERSION -80 REM **** PUBLISHED IN DEC'S "101 BASIC GAMES", BY DAVE AHL. -90 REM **** MODIFICATIONS TO THE LATTER (PLUS DEBUGGING) BY BOB -100 REM *** LEEDOM - APRIL & DECEMBER 1974, -110 REM *** WITH A LITTLE HELP FROM HIS FRIENDS . . . -120 REM *** COMMENTS, EPITHETS, AND SUGGESTIONS SOLICITED -- -130 REM *** SEND TO: R. C. LEEDOM -140 REM *** WESTINGHOUSE DEFENSE & ELECTRONICS SYSTEMS CNTR. -150 REM *** BOX 746, M.S. 338 -160 REM *** BALTIMORE, MD 21203 -170 REM *** -180 REM *** CONVERTED TO MICROSOFT 8 K BASIC 3/16/78 BY JOHN GORDERS -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 -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" -227 PRINT:PRINT:PRINT:PRINT:PRINT -260 REM CLEAR 600 -270 Z$=" " -330 DIM G(8,8),C(9,2),K(3,3),N(3),Z(8,8),D(8) -370 T=INT(RND(1)*20+20)*100:T0=T:T9=25+INT(RND(1)*10):D0=0:E=3000:E0=E -440 P=10:P0=P:S9=200:S=0:B9=2:K9=0:X$="":X0$=" IS " -470 DEF FND(D)=SQR((K(I,1)-S1)^2+(K(I,2)-S2)^2) -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 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 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 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: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" -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 . . ." -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" -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: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!!":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 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)" -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 -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;"!'":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 IF S=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 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: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<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 -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 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):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 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>=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 -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>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 -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" -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: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 -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 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 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 -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 -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>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 -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 -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<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 -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 -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 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: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<=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 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)>.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 -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: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$: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 -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)<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 -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$="---------------------------------":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 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 -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 -7320 INPUT"COMPUTER ACTIVE AND AWAITING COMMAND";A:IF A<0 THEN 1990 -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" -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 -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 -7546 PRINT -7550 PRINT " 1 2 3 4 5 6 7 8" -7560 O1$=" ----- ----- ----- ----- ----- ----- ----- -----" -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$)):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" -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 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$ -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 -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 -8260 IF X>0 THEN 8280 -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 -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 -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 -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$)<>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 -8780 REM PRINTS DEVICE NAME -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 -8798 G2$="PHASER CONTROL":RETURN -8800 G2$="PHOTON TUBES":RETURN -8802 G2$="DAMAGE CONTROL":RETURN -8804 G2$="SHIELD CONTROL":RETURN -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 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 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 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 -9250 G2$=G2$+" III":RETURN -9260 G2$=G2$+" IV":RETURN diff --git a/00_Alternate_Languages/84_Super_Star_Trek/superstartrekins.bas b/00_Alternate_Languages/84_Super_Star_Trek/superstartrekins.bas deleted file mode 100644 index b3aa1daa6..000000000 --- a/00_Alternate_Languages/84_Super_Star_Trek/superstartrekins.bas +++ /dev/null @@ -1,127 +0,0 @@ -10 REM INSTRUCTIONS FOR "SUPER STARTREK" MAR 5, 1978 -20 FOR I=1 TO 12:PRINT:NEXT I -21 PRINT TAB(10);"*************************************" -22 PRINT TAB(10);"* *" -23 PRINT TAB(10);"* *" -30 PRINT TAB(10);"* * * SUPER STAR TREK * * *" -31 PRINT TAB(10);"* *" -32 PRINT TAB(10);"* *" -35 PRINT TAB(10);"*************************************" -36 FOR I=1 TO 8:PRINT:NEXT I -40 INPUT "DO YOU NEED INSTRUCTIONS (Y/N)";K$:IF K$="N" THEN 2000 -44 PRINT -45 REM PRINT "TURN THE TTY ON-LINE AND HIT ANY KEY EXCEPT RETURN" -46 REM IF INP(1)=13 THEN 46 -50 REM POKE 1229,2:POKE 1237,3:NULL 1 -90 PRINT" INSTRUCTIONS FOR 'SUPER STAR TREK'" -100 PRINT -110 PRINT"1. WHEN YOU SEE \COMMAND ?\ PRINTED, ENTER ONE OF THE LEGAL" -120 PRINT" COMMANDS (NAV,SRS,LRS,PHA,TOR,SHE,DAM,COM, OR XXX)." -130 PRINT"2. IF YOU SHOULD TYPE IN AN ILLEGAL COMMAND, YOU'LL GET A SHORT" -140 PRINT" LIST OF THE LEGAL COMMANDS PRINTED OUT." -150 PRINT"3. SOME COMMANDS REQUIRE YOU TO ENTER DATA (FOR EXAMPLE, THE" -160 PRINT" 'NAV' COMMAND COMES BACK WITH 'COURSE (1-9) ?'.) IF YOU" -170 PRINT" TYPE IN ILLEGAL DATA (LIKE NEGATIVE NUMBERS), THAN COMMAND" -180 PRINT" WILL BE ABORTED" -190 PRINT -270 PRINT" THE GALAXY IS DIVIDED INTO AN 8 X 8 QUADRANT GRID," -280 PRINT"AND EACH QUADRANT IS FURTHER DIVIDED INTO AN 8 X 8 SECTOR GRID." -290 PRINT -300 PRINT" YOU WILL BE ASSIGNED A STARTING POINT SOMEWHERE IN THE" -310 PRINT"GALAXY TO BEGIN A TOUR OF DUTY AS COMANDER OF THE STARSHIP" -320 PRINT"\ENTERPRISE\; YOUR MISSION: TO SEEK AND DESTROY THE FLEET OF" -330 PRINT"KLINGON WARWHIPS WHICH ARE MENACING THE UNITED FEDERATION OF" -340 PRINT"PLANETS." -360 PRINT -370 PRINT" YOU HAVE THE FOLLOWING COMMANDS AVAILABLE TO YOU AS CAPTAIN" -380 PRINT"OF THE STARSHIP ENTERPRISE:" -385 PRINT -390 PRINT"\NAV\ COMMAND = WARP ENGINE CONTROL --" -400 PRINT" COURSE IS IN A CIRCULAR NUMERICAL 4 3 2" -410 PRINT" VECTOR ARRANGEMENT AS SHOWN . . ." -420 PRINT" INTEGER AND REAL VALUES MAY BE ..." -430 PRINT" USED. (THUS COURSE 1.5 IS HALF- 5 ---*--- 1" -440 PRINT" WAY BETWEEN 1 AND 2 ..." -450 PRINT" . . ." -460 PRINT" VALUES MAY APPROACH 9.0, WHICH 6 7 8" -470 PRINT" ITSELF IS EQUIVALENT TO 1.0" -480 PRINT" COURSE" -490 PRINT" ONE WARP FACTOR IS THE SIZE OF " -500 PRINT" ONE QUADTANT. THEREFORE, TO GET" -510 PRINT" FROM QUADRANT 6,5 TO 5,5, YOU WOULD" -520 PRINT" USE COURSE 3, WARP FACTOR 1." -530 PRINT -540 PRINT"\SRS\ COMMAND = SHORT RANGE SENSOR SCAN" -550 PRINT" SHOWS YOU A SCAN OF YOUR PRESENT QUADRANT." -555 PRINT -560 PRINT" SYMBOLOGY ON YOUR SENSOR SCREEN IS AS FOLLOWS:" -570 PRINT" <*> = YOUR STARSHIP'S POSITION" -580 PRINT" +K+ = KLINGON BATTLE CRUISER" -590 PRINT" >!< = FEDERATION STARBASE (REFUEL/REPAIR/RE-ARM HERE!)" -600 PRINT" * = STAR" -605 PRINT -610 PRINT" A CONDENSED 'STATUS REPORT' WILL ALSO BE PRESENTED." -620 PRINT -640 PRINT"\LRS\ COMMAND = LONG RANGE SENSOR SCAN" -650 PRINT" SHOWS CONDITIONS IN SPACE FOR ONE QUADRANT ON EACH SIDE" -660 PRINT" OF THE ENTERPRISE (WHICH IS IN THE MIDDLE OF THE SCAN)" -670 PRINT" THE SCAN IS CODED IN THE FORM \###\, WHERE TH UNITS DIGIT" -680 PRINT" IS THE NUMBER OF STARS, THE TENS DIGIT IS THE NUMBER OF" -690 PRINT" STARBASES, AND THE HUNDRESDS DIGIT IS THE NUMBER OF" -700 PRINT" KLINGONS." -705 PRINT -706 PRINT" EXAMPLE - 207 = 2 KLINGONS, NO STARBASES, & 7 STARS." -710 PRINT -720 PRINT"\PHA\ COMMAND = PHASER CONTROL." -730 PRINT" ALLOWS YOU TO DESTROY THE KLINGON BATTLE CRUISERS BY " -740 PRINT" ZAPPING THEM WITH SUITABLY LARGE UNITS OF ENERGY TO" -750 PRINT" DEPLETE THEIR SHIELD POWER. (REMEMBER, KLINGONS HAVE" -760 PRINT" PHASERS TOO!)" -770 PRINT -780 PRINT"\TOR\ COMMAND = PHOTON TORPEDO CONTROL" -790 PRINT" TORPEDO COURSE IS THE SAME AS USED IN WARP ENGINE CONTROL" -800 PRINT" IF YOU HIT THE KLINGON VESSEL, HE IS DESTROYED AND" -810 PRINT" CANNOT FIRE BACK AT YOU. IF YOU MISS, YOU ARE SUBJECT TO" -820 PRINT" HIS PHASER FIRE. IN EITHER CASE, YOU ARE ALSO SUBJECT TO " -825 PRINT" THE PHASER FIRE OF ALL OTHER KLINGONS IN THE QUADRANT." -830 PRINT -835 PRINT" THE LIBRARY-COMPUTER (\COM\ COMMAND) HAS AN OPTION TO " -840 PRINT" COMPUTE TORPEDO TRAJECTORY FOR YOU (OPTION 2)" -850 PRINT -860 PRINT"\SHE\ COMMAND = SHIELD CONTROL" -870 PRINT" DEFINES THE NUMBER OF ENERGY UNITS TO BE ASSIGNED TO THE" -880 PRINT" SHIELDS. ENERGY IS TAKEN FROM TOTAL SHIP'S ENERGY. NOTE" -890 PRINT" THAN THE STATUS DISPLAY TOTAL ENERGY INCLUDES SHIELD ENERGY" -900 PRINT -910 PRINT"\DAM\ COMMAND = DAMMAGE CONTROL REPORT" -920 PRINT" GIVES THE STATE OF REPAIR OF ALL DEVICES. WHERE A NEGATIVE" -930 PRINT" 'STATE OF REPAIR' SHOWS THAT THE DEVICE IS TEMPORARILY" -940 PRINT" DAMAGED." -950 PRINT -960 PRINT"\COM\ COMMAND = LIBRARY-COMPUTER" -970 PRINT" THE LIBRARY-COMPUTER CONTAINS SIX OPTIONS:" -980 PRINT" OPTION 0 = CUMULATIVE GALACTIC RECORD" -990 PRINT" THIS OPTION SHOWES COMPUTER MEMORY OF THE RESULTS OF ALL" -1000 PRINT" PREVIOUS SHORT AND LONG RANGE SENSOR SCANS" -1010 PRINT" OPTION 1 = STATUS REPORT" -1020 PRINT" THIS OPTION SHOWS THE NUMBER OF KLINGONS, STARDATES," -1030 PRINT" AND STARBASES REMAINING IN THE GAME." -1040 PRINT" OPTION 2 = PHOTON TORPEDO DATA" -1050 PRINT" WHICH GIVES DIRECTIONS AND DISTANCE FROM THE ENTERPRISE" -1060 PRINT" TO ALL KLINGONS IN YOUR QUADRANT" -1070 PRINT" OPTION 3 = STARBASE NAV DATA" -1080 PRINT" THIS OPTION GIVES DIRECTION AND DISTANCE TO ANY " -1090 PRINT" STARBASE WITHIN YOUR QUADRANT" -1100 PRINT" OPTION 4 = DIRECTION/DISTANCE CALCULATOR" -1110 PRINT" THIS OPTION ALLOWS YOU TO ENTER COORDINATES FOR" -1120 PRINT" DIRECTION/DISTANCE CALCULATIONS" -1130 PRINT" OPTION 5 = GALACTIC /REGION NAME/ MAP" -1140 PRINT" THIS OPTION PRINTS THE NAMES OF THE SIXTEEN MAJOR " -1150 PRINT" GALACTIC REGIONS REFERRED TO IN THE GAME." -1990 REM POKE 1229,0:POKE 1237,1:NULL 0 -2000 REM PRINT:PRINT:PRINT -2010 REM PRINT "TURN CASSETTE PLAYER ON AND HIT ANY KEY EXCEPT RETURN" -2020 REM IF INP(1)=13 THEN 2020 -2030 REM PRINT -2040 REM PRINT "TURN CASSETTE PLAYER OFF AND " -2050 REM PRINT "TYPE 'RUN' WHEN COMPUTER PRINTS 'OK'" diff --git a/00_Alternate_Languages/85_Synonym/MiniScript/README.md b/00_Alternate_Languages/85_Synonym/MiniScript/README.md deleted file mode 100644 index f887013c7..000000000 --- a/00_Alternate_Languages/85_Synonym/MiniScript/README.md +++ /dev/null @@ -1,17 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: -``` - miniscript synonym.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: -``` - load "synonym" - run -``` diff --git a/00_Alternate_Languages/85_Synonym/MiniScript/synonym.ms b/00_Alternate_Languages/85_Synonym/MiniScript/synonym.ms deleted file mode 100644 index c64c4f52e..000000000 --- a/00_Alternate_Languages/85_Synonym/MiniScript/synonym.ms +++ /dev/null @@ -1,47 +0,0 @@ -words = [["first", "start", "beginning", "onset", "initial"], -["similar", "alike", "same", "like", "resembling"], -["model", "pattern", "prototype", "standard", "criterion"], -["small", "insignificant", "little", "tiny", "minute"], -["stop", "halt", "stay", "arrest", "check", "standstill"], -["house", "dwelling", "residence", "domicile", "lodging", "habitation"], -["pit", "hole", "hollow", "well", "gulf", "chasm", "abyss"], -["push", "shove", "thrust", "prod","poke","butt", "press"], -["red", "rouge", "scarlet", "crimson", "flame", "ruby"], -["pain", "suffering", "hurt", "misery", "distress", "ache", "discomfort"]] - -words.shuffle - -responses = ["Right","Correct","Fine","Good!","Check"] - -print " " * 33 + "SYNONYM" -print " " * 15 + "Creative Computing Morristown, New Jersey" -print; print; print -print "A synonym of a word means another word in the English" -print "language which has the same or very nearly the same meaning." -print "I choose a word -- you type a synonym." -print "If you can't think a synonym, type the word 'HELP'" -print "and I will tell you a synonym." -print - -for synonyms in words - word = synonyms[0] - synonyms = synonyms[1:] - responses.shuffle - - print - while 1 - guess = input(" What is a synonym of " + word + "? ").lower - if guess == "help" then - synonyms.shuffle - print "**** A synonym of " + word + " is " + synonyms[0] + "." - print - else if guess == word or synonyms.indexOf(guess) == null then - print " Try again." - else - print responses[0] - break - end if - end while -end for -print -print "Synonym drill completed." diff --git a/00_Alternate_Languages/85_Synonym/README.md b/00_Alternate_Languages/85_Synonym/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/85_Synonym/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/85_Synonym/synonym.bas b/00_Alternate_Languages/85_Synonym/synonym.bas deleted file mode 100644 index 868657d98..000000000 --- a/00_Alternate_Languages/85_Synonym/synonym.bas +++ /dev/null @@ -1,53 +0,0 @@ -2 PRINT TAB(33);"SYNONYM" -4 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -6 PRINT: PRINT: PRINT -10 DIM R$(5),W$(10),L(30),R(30) -20 R$(1)="RIGHT": R$(2)="CORRECT": R$(3)="FINE": R$(4)="GOOD!" -30 R$(5)="CHECK" -70 C=0 -90 PRINT "A SYNONYM OF A WORD MEANS ANOTHER WORD IN THE ENGLISH" -100 PRINT "LANGUAGE WHICH HAS THE SAME OR VERY NEARLY THE SAME"; -110 PRINT " MEANING." -130 PRINT "I CHOOSE A WORD -- YOU TYPE A SYNONYM." -140 PRINT "IF YOU CAN'T THINK OF A SYNONYM, TYPE THE WORD 'HELP'" -145 PRINT "AND I WILL TELL YOU A SYNONYM.": PRINT -150 RESTORE: C=C+1: READ N -160 IF C>N THEN 420 -170 N1=INT(RND(1)*N+1) -174 IF R(N1)=1 THEN 170 -176 R(N1)=1 -180 FOR I=1 TO N1 -190 READ N2 -200 FOR J=1 TO N2 -210 READ W$(J) -220 NEXT J -230 NEXT I -232 FOR J=1 TO N2: L(J)=J: NEXT J -235 L(0)=N2: G=1: PRINT -237 L(G)=L(L(0)): L(0)=N2-1: PRINT -240 PRINT " WHAT IS A SYNONYM OF ";W$(G);: INPUT A$ -250 IF A$="HELP" THEN 340 -260 FOR K=1 TO N2 -270 IF G=K THEN 290 -280 IF A$=W$(K) THEN 320 -290 NEXT K -300 PRINT " TRY AGAIN.": GOTO 240 -320 PRINT R$(INT(RND(1)*5+1)): GOTO 150 -340 G1=INT(RND(1)*L(0)+1) -360 PRINT "**** A SYNONYM OF ";W$(G);" IS ";W$(L(G1));".": PRINT -370 L(G1)=L(L(0)): L(0)=L(0)-1: GOTO 240 -420 PRINT: PRINT "SYNONYM DRILL COMPLETED.": GOTO 999 -500 DATA 10 -510 DATA 5,"FIRST","START","BEGINNING","ONSET","INITIAL" -520 DATA 5,"SIMILAR","ALIKE","SAME","LIKE","RESEMBLING" -530 DATA 5,"MODEL","PATTERN","PROTOTYPE","STANDARD","CRITERION" -540 DATA 5,"SMALL","INSIGNIFICANT","LITTLE","TINY","MINUTE" -550 DATA 6,"STOP","HALT","STAY","ARREST","CHECK","STANDSTILL" -560 DATA 6,"HOUSE","DWELLING","RESIDENCE","DOMICILE","LODGING" -565 DATA "HABITATION" -570 DATA 7,"PIT","HOLE","HOLLOW","WELL","GULF","CHASM","ABYSS" -580 DATA 7,"PUSH","SHOVE","THRUST","PROD","POKE","BUTT","PRESS" -590 DATA 6,"RED","ROUGE","SCARLET","CRIMSON","FLAME","RUBY" -600 DATA 7,"PAIN","SUFFERING","HURT","MISERY","DISTRESS","ACHE" -605 DATA "DISCOMFORT" -999 END diff --git a/00_Alternate_Languages/86_Target/MiniScript/README.md b/00_Alternate_Languages/86_Target/MiniScript/README.md deleted file mode 100644 index c06194764..000000000 --- a/00_Alternate_Languages/86_Target/MiniScript/README.md +++ /dev/null @@ -1,17 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: -``` - miniscript target.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: -``` - load "target" - run -``` diff --git a/00_Alternate_Languages/86_Target/MiniScript/target.ms b/00_Alternate_Languages/86_Target/MiniScript/target.ms deleted file mode 100644 index 125fe2ff5..000000000 --- a/00_Alternate_Languages/86_Target/MiniScript/target.ms +++ /dev/null @@ -1,114 +0,0 @@ -degToRad = function(n) - return n * pi / 180 -end function - -radToDeg = function(n) - return n * 180 / pi -end function - -roundDown = function(n, r) - return floor(n / r) * r -end function - -getCoord = function(distance, radX, radZ) - xc = sin(radZ)*cos(radX)*distance - yc = sin(radZ)*sin(radX)*distance - zc = cos(radZ)*distance - return [xc,yc,zc] -end function - -distanceBetween = function (d1,d2) - return ((d1[0]-d2[0])^2 + (d1[1]-d2[1])^2 + (d1[2]-d2[2])^2)^.5 -end function - -coordStr = function(coords) - return "X = " + round(coords[0]) + - " Y = " + round(coords[1]) + " Z = " + round(coords[2]) -end function - -print " " * 33 + "TARGET" -print " " * 15 + "Creative Computing Morristown, New Jersey" -print; print; print - -print "You are the weapons officer on the Starship Enterprise" -print "and this is a test to see how accurae a shot you" -print "are in a 3-dimensional range. You will be told" -print "the radian offset for the X and Z axes, the location" -print "of the target in 3-dimensional rectangular coordinates," -print "the approximate number of degrees from the X and Z" -print "axes, and the approximate distance to the target." -print "You will then proceed to shoot at the target until it is" -print "destroyed!" -print; print -print "Good luck!" -roundToList = [20,10,2,1] -ready = true -while ready - turns = -1 - radX = rnd * 2 * pi - radZ = rnd * 2 * pi - print "Radians from X axis = " + radX + " from Z axis = " + radZ - - distance = 100000 * rnd * rnd - coords = getCoord(distance, radX, radZ) - - print "Target sighted: Approx Coordinates: " + coordStr(coords) - - gameRunning = true - while gameRunning - turns += 1 - if turns >=4 then - estDistance = distance - else - estDistance = roundDown(distance, roundToList[turns]) - end if - - print " Estimated Distance: " + estDistance - print - tx = input("Input angle deviation from X in degrees: ").val - tz = input("Input angle deviation from Z in degrees: ").val - tdist = input("Input distance: ").val - print - if tdist < 20 then - print "You blew yourself up!!" - gameRunning = false - else - tx = degToRad(tx) - tz = degToRad(tz) - - print "Radians from X-axis = " + tx + " from Z-axis = " + tz - targeted = getCoord(tdist, tx,tz) - distBet = distanceBetween(coords, targeted) - if distBet > 20 then - dx = targeted[0] - coords[0] - dy = targeted[1] - coords[1] - dz = targeted[2] - coords[2] - xMsg = {false: "Shot in front of target ", true: "Shot behind target "} - print xMsg[dx<0] + dx + " kilometers." - yMsg = {false: "Shot to left of target ", true: "Shot to right of target "} - print yMsg[dy<0] + dy + " kilometers." - zMsg = {false: "Shot above target ", true: "Shot below target "} - print zMsg[dz<0] + dz + " kilometers." - - print "Approx position of explosion: " + coordStr(targeted) - print " Distance from target = " + distBet - print - print - - else - print - print " * * * HIT * * * Target is non-functional" - print - print "Distance of explosion from target was " + distBet + "kilometers." - print - print "Mission accomplished in " + (turns+1) + " shots." - print - gameRunning = false - end if - end if - end while - print - ans = input("Ready for next target? ").lower - ready = ans and ans[0].lower == "y" - print -end while diff --git a/00_Alternate_Languages/86_Target/README.md b/00_Alternate_Languages/86_Target/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/86_Target/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/86_Target/target.bas b/00_Alternate_Languages/86_Target/target.bas deleted file mode 100644 index 7e99d3bb6..000000000 --- a/00_Alternate_Languages/86_Target/target.bas +++ /dev/null @@ -1,51 +0,0 @@ -10 PRINT TAB(33);"TARGET" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT: PRINT: PRINT -100 R=1: R1=57.296: P=3.14159 -110 PRINT "YOU ARE THE WEAPONS OFFICER ON THE STARSHIP ENTERPRISE" -120 PRINT "AND THIS IS A TEST TO SEE HOW ACCURATE A SHOT YOU" -130 PRINT "ARE IN A THREE-DIMENSIONAL RANGE. YOU WILL BE TOLD" -140 PRINT "THE RADIAN OFFSET FOR THE X AND Z AXES, THE LOCATION" -150 PRINT "OF THE TARGET IN THREE DIMENSIONAL RECTANGULAR COORDINATES," -160 PRINT "THE APPROXIMATE NUMBER OF DEGREES FROM THE X AND Z" -170 PRINT "AXES, AND THE APPROXIMATE DISTANCE TO THE TARGET." -180 PRINT "YOU WILL THEN PROCEEED TO SHOOT AT THE TARGET UNTIL IT IS" -190 PRINT "DESTROYED!": PRINT: PRINT "GOOD LUCK!!":PRINT: PRINT -220 A=RND(1)*2*P: B=RND(1)*2*P: Q=INT(A*R1): W=INT(B*R1) -260 PRINT "RADIANS FROM X AXIS =";A;" FROM Z AXIS =";B -280 P1=100000*RND(1)+RND(1): X=SIN(B)*COS(A)*P1: Y=SIN(B)*SIN(A)*P1 -290 Z=COS(B)*P1 -340 PRINT "TARGET SIGHTED: APPROXIMATE COORDINATES: X=";X;" Y=";Y;" Z=";Z -345 R=R+1: IF R>5 THEN 390 -350 ON R GOTO 355,360,365,370,375 -355 P3=INT(P1*.05)*20: GOTO 390 -360 P3=INT(P1*.1)*10: GOTO 390 -365 P3=INT(P1*.5)*2: GOTO 390 -370 P3=INT(P1): GOTO 390 -375 P3=P1 -390 PRINT " ESTIMATED DISTANCE:";P3 -400 PRINT:PRINT "INPUT ANGLE DEVIATION FROM X, DEVIATION FROM Z, DISTANCE"; -405 INPUT A1,B1,P2 -410 PRINT: IF P2<20 THEN PRINT "YOU BLEW YOURSELF UP!!": GOTO 580 -420 A1=A1/R1: B1=B1/R1: PRINT "RADIANS FROM X AXIS =";A1;" "; -425 PRINT "FROM Z AXIS =";B1 -480 X1=P2*SIN(B1)*COS(A1): Y1=P2*SIN(B1)*SIN(A1): Z1=P2*COS(B1) -510 D=((X1-X)^2+(Y1-Y)^2+(Z1-Z)^2)^(1/2) -520 IF D>20 THEN 670 -530 PRINT: PRINT " * * * HIT * * * TARGET IS NON-FUNCTIONAL": PRINT -550 PRINT "DISTANCE OF EXPLOSION FROM TARGET WAS";D;"KILOMETERS." -570 PRINT: PRINT "MISSION ACCOMPLISHED IN ";R;" SHOTS." -580 R=0: FOR I=1 TO 5: PRINT: NEXT I: PRINT "NEXT TARGET...": PRINT -590 GOTO 220 -670 X2=X1-X: Y2=Y1-Y: Z2=Z1-Z: IF X2<0 THEN 730 -710 PRINT "SHOT IN FRONT OF TARGET";X2;"KILOMETERS.": GOTO 740 -730 PRINT "SHOT BEHIND TARGET";-X2;"KILOMETERS." -740 IF Y2<0 THEN 770 -750 PRINT "SHOT TO LEFT OF TARGET";Y2;"KILOMETERS.": GOTO 780 -770 PRINT "SHOT TO RIGHT OF TARGET";-Y2;"KILOMETERS." -780 IF Z2<0 THEN 810 -790 PRINT "SHOT ABOVE TARGET";Z2;"KILOMETERS.": GOTO 820 -810 PRINT "SHOT BELOW TARGET";-Z2;"KILOMETERS." -820 PRINT "APPROX POSITION OF EXPLOSION: X=";X1;" Y=";Y1;" Z=";Z1 -830 PRINT " DISTANCE FROM TARGET =";D: PRINT: PRINT: PRINT: GOTO 345 -999 END diff --git a/00_Alternate_Languages/87_3-D_Plot/3dplot.bas b/00_Alternate_Languages/87_3-D_Plot/3dplot.bas deleted file mode 100644 index 4ee0f8a5e..000000000 --- a/00_Alternate_Languages/87_3-D_Plot/3dplot.bas +++ /dev/null @@ -1,17 +0,0 @@ -1 PRINT TAB(32);"3D PLOT" -2 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -3 PRINT:PRINT:PRINT -5 DEF FNA(Z)=30*EXP(-Z*Z/100) -100 PRINT -110 FOR X=-30 TO 30 STEP 1.5 -120 L=0 -130 Y1=5*INT(SQR(900-X*X)/5) -140 FOR Y=Y1 TO -Y1 STEP -5 -150 Z=INT(25+FNA(SQR(X*X+Y*Y))-.7*Y) -160 IF Z<=L THEN 190 -170 L=Z -180 PRINT TAB(Z);"*"; -190 NEXT Y -200 PRINT -210 NEXT X -300 END diff --git a/00_Alternate_Languages/87_3-D_Plot/MiniScript/3dplot.ms b/00_Alternate_Languages/87_3-D_Plot/MiniScript/3dplot.ms deleted file mode 100644 index 0cf1e5169..000000000 --- a/00_Alternate_Languages/87_3-D_Plot/MiniScript/3dplot.ms +++ /dev/null @@ -1,26 +0,0 @@ -// 3dPlot -// -// Converted from BASIC to MiniScript by Joe Strout - -print " "*32 + "3D PLOT" -print " "*15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -print; print; print -e = 2.71828 - -fna = function(z) - return 30 * e^(-z*z/100) -end function - -for x in range(-30, 30, 1.5) - lastZ = 0 - y1 = 5 * floor(sqrt(900-x*x)/5) - for y in range(y1, -y1, -5) - z = floor(25+fna(sqrt(x*x+y*y))-.7*y) - if z > lastZ then - print " "*(z-lastZ) + "*", "" - lastZ = z - end if - end for - print - wait 0.1 // (optional) -end for diff --git a/00_Alternate_Languages/87_3-D_Plot/MiniScript/README.md b/00_Alternate_Languages/87_3-D_Plot/MiniScript/README.md deleted file mode 100644 index 2bcec68c8..000000000 --- a/00_Alternate_Languages/87_3-D_Plot/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript number.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "number" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/87_3-D_Plot/README.md b/00_Alternate_Languages/87_3-D_Plot/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/87_3-D_Plot/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/87_3-D_Plot/d/.gitignore b/00_Alternate_Languages/87_3-D_Plot/d/.gitignore deleted file mode 100644 index d969f6b2c..000000000 --- a/00_Alternate_Languages/87_3-D_Plot/d/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.exe -*.obj diff --git a/00_Alternate_Languages/87_3-D_Plot/d/README.md b/00_Alternate_Languages/87_3-D_Plot/d/README.md deleted file mode 100644 index 8a01faf3c..000000000 --- a/00_Alternate_Languages/87_3-D_Plot/d/README.md +++ /dev/null @@ -1,182 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html) - -Converted to [D](https://dlang.org/) by [Bastiaan Veelo](https://github.com/veelo). - -## Running the code - -Assuming the reference [dmd](https://dlang.org/download.html#dmd) compiler: -```shell -dmd -dip1000 -run threedeeplot.d -``` - -[Other compilers](https://dlang.org/download.html) also exist. - -## On rounding floating point values to integer values - -The D equivalent of Basic `INT` is [`floor`](https://dlang.org/phobos/std_math_rounding.html#.floor), -which rounds towards negative infinity. If you change occurrences of `floor` to -[`lrint`](https://dlang.org/phobos/std_math_rounding.html#.lrint), you'll see that the plots show a bit more detail, -as is done in the bonus below. - -## Bonus: Self-writing programs - -With a small modification to the source, the program can be extended to **plot a random function**, and **print its formula**. - -```shell -rdmd -dip1000 threedeeplot_random.d -``` -(`rdmd` caches the executable, which results in speedy execution when the source does not change.) - -### Example output -``` - 3D Plot - (After Creative Computing Morristown, New Jersey) - - - f(z) = 30 * sin(z / 10.0) - - * - * * * * - * * * * * - * * * * * - * * * * * * - * * * * * * - * * * * * ** - * * * * * * * - * * * * * * ** - * * * * * * * * - * * * * * * * * - * * * * * * * ** - * * * * * * * * * - * * * * ** * * * * - * * * * ** * * * - * * * * * * * * - * * * * * * * * - * * * ** * * ** - * * * ** * ** - * * * * * ** - * * * * * ** - * * * * * ** - * * * ** * ** - * * * ** * * ** - * * * * * * * * - * * * * * * * * - * * * * ** * * * - * * * * ** * * * * - * * * * * * * * * - * * * * * * * ** - * * * * * * * * - * * * * * * * * - * * * * * * ** - * * * * * * * - * * * * * ** - * * * * * * - * * * * * * - * * * * * - * * * * * - * * * * - * -``` - -### Breakdown of differences - -Have a look at the relevant differences between `threedeeplot.d` and `threedeeplot_random.d`. -This is the original function with the single expression that is evaluated for the plot: -```d - static float fna(float z) - { - return 30.0 * exp(-z * z / 100.0); - } -``` -Here `static` means that the nested function does not need acces to its enclosing scope. - -Now, by inserting the following: -```d - enum functions = ["30.0 * exp(-z * z / 100.0)", - "sqrt(900.01 - z * z) * .9 - 2", - "30 * (cos(z / 16.0) + .5)", - "30 - 30 * sin(z / 18.0)", - "30 * exp(-cos(z / 16.0)) - 30", - "30 * sin(z / 10.0)"]; - - size_t index = uniform(0, functions.length); - writeln(center("f(z) = " ~ functions[index], width), "\n"); -``` -and changing the implementation of `fna` to -```d - float fna(float z) - { - final switch (index) - { - static foreach (i, f; functions) - case i: - mixin("return " ~ f ~ ";"); - } - } -``` -we unlock some very special abilities of D. Let's break it down: - -```d - enum functions = ["30.0 * exp(-z * z / 100.0)", /*...*/]; -``` -This defines an array of strings, each containing a mathematical expression. Due to the `enum` keyword, this is an -array that really only exists at compile-time. - -```d - size_t index = uniform(0, functions.length); -``` -This defines a random index into the array. `functions.length` is evaluated at compile-time, due to D's compile-time -function evaluation (CTFE). - -```d - writeln(center("f(z) = " ~ functions[index], width), "\n"); -``` -Unmistakenly, this prints the formula centered on a line. What happens behind the scenes is that `functions` (which -only existed at compile-time before now) is pasted in, so that an instance of that array actually exists at run-time -at this spot, and is instantly indexed. - -```d - float fna(float z) - { - final switch (index) - { - // ... - } - } -``` -`static` has been dropped from the nested function because we want to evaluate `index` inside it. The function contains -an ordinary `switch`, with `final` providing some extra robustness. It disallows a `default` case and produces an error -when the switch doesn't handle all cases. The `switch` body is where the magic happens and consists of these three -lines: -```d - static foreach (i, f; functions) - case i: - mixin("return " ~ f ~ ";"); -``` -The `static foreach` iterates over `functions` at compile-time, producing one `case` for every element in `functions`. -`mixin` takes a string, which is constructed at compile-time, and pastes it right into the source. - -In effect, the implementation of `float fna(float z)` unrolls itself into -```d - float fna(float z) - { - final switch (index) - { - case 0: - return 30.0 * exp(-z * z / 100.0); - case 1: - return sqrt(900.01 - z * z) * .9 - 2; - case 2: - return 30 * (cos(z / 16.0) + .5); - case 3: - return 30 - 30 * sin(z / 18.0); - case 4: - return 30 * exp(-cos(z / 16.0)) - 30; - case 5: - return 30 * sin(z / 10.0)"; - } - } -``` - -So if you feel like adding another function, all you need to do is append it to the `functions` array, and the rest of -the program *rewrites itself...* diff --git a/00_Alternate_Languages/87_3-D_Plot/d/threedeeplot.d b/00_Alternate_Languages/87_3-D_Plot/d/threedeeplot.d deleted file mode 100644 index a3660321e..000000000 --- a/00_Alternate_Languages/87_3-D_Plot/d/threedeeplot.d +++ /dev/null @@ -1,35 +0,0 @@ -@safe: // Make @safe the default for this file, enforcing memory-safety. -import std.stdio, std.string, std.math, std.range, std.conv, std.algorithm; - -void main() -{ - enum width = 80; - writeln(center("3D Plot", width)); - writeln(center("(After Creative Computing Morristown, New Jersey)\n\n\n", width)); - - static float fna(float z) - { - return 30.0 * exp(-z * z / 100.0); - } - - char[] row; - - for (float x = -30.0; x <= 30.0; x += 1.5) - { - size_t max_z = 0L; - auto y1 = 5 * floor((sqrt(900 - x * x)) / 5.0); - for (float y = y1; y >= -y1; y -= 5) - { - auto z = to!size_t(max(0, floor(25 + fna(sqrt(x * x + y * y)) - .7 * y))); - if (z > max_z) // Visible - { - max_z = z; - if (z + 1 > row.length) // row needs to grow - row ~= ' '.repeat(z + 1 - row.length).array; - row[z] = '*'; - } - } - writeln(row); - row = null; - } -} diff --git a/00_Alternate_Languages/87_3-D_Plot/d/threedeeplot_random.d b/00_Alternate_Languages/87_3-D_Plot/d/threedeeplot_random.d deleted file mode 100644 index 3db1a2cda..000000000 --- a/00_Alternate_Languages/87_3-D_Plot/d/threedeeplot_random.d +++ /dev/null @@ -1,50 +0,0 @@ -@safe: // Make @safe the default for this file, enforcing memory-safety. -import std.stdio, std.string, std.math, std.range, std.conv, std.random, std.algorithm; - -void main() -{ - enum width = 80; - writeln(center("3D Plot", width)); - writeln(center("(After Creative Computing Morristown, New Jersey)\n\n", width)); - - enum functions = ["30.0 * exp(-z * z / 100.0)", - "sqrt(900.01 - z * z) * .9 - 2", - "30 * (cos(z / 16.0) + .5)", - "30 - 30 * sin(z / 18.0)", - "30 * exp(-cos(z / 16.0)) - 30", - "30 * sin(z / 10.0)"]; - - size_t index = uniform(0, functions.length); - writeln(center("f(z) = " ~ functions[index], width), "\n"); - - float fna(float z) - { - final switch (index) - { - static foreach (i, f; functions) - case i: - mixin("return " ~ f ~ ";"); - } - } - - char[] row; - - for (float x = -30.0; x <= 30.0; x += 1.5) - { - size_t max_z = 0L; - auto y1 = 5 * lrint((sqrt(900 - x * x)) / 5.0); - for (float y = y1; y >= -y1; y -= 5) - { - auto z = to!size_t(max(0, lrint(25 + fna(sqrt(x * x + y * y)) - .7 * y))); - if (z > max_z) // Visible - { - max_z = z; - if (z + 1 > row.length) // row needs to grow - row ~= ' '.repeat(z + 1 - row.length).array; - row[z] = '*'; - } - } - writeln(row); - row = null; - } -} diff --git a/00_Alternate_Languages/88_3-D_Tic-Tac-Toe/MiniScript/README.md b/00_Alternate_Languages/88_3-D_Tic-Tac-Toe/MiniScript/README.md deleted file mode 100644 index 12d6406ec..000000000 --- a/00_Alternate_Languages/88_3-D_Tic-Tac-Toe/MiniScript/README.md +++ /dev/null @@ -1,18 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: -``` - miniscript qubit.ms -``` - -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: -``` - load "qubit" - run -``` diff --git a/00_Alternate_Languages/88_3-D_Tic-Tac-Toe/MiniScript/qubit.ms b/00_Alternate_Languages/88_3-D_Tic-Tac-Toe/MiniScript/qubit.ms deleted file mode 100644 index 3074be2d4..000000000 --- a/00_Alternate_Languages/88_3-D_Tic-Tac-Toe/MiniScript/qubit.ms +++ /dev/null @@ -1,361 +0,0 @@ -print " "*33 + "QUBIC" -print " "*15 + "Creative Computing Morristown New Jersey" -print; print; print - -getYesNo = function(prompt) - while true - yn = input(prompt + "? ").lower + " " - if yn[0] == "y" then return "yes" - if yn[0] == "n" then return "no" - print "Incorrect answer. Please type 'yes' or 'no'" - end while -end function - -// Data defining "lines" as sets of board indexes which form 4-in-a-row: -ma = [null, - [null, 1,2,3,4], // 1 - [null, 5,6,7,8], // 2 - [null, 9,10,11,12], // 3 - [null, 13,14,15,16], // 4 - [null, 17,18,19,20], // 5 - [null, 21,22,23,24], // 6 - [null, 25,26,27,28], // 7 - [null, 29,30,31,32], // 8 - [null, 33,34,35,36], // 9 - [null, 37,38,39,40], // 10 - [null, 41,42,43,44], // 11 - [null, 45,46,47,48], // 12 - [null, 49,50,51,52], // 13 - [null, 53,54,55,56], // 14 - [null, 57,58,59,60], // 15 - [null, 61,62,63,64], // 16 - [null, 1,17,33,49], // 17 - [null, 5,21,37,53], // 18 - [null, 9,25,41,57], // 19 - [null, 13,29,45,61], // 20 - [null, 2,18,34,50], // 21 - [null, 6,22,38,54], // 22 - [null, 10,26,42,58], // 23 - [null, 14,30,46,62], // 24 - [null, 3,19,35,51], // 25 - [null, 7,23,39,55], // 26 - [null, 11,27,43,59], // 27 - [null, 15,31,47,63], // 28 - [null, 4,20,36,52], // 29 - [null, 8,24,40,56], // 30 - [null, 12,28,44,60], // 31 - [null, 16,32,48,64], // 32 - [null, 1,5,9,13], // 33 - [null, 17,21,25,29], // 34 - [null, 33,37,41,45], // 35 - [null, 49,53,57,61], // 36 - [null, 2,6,10,14], // 37 - [null, 18,22,26,30], // 38 - [null, 34,38,42,46], // 39 - [null, 50,54,58,62], // 40 - [null, 3,7,11,15], // 41 - [null, 19,23,27,31], // 42 - [null, 35,39,43,47], // 43 - [null, 51,55,59,63], // 44 - [null, 4,8,12,16], // 45 - [null, 20,24,28,32], // 46 - [null, 36,40,44,48], // 47 - [null, 52,56,60,64], // 48 - [null, 1,6,11,16], // 49 - [null, 17,22,27,32], // 50 - [null, 33,38,43,48], // 51 - [null, 49,54,59,64], // 52 - [null, 13,10,7,4], // 53 - [null, 29,26,23,20], // 54 - [null, 45,42,39,36], // 55 - [null, 61,58,55,52], // 56 - [null, 1,21,41,61], // 57 - [null, 2,22,42,62], // 58 - [null, 3,23,43,63], // 59 - [null, 4,24,44,64], // 60 - [null, 49,37,25,13], // 61 - [null, 50,38,26,14], // 62 - [null, 51,39,27,15], // 63 - [null, 52,40,28,16], // 64 - [null, 1,18,35,52], // 65 - [null, 5,22,39,56], // 66 - [null, 9,26,43,60], // 67 - [null, 13,30,47,64], // 68 - [null, 49,34,19,4], // 69 - [null, 53,38,23,8], // 70 - [null, 57,42,27,12], // 71 - [null, 61,46,31,16], // 72 - [null, 1,22,43,64], // 73 - [null, 16,27,38,49], // 74 - [null, 4,23,42,61], // 75 - [null, 13,26,39,52]] // 76 - -// "opening book", i.e. spots that are generally good to hold if available -ya = [null, 1,49,52,4,13,61,64,16,22,39,23,38,26,42,27,43] - -showBoard = function - for i in range(1,9); print; end for - for i in range(1, 4) - print - for j in range(1, 4) - str = " " * j - for k in range(1, 4) - q = 16 * i + 4 * j + k - 20 - if xa[q] == 5 then - str += "(M)" - else if xa[q] == 1 then - str += "(Y)" - else - str += "( )" - end if - str += " " - end for - print str - // print (makes display too tall for the screen) - end for - print - end for -end function - -clearFractions = function - for i in range(1, 64) - if xa[i] == 1/8 then xa[i] = 0 - end for -end function - -checkForLines = function - for s in range(1, 76) - j1 = ma[s][1]; - j2 = ma[s][2]; - j3 = ma[s][3]; - j4 = ma[s][4]; - la[s] = xa[j1] + xa[j2] + xa[j3] + xa[j4] - end for -end function - -doPlayerMove = function - clearFractions - while true - print - inp = input("Your move? ") - if inp == "0" then - showBoard - continue - end if - if inp == "1" then exit - ok = true - if inp.len != 3 then - ok = false - else - i = inp[0].val - j = inp[1].val - k = inp[2].val - ok = (0 < i < 5) and (0 < j < 5) and (0 < k < 5) - end if - if not ok then - print "Incorrect move, retype it--" - else - m = 16 * i + 4 * j + k - 20 - if xa[m] != 0 then - print "That square is used, try again." - else - xa[m] = 1 - break - end if - end if - end while -end function - -selectMove = function(lineIndex, valueToReplace) - if lineIndex % 4 <= 1 then a = 1 else a = 2 - for j in range(a, 5 - a, 5 - 2 * a) - if xa[ma[lineIndex][j]] == valueToReplace then - xa[ma[lineIndex][j]] = 5 - m = ma[lineIndex][j] - print "Machine takes " + squareName(m) - return true - end if - end for - return false -end function - -doComputerMove = function - // look for lines with two M's and two blanks; add 1/8 to the blank spots - for i in range(1, 76) - la[i] = xa[ma[i][1]] + xa[ma[i][2]] + xa[ma[i][3]] + xa[ma[i][4]] - l = la[i] - if l == 10 then - for j in range(1, 4) - if (xa[ma[i][j]] == 0) then xa[ma[i][j]] = 1/8 - end for - end if - end for - // ...and if we now find lines containing 4 such spots, or 1 M and 3 such spots, - // then pick one of those spots for our move - checkForLines - for i in range(1, 76) - if la[i] == 4/8 or la[i] == 5 + 3/8 then - selectMove i, 1/8 - return true - end if - end for - - // now look for lines containing 2 Y's, and mark (with 1/8) the blank spots - clearFractions - for i in range(1, 76) - la[i] = xa[ma[i][1]] + xa[ma[i][2]] + xa[ma[i][3]] + xa[ma[i][4]] - l = la[i] - if l == 2 then - for j in range(1, 4) - if (xa[ma[i][j]] == 0) then xa[ma[i][j]] = 1 / 8 - end for - end if - end for - // ...and again, if we find 4 such spots in a row, or 1 player move plus - // 3 marked spots, then pick one of those - checkForLines - for i in range(1, 76) - if la[i] == 4/8 or la[i] == 1 + 3/8 then - selectMove 1/8 - return true - end if - end for - - // do mysterious stuff that depends on the order of lines in ma - // in ways I don't understand - for k in range(1, 18) - p = 0 - for i in range(4 * k - 3, 4 * k) - for j in range(1, 4) - p += xa[ma[i][j]] - end for - end for - if p == 4 or p == 9 then - for i in range(4 * k - 3, 4 * k) - if selectMove(1/8) then return true - end for - s = 0 - end if - end for - - // look for certain "good" spots in our ya array that are still available - clearFractions - found = false - for z in range(1, 17) - if xa[ya[z]] == 0 then - found = true - break - end if - end for - if not found then - // getting desperate, look for any open spot - for i in range(1, 64) - if xa[i] == 0 then - xa[i] = 5 - print "Machine likes " + squareName(i) - return true - end if - end for - print "The game is a draw." - return false - end if - m = ya[z] - xa[m] = 5 - print "Machine moves to " + squareName(m) - return true -end function - -squareName = function(m) - k1 = floor((m - 1) / 16) + 1 - j2 = m - 16 * (k1 - 1) - k2 = floor((j2 - 1) / 4) + 1 - k3 = m - (k1 - 1) * 16 - (k2 - 1) * 4 - return str(k1) + k2 + k3 -end function - -doOneGame = function - globals.xa = [null] + [0] * 64 // board state - globals.la = [null] + [0] * 76 // line data - skipFirst = getYesNo("Do you want to move first") == "no" - while true - if skipFirst then - skipFirst = false - else - doPlayerMove - end if - checkForLines - machineDone = false - // take three passes over the straight lines in the board - for j in range(1, 3) - for i in range(1, 76) - // first pass: check for player win - if j == 1 then - if la[i] != 4 then continue; - print "You win as follows" + " (line " + i + ")" - for j in range(1, 4) - print squareName(ma[i][j]) - end for - return - end if - // second pass: check for machine able to win - if j == 2 then - if la[i] != 15 then continue; - for j in range(1, 4) - m = ma[i][j] - if (xa[m] != 0) then continue; - xa[m] = 5 - break - end for - print "Machine moves to " + squareName(m) + ", and wins as follows" - for j in range(1, 4) - print squareName(ma[i][j]) - end for - return - end if - // third pass: check for player about to win - if j == 3 then - if la[i] != 3 then continue - for j in range(1, 4) - m = ma[i][j] - if xa[m] != 0 then continue - xa[m] = 5 - print "Nice try, machine moves to " + squareName(m) - machineDone = true - end for - break - end if - end for - end for - if (machineDone) then continue - - if not doComputerMove then break - end while -end function - - -// Main program -if getYesNo("Do you want instructions") == "yes" then - print - print "The game is tic-tac-toe in a 4 x 4 x 4 cube." - print "Each move is indicated by a 3 digit number, with each" - print "digit between 1 and 4 inclusive. The digits indicate the" - print "level, row, and column, respectively, of the occupied" - print "place. " - print - print "To print the playing board, type 0 (zero) as your move." - print "The program will print the board with your moves indi-" - print "cated with a (Y), the machine's moves with an (M), and" - print "unused squares with a ( )." // "output is on paper." - print - print "To stop the program run, type 1 as your move." - print - print -end if -while true - doOneGame - print - if getYesNo("Do you want to try another game") == "no" then break -end while - - - diff --git a/00_Alternate_Languages/88_3-D_Tic-Tac-Toe/README.md b/00_Alternate_Languages/88_3-D_Tic-Tac-Toe/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/88_3-D_Tic-Tac-Toe/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/88_3-D_Tic-Tac-Toe/qubit.bas b/00_Alternate_Languages/88_3-D_Tic-Tac-Toe/qubit.bas deleted file mode 100644 index 473e955aa..000000000 --- a/00_Alternate_Languages/88_3-D_Tic-Tac-Toe/qubit.bas +++ /dev/null @@ -1,281 +0,0 @@ -50 PRINT CHR$(26):REM WIDTH 80 -100 PRINT TAB(33);"QUBIC":PRINT -110 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -120 PRINT:PRINT:PRINT -210 PRINT "DO YOU WANT INSTRUCTIONS"; -220 INPUT C$ -230 IF LEFT$(C$,1)="N" THEN 315 -240 IF LEFT$(C$,1)="Y" THEN 265 -250 PRINT "INCORRECT ANSWER. PLEASE TYPE 'YES' OR 'NO'"; -260 GOTO 220 -265 PRINT -270 PRINT "THE GAME IS TIC-TAC-TOE IN A 4 X 4 X 4 CUBE." -280 PRINT "EACH MOVE IS INDICATED BY A 3 DIGIT NUMBER, WITH EACH" -290 PRINT "DIGIT BETWEEN 1 AND 4 INCLUSIVE. THE DIGITS INDICATE THE" -300 PRINT "LEVEL, ROW, AND COLUMN, RESPECTIVELY, OF THE OCCUPIED" -305 PRINT "PLACE. " -306 PRINT -307 PRINT "TO PRINT THE PLAYING BOARD, TYPE 0 (ZERO) AS YOUR MOVE." -308 PRINT "THE PROGRAM WILL PRINT THE BOARD WITH YOUR MOVES INDI-" -309 PRINT "CATED WITH A (Y), THE MACHINE'S MOVES WITH AN (M), AND" -310 PRINT "UNUSED SQUARES WITH A ( ). OUTPUT IS ON PAPER." -311 PRINT -312 PRINT "TO STOP THE PROGRAM RUN, TYPE 1 AS YOUR MOVE." -313 PRINT:PRINT -315 DIM X(64),L(76),M(76,4),Y(16) -320 FOR I = 1 TO 16 -330 READ Y(I) -340 NEXT I -350 FOR I=1 TO 76 -360 FOR J = 1 TO 4 -370 READ M(I,J) -380 NEXT J -390 NEXT I -400 FOR I = 1 TO 64 -410 LET X (I) =0 -420 NEXT I -430 LET Z=1 -440 PRINT "DO YOU WANT TO MOVE FIRST"; -450 INPUT S$ -460 IF LEFT$(S$,1)="N" THEN 630 -470 IF LEFT$(S$,1)="Y" THEN 500 -480 PRINT "INCORRECT ANSWER. PLEASE TYPE 'YES' OR 'NO'."; -490 GOTO 450 -500 PRINT " " -510 PRINT "YOUR MOVE"; -520 INPUT J1 -521 IF J1=1 THEN 2770 -522 IF J1<>0 THEN 525 -523 GOSUB 2550 -524 GOTO 500 -525 IF J1<111 THEN 2750 -526 IF J1>444 THEN 2750 -530 GOSUB 2500 -540 LET K1=INT(J1/100) -550 LET J2=(J1-K1*100) -560 LET K2=INT(J2/10) -570 LET K3= J1 - K1*100 -K2*10 -580 LET M=16*K1+4*K2+K3-20 -590 IF X(M)=0 THEN 620 -600 PRINT "THAT SQUARE IS USED, TRY AGAIN." -610 GOTO 500 -620 LET X(M)=1 -630 GOSUB 1640 -640 J=1 -650 I=1 -660 IF J=1 THEN 720 -670 IF J=2 THEN 790 -680 IF J=3 THEN 930 -690 I=I+1: IF I<=76 THEN 660 -700 J=J+1: IF J<=3 THEN 650 -710 GOTO 1300 -720 IF L(I)<>4 THEN 690 -730 PRINT "YOU WIN AS FOLLOWS"; -740 FOR J=1 TO 4 -750 LET M=M(I,J) -760 GOSUB 1570 -770 NEXT J -780 GOTO 1490 -790 IF L(I)<>15 THEN 690 -800 FOR J=1 TO 4 -810 LET M=M(I,J) -820 IF X(M)<>0 THEN 860 -830 LET X(M)=5 -840 PRINT "MACHINE MOVES TO"; -850 GOSUB 1570 -860 NEXT J -870 PRINT ", AND WINS AS FOLLOWS" -880 FOR J=1 TO 4 -890 LET M=M(I,J) -900 GOSUB 1570 -910 NEXT J -920 GOTO 1490 -930 IF L(I)<>3 THEN 690 -940 PRINT "NICE TRY. MACHINE MOVES TO"; -950 FOR J=1 TO 4 -960 LET M=M(I,J) -970 IF X(M)<>0 THEN 1010 -980 LET X(M)=5 -990 GOSUB 1570 -1000 GOTO 500 -1010 NEXT J -1020 GOTO 1300 -1030 I=1 -1040 LET L(I)=X(M(I,1))+X(M(I,2))+X(M(I,3))+X(M(I,4)) -1050 LET L = L(I) -1060 IF L <2 THEN 1130 -1070 IF L>=3 THEN 1130 -1080 IF L>2 THEN 2230 -1090 FOR J = 1 TO 4 -1100 IF X(M(I,J))<>0 THEN 1120 -1110 LET X(M(I,J))=1/8 -1120 NEXT J -1130 I=I+1: IF I<=76 THEN 1040 -1140 GOSUB 1640 -1150 I=1 -1160 IF L(I)=1/2 THEN 2360 -1170 IF L(I)=1+3/8 THEN 2360 -1180 I=I+1: IF I<=76 THEN 1160 -1190 GOTO 1830 -1200 LET Z = 1 -1210 IF X(Y(Z))=0 THEN 1250 -1220 LET Z=Z+1 -1230 IF Z<>17 THEN 1210 -1240 GOTO 1720 -1250 LET M=Y(Z) -1260 LET X(M)=5 -1270 PRINT "MACHINE MOVES TO"; -1280 GOSUB 1570 -1290 GOTO 500 -1300 LET X=X -1310 I=1 -1320 LET L(I)=X(M(I,1))+X(M(I,2))+X(M(I,3))+X(M(I,4)) -1330 LET L=L(I) -1340 IF L<10 THEN 1410 -1350 IF L>=11 THEN 1410 -1360 IF L>10 THEN 2230 -1370 FOR J=1 TO 4 -1380 IF X(M(I,J))<>0 THEN 1400 -1390 LET X(M(I,J))=1/8 -1400 NEXT J -1410 I=I+1: IF I<=76 THEN 1320 -1420 GOSUB 1640 -1430 I=1 -1440 IF L(I)=.5 THEN 2360 -1450 IF L(I)=5+3/8 THEN 2360 -1460 I=I+1: IF I<=76 THEN 1440 -1470 GOSUB 2500 -1480 GOTO 1030 -1490 PRINT " " -1500 PRINT "DO YOU WANT TO TRY ANOTHER GAME"; -1510 INPUT X$ -1520 IF LEFT$(X$,1)="Y" THEN 400 -1530 IF LEFT$(X$,1)="N" THEN 1560 -1540 PRINT "INCORRECT ANSWER. PLEASE TYPE 'YES' OR 'NO'"; -1550 GOTO 1510 -1560 END -1570 LET K1=INT((M-1)/16)+1 -1580 LET J2=M-16*(K1-1) -1590 LET K2=INT((J2-1)/4)+1 -1600 LET K3=M-(K1-1)*16-(K2-1)*4 -1610 LET M=K1*100+K2*10+K3 -1620 PRINT M; -1630 RETURN -1640 FOR S=1 TO 76 -1650 LET J1 = M(S,1) -1660 LET J2=M(S,2) -1670 LET J3=M(S,3) -1680 LET J4=M(S,4) -1690 LET L(S)=X(J1)+X(J2)+X(J3)+X(J4) -1700 NEXT S -1710 RETURN -1720 FOR I=1 TO 64 -1730 IF X(I)<>0 THEN 1800 -1740 LET X(I)=5 -1750 LET M=I -1760 PRINT "MACHINE LIKES"; -1770 GOSUB 1570 -1780 PRINT " " -1790 GOTO 500 -1800 NEXT I -1810 PRINT "THE GAME IS A DRAW." -1820 GOTO 1490 -1830 FOR K=1 TO 18 -1840 LET P=0 -1850 FOR I=4*K-3 TO 4*K -1860 FOR J=1 TO 4 -1870 LET P=P+X(M(I,J)) -1880 NEXT J -1890 NEXT I -1900 IF P<4 THEN 1940 -1910 IF P<5 THEN 1970 -1920 IF P<9 THEN 1940 -1930 IF P<10 THEN 1970 -1940 NEXT K -1950 GOSUB 2500 -1960 GOTO 1200 -1970 LET S=1/8 -1980 FOR I=4*K-3 TO 4*K -1990 GOTO 2370 -2000 NEXT I -2010 LET S=0 -2020 GOTO 1980 -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 -2230 FOR J=1 TO 4 -2240 IF X(M(I,J))<>1/8 THEN 2330 -2250 LET X(M(I,J))=5 -2260 IF L(I)<5 THEN 2290 -2270 PRINT "LET'S SEE YOU GET OUT OF THIS: MACHINE MOVES TO"; -2280 GOTO 2300 -2290 PRINT "YOU FOX. JUST IN THE NICK OF TIME, MACHINE MOVES TO"; -2300 LET M=M(I,J) -2310 GOSUB 1570 -2320 GOTO 500 -2330 NEXT J -2340 PRINT "MACHINE CONCEDES THIS GAME." -2350 GOTO 1490 -2360 LET S=1/8 -2370 IF I-INT(I/4)*4>1 THEN 2400 -2380 LET A=1 -2390 GOTO 2410 -2400 LET A=2 -2410 FOR J=A TO 5-A STEP 5-2*A -2420 IF X(M(I,J))=S THEN 2450 -2430 NEXT J -2440 GOTO 2000 -2450 LET X(M(I,J))=5 -2460 LET M=M(I,J) -2470 PRINT "MACHINE TAKES"; -2480 GOSUB 1570 -2490 GOTO 500 -2500 FOR I=1 TO 64 -2510 IF X(I)<>1/8 THEN 2530 -2520 LET X(I)=0 -2530 NEXT I -2540 RETURN -2550 FOR XX=1 TO 9:PRINT:NEXT:FOR I=1 TO 4 -2560 FOR J=1 TO 4 -2562 FOR I1=1 TO J -2564 PRINT" "; -2566 NEXT I1 -2570 FOR K=1 TO 4 -2600 LET Q=16*I+4*J+K-20 -2610 IF X(Q)<>O THEN 2630 -2620 PRINT"( ) "; -2630 IF X(Q)<>5 THEN 2650 -2640 PRINT"(M) "; -2650 IF X(Q)<>1 THEN 2660 -2655 PRINT"(Y) "; -2660 IF X(Q)<>1/8 THEN 2670 -2665 PRINT"( ) "; -2670 NEXT K -2680 PRINT -2690 PRINT -2700 NEXT J -2710 PRINT -2720 PRINT -2730 NEXT I -2735 REM PRINT CHR$(12) -2740 RETURN -2750 PRINT"INCORRECT MOVE, RETYPE IT--"; -2760 GOTO 520 -2770 END diff --git a/00_Alternate_Languages/89_Tic-Tac-Toe/MiniScript/README.md b/00_Alternate_Languages/89_Tic-Tac-Toe/MiniScript/README.md deleted file mode 100644 index c3c2c9259..000000000 --- a/00_Alternate_Languages/89_Tic-Tac-Toe/MiniScript/README.md +++ /dev/null @@ -1,20 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from , install, and then run the program with a command such as: - -``` - miniscript tictactoe.ms -``` - -2. Mini Micro: -Download Mini Micro from , launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "tictactoe" - run -``` diff --git a/00_Alternate_Languages/89_Tic-Tac-Toe/MiniScript/tictactoe.ms b/00_Alternate_Languages/89_Tic-Tac-Toe/MiniScript/tictactoe.ms deleted file mode 100644 index 8d472a7bb..000000000 --- a/00_Alternate_Languages/89_Tic-Tac-Toe/MiniScript/tictactoe.ms +++ /dev/null @@ -1,90 +0,0 @@ -// This program plays Tic Tac Toe -// The machine goes first and the way this is set up -// there's no way the human player can win. At best -// it will be a draw. -computerNext = function(x) - return x - 8 * floor((x - 1) / 8) -end function - -print " " * 30 + "TIC TAC TOE" -print " " * 15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -print; print; print - -print "The game board is numbered:" -print -print "1 2 3" -print "8 9 4" -print "7 6 5" -print - -while true - computer = 9 - gameOver = false - // MOVE ONE line 240 in original - // Computer always moves first and takes the center - print "Computer moves " + computer - player = input("Your move? ").val - playerFirstMove = player - - // MOVE TWO line 280 - // Computer's 2nd move - always the next space clockwise - // from the player's - computer = computerNext(player + 1) - canWinAt = computerNext(computer+4) - print "Computer moves " + computer - player = input("Your move? ").val - - // MOVE THREE line 300 - // Computer has two consecutive cells. This includes the - // middle so, to complete this 3-in-a-row, get the opposite - // value of comp's last move - which is four cells clockwise away. - - if player != canWinAt then - computer = canWinAt - print "Computer moves " + computer - print "... and wins ********" - gameOver = true - else - // Blocked - so two cells away from comp's last move - // line 360 - computer = computerNext(computer + 2) - print "Computer moves " + computer - end if - - if gameOver == false then - canWinAt = computerNext(computer+4) - player = input("Your move? ").val - - // MOVE FOUR - line 400 - if player != canWinAt then - computer = canWinAt - print "Computer moves " + computer - print "... and wins ********" - gameOver = true - else - // Foiled again! - line 450 - if playerFirstMove % 2 == 0 then - computer = computerNext(computer + 7) - print "Computer moves " + computer - print "... and wins ********" - gameOver = true - else // line 500 - computer = computerNext(computer + 3) - print "Computer moves " + computer - end if - end if - end if - - if gameOver == false then - // line 520 - player = input("Your move? ").val - if player != computerNext(computer + 4) then - computer = computerNext(computer + 4) - else - computer = computerNext(computer + 6) - end if - print "Computer moves " + computer - print "The game is a draw." - end if - print -end while diff --git a/00_Alternate_Languages/89_Tic-Tac-Toe/MiniScript/tictactoe2.ms b/00_Alternate_Languages/89_Tic-Tac-Toe/MiniScript/tictactoe2.ms deleted file mode 100644 index 20981ab08..000000000 --- a/00_Alternate_Languages/89_Tic-Tac-Toe/MiniScript/tictactoe2.ms +++ /dev/null @@ -1,155 +0,0 @@ -solutions = [[0,1,2],[3,4,5],[6,7,8]] -solutions += [[0,3,6],[1,4,7],[2,5,8]] -solutions += [[0,4,8],[2,4,6]] - -TicTacToe = {} -TicTacToe.grid = (" " * 9).split("") -TicTacToe.markers = {true: "X",false:"O"} -TicTacToe.AI = "X" -TicTacToe.human = "O" -TicTacToe.next = "X" -TicTacToe.lastMove = -1 - -TicTacToe.show = function - print " " + self.grid[0:3].join(" ! ") - print "---+---+---" - print " " + self.grid[3:6].join(" ! ") - print "---+---+---" - print " " + self.grid[6:].join(" ! ") - print - print -end function - -TicTacToe.set = function(player, pos) - if self.grid[pos] != " " then - return false - end if - self.grid[pos] = player - self.lastMove = pos - return true -end function - -TicTacToe.setMarkers = function(mark) - self.human = self.markers[mark == "X"] - self.AI = self.markers[mark == "O"] -end function - -TicTacToe.getWinner = function - for mark in self.markers.values - for solution in solutions - cnt = 0 - for i in solution - cnt += (self.grid[i] == mark) - end for - if cnt == 3 then return mark - end for - end for - return null -end function - -TicTacToe.potentialWins = function - potential = {"X": [], "O": []} - for mark in self.markers.values - for solution in solutions - cnt = 0 - emptyCells = [] - for i in solution - cnt += (self.grid[i] == mark) - if self.grid[i] == " " then emptyCells.push(i) - end for - if cnt == 2 and emptyCells.len == 1 then potential[mark].push(emptyCells[0]) - end for - end for - return potential -end function - -TicTacToe.moveAvailable = function - return self.grid.indexOf(" ") != null -end function - -TicTacToe.selectAI = function - if self.grid[4] == " " then return 4 - - potential = self.potentialWins - - AIWins = potential[self.AI] - if AIWins.len >0 then return AIWins[0] - - HumanWins = potential[self.human] - - if HumanWins.len > 0 then return HumanWins[0] - - if [1,3,5,7].indexOf(self.lastMove) != null then - for corner in [8,6,2,0] - if self.grid[corner] == " " then - self.grid[corner] = self.AI - potential = self.potentialWins - self.grid[corner] = " " - AIWins = potential[self.AI] - if AIWins.len > 0 then return corner - end if - end for - else - for side in [1,3,5,7] - if self.grid[side] == " " then - self.grid[side] = self.AI - potential = self.potentialWins - self.grid[side] = " " - AIWins = potential[self.AI] - if AIWins.len > 0 then return side - end if - end for - end if - for ix in range(0,8) - if self.grid[ix] == " " then return ix - end for - - return null -end function - -print " " * 15 + "Creative Computing Morristown, New Jersey" -print; print; print -print "The board is numbered." -print; print; print -print " 1 2 3" -print " 4 5 6" -print " 7 8 9" -print -ans = input("Do you want to 'X' or 'O'? ") -if ans.upper != "X" then ans = "O" -TicTacToe.setMarkers(ans.upper) -winner = null -print -while TicTacToe.moveAvailable and winner == null - - if TicTacToe.next == TicTacToe.AI then - move = TicTacToe.selectAI - TicTacToe.set(TicTacToe.AI, move) - TicTacToe.next = TicTacToe.human - print "The computer moves to..." - else - move = input("Where do you move? ").val - if move < 1 or move > 9 then - print "Thanks for the game." - exit - else if not TicTacToe.set(TicTacToe.human, move-1) then - print "That square is occupied." - print - continue - else - TicTacToe.next = TicTacToe.AI - end if - end if - - TicTacToe.show - winner = TicTacToe.getWinner -end while - -if winner == null then - print "It's a draw. Thank you." -else if winner == TicTacToe.AI then - print "I win, turkey!!" -else - print "You beat me! Good game!" -end if - diff --git a/00_Alternate_Languages/89_Tic-Tac-Toe/README.md b/00_Alternate_Languages/89_Tic-Tac-Toe/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/89_Tic-Tac-Toe/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/89_Tic-Tac-Toe/go/src/tictactoe1.go b/00_Alternate_Languages/89_Tic-Tac-Toe/go/src/tictactoe1.go deleted file mode 100644 index 416830fee..000000000 --- a/00_Alternate_Languages/89_Tic-Tac-Toe/go/src/tictactoe1.go +++ /dev/null @@ -1,87 +0,0 @@ -package main - -import ( - "fmt" - "strconv" -) - -func main() { - // Print text on the screen with 30 spaces before text - fmt.Printf("%30s\n", "TIC TAC TOE") - // Print text on screen with 15 spaces before text - // And print three lines break on screen - fmt.Printf("%15s\n\n\n\n", "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") - // THIS PROGRAM PLAYS TIC TAC TOE - fmt.Printf("THE GAME BOARD IS NUMBERED:\n\n") - fmt.Println("1 2 3") - fmt.Println("8 9 4") - fmt.Println("7 6 5") - - // Main program - for { - var ( - a, b, c, d, e int - p, q, r, s int - ) - a = 9 - fmt.Printf("\n\n") - // THE MACHINE GOES FIRST - computerMoves(a) - p = readYourMove() - b = move(p + 1) - computerMoves(b) - q = readYourMove() - if q == move(b+4) { - c = move(b + 2) - computerMoves(c) - r = readYourMove() - if r == move(c+4) { - if p%2 != 0 { - d = move(c + 3) - computerMoves(d) - s = readYourMove() - if s == move(d+4) { - e = move(d + 6) - computerMoves(e) - fmt.Println("THE GAME IS A DRAW.") - } else { - e = move(d + 4) - computerMoves(e) - fmt.Println("AND WINS ********") - } - } else { - d = move(c + 7) - computerMoves(d) - fmt.Println("AND WINS ********") - } - } else { - d = move(c + 4) - computerMoves(d) - fmt.Println("AND WINS ********") - } - } else { - c = move(b + 4) - computerMoves(c) - fmt.Println("AND WINS ********") - } - } -} -func computerMoves(move int) { - fmt.Printf("COMPUTER MOVES %v\n", move) -} - -func readYourMove() int { - for { - fmt.Printf("YOUR MOVE?") - var input string - fmt.Scan(&input) - number, err := strconv.Atoi(input) - if err == nil { - return number - } - } -} - -func move(number int) int { - return number - 8*(int)((number-1)/8) -} diff --git a/00_Alternate_Languages/89_Tic-Tac-Toe/pascal/tictactoe1.pas b/00_Alternate_Languages/89_Tic-Tac-Toe/pascal/tictactoe1.pas deleted file mode 100644 index 2fed68d75..000000000 --- a/00_Alternate_Languages/89_Tic-Tac-Toe/pascal/tictactoe1.pas +++ /dev/null @@ -1,103 +0,0 @@ -program tictactoe1; -var - a, b, c, d, e: integer; - p, q, r, s: integer; -procedure computerMoves(m: integer); -begin - write('COMPUTER MOVES '); - writeln(m); -end; - -function readYourMove() : integer; -var number: integer; -begin - write('YOUR MOVE?'); - readln(number); - readYourMove := number; -end; - -function move(number: integer): integer; -begin - move := number - 8 * trunc((number - 1) / 8); -end; - -function padLeft(m: string; n: integer): string; -var tmp: string; -begin - tmp := ''; - repeat - tmp := tmp + ' '; - n := n - 1; - until n = 0; - tmp := tmp + m; - padLeft := tmp; -end; - -begin - writeln(padLeft('TIC TAC TOE', 30)); - writeln(padLeft('CREATIVE COMPUTING MORRISTOWN, NEW JERSEY', 15)); - writeln(''); - writeln(''); - writeln(''); - writeln('THE GAME BOARD IS NUMBERED:'); - writeln(''); - writeln('1 2 3'); - writeln('8 9 4'); - writeln('7 6 5'); - while(true) do - begin - writeln(''); - writeln(''); - a := 9; - computerMoves(a); - p := readYourMove(); - b := move(p + 1); - computerMoves(b); - q := readYourMove(); - if (q = move(b + 4)) then - begin - c := move(b + 2); - computerMoves(c); - r := readYourMove(); - if (r = move(c + 4)) then - begin - if (p mod 2 <> 0) then - begin - d := move(c + 3); - computerMoves(d); - s := readYourMove(); - if (s = move(d + 4)) then - begin - e := move(d + 6); - computerMoves(e); - writeln('THE GAME IS A DRAW.'); - end - else - begin - e := move(d + 4); - computerMoves(e); - writeln('AND WINS ********'); - end - end - else - begin - d := move(c + 7); - computerMoves(d); - writeln('AND WINS ********'); - end - end - else - begin - d := move(c + 4); - computerMoves(d); - writeln('AND WINS ********'); - end - end - else - begin - c := move(b + 4); - computerMoves(c); - writeln('AND WINS ********'); - end; - end; -end. diff --git a/00_Alternate_Languages/89_Tic-Tac-Toe/tictactoe1.bas b/00_Alternate_Languages/89_Tic-Tac-Toe/tictactoe1.bas deleted file mode 100644 index 57eace475..000000000 --- a/00_Alternate_Languages/89_Tic-Tac-Toe/tictactoe1.bas +++ /dev/null @@ -1,69 +0,0 @@ -10 PRINT TAB(30);"TIC TAC TOE" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT:PRINT:PRINT -50 REM -100 REM THIS PROGRAM PLAYS TIC TAC TOE -110 REM THE MACHINE GOES FIRST -120 PRINT "THE GAME BOARD IS NUMBERED:": PRINT -130 PRINT "1 2 3": PRINT "8 9 4": PRINT "7 6 5" -140 PRINT -150 REM -160 REM -170 REM -180 DEF FNM(X)=X-8*INT((X-1)/8) -190 REM -200 REM MAIN PROGRAM -210 PRINT -220 PRINT -230 A=9 -240 M=A -250 GOSUB 650 -260 P=M -270 B=FNM(P+1) -280 M=B -290 GOSUB 650 -300 Q=M -310 IF Q=FNM(B+4) THEN 360 -320 C=FNM(B+4) -330 M=C -340 GOSUB 700 -350 GOTO 730 -360 C=FNM(B+2) -370 M=C -380 GOSUB 650 -390 R=M -400 IF R=FNM(C+4) THEN 450 -410 D=FNM(C+4) -420 M=D -430 GOSUB 700 -440 GOTO 730 -450 IF P/2<>INT(P/2) THEN 500 -460 D=FNM(C+7) -470 M=D -480 GOSUB 700 -490 GOTO 730 -500 D=FNM(C+3) -510 M=D -520 GOSUB 650 -530 S=M -540 IF S=FNM(D+4) THEN 590 -550 E=FNM(D+4) -560 M=E -570 GOSUB 700 -580 REM -590 E=FNM(D+6) -600 M=E -610 GOSUB 700 -620 PRINT "THE GAME IS A DRAW." -630 GOTO 210 -640 REM -650 GOSUB 700 -660 PRINT "YOUR MOVE"; -670 INPUT M -680 RETURN -700 PRINT "COMPUTER MOVES";M -710 RETURN -720 REM -730 PRINT "AND WINS ********" -740 GOTO 210 -750 END diff --git a/00_Alternate_Languages/89_Tic-Tac-Toe/tictactoe2.bas b/00_Alternate_Languages/89_Tic-Tac-Toe/tictactoe2.bas deleted file mode 100644 index ef6fee8e4..000000000 --- a/00_Alternate_Languages/89_Tic-Tac-Toe/tictactoe2.bas +++ /dev/null @@ -1,114 +0,0 @@ -2 PRINT TAB(30);"TIC-TAC-TOE" -4 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -6 PRINT:PRINT:PRINT -8 PRINT "THE BOARD IS NUMBERED:" -10 PRINT " 1 2 3" -12 PRINT " 4 5 6" -14 PRINT " 7 8 9" -16 PRINT:PRINT:PRINT -20 DIM S(9) -50 INPUT"DO YOU WANT 'X' OR 'O'";C$ -55 IF C$="X"THEN 475 -60 P$="O":Q$="X" -100 G=-1:H=1:IF S(5)<>0 THEN 103 -102 S(5)=-1:GOTO 195 -103 IF S(5)<>1 THEN 106 -104 IF S(1)<>0 THEN 110 -105 S(1)=-1:GOTO 195 -106 IF S(2)=1 AND S(1)=0 THEN 181 -107 IF S(4)=1 AND S(1)=0 THEN 181 -108 IF S(6)=1 AND S(9)=0 THEN 189 -109 IF S(8)=1 AND S(9)=0 THEN 189 -110 IF G=1 THEN 112 -111 GOTO 118 -112 J=3*INT((M-1)/3)+1 -113 IF 3*INT((M-1)/3)+1=M THEN K=1 -114 IF 3*INT((M-1)/3)+2=M THEN K=2 -115 IF 3*INT((M-1)/3)+3=M THEN K=3 -116 GOTO 120 -118 FOR J=1 TO 7 STEP 3:FOR K=1 TO 3 -120 IF S(J)<>G THEN 130 -122 IF S(J+2)<>G THEN 135 -126 IF S(J+1)<>0 THEN 150 -128 S(J+1)=-1:GOTO 195 -130 IF S(J)=H THEN 150 -131 IF S(J+2)<>G THEN 150 -132 IF S(J+1)<>G THEN 150 -133 S(J)=-1:GOTO 195 -135 IF S(J+2)<>0 THEN 150 -136 IF S(J+1)<>G THEN 150 -138 S(J+2)=-1:GOTO 195 -150 IF S(K)<>G THEN 160 -152 IF S(K+6)<>G THEN 165 -156 IF S(K+3)<>0 THEN 170 -158 S(K+3)=-1:GOTO 195 -160 IF S(K)=H THEN 170 -161 IF S(K+6)<>G THEN 170 -162 IF S(K+3)<>G THEN 170 -163 S(K)=-1:GOTO 195 -165 IF S(K+6)<>0 THEN 170 -166 IF S(K+3)<>G THEN 170 -168 S(K+6)=-1:GOTO 195 -170 GOTO 450 -171 IF S(3)=G AND S(7)=0 THEN 187 -172 IF S(9)=G AND S(1)=0 THEN 181 -173 IF S(7)=G AND S(3)=0 THEN 183 -174 IF S(9)=0 AND S(1)=G THEN 189 -175 IF G=-1 THEN G=1:H=-1:GOTO 110 -176 IF S(9)=1 AND S(3)=0 THEN 182 -177 FOR I=2 TO 9:IF S(I)<>0 THEN 179 -178 S(I)=-1:GOTO 195 -179 NEXT I -181 S(1)=-1:GOTO 195 -182 IF S(1)=1 THEN 177 -183 S(3)=-1:GOTO 195 -187 S(7)=-1:GOTO 195 -189 S(9)=-1 -195 PRINT:PRINT"THE COMPUTER MOVES TO..." -202 GOSUB 1000 -205 GOTO 500 -450 IF G=1 THEN 465 -455 IF J=7 AND K=3 THEN 465 -460 NEXT K,J -465 IF S(5)=G THEN 171 -467 GOTO 175 -475 P$="X":Q$="O" -500 PRINT:INPUT"WHERE DO YOU MOVE";M -502 IF M=0 THEN PRINT"THANKS FOR THE GAME.":GOTO 2000 -503 IF M>9 THEN 506 -505 IF S(M)=0 THEN 510 -506 PRINT"THAT SQUARE IS OCCUPIED.":PRINT:PRINT:GOTO 500 -510 G=1:S(M)=1 -520 GOSUB 1000 -530 GOTO 100 -1000 PRINT:FOR I=1 TO 9:PRINT" ";:IF S(I)<>-1 THEN 1014 -1012 PRINT Q$" ";:GOTO 1020 -1014 IF S(I)<>0 THEN 1018 -1016 PRINT" ";:GOTO 1020 -1018 PRINT P$" "; -1020 IF I<>3 AND I<>6 THEN 1050 -1030 PRINT:PRINT"---+---+---" -1040 GOTO 1080 -1050 IF I=9 THEN 1080 -1060 PRINT"!"; -1080 NEXT I:PRINT:PRINT:PRINT -1095 FOR I=1 TO 7 STEP 3 -1100 IF S(I)<>S(I+1)THEN 1115 -1105 IF S(I)<>S(I+2)THEN 1115 -1110 IF S(I)=-1 THEN 1350 -1112 IF S(I)=1 THEN 1200 -1115 NEXT I:FOR I=1 TO 3:IF S(I)<>S(I+3)THEN 1150 -1130 IF S(I)<>S(I+6)THEN 1150 -1135 IF S(I)=-1 THEN 1350 -1137 IF S(I)=1 THEN 1200 -1150 NEXT I:FOR I=1 TO 9:IF S(I)=0 THEN 1155 -1152 NEXT I:GOTO 1400 -1155 IF S(5)<>G THEN 1170 -1160 IF S(1)=G AND S(9)=G THEN 1180 -1165 IF S(3)=G AND S(7)=G THEN 1180 -1170 RETURN -1180 IF G=-1 THEN 1350 -1200 PRINT"YOU BEAT ME!! GOOD GAME.":GOTO 2000 -1350 PRINT"I WIN, TURKEY!!!":GOTO 2000 -1400 PRINT"IT'S A DRAW. THANK YOU." -2000 END diff --git a/00_Alternate_Languages/90_Tower/MiniScript/README.md b/00_Alternate_Languages/90_Tower/MiniScript/README.md deleted file mode 100644 index fc9672037..000000000 --- a/00_Alternate_Languages/90_Tower/MiniScript/README.md +++ /dev/null @@ -1,18 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: -``` - miniscript tower.ms -``` - -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: -``` - load "tower" - run -``` diff --git a/00_Alternate_Languages/90_Tower/MiniScript/tower.ms b/00_Alternate_Languages/90_Tower/MiniScript/tower.ms deleted file mode 100644 index a1846545a..000000000 --- a/00_Alternate_Languages/90_Tower/MiniScript/tower.ms +++ /dev/null @@ -1,202 +0,0 @@ -kInvalidDisk = 100 -kNotTopDisk = 200 -kNotTower = 300 -kGameOver = 300 - -Tower = {"disks": []} -Tower.init = function - noob = new Tower - noob.disks = [] - return noob -end function - -Tower.height = function - return self.disks.len -end function - -Tower.top = function - if self.height == 0 then return 100 - return self.disks[-1] -end function - -Game = {} -Game.towers = [] -Game.numOfDisks = 0 -Game.rangeOfDisks = [] -Game.selectedDisk = 0 -Game.selectedDiskOn = 0 -Game.selectedTower = 0 -Game.inputErrors = 0 -Game.turns = 0 - -Game.display = function - print - for r in range(7,1) - rowstr = "" - for tower in self.towers - if r > tower.height then - rowstr += " " * 12 + "#" + " " * 7 - else - spaces = (15 - tower.disks[r-1])/2 - disks = " " * 4 + tower.disks[r-1] - rowstr += disks[-5:] + " " * spaces - rowstr += "#" * tower.disks[r-1] - rowstr += " " * spaces - end if - rowstr += " " - end for - print rowstr - end for - rowstr = (" " * 5 + "=" * 15 + " ") * 3 - print rowstr - print -end function - -Game.init = function(num) - if num < 1 or num > 7 then - self.inputErrors += 1 - return false - end if - Game.towers = [] - for i in range(0,2) - Game.towers.push(Tower.init) - end for - - first = self.towers[0] - first.disks = range(15, 17 - num * 2, -2) - self.numOfDisks = num - self.rangeOfDisks = range(17 -num * 2, 15, 2) - - // This game doesn't like to be bothered - // and keeps track of how many incorrect inputs - // are made before it stops the game - self.inputErrors = 0 - self.turns = 0 - return true -end function - -Game.diskStatus = function - n = self.selectedDisk - if self.rangeOfDisks.indexOf(n) == null then - self.inputErrors +=1 - return kInvalidDisk - end if - self.inputErrors = 0 - for i in range(0, self.towers.len - 1) - if self.towers[i].top == n then - self.selectedDiskOn = i - self.inputErrors = 0 - return i - end if - end for - return kNotTopDisk -end function - -Game.pickDisk = function - self.selectedDisk = input("Which disk would you like to move? ").val - return self.diskStatus -end function - -Game.pickTower = function - self.selectedTower = input("Place disk on which needle? ").val - 1 - if not(0<= self.selectedTower and self.selectedTower <= 2) then - self.inputErrors += 1 - return kNotTower - end if - return self.selectedTower -end function - -Game.doneWithYou = function - return self.inputErrors >= 2 -end function - -Game.isFinish = function - return self.towers[0].disks.len == 0 and self.towers[1].disks.len == 0 -end function - -Game.move = function - print "Take turn # " + (self.turns + 1) - status = -1 - self.inputErrors = 0 - while 1 - status = self.pickDisk - if 0 <= status and status <= 2 then break - if status == kInvalidDisk and self.doneWithYou then - print "Stop wasting my time. Go bother someone else." - exit - else if status == kInvalidDisk then - msg = "Illegal entry ... you may only type " - msg += self.rangeOfDisks[0:-1].join(",") + " " - if self.rangeOfDisks.len > 1 then - msg += "or " - end if - msg += "15" - print msg - else if status == kNotTopDisk then - print "That disk is below another. Make another choice." - end if - end while - - self.inputErrors = 0 - while 1 - status = self.pickTower - if 0 <= status and status <= 2 then break - if status == kNotTower and self.doneWithYou then - print "I tried to warn you. But you wouldn't listen." - print "Bye bye, big shot." - exit - else if status == kNotTower then - print "I'll assume you hit the wrong key this time. But watch it," - print "I only allow one mistake." - end if - end while - - if self.selectedDisk > self.towers[self.selectedTower].top then - print "You can't place a larger disk on a top of a smaller one," - print "it may crush it!" - else - n=self.towers[self.selectedDiskOn].disks.pop - self.towers[self.selectedTower].disks.push(n) - self.turns += 1 - self.inputErrors = 0 - end if -end function - - -print " " * 33 + "TOWERS" -print " " * 15 + "Creative Computing Morristown, New Jersey" -print; print -print "You must transfer the disks from the left to the right" -print "tower, one at a time, never putting a larger disk on a" -print "smaller disk." -print - -ans = "Y" -while ans[0].upper == "Y" - while 1 - disks = input("How many disks do you want to move (7 is MAX)? ").val - status = Game.init(disks) - if status == false and Game.doneWithYou then - print "All right, wise guy, if you can't play the game right, I'll" - print "take my puzzle and go home. So long." - exit - else if not status then - print "Sorry, but I can't do that job for you" - else - break - end if - end while - - while not Game.isFinish - Game.display - - Game.move - end while - Game.display - print "Congratulations!" - print "You performed the task in " + Game.turns + " moves." - print - ans = input("Play again (Yes or No)? ") + " " -end while -print -print "Thanks for the game!" diff --git a/00_Alternate_Languages/90_Tower/README.md b/00_Alternate_Languages/90_Tower/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/90_Tower/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/90_Tower/tower.bas b/00_Alternate_Languages/90_Tower/tower.bas deleted file mode 100644 index ee826c18b..000000000 --- a/00_Alternate_Languages/90_Tower/tower.bas +++ /dev/null @@ -1,125 +0,0 @@ -10 PRINT TAB(33);"TOWERS" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT:PRINT:PRINT -90 PRINT -100 REM*** INITIALIZE -110 DIM T(7,3) -120 E=0 -130 FOR D=1 TO 7 -140 FOR N=1 TO 3 -150 T(D,N)=0 -160 NEXT N -170 NEXT D -180 PRINT "TOWERS OF HANOI PUZZLE.": PRINT -200 PRINT "YOU MUST TRANSFER THE DISKS FROM THE LEFT TO THE RIGHT" -205 PRINT "TOWER, ONE AT A TIME, NEVER PUTTING A LARGER DISK ON A" -210 PRINT "SMALLER DISK.": PRINT -215 INPUT "HOW MANY DISKS DO YOU WANT TO MOVE (7 IS MAX)";S -220 PRINT -230 M=0 -240 FOR Q=1 TO 7 -250 IF Q=S THEN 350 -260 NEXT Q -270 E=E+1 -280 IF E>2 THEN 310 -290 PRINT "SORRY, BUT I CAN'T DO THAT JOB FOR YOU.": GOTO 215 -310 PRINT "ALL RIGHT, WISE GUY, IF YOU CAN'T PLAY THE GAME RIGHT, I'LL" -320 PRINT "JUST TAKE MY PUZZLE AND GO HOME. SO LONG.": STOP -340 REM *** STORE DISKS FROM SMALLEST TO LARGEST -350 PRINT "IN THIS PROGRAM, WE SHALL REFER TO DISKS BY NUMERICAL CODE." -355 PRINT "3 WILL REPRESENT THE SMALLEST DISK, 5 THE NEXT SIZE," -360 PRINT "7 THE NEXT, AND SO ON, UP TO 15. IF YOU DO THE PUZZLE WITH" -365 PRINT "2 DISKS, THEIR CODE NAMES WOULD BE 13 AND 15. WITH 3 DISKS" -370 PRINT "THE CODE NAMES WOULD BE 11, 13 AND 15, ETC. THE NEEDLES" -375 PRINT "ARE NUMBERED FROM LEFT TO RIGHT, 1 TO 3. WE WILL" -380 PRINT "START WITH THE DISKS ON NEEDLE 1, AND ATTEMPT TO MOVE THEM" -385 PRINT "TO NEEDLE 3." -390 PRINT: PRINT "GOOD LUCK!": PRINT -400 Y=7: D=15 -420 FOR X=S TO 1 STEP -1 -430 T(Y,1)=D: D=D-2: Y=Y-1 -460 NEXT X -470 GOSUB 1230 -480 PRINT "WHICH DISK WOULD YOU LIKE TO MOVE";:E=0 -500 INPUT D -510 IF (D-3)*(D-5)*(D-7)*(D-9)*(D-11)*(D-13)*(D-15)=0 THEN 580 -520 PRINT "ILLEGAL ENTRY... YOU MAY ONLY TYPE 3,5,7,9,11,13, OR 15." -530 E=E+1: IF E>1 THEN 560 -550 GOTO 500 -560 PRINT "STOP WASTING MY TIME. GO BOTHER SOMEONE ELSE.": STOP -580 REM *** CHECK IF REQUESTED DISK IS BELOW ANOTHER -590 FOR R=1 TO 7 -600 FOR C=1 TO 3 -610 IF T(R,C)=D THEN 640 -620 NEXT C: NEXT R -640 FOR Q=R TO 1 STEP -1 -645 IF T(Q,C)=0 THEN 660 -650 IF T(Q,C)1 THEN 780 -750 PRINT "I'LL ASSUME YOU HIT THE WRONG KEY THIS TIME. BUT WATCH IT," -760 PRINT "I ONLY ALLOW ONE MISTAKE.": GOTO 705 -780 PRINT "I TRIED TO WARN YOU, BUT YOU WOULDN'T LISTEN." -790 PRINT "BYE BYE, BIG SHOT.":STOP -800 FOR R=1 TO 7 -810 IF T(R,N)<>0 THEN 840 -820 NEXT R -830 GOTO 880 -835 REM *** CHECK IF DISK TO BE PLACED ON A LARGER ONE -840 IF D0 THEN 970 -950 NEXT U -960 U=7: GOTO 980 -965 REM *** MOVE DISK AND SET OLD LOCATION TO 0 -970 U=U-1 -980 T(U,N)=T(V,W): T(V,W)=0 -995 REM *** PRINT OUT CURRENT STATUS -1000 GOSUB 1230 -1018 REM *** CHECK IF DONE -1020 M=M+1 -1030 FOR R=1 TO 7: FOR C=1 TO 2 -1050 IF T(R,C)<>0 THEN 1090 -1060 NEXT C: NEXT R -1080 GOTO 1120 -1090 IF M<=128 THEN 480 -1100 PRINT "SORRY, BUT I HAVE ORDERS TO STOP IF YOU MAKE MORE THAN" -1110 PRINT "128 MOVES.": STOP -1120 IF M<>2^S-1 THEN 1140 -1130 PRINT:PRINT "CONGRATULATIONS!!":PRINT -1140 PRINT "YOU HAVE PERFORMED THE TASK IN";M;"MOVES." -1150 PRINT: PRINT "TRY AGAIN (YES OR NO)";: INPUT A$ -1160 IF A$="NO" THEN 1390 -1170 IF A$="YES" THEN 90 -1180 PRINT: PRINT "'YES' OR 'NO' PLEASE";: INPUT A$: GOTO 1160 -1230 REM *** PRINT SUBROUTINE -1240 FOR K=1 TO 7 -1250 Z=10 -1260 FOR J=1 TO 3 -1270 IF T(K,J)=0 THEN 1330 -1280 PRINT TAB(Z-INT(T(K,J)/2)); -1290 FOR V=1 TO T(K,J) -1300 PRINT "*"; -1310 NEXT V -1320 GOTO 1340 -1330 PRINT TAB(Z);"*"; -1340 Z=Z+21 -1350 NEXT J -1360 PRINT -1370 NEXT K -1380 RETURN -1390 PRINT: PRINT "THANKS FOR THE GAME!": PRINT: END diff --git a/00_Alternate_Languages/91_Train/D/README.md b/00_Alternate_Languages/91_Train/D/README.md deleted file mode 100644 index 6c77f0a9e..000000000 --- a/00_Alternate_Languages/91_Train/D/README.md +++ /dev/null @@ -1,3 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://dlang.org). \ No newline at end of file diff --git a/00_Alternate_Languages/91_Train/D/train.d b/00_Alternate_Languages/91_Train/D/train.d deleted file mode 100644 index b4e595a0b..000000000 --- a/00_Alternate_Languages/91_Train/D/train.d +++ /dev/null @@ -1,50 +0,0 @@ -import std.stdio; -import std.random : uniform; - -float abs(float num) { - if(num<0){ - return num*-1; - } - - return num; -} - -void main() { - - writeln("\nTIME - SPEED DISTANCE EXERCISE"); - - bool keep_playing = true; - float error_margin = 5.0; - - while(keep_playing){ - int car_speed = uniform!"[]"(40,65); //Random number between 40 and 65 - int delta_time = uniform!"(]"(4,20); //Between 5 and 20 - int train_speed = uniform!"[)"(20,40); //Between 20 and 39; This is the default if not specified: uniform(x,y) - - writeln("\nA CAR TRAVELING AT ", car_speed, " MPH CAN MAKE A CERTAIN TRIP IN ", delta_time, - " HOURS LESS THAN A TRAIN TRAVELING AT ", train_speed, "MPH." ); - - float input; - write("HOW LONG DOES THE TRIP TAKE BY CAR? "); - readf!"%f\n"(input); - - float car_time = cast(float)delta_time * train_speed / (car_speed - train_speed); - int percent = cast(int)( abs(car_time-input) * 100 / car_time + .5); - - if(percent > error_margin){ - writeln("SORRY. YOU WERE OFF BY ", percent, " PERCENT."); - }else{ - writeln("GOOD! ANSWER WITHIN ", percent, " PERCENT."); - } - writeln("CORRECT ANSWER IS ", car_time, " HOURS."); - - string answer; - write("\nANOTHER PROBLEM (YES OR NO)? "); - readf!"%s\n"(answer); - - if( !(answer == "YES" || answer == "Y" || answer == "yes" || answer == "y") ){ - keep_playing = false; - } - } - -} \ No newline at end of file diff --git a/00_Alternate_Languages/91_Train/MiniScript/README.md b/00_Alternate_Languages/91_Train/MiniScript/README.md deleted file mode 100644 index 13928cccc..000000000 --- a/00_Alternate_Languages/91_Train/MiniScript/README.md +++ /dev/null @@ -1,22 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -0. "Try-It!" page on the web: -Go to https://miniscript.org/tryit/, clear the default program from the source code editor, paste in the contents of train.ms, and click the "Run Script" button. - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript train.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "train" - run -``` diff --git a/00_Alternate_Languages/91_Train/MiniScript/train.ms b/00_Alternate_Languages/91_Train/MiniScript/train.ms deleted file mode 100644 index 27ce5b98f..000000000 --- a/00_Alternate_Languages/91_Train/MiniScript/train.ms +++ /dev/null @@ -1,28 +0,0 @@ -// TRAIN -// -// Converted from BASIC to MiniScript by Ryushinaka and Joe Strout - -while true - print "TRAIN" - print "CREATIVE COMPUTER MORRISTOWN, NEW JERSEY" - print "" - print "TIME - SPEED DISTANCE EXERCISE" - - carSpeed = floor(25*rnd + 40) - difference = floor(15*rnd + 5) - trainSpeed = floor(19*rnd + 20) - print " A car traveling " + carSpeed + " MPH can make a certain trip in" - print difference + " hours less than a train traveling at " + trainSpeed + " MPH." - answer = input("How long does the trip take by car? ").val - carTime = difference*trainSpeed/(carSpeed-trainSpeed) - error = round(abs((carTime-answer)*100/answer)) - if error < 5 then - print "GOOD! Answer within " + error + " PERCENT." - else - print "Sorry. You were off by " + floor(error) + " percent." - print "Correct answer is " + round(carTime, 1) + " hours." - end if - - answer = input("Another problem (YES or NO)? ") - if not answer or answer[0].upper != "Y" then break -end while diff --git a/00_Alternate_Languages/91_Train/README.md b/00_Alternate_Languages/91_Train/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/91_Train/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/91_Train/nim/train.nim b/00_Alternate_Languages/91_Train/nim/train.nim deleted file mode 100644 index aa92c1a70..000000000 --- a/00_Alternate_Languages/91_Train/nim/train.nim +++ /dev/null @@ -1,38 +0,0 @@ -import std/[random,strutils] - -var - carSpeed, diff, err, guess, trainSpeed, carTime: int - stillplaying: bool = true - -randomize() # Seed the random number generator - -# Return a tuple that'll be carSpeed, diff, trainSpeed -proc randomNumbers(): (int,int,int) = - result = (rand(41..65), rand(6..20), rand(21..39)) - -# Do we want to play again? -proc tryAgain(): bool = - echo "ANOTHER PROBLEM (YES OR NO)" - var answer = readLine(stdin).normalize() - result = (answer == "y") or (answer == "yes") - -echo spaces(33), "TRAIN" -echo spaces(15), "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -echo "\n" -echo "TIME - SPEED DISTANCE EXERCISE" - -while stillplaying: - echo "" - (carSpeed, diff, trainSpeed) = randomNumbers() # Get random numbers for prompt - echo "A CAR TRAVELING ", carSpeed, " MPH CAN MAKE A CERTAIN TRIP IN" - echo diff, " HOURS LESS THAN A TRAIN TRAVELING AT ", trainSpeed, " MPH." - echo "HOW LONG DOES THE TRIP TAKE BY CAR?" - guess = readLine(stdin).parseInt() # Get guess - carTime = (diff * trainSpeed / (carSpeed - trainSpeed)).toInt() # Calculate answer - err = (((carTime - guess) * 100) / guess).toInt().abs() # Calculate error to an absolute value - if err > 5: # Error within 5%? - echo "SORRY. YOU WERE OFF BY ", err, " PERCENT." - else: - echo "GOOD! ANSWER WITHIN ", err, " PERCENT." - echo "CORRECT ANSWER IS ", carTime, " HOURS." - stillplaying = tryAgain() diff --git a/00_Alternate_Languages/91_Train/train.bas b/00_Alternate_Languages/91_Train/train.bas deleted file mode 100644 index b98176167..000000000 --- a/00_Alternate_Languages/91_Train/train.bas +++ /dev/null @@ -1,24 +0,0 @@ -1 PRINT TAB(33);"TRAIN" -2 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -3 PRINT: PRINT: PRINT -4 PRINT "TIME - SPEED DISTANCE EXERCISE": PRINT -10 C=INT(25*RND(1))+40 -15 D=INT(15*RND(1))+5 -20 T=INT(19*RND(1))+20 -25 PRINT " A CAR TRAVELING";C;"MPH CAN MAKE A CERTAIN TRIP IN" -30 PRINT D;"HOURS LESS THAN A TRAIN TRAVELING AT";T;"MPH." -35 PRINT "HOW LONG DOES THE TRIP TAKE BY CAR"; -40 INPUT A -45 V=D*T/(C-T) -50 E=INT(ABS((V-A)*100/A)+.5) -55 IF E>5 THEN 70 -60 PRINT "GOOD! ANSWER WITHIN";E;"PERCENT." -65 GOTO 80 -70 PRINT "SORRY. YOU WERE OFF BY";E;"PERCENT." -80 PRINT "CORRECT ANSWER IS";V;"HOURS." -90 PRINT -95 PRINT "ANOTHER PROBLEM (YES OR NO)"; -100 INPUT A$ -105 PRINT -110 IF A$="YES" THEN 10 -999 END diff --git a/00_Alternate_Languages/92_Trap/MiniScript/README.md b/00_Alternate_Languages/92_Trap/MiniScript/README.md deleted file mode 100644 index 521d3aff7..000000000 --- a/00_Alternate_Languages/92_Trap/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript trap.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "trap" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/92_Trap/MiniScript/trap.ms b/00_Alternate_Languages/92_Trap/MiniScript/trap.ms deleted file mode 100644 index 687a7a1ea..000000000 --- a/00_Alternate_Languages/92_Trap/MiniScript/trap.ms +++ /dev/null @@ -1,69 +0,0 @@ -// TRAP -// STEVE ULLMAN, 8-1-72 -// Ported to MiniScript by Ryushinaka and Joe Strout, 2023 - -print " "*34 + "TRAP" -print " "*15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -print - -// constants: -G = 6 // number of guesses -N = 100 // range of numbers - -// Get a yes/no (or at least y/n) response from the user. -askYesNo = function(prompt) - while true - answer = input(prompt).lower[:1] - if answer == "y" or answer == "n" then return answer - end while -end function - -if askYesNo("Instructions? ") == "y" then - print "I am thinking of a number between 1 and " + N - print "Try to guess my number. On each guess, " - print "you are to enter 2 numbers, trying to trap" - print "my number between the two numbers. I will" - print "tell you if you have trapped my number, if my" - print "number is larger than your two numbers, or if" - print "my number is smaller than your two numbers." - print "If you want to guess one single number, type" - print "your guess for both your trap numbers." - print "You get " + G + " guesses to get my number." - print -end if - -doOneGame = function - computers_number = ceil(N*rnd) - - for Q in range(1,G) - print "" - while true - guess = input("Guess #" + Q + ": ").replace(" ","") - guess = guess.split(",") - if guess.len == 2 then break - print "Enter your guess like: 30,40" - end while - A = guess[0].val - B = guess[1].val - - if A == computers_number and B == computers_number then - print "You got it!!!" - return - else if A <= computers_number and B >= computers_number then - print "You have trapped my number." - else if A > computers_number and B > computers_number then - print "My number is smaller than your trap numbers." - else if A < computers_number and B < computers_number then - print "My number is larger than your trap numbers." - end if - end for - print "Sorry, that's " + G + " guesses. The number was " + computers_number -end function - -// main loop -while true - print - doOneGame - print - if askYesNo("Try Again? ") == "n" then break -end while diff --git a/00_Alternate_Languages/92_Trap/README.md b/00_Alternate_Languages/92_Trap/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/92_Trap/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/92_Trap/trap.bas b/00_Alternate_Languages/92_Trap/trap.bas deleted file mode 100644 index 7827f8ca0..000000000 --- a/00_Alternate_Languages/92_Trap/trap.bas +++ /dev/null @@ -1,49 +0,0 @@ -1 PRINT TAB(34);"TRAP" -2 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -3 PRINT:PRINT:PRINT -10 G=6 -20 N=100 -30 REM-TRAP -40 REM-STEVE ULLMAN, 8-1-72 -50 PRINT "INSTRUCTIONS"; -60 INPUT Z$ -70 IF LEFT$(Z$,1)<>"Y" THEN 180 -80 PRINT "I AM THINKING OF A NUMBER BETWEEN 1 AND";N -90 PRINT "TRY TO GUESS MY NUMBER. ON EACH GUESS," -100 PRINT "YOU ARE TO ENTER 2 NUMBERS, TRYING TO TRAP" -110 PRINT "MY NUMBER BETWEEN THE TWO NUMBERS. I WILL" -120 PRINT "TELL YOU IF YOU HAVE TRAPPED MY NUMBER, IF MY" -130 PRINT "NUMBER IS LARGER THAN YOUR TWO NUMBERS, OR IF" -140 PRINT "MY NUMBER IS SMALLER THAN YOUR TWO NUMBERS." -150 PRINT "IF YOU WANT TO GUESS ONE SINGLE NUMBER, TYPE" -160 PRINT "YOUR GUESS FOR BOTH YOUR TRAP NUMBERS." -170 PRINT "YOU GET";G;"GUESSES TO GET MY NUMBER." -180 X=INT(N*RND(1))+1 -190 FOR Q=1 TO G -200 PRINT -210 PRINT "GUESS #";Q; -220 INPUT A,B -230 IF A=B AND X=A THEN 400 -240 IF A <= B THEN 260 -250 GOSUB 360 -260 IF A <= X AND X <= B THEN 320 -270 IF X 3 THEN 430 -330 IF K <= 0 THEN 430 -340 N = N - K -350 PRINT "THERE ARE NOW";N;"MATCHES REMAINING." -351 IF N = 4 THEN 381 -352 IF N = 3 THEN 383 -353 IF N = 2 THEN 385 -360 IF N <= 1 THEN 530 -370 Z = 4 - K -372 GOTO 390 -380 PRINT -381 Z = 3 -382 GOTO 390 -383 Z = 2 -384 GOTO 390 -385 Z = 1 -390 PRINT "MY TURN ! I REMOVE" Z "MATCHES" -400 N = N - Z -410 IF N <= 1 THEN 470 -420 GOTO 270 -430 PRINT "VERY FUNNY! DUMMY!" -440 PRINT "DO YOU WANT TO PLAY OR GOOF AROUND?" -450 PRINT "NOW, HOW MANY MATCHES DO YOU WANT", -460 GOTO 310 -470 PRINT -480 PRINT"YOU POOR BOOB! YOU TOOK THE LAST MATCH! I GOTCHA!!" -490 PRINT "HA ! HA ! I BEAT YOU !!!" -500 PRINT -510 PRINT "GOOD BYE LOSER!" -520 GOTO 560 -530 PRINT "YOU WON, FLOPPY EARS !" -540 PRINT "THINK YOU'RE PRETTY SMART !" -550 PRINT "LETS PLAY AGAIN AND I'LL BLOW YOUR SHOES OFF !!" -560 STOP -570 END diff --git a/00_Alternate_Languages/93_23_Matches/MiniScript/23matches.ms b/00_Alternate_Languages/93_23_Matches/MiniScript/23matches.ms deleted file mode 100644 index 645082acf..000000000 --- a/00_Alternate_Languages/93_23_Matches/MiniScript/23matches.ms +++ /dev/null @@ -1,70 +0,0 @@ -print " "*31 + "23 MATCHES" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print - -print "This is a game called '23 Matches'." -print -print "When it is your turn, you may take one, two, or three" -print "matches. The object of the game is not to have to take" -print "the last match." -print -print "Let's flip a coin to see who goes first." -print "If it comes up heads, I will win the toss." -print -matches = 23 -humanTurn = floor(rnd * 2) - -if humanTurn then - print "Tails! You go first." - prompt = "How many do you wish to remove? " -else - print "Heads! I win! Ha! Ha!" - print "Prepare to lose, meatball-nose!!" -end if - -choice = 2 -while matches > 0 - if humanTurn then - if matches < 23 then print "Your turn -- you may take 1, 2 or 3 matches." - prompt = "How many do you wish to remove? " - choice = 0 - if matches == 1 then choice = 1 - while choice == 0 - choice = input(prompt).val - if choice < 1 or choice > 3 or choice > matches then - choice = 0 - print "Very funny! Dummy!" - print "Do you want to play or goof around?" - prompt = "Now, how many matches do you want? " - end if - end while - matches = matches - choice - if matches == 0 then - print "You poor boob! You took the last match! I gotcha!!" - print "Ha ! Ha ! I beat you !!" - print - print "Good bye loser!" - else - print "There are now " + matches + " matches remaining." - print - end if - else - choice_comp = 4 - choice - if matches == 1 then - choice_comp = 1 - else if 1 < matches and matches < 4 then - choice_comp = matches - 1 - end if - matches = matches - choice_comp - if matches == 0 then - print "You won, floppy ears!" - print "Think you're pretty smart!" - print "Let's play again and I'll blow your shoes off!!" - else - print "My turn! I remove " + choice_comp + " matches" - print "The number of matches is now " + matches - print - end if - end if - humanTurn = not humanTurn -end while diff --git a/00_Alternate_Languages/93_23_Matches/MiniScript/README.md b/00_Alternate_Languages/93_23_Matches/MiniScript/README.md deleted file mode 100644 index 8b9bc04ca..000000000 --- a/00_Alternate_Languages/93_23_Matches/MiniScript/README.md +++ /dev/null @@ -1,18 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: -``` - miniscript 23matches.ms -``` - -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: -``` - load "23matches" - run -``` diff --git a/00_Alternate_Languages/93_23_Matches/README.md b/00_Alternate_Languages/93_23_Matches/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/93_23_Matches/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/94_War/MiniScript/README.md b/00_Alternate_Languages/94_War/MiniScript/README.md deleted file mode 100644 index 0d964946f..000000000 --- a/00_Alternate_Languages/94_War/MiniScript/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: - -``` - miniscript war.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: - -``` - load "war" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/94_War/MiniScript/war.ms b/00_Alternate_Languages/94_War/MiniScript/war.ms deleted file mode 100644 index acc432157..000000000 --- a/00_Alternate_Languages/94_War/MiniScript/war.ms +++ /dev/null @@ -1,65 +0,0 @@ -print " "*33 + "WAR" -print " "*15 + "CREATIVE COMPUTER MORRISTOWN, NEW JERSEY" -print; print; print - -print "This is the card game of War. Each card is given by SUIT-#" -print "as S-7 for Spade 7." - -// Get a yes/no (or at least y/n) response from the user. -askYesNo = function(prompt) - while true - answer = input(prompt + "? ").lower[:1] - if answer == "y" or answer == "n" then return answer - print "Answer yes or no, please." - end while -end function - -if askYesNo("Do you want directions") == "y" then - print "The computer gives you and it a 'card'. The higher card" - print "(numerically) wins. The game ends when you choose not to" - print "continue or when you have finished the pack." -end if -print -print - -cardValues = "2 3 4 5 6 7 8 9 10 J Q K A".split -deck = [] -for suits in "SHCD" - for value in cardValues - deck.push suits + "-" + value - end for -end for -deck.shuffle - -playerScore = 0 -computerScore = 0 - -while true - m1 = deck.pop - m2 = deck.pop - print "You: " + m1 + "; Computer: " + m2 - n1 = cardValues.indexOf(m1[2:]) - n2 = cardValues.indexOf(m2[2:]) - if n1 > n2 then - playerScore += 1 - print "You win. You have " + playerScore + " and the computer has " + computerScore - else if n2 > n1 then - computerScore += 1 - print "The computer wins!!! You have " + playerScore + " and the computer has " + computerScore - else - print "Tie. No score change." - end if - if not deck then break - if askYesNo("Do you want to continue") == "n" then break -end while - -if not deck then - print - print - print "We have run out of cards. Final score: You: " + playerScore + - " The computer: " + computerScore - print -end if -print "Thanks for playing. It was fun." -print - \ No newline at end of file diff --git a/00_Alternate_Languages/94_War/README.md b/00_Alternate_Languages/94_War/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/94_War/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/94_War/d/.gitignore b/00_Alternate_Languages/94_War/d/.gitignore deleted file mode 100644 index d969f6b2c..000000000 --- a/00_Alternate_Languages/94_War/d/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.exe -*.obj diff --git a/00_Alternate_Languages/94_War/d/README.md b/00_Alternate_Languages/94_War/d/README.md deleted file mode 100644 index 2bc48a124..000000000 --- a/00_Alternate_Languages/94_War/d/README.md +++ /dev/null @@ -1,125 +0,0 @@ -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/00_Alternate_Languages/94_War/d/war.d b/00_Alternate_Languages/94_War/d/war.d deleted file mode 100644 index d5a453faf..000000000 --- a/00_Alternate_Languages/94_War/d/war.d +++ /dev/null @@ -1,80 +0,0 @@ -@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); - } -} diff --git a/00_Alternate_Languages/94_War/war.bas b/00_Alternate_Languages/94_War/war.bas deleted file mode 100644 index 388b0ec45..000000000 --- a/00_Alternate_Languages/94_War/war.bas +++ /dev/null @@ -1,68 +0,0 @@ -10 PRINT TAB(33);"WAR" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT: PRINT: PRINT -100 PRINT "THIS IS THE CARD GAME OF WAR. EACH CARD IS GIVEN BY SUIT-#" -110 PRINT "AS S-7 FOR SPADE 7. "; -120 PRINT "DO YOU WANT DIRECTIONS"; -130 INPUT B$ -140 IF B$="NO" THEN 210 -150 IF B$="YES" THEN 180 -160 PRINT "YES OR NO, PLEASE. "; -170 GOTO 120 -180 PRINT "THE COMPUTER GIVES YOU AND IT A 'CARD'. THE HIGHER CARD" -190 PRINT "(NUMERICALLY) WINS. THE GAME ENDS WHEN YOU CHOOSE NOT TO" -200 PRINT "CONTINUE OR WHEN YOU HAVE FINISHED THE PACK." -210 PRINT -220 PRINT -230 DIM A$(52),L(54) -240 FOR I=1 TO 52 -250 READ A$(I) -260 NEXT I -270 REM -280 FOR J=1 TO 52 -290 LET L(J)=INT(52*RND(1))+1 -295 IF J=1 THEN 350 -300 FOR K=1 TO J-1 -310 IF L(K)<>L(J) THEN 340 -320 REM -330 GOTO 290 -340 NEXT K -350 NEXT J -360 P=P+1 -370 M1=L(P) -380 P=P+1 -390 M2=L(P) -400 PRINT -420 PRINT "YOU: ";A$(M1),"COMPUTER: ";A$(M2) -430 N1=INT((M1-.5)/4) -440 N2=INT((M2-.5)/4) -450 IF N1>=N2 THEN 490 -460 A1=A1+1 -470 PRINT "THE COMPUTER WINS!!! YOU HAVE";B1;"AND THE COMPUTER HAS";A1 -480 GOTO 540 -490 IF N1=N2 THEN 530 -500 B1=B1+1 -510 PRINT "YOU WIN. YOU HAVE";B1;"AND THE COMPUTER HAS";A1 -520 GOTO 540 -530 PRINT "TIE. NO SCORE CHANGE." -540 IF L(P+1)=0 THEN 610 -550 PRINT "DO YOU WANT TO CONTINUE"; -560 INPUT V$ -570 IF V$="YES" THEN 360 -580 IF V$="NO" THEN 650 -590 PRINT "YES OR NO, PLEASE. "; -600 GOTO 540 -610 PRINT -620 PRINT -630 PRINT "WE HAVE RUN OUT OF CARDS. FINAL SCORE: YOU: ";B1; -640 PRINT " THE COMPUTER: ";A1:PRINT -650 PRINT "THANKS FOR PLAYING. IT WAS FUN." -655 PRINT -660 DATA "S-2","H-2","C-2","D-2","S-3","H-3","C-3","D-3" -670 DATA "S-4","H-4","C-4","D-4","S-5","H-5","C-5","D-5" -680 DATA "S-6","H-6","C-6","D-6","S-7","H-7","C-7","D-7" -690 DATA "S-8","H-8","C-8","D-8","S-9","H-9","C-9","D-9" -700 DATA "S-10","H-10","C-10","D-10","S-J","H-J","C-J","D-J" -710 DATA "S-Q","H-Q","C-Q","D-Q","S-K","H-K","C-K","D-K" -720 DATA "S-A","H-A","C-A","D-A" -999 END diff --git a/00_Alternate_Languages/95_Weekday/MiniScript/README.md b/00_Alternate_Languages/95_Weekday/MiniScript/README.md deleted file mode 100644 index 218cb4cc9..000000000 --- a/00_Alternate_Languages/95_Weekday/MiniScript/README.md +++ /dev/null @@ -1,17 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: -``` - miniscript weekday.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: -``` - load "weekday" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/95_Weekday/MiniScript/weekday.ms b/00_Alternate_Languages/95_Weekday/MiniScript/weekday.ms deleted file mode 100644 index 65641ebc3..000000000 --- a/00_Alternate_Languages/95_Weekday/MiniScript/weekday.ms +++ /dev/null @@ -1,182 +0,0 @@ -TAB = char(9) - -Age = {"m": 0, "d": 0, "y": 0} -Age.init = function(m,d,y) - noob = new Age - noob.m = m;noob.d = d;noob.y = y - return noob -end function - -Age.sub = function(a) - m1 = self.m; d1 = self.d; y1 = self.y - d1 = d1 - a.d - if d1 < 0 then - d1 = d1 + 30 - m1 = m1 - 1 - end if - m1 = m1 - a.m - if m1 < 0then - m1 = m1 + 12 - y1 = y1 - 1 - end if - y1 = y1 - a.y - return Age.init(m1,d1,y1) -end function - -Age.multiply = function(multiplier) - ageInDays = self.y *365 + self.m * 30 + self.d + floor(self.m / 2) - newAge = ageInDays * multiplier - years = floor(newAge/ 365) - leftover = newAge % 365 - months = floor(leftover / 30) - days = floor(leftover % 30) - return Age.init(months, days, years) -end function - -Date = {"m": null, "d": null, "y": null} - -// the number of days between the 1st of one month to the next -Date.daysPerMonth = [0,31,28,31,30,31,30, 31,31,30,31,30] -Date.dayNames = ["Sunday", "Monday", "Tuesday", "Wednesday", -"Thursday", "Friday", "Saturday"] - -Date.init = function(dt) - d = dt.split(",") - if d.len != 3 then return - noob = new Date - noob.m = d[0].val - noob.d = d[1].val - noob.y = d[2].val - return noob -end function - -Date.diff = function(mdy) - dday = self.d - mdy.d - dmonth = self.m - mdy.m - if dday < 0 then - dmonth -= 1 - dday += 30 - end if - - dyear = self.y - mdy.y - if dmonth <0 then - dyear -= 1 - dmonth += 12 - end if - return Age.init(dmonth, dday, dyear) -end function - -Date._isLeapYear = function - return (self.y % 4 == 0 and self.y % 100 != 0) or self.y % 400 == 0 -end function - -Date.value = function - //Not accepting dates Jan 1st 1583 this because the - //transistion to Gregorian calendar occurred in 1582. - - //calculating days since the end of 1582 - years = self.y - 1583 - days = years * 365 + self._leapYears + Date.daysPerMonth[:self.m].sum + self.d - return days // returns 1 for 1,1,1583 -end function - -Date.dayOfWeek = function - // 1,1,1583 is a Saturday - // Date.value calculates a value of 1 for that date - return (self.value + 5) % 7 -end function - -Date.weekday = function - return Date.dayNames[self.dayOfWeek] -end function - -// get # of lear yeaps since the change to Gregorian -Date._leapYears = function - ly = floor((self.y - 1580) / 4) - - //exclude centuries - centuries = floor((self.y - 1500) / 100) - - //unless centuries divisible by 400 - centuries400 = floor((self.y - 1200) / 400) - ly = ly - centuries + centuries400 - - if self._isLeapYear and self.m < 3 then ly -= 1 - return ly -end function - -print " "*32 + "WEEKDAY" -print " "*15 + "Creative Computing Morristown, New Jersey" -print; print; print - -print "WEEKDAY is a computer demonstration that" -print "gives facts about a date of interest to you." -print - -mdy = input("Enter today's date in the form: 3,24,1979? ") -today = Date.init(mdy) - - -mdy = input("Enter day of birth (or other day of interest)? ") -dob = Date.init(mdy) - -print -if dob.y < 1583 then - print "Not prepared to give day of the week prior to 1583" - exit -end if - -verb = " was a " -if today.value < dob.value then verb= " will be a " -if today.value == dob.value then verb = " is a " - -if dob.d == 13 and dob.weekday == "Friday" then - endMsg = " The Thirteenth--Beware!" -else - endMsg = "." -end if -print dob.m + "/" + dob.d + "/" + dob.y + verb + dob.weekday + endMsg - -age = today.diff(dob) - -totalAge = Age.init(age.m,age.d,age.y) -if verb == " was a " then - if dob.d == today.d and dob.m == today.m then print "***HAPPY BIRTHDAY***" - - lines= [["", "YEARS", "MONTHS", "DAYS"]] - lines.push(["", "-----", "------", "----"]) - lines.push(["Your age (if birthdate)", age.y,age.m, age.d]) - - spent = age.multiply(.35) - lines.push(["You have slept", spent.y,spent.m, spent.d]) - totalAge = totalAge.sub(spent) - - spent = age.multiply(.17) - lines.push(["You have eaten", spent.y,spent.m, spent.d]) - totalAge = totalAge.sub(spent) - - if totalAge.y <= 3 then - phrase = "You have played" - else if totalAge.y <= 9 then - phrase = "You have played/studied" - else - phrase = "You have worked/played" - end if - - spent = age.multiply(.23) - lines.push([phrase, spent.y,spent.m, spent.d]) - totalAge = totalAge.sub(spent) - - relaxed = totalAge - lines.push(["You have relaxed", relaxed.y, relaxed.m, relaxed.d]) - for line in lines - col0 = (" " * 25 + line[0])[-25:] - col1 = (line[1] + " " * 6)[:6] - col2 = (line[2] + " " * 7)[:7] - col3 = (line[3] + " " * 5)[:5] - print (col0+" " + col1+col2+col3) - end for -end if - -print -print " "*16 + "*** You may retire in " + (dob.y + 65) + " ***" diff --git a/00_Alternate_Languages/95_Weekday/README.md b/00_Alternate_Languages/95_Weekday/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/95_Weekday/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/95_Weekday/weekday.bas b/00_Alternate_Languages/95_Weekday/weekday.bas deleted file mode 100644 index 33f982e88..000000000 --- a/00_Alternate_Languages/95_Weekday/weekday.bas +++ /dev/null @@ -1,150 +0,0 @@ -10 PRINT TAB(32);"WEEKDAY" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT:PRINT:PRINT -100 PRINT "WEEKDAY IS A COMPUTER DEMONSTRATION THAT" -110 PRINT"GIVES FACTS ABOUT A DATE OF INTEREST TO YOU." -120 PRINT -130 PRINT "ENTER TODAY'S DATE IN THE FORM: 3,24,1979 "; -140 INPUT M1,D1,Y1 -150 REM THIS PROGRAM DETERMINES THE DAY OF THE WEEK -160 REM FOR A DATE AFTER 1582 -170 DEF FNA(A)=INT(A/4) -180 DIM T(12) -190 DEF FNB(A)=INT(A/7) -200 REM SPACE OUTPUT AND READ IN INITIAL VALUES FOR MONTHS. -210 FOR I= 1 TO 12 -220 READ T(I) -230 NEXT I -240 PRINT"ENTER DAY OF BIRTH (OR OTHER DAY OF INTEREST)"; -250 INPUT M,D,Y -260 PRINT -270 LET I1 = INT((Y-1500)/100) -280 REM TEST FOR DATE BEFORE CURRENT CALENDAR. -290 IF Y-1582 <0 THEN 1300 -300 LET A = I1*5+(I1+3)/4 -310 LET I2=INT(A-FNB(A)*7) -320 LET Y2=INT(Y/100) -330 LET Y3 =INT(Y-Y2*100) -340 LET A =Y3/4+Y3+D+T(M)+I2 -350 LET B=INT(A-FNB(A)*7)+1 -360 IF M > 2 THEN 470 -370 IF Y3 = 0 THEN 440 -380 LET T1=INT(Y-FNA(Y)*4) -390 IF T1 <> 0 THEN 470 -400 IF B<>0 THEN 420 -410 LET B=6 -420 LET B = B-1 -430 GOTO 470 -440 LET A = I1-1 -450 LET T1=INT(A-FNA(A)*4) -460 IF T1 = 0 THEN 400 -470 IF B <>0 THEN 490 -480 LET B = 7 -490 IF (Y1*12+M1)*31+D1<(Y*12+M)*31+D THEN 550 -500 IF (Y1*12+M1)*31+D1=(Y*12+M)*31+D THEN 530 -510 PRINT M;"/";D;"/";Y;" WAS A "; -520 GOTO 570 -530 PRINT M;"/";D;"/";Y;" IS A "; -540 GOTO 570 -550 PRINT M;"/";D;"/";Y;" WILL BE A "; -560 REM PRINT THE DAY OF THE WEEK THE DATE FALLS ON. -570 IF B <>1 THEN 590 -580 PRINT "SUNDAY." -590 IF B<>2 THEN 610 -600 PRINT "MONDAY." -610 IF B<>3 THEN 630 -620 PRINT "TUESDAY." -630 IF B<>4 THEN 650 -640 PRINT "WEDNESDAY." -650 IF B<>5 THEN 670 -660 PRINT "THURSDAY." -670 IF B<>6 THEN 690 -680 GOTO 1250 -690 IF B<>7 THEN 710 -700 PRINT "SATURDAY." -710 IF (Y1*12+M1)*31+D1=(Y*12+M)*31+D THEN 1120 -720 LET I5=Y1-Y -730 PRINT -740 LET I6=M1-M -750 LET I7=D1-D -760 IF I7>=0 THEN 790 -770 LET I6= I6-1 -780 LET I7=I7+30 -790 IF I6>=0 THEN 820 -800 LET I5=I5-1 -810 LET I6=I6+12 -820 IF I5<0 THEN 1310 -830 IF I7 <> 0 THEN 850 -835 IF I6 <> 0 THEN 850 -840 PRINT"***HAPPY BIRTHDAY***" -850 PRINT " "," ","YEARS","MONTHS","DAYS" -855 PRINT " "," ","-----","------","----" -860 PRINT "YOUR AGE (IF BIRTHDATE) ",I5,I6,I7 -870 LET A8 = (I5*365)+(I6*30)+I7+INT(I6/2) -880 LET K5 = I5 -890 LET K6 = I6 -900 LET K7 = I7 -910 REM CALCULATE RETIREMENT DATE. -920 LET E = Y+65 -930 REM CALCULATE TIME SPENT IN THE FOLLOWING FUNCTIONS. -940 LET F = .35 -950 PRINT "YOU HAVE SLEPT ", -960 GOSUB 1370 -970 LET F = .17 -980 PRINT "YOU HAVE EATEN ", -990 GOSUB 1370 -1000 LET F = .23 -1010 IF K5 > 3 THEN 1040 -1020 PRINT "YOU HAVE PLAYED", -1030 GOTO 1080 -1040 IF K5 > 9 THEN 1070 -1050 PRINT "YOU HAVE PLAYED/STUDIED", -1060 GOTO 1080 -1070 PRINT "YOU HAVE WORKED/PLAYED", -1080 GOSUB 1370 -1085 GOTO 1530 -1090 PRINT "YOU HAVE RELAXED ",K5,K6,K7 -1100 PRINT -1110 PRINT TAB(16);"*** YOU MAY RETIRE IN";E;" ***" -1120 PRINT -1140 PRINT -1200 PRINT -1210 PRINT -1220 PRINT -1230 PRINT -1240 END -1250 IF D=13 THEN 1280 -1260 PRINT "FRIDAY." -1270 GOTO 710 -1280 PRINT "FRIDAY THE THIRTEENTH---BEWARE!" -1290 GOTO 710 -1300 PRINT "NOT PREPARED TO GIVE DAY OF WEEK PRIOR TO MDLXXXII. " -1310 GOTO 1140 -1320 REM TABLE OF VALUES FOR THE MONTHS TO BE USED IN CALCULATIONS. -1330 DATA 0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5 -1340 REM THIS IS THE CURRENT DATE USED IN THE CALCULATIONS. -1350 REM THIS IS THE DATE TO BE CALCULATED ON. -1360 REM CALCULATE TIME IN YEARS, MONTHS, AND DAYS -1370 LET K1=INT(F*A8) -1380 LET I5 = INT(K1/365) -1390 LET K1 = K1- (I5*365) -1400 LET I6 = INT(K1/30) -1410 LET I7 = K1 -(I6*30) -1420 LET K5 = K5-I5 -1430 LET K6 =K6-I6 -1440 LET K7 = K7-I7 -1450 IF K7>=0 THEN 1480 -1460 LET K7=K7+30 -1470 LET K6=K6-1 -1480 IF K6>0 THEN 1510 -1490 LET K6=K6+12 -1500 LET K5=K5-1 -1510 PRINT I5,I6,I7 -1520 RETURN -1530 IF K6=12 THEN 1550 -1540 GOTO 1090 -1550 LET K5=K5+1 -1560 LET K6=0 -1570 GOTO 1090 -1580 REM -1590 END diff --git a/00_Alternate_Languages/96_Word/MiniScript/README.md b/00_Alternate_Languages/96_Word/MiniScript/README.md deleted file mode 100644 index 567a84baf..000000000 --- a/00_Alternate_Languages/96_Word/MiniScript/README.md +++ /dev/null @@ -1,17 +0,0 @@ -Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). - -Conversion to [MiniScript](https://miniscript.org). - -Ways to play: - -1. Command-Line MiniScript: -Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: -``` - miniscript word.ms -``` -2. Mini Micro: -Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: -``` - load "word" - run -``` \ No newline at end of file diff --git a/00_Alternate_Languages/96_Word/MiniScript/word.ms b/00_Alternate_Languages/96_Word/MiniScript/word.ms deleted file mode 100644 index 190ad6117..000000000 --- a/00_Alternate_Languages/96_Word/MiniScript/word.ms +++ /dev/null @@ -1,63 +0,0 @@ -words = ["dinky", "smoke", "water", "grass", "train", "might", - "first", "candy", "champ", "would", "clump", "dopey"] - -playGame = function - secret = words[rnd * words.len] - guesses = 0 - exact = ["-"]*5 - - print "You are starting a new game..." - while true - guess = "" - while guess == "" - print - guess = input("Guess a five letter word. ").lower - if guess == "?" then break - if guess.len != 5 then - guess = "" - print "You must guess a five letter word. Try again." - end if - end while - guesses += 1 - - if guess == "?" then - print "The secret word is " + secret - break - else - common = "" - for i in range(0, 4) - if secret.indexOf(guess[i]) != null then - common += guess[i] - if secret[i] == guess[i] then - exact[i] = guess[i] - end if - end if - end for - print "There were " + common.len + " matches and the common letters were..." + common - print "From the exact letter matches, you know"+"."*16 + exact.join("") - - if secret == guess or secret == exact.join("") then - print "You have guessed the word. It took " + guesses + " guesses!" - break - else if common.len < 2 then - print - print "If you give up, type '?' for your next guess." - end if - end if - end while -end function - -print " " * 33 + "WORD" -print " " * 15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -print -print "I am thinking of a word -- you guess it. I will give you" -print "clues to help you get it. Good luck!" -print - -playing = "y" -while playing == "y" - playGame - print - playing = input("Want to play again? ") + " " - playing = playing[0].lower -end while diff --git a/00_Alternate_Languages/96_Word/README.md b/00_Alternate_Languages/96_Word/README.md deleted file mode 100644 index 50a7a8b49..000000000 --- a/00_Alternate_Languages/96_Word/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Please refer to the `readme.md` in the parent folder. - -Each subfolder represents a port of this program to a language which is _not_ one of the agreed upon 10 languages, which are intended to meet these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -We welcome additional ports, but these additional ports are for educational purposes only. \ No newline at end of file diff --git a/00_Alternate_Languages/96_Word/word.bas b/00_Alternate_Languages/96_Word/word.bas deleted file mode 100644 index 46e690619..000000000 --- a/00_Alternate_Languages/96_Word/word.bas +++ /dev/null @@ -1,65 +0,0 @@ -2 PRINT TAB(33);"WORD" -3 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -4 PRINT: PRINT: PRINT -5 DIM S(7),A(7),L(7),D(7),P(7) -10 PRINT "I AM THINKING OF A WORD -- YOU GUESS IT. I WILL GIVE YOU" -15 PRINT "CLUES TO HELP YOU GET IT. GOOD LUCK!!": PRINT: PRINT -20 REM -30 PRINT: PRINT: PRINT "YOU ARE STARTING A NEW GAME..." -35 RESTORE -40 READ N -50 C=INT(RND(1)*N+1) -60 FOR I=1 TO C -70 READ S$ -80 NEXT I -90 G=0 -95 S(0)=LEN(S$) -100 FOR I=1 TO LEN(S$): S(I)=ASC(MID$(S$,I,1)): NEXT I -110 FOR I=1 TO 5 -120 A(I)=45 -130 NEXT I -140 FOR J=1 TO 5 -144 P(J)=0 -146 NEXT J -150 PRINT "GUESS A FIVE LETTER WORD"; -160 INPUT L$ -170 G=G+1 -172 IF S$=L$ THEN 500 -173 FOR I=1 TO 7: P(I)=0: NEXT I -175 L(0)=LEN(L$) -180 FOR I=1 TO LEN(L$): L(I)=ASC(MID$(L$,I,1)): NEXT I -190 IF L(1)=63 THEN 300 -200 IF L(0)<>5 THEN 400 -205 M=0: Q=1 -210 FOR I=1 TO 5 -220 FOR J=1 TO 5 -230 IF S(I)<>L(J) THEN 260 -231 P(Q)=L(J) -232 Q=Q+1 -233 IF I<>J THEN 250 -240 A(J)=L(J) -250 M=M+1 -260 NEXT J -265 NEXT I -270 A(0)=5 -272 P(0)=M -275 A$="": FOR I=1 TO A(0): A$=A$+CHR$(A(I)): NEXT I -277 P$="": FOR I=1 TO P(0): P$=P$+CHR$(P(I)): NEXT I -280 PRINT "THERE WERE";M;"MATCHES AND THE COMMON LETTERS WERE...";P$ -285 PRINT "FROM THE EXACT LETTER MATCHES, YOU KNOW................";A$ -286 IF A$=S$ THEN 500 -287 IF M>1 THEN 289 -288 PRINT: PRINT "IF YOU GIVE UP, TYPE '?' FOR YOUR NEXT GUESS." -289 PRINT -290 GOTO 150 -300 S$="": FOR I=1 TO 7: S$=S$+CHR$(S(I)): NEXT I -310 PRINT "THE SECRET WORD IS ";S$: PRINT -320 GOTO 30 -400 PRINT "YOU MUST GUESS A 5 LETTER WORD. START AGAIN." -410 PRINT: G=G-1: GOTO 150 -500 PRINT "YOU HAVE GUESSED THE WORD. IT TOOK";G;"GUESSES!": PRINT -510 INPUT "WANT TO PLAY AGAIN";Q$ -520 IF Q$="YES" THEN 30 -530 DATA 12,"DINKY","SMOKE","WATER","GRASS","TRAIN","MIGHT","FIRST" -540 DATA "CANDY","CHAMP","WOULD","CLUMP","DOPEY" -999 END diff --git a/00_Alternate_Languages/README.md b/00_Alternate_Languages/README.md deleted file mode 100644 index 0cbe947e1..000000000 --- a/00_Alternate_Languages/README.md +++ /dev/null @@ -1,15 +0,0 @@ -#### Alternate Languages - -This folder contains implementations of each program in alternate languages which are _not_ one of the agreed upon 10 languages. - -Implementations here are NOT bound to these three criteria: - -1. Popular (by TIOBE index) -2. Memory safe -3. Generally considered a 'scripting' language - -So for example, (here only) C or PASCAL are allowed. Please still remain faithful to original look-and-feel (console applications). -Try to keep your code portable (unless it is not possible, and then be very explicit about this limitation in your -README and your folder naming). - -We welcome additional ports in whatever language you prefer, but these additional ports are for educational purposes only, and do not count towards the donation total at the end of the project. diff --git a/00_Common/BASIC_Tests/InputTest.bas b/00_Common/BASIC_Tests/InputTest.bas deleted file mode 100644 index 0b9af8659..000000000 --- a/00_Common/BASIC_Tests/InputTest.bas +++ /dev/null @@ -1,4 +0,0 @@ -10 INPUT "Enter 3 numbers";A,B,C -20 PRINT "You entered: ";A;B;C -30 PRINT "--------------------------" -40 GOTO 10 diff --git a/00_Common/BASIC_Tests/OutputTest.bas b/00_Common/BASIC_Tests/OutputTest.bas deleted file mode 100644 index 07d5f1566..000000000 --- a/00_Common/BASIC_Tests/OutputTest.bas +++ /dev/null @@ -1,2 +0,0 @@ -10 A=1: B=-2: C=0.7: D=123456789: E=-0.0000000001 -20 PRINT "|";A;"|";B;"|";C;"|";D;"|";E;"|" diff --git a/00_Common/BASIC_Tests/RndTest.bas b/00_Common/BASIC_Tests/RndTest.bas deleted file mode 100644 index c994c6db1..000000000 --- a/00_Common/BASIC_Tests/RndTest.bas +++ /dev/null @@ -1,4 +0,0 @@ -10 PRINT "1: ";RND(1);RND(1);RND(0);RND(0);RND(1) -20 PRINT "2: ";RND(-2);RND(1);RND(1);RND(1) -30 PRINT "3: ";RND(-5);RND(1);RND(1);RND(1) -40 PRINT "4: ";RND(-2);RND(1);RND(1);RND(1) diff --git a/00_Common/README.md b/00_Common/README.md deleted file mode 100644 index 5b207e05c..000000000 --- a/00_Common/README.md +++ /dev/null @@ -1,185 +0,0 @@ -# Common Library - -## Purpose - -The primary purpose of this library is to implement common behaviours of the BASIC interpreter that impact gameplay, to -free coders porting the games to concentrate on the explicit game logic. - -The behaviours implemented by this library are: - -* Complex interactions involved in text input. -* Formatting of number in text output. -* Behaviour of the BASIC `RND(float)` PRNG function. - -A secondary purpose is to provide common services that, with dependency injection, would allow a ported game to be -driven programmatically to permit full-game acceptance tests to be written. - -The library is **NOT** intended to be: - -* a repository for common game logic that is implemented in the BASIC code of the games; or -* a DSL allowing the BASIC code to be compiled in a different language environment with minimal changes. This implies - that implementations of the above behaviours should use method names, etc, that are idiomatic of the specific - language's normal routines for that behaviour. - -## Text Input - -The behaviour of the BASIC interpreter when accepting text input from the user is a major element of the original -gameplay experience that is seen to be valuable to maintain. This behaviour is complex and non-trivial to implement, and -is better implemented once for other developers to use so they can concentrate on the explicit game logic. - -The text input/output behaviour can be investigated using a basic program such as: - -**`BASIC_Tests/InputTest.bas`** - -```basic -10 INPUT "Enter 3 numbers";A,B,C -20 PRINT "You entered: ";A;B;C -30 PRINT "--------------------------" -40 GOTO 10 -``` - -The following transcript shows the use of this program, and some interesting behaviours of the BASIC interpreter INPUT -routine. There are some other behaviours which can be seen in the unit tests for the C# library implementation. - -```dos -Enter 3 numbers? -1,2,3.141 <-- multiple numbers are separated by commas -You entered: -1 2 3.141 --------------------------- -Enter 3 numbers? 1 <-- ... or entered on separate lines -?? 2 -?? 3 -You entered: 1 2 3 --------------------------- -Enter 3 numbers? 1,2 <-- ... or both -?? 3 -You entered: 1 2 3 --------------------------- -Enter 3 numbers? 1,-2,3,4 <-- Extra input is ignore with a warning -!EXTRA INPUT IGNORED -You entered: 1 -2 3 --------------------------- -Enter 3 numbers? 5 , 6.7, -8 ,10 <-- Whitespace around values is ignored -!EXTRA INPUT IGNORED -You entered: 5 6.7 -8 --------------------------- -Enter 3 numbers? abcd,e,f <-- Non-numeric entries must be retried -!NUMBER EXPECTED - RETRY INPUT LINE -? 1,2,abc <-- A single non-numeric invalidates the whole line -!NUMBER EXPECTED - RETRY INPUT LINE -? 1de,2.3f,10k,abcde <-- ... except for trailing non-digit chars and extra input -!EXTRA INPUT IGNORED -You entered: 1 2.3 10 --------------------------- -Enter 3 numbers? 1,"2,3",4 <-- Double-quotes enclose a single parsed value -You entered: 1 2 4 --------------------------- -Enter 3 numbers? 1,2,"3 <-- An unmatched double-quote crashes the interpreter -vintbas.exe: Mismatched inputbuf in inputVars -CallStack (from HasCallStack): - error, called at src\Language\VintageBasic\Interpreter.hs:436:21 in main:Language.VintageBasic.Interpreter -``` - -I propose to ignore this last behaviour - the interpreter crash - and instead treat the end of the input line as the end -of a quoted value. There are some additional behaviours to those shown above which can be seen in the unit tests for -the C# implementation of the library. - -Note also that BASIC numeric variables store a single-precision floating point value, so numeric input functions should -return a value of that type. - -### Implementation Notes - -The usage of the `INPUT` command in the BASIC code of the games was analysed, with the variables used designated as -`num`, for a numeric variable (eg. `M1`), or `str`, for a string variable (eg. `C$`). The result of this usage analysis -across all game programs is: - -Variable number and type|Count ----|--- -str|137 -str str|2 -num|187 -num num|27 -num num num|7 -num num num num|1 -num num num num num num num num num num|1 - -The usage count is interesting, but not important. What is important is the variable type and number for each usage. -Implementers if the above behaviours do not need to cater for mixed variable types in their input routines (although the -BASIC interpreter does support this). Input routines also need to cater only for 1 or 2 string values, and 1, 2, 3, 4, -or 10 numeric values. - -## Numbers in Text Output - -As seen in the transcript above, the BASIC interpreter has some particular rules for formatting numbers in text output. -Negative numbers are printed with a leading negative sign (`-`) and a trailing space. Positive numbers are printed also -with the trailing space, but with a leading space in place of the sign character. - -Additional formatting rules can be seen by running this program: - -**`BASIC_Tests/OutputTest.bas`** - -```basic -10 A=1: B=-2: C=0.7: D=123456789: E=-0.0000000001 -20 PRINT "|";A;"|";B;"|";C;"|";D;"|";E;"|" -``` - -The output is: - -```dos -| 1 |-2 | .7 | 1.2345679E+8 |-1.E-10 | -``` - -This clearly shows the leading and trailing spaces, but also shows that: - -* numbers without an integer component are printed without a leading zero to the left of the decimal place; -* numbers above and below a certain magnitude are printed in scientific notation. - - -### Implementation Notes - - -I think the important piece of this number formatting behaviour, in terms of its impact on replicating the text output -of the original games, is the leading and trailing spaces. This should be the minimum behaviour supported for numeric -output. Additional formatting behaviours may be investigated and supported by library implementers as they choose. - -## The BASIC `RND(float)` function - -The [Vintage BASIC documentation](http://vintage-basic.net/downloads/Vintage_BASIC_Users_Guide.html) describes the -behaviour of the `RND(float)` function: - -> Psuedorandom number generator. The behavior is different depending on the value passed. If the value is positive, the -> result will be a new random value between 0 and 1 (including 0 but not 1). If the value is zero, the result will be a -> repeat of the last random number generated. If the value is negative, it will be rounded down to the nearest integer -> and used to reseed the random number generator. Pseudorandom sequences can be repeated by reseeding with the same -> number. - -This behaviour can be shown by the program: - -**`BASIC_Tests/RndTest.bas`** - -```basic -10 PRINT "1: ";RND(1);RND(1);RND(0);RND(0);RND(1) -20 PRINT "2: ";RND(-2);RND(1);RND(1);RND(1) -30 PRINT "3: ";RND(-5);RND(1);RND(1);RND(1) -40 PRINT "4: ";RND(-2);RND(1);RND(1);RND(1) -``` - -The output of this program is: - -```dos -1: .97369444 .44256502 .44256502 .44256502 .28549057 <-- Repeated values due to RND(0) -2: .4986506 4.4510484E-2 .96231 .35997057 -3: .8113741 .13687313 6.1034977E-2 .7874807 -4: .4986506 4.4510484E-2 .96231 .35997057 <-- Same sequence as line 2 due to same seed -``` - - -### Implementation Notes - - -While the BASIC `RND(x)` function always returns a number between 0 (inclusive) and 1 (exclusive) for positive non-zero -values of `x`, game porters would find it convenient for the library to include functions returning a random float or -integer in a range from an inclusive minimum to an exclusive maximum. - -As one of the games, "Football", makes use of `RND(0)` with different scaling applied than the previous use of `RND(1)`, -a common library implementation should always generate a value between 0 and 1, and scale that for a function with a -range, so that a call to the equivalent of the `RND(0)` function can return the previous value between 0 and 1. diff --git a/00_Common/dotnet/Directory.Build.props b/00_Common/dotnet/Directory.Build.props deleted file mode 100644 index f5a054dc5..000000000 --- a/00_Common/dotnet/Directory.Build.props +++ /dev/null @@ -1,8 +0,0 @@ - - - - enable - 10.0 - - - diff --git a/00_Common/dotnet/Games.Common.Test/Games.Common.Test.csproj b/00_Common/dotnet/Games.Common.Test/Games.Common.Test.csproj deleted file mode 100644 index c90ed5189..000000000 --- a/00_Common/dotnet/Games.Common.Test/Games.Common.Test.csproj +++ /dev/null @@ -1,26 +0,0 @@ - - - - net6.0 - false - - - - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - - - - - - diff --git a/00_Common/dotnet/Games.Common.Test/IO/TextIOTests/NumberFormatTests.cs b/00_Common/dotnet/Games.Common.Test/IO/TextIOTests/NumberFormatTests.cs deleted file mode 100644 index 670a73661..000000000 --- a/00_Common/dotnet/Games.Common.Test/IO/TextIOTests/NumberFormatTests.cs +++ /dev/null @@ -1,79 +0,0 @@ -using System; -using System.IO; -using FluentAssertions; -using Xunit; - -namespace Games.Common.IO.TextIOTests; - -public class NumberFormatTests -{ - [Theory] - [MemberData(nameof(WriteFloatTestCases))] - public void Write_Float_FormatsNumberSameAsBasic(float value, string basicString) - { - var outputWriter = new StringWriter(); - var io = new TextIO(new StringReader(""), outputWriter); - - io.Write(value); - - outputWriter.ToString().Should().BeEquivalentTo(basicString); - } - - [Theory] - [MemberData(nameof(WriteFloatTestCases))] - public void WriteLine_Float_FormatsNumberSameAsBasic(float value, string basicString) - { - var outputWriter = new StringWriter(); - var io = new TextIO(new StringReader(""), outputWriter); - - io.WriteLine(value); - - outputWriter.ToString().Should().BeEquivalentTo(basicString + Environment.NewLine); - } - - public static TheoryData WriteFloatTestCases() - => new() - { - { 1000F, " 1000 " }, - { 3.1415927F, " 3.1415927 " }, - { 1F, " 1 " }, - { 0F, " 0 " }, - { -1F, "-1 " }, - { -3.1415927F, "-3.1415927 " }, - { -1000F, "-1000 " }, - }; - - [Theory] - [MemberData(nameof(WriteIntTestCases))] - public void Write_Int_FormatsNumberSameAsBasic(int value, string basicString) - { - var outputWriter = new StringWriter(); - var io = new TextIO(new StringReader(""), outputWriter); - - io.Write(value); - - outputWriter.ToString().Should().BeEquivalentTo(basicString); - } - - [Theory] - [MemberData(nameof(WriteIntTestCases))] - public void WriteLine_Int_FormatsNumberSameAsBasic(int value, string basicString) - { - var outputWriter = new StringWriter(); - var io = new TextIO(new StringReader(""), outputWriter); - - io.WriteLine(value); - - outputWriter.ToString().Should().BeEquivalentTo(basicString + Environment.NewLine); - } - - public static TheoryData WriteIntTestCases() - => new() - { - { 1000, " 1000 " }, - { 1, " 1 " }, - { 0, " 0 " }, - { -1, "-1 " }, - { -1000, "-1000 " }, - }; -} diff --git a/00_Common/dotnet/Games.Common.Test/IO/TextIOTests/ReadMethodTests.cs b/00_Common/dotnet/Games.Common.Test/IO/TextIOTests/ReadMethodTests.cs deleted file mode 100644 index 119bacd05..000000000 --- a/00_Common/dotnet/Games.Common.Test/IO/TextIOTests/ReadMethodTests.cs +++ /dev/null @@ -1,165 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using FluentAssertions; -using FluentAssertions.Execution; -using Xunit; - -using TwoStrings = System.ValueTuple; -using TwoNumbers = System.ValueTuple; -using ThreeNumbers = System.ValueTuple; -using FourNumbers = System.ValueTuple; - -using static System.Environment; -using static Games.Common.IO.Strings; - -namespace Games.Common.IO.TextIOTests; - -public class ReadMethodTests -{ - [Theory] - [MemberData(nameof(ReadStringTestCases))] - [MemberData(nameof(Read2StringsTestCases))] - [MemberData(nameof(ReadNumberTestCases))] - [MemberData(nameof(Read2NumbersTestCases))] - [MemberData(nameof(Read3NumbersTestCases))] - [MemberData(nameof(Read4NumbersTestCases))] - [MemberData(nameof(ReadNumbersTestCases))] - public void ReadingValuesHasExpectedPromptsAndResults( - Func read, - string input, - string expectedOutput, - T expectedResult) - { - var inputReader = new StringReader(input + Environment.NewLine); - var outputWriter = new StringWriter(); - var io = new TextIO(inputReader, outputWriter); - - var result = read.Invoke(io); - var output = outputWriter.ToString(); - - using var _ = new AssertionScope(); - output.Should().Be(expectedOutput); - result.Should().BeEquivalentTo(expectedResult); - } - - [Fact] - public void ReadNumbers_ArrayEmpty_ThrowsArgumentException() - { - var io = new TextIO(new StringReader(""), new StringWriter()); - - Action readNumbers = () => io.ReadNumbers("foo", Array.Empty()); - - readNumbers.Should().Throw() - .WithMessage("'values' must have a non-zero length.*") - .WithParameterName("values"); - } - - public static TheoryData, string, string, string> ReadStringTestCases() - { - static Func ReadString(string prompt) => io => io.ReadString(prompt); - - return new() - { - { ReadString("Name"), "", "Name? ", "" }, - { ReadString("prompt"), " foo ,bar", $"prompt? {ExtraInput}{NewLine}", "foo" } - }; - } - - public static TheoryData, string, string, TwoStrings> Read2StringsTestCases() - { - static Func Read2Strings(string prompt) => io => io.Read2Strings(prompt); - - return new() - { - { Read2Strings("2 strings"), ",", "2 strings? ", ("", "") }, - { - Read2Strings("Input please"), - $"{NewLine}x,y", - $"Input please? ?? {ExtraInput}{NewLine}", - ("", "x") - } - }; - } - - public static TheoryData, string, string, float> ReadNumberTestCases() - { - static Func ReadNumber(string prompt) => io => io.ReadNumber(prompt); - - return new() - { - { ReadNumber("Age"), $"{NewLine}42,", $"Age? {NumberExpected}{NewLine}? {ExtraInput}{NewLine}", 42 }, - { ReadNumber("Guess"), "3,4,5", $"Guess? {ExtraInput}{NewLine}", 3 } - }; - } - - public static TheoryData, string, string, TwoNumbers> Read2NumbersTestCases() - { - static Func Read2Numbers(string prompt) => io => io.Read2Numbers(prompt); - - return new() - { - { Read2Numbers("Point"), "3,4,5", $"Point? {ExtraInput}{NewLine}", (3, 4) }, - { - Read2Numbers("Foo"), - $"x,4,5{NewLine}4,5,x", - $"Foo? {NumberExpected}{NewLine}? {ExtraInput}{NewLine}", - (4, 5) - } - }; - } - - public static TheoryData, string, string, ThreeNumbers> Read3NumbersTestCases() - { - static Func Read3Numbers(string prompt) => io => io.Read3Numbers(prompt); - - return new() - { - { Read3Numbers("Point"), "3.2, 4.3, 5.4, 6.5", $"Point? {ExtraInput}{NewLine}", (3.2F, 4.3F, 5.4F) }, - { - Read3Numbers("Bar"), - $"x,4,5{NewLine}4,5,x{NewLine}6,7,8,y", - $"Bar? {NumberExpected}{NewLine}? {NumberExpected}{NewLine}? {ExtraInput}{NewLine}", - (6, 7, 8) - } - }; - } - - public static TheoryData, string, string, FourNumbers> Read4NumbersTestCases() - { - static Func Read4Numbers(string prompt) => io => io.Read4Numbers(prompt); - - return new() - { - { Read4Numbers("Point"), "3,4,5,6,7", $"Point? {ExtraInput}{NewLine}", (3, 4, 5, 6) }, - { - Read4Numbers("Baz"), - $"x,4,5,6{NewLine} 4, 5 , 6,7 ,x", - $"Baz? {NumberExpected}{NewLine}? {ExtraInput}{NewLine}", - (4, 5, 6, 7) - } - }; - } - - public static TheoryData>, string, string, float[]> ReadNumbersTestCases() - { - static Func> ReadNumbers(string prompt) => - io => - { - var numbers = new float[6]; - io.ReadNumbers(prompt, numbers); - return numbers; - }; - - return new() - { - { ReadNumbers("Primes"), "2, 3, 5, 7, 11, 13", $"Primes? ", new float[] { 2, 3, 5, 7, 11, 13 } }, - { - ReadNumbers("Qux"), - $"42{NewLine}3.141, 2.718{NewLine}3.0e8, 6.02e23{NewLine}9.11E-28", - $"Qux? ?? ?? ?? ", - new[] { 42, 3.141F, 2.718F, 3.0e8F, 6.02e23F, 9.11E-28F } - } - }; - } -} diff --git a/00_Common/dotnet/Games.Common.Test/IO/TokenReaderTests.cs b/00_Common/dotnet/Games.Common.Test/IO/TokenReaderTests.cs deleted file mode 100644 index d4d8458e7..000000000 --- a/00_Common/dotnet/Games.Common.Test/IO/TokenReaderTests.cs +++ /dev/null @@ -1,106 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using FluentAssertions; -using FluentAssertions.Execution; -using Xunit; - -using static System.Environment; -using static Games.Common.IO.Strings; - -namespace Games.Common.IO; - -public class TokenReaderTests -{ - private readonly StringWriter _outputWriter; - - public TokenReaderTests() - { - _outputWriter = new StringWriter(); - } - - [Fact] - public void ReadTokens_QuantityNeededZero_ThrowsArgumentException() - { - var sut = TokenReader.ForStrings(new TextIO(new StringReader(""), _outputWriter)); - - Action readTokens = () => sut.ReadTokens("", 0); - - readTokens.Should().Throw() - .WithMessage("'quantityNeeded' must be greater than zero.*") - .WithParameterName("quantityNeeded"); - } - - - [Theory] - [MemberData(nameof(ReadTokensTestCases))] - public void ReadTokens_ReadingValuesHasExpectedPromptsAndResults( - string prompt, - uint tokenCount, - string input, - string expectedOutput, - string[] expectedResult) - { - var sut = TokenReader.ForStrings(new TextIO(new StringReader(input + NewLine), _outputWriter)); - - var result = sut.ReadTokens(prompt, tokenCount); - var output = _outputWriter.ToString(); - - using var _ = new AssertionScope(); - output.Should().Be(expectedOutput); - result.Select(t => t.String).Should().BeEquivalentTo(expectedResult); - } - - [Theory] - [MemberData(nameof(ReadNumericTokensTestCases))] - public void ReadTokens_Numeric_ReadingValuesHasExpectedPromptsAndResults( - string prompt, - uint tokenCount, - string input, - string expectedOutput, - float[] expectedResult) - { - var sut = TokenReader.ForNumbers(new TextIO(new StringReader(input + NewLine), _outputWriter)); - - var result = sut.ReadTokens(prompt, tokenCount); - var output = _outputWriter.ToString(); - - using var _ = new AssertionScope(); - output.Should().Be(expectedOutput); - result.Select(t => t.Number).Should().BeEquivalentTo(expectedResult); - } - - public static TheoryData ReadTokensTestCases() - { - return new() - { - { "Name", 1, "Bill", "Name? ", new[] { "Bill" } }, - { "Names", 2, " Bill , Bloggs ", "Names? ", new[] { "Bill", "Bloggs" } }, - { "Names", 2, $" Bill{NewLine}Bloggs ", "Names? ?? ", new[] { "Bill", "Bloggs" } }, - { - "Foo", - 6, - $"1,2{NewLine}\" a,b \"{NewLine},\"\"c,d{NewLine}d\"x,e,f", - $"Foo? ?? ?? ?? {ExtraInput}{NewLine}", - new[] { "1", "2", " a,b ", "", "", "d\"x" } - } - }; - } - - public static TheoryData ReadNumericTokensTestCases() - { - return new() - { - { "Age", 1, "23", "Age? ", new[] { 23F } }, - { "Constants", 2, " 3.141 , 2.71 ", "Constants? ", new[] { 3.141F, 2.71F } }, - { "Answer", 1, $"Forty-two{NewLine}42 ", $"Answer? {NumberExpected}{NewLine}? ", new[] { 42F } }, - { - "Foo", - 6, - $"1,2{NewLine}\" a,b \"{NewLine}3, 4 {NewLine}5.6,7,a, b", - $"Foo? ?? {NumberExpected}{NewLine}? ?? {ExtraInput}{NewLine}", - new[] { 1, 2, 3, 4, 5.6F, 7 } - } - }; - } -} diff --git a/00_Common/dotnet/Games.Common.Test/IO/TokenTests.cs b/00_Common/dotnet/Games.Common.Test/IO/TokenTests.cs deleted file mode 100644 index e91922d84..000000000 --- a/00_Common/dotnet/Games.Common.Test/IO/TokenTests.cs +++ /dev/null @@ -1,42 +0,0 @@ -using FluentAssertions; -using Xunit; - -namespace Games.Common.IO; - -public class TokenTests -{ - [Theory] - [MemberData(nameof(TokenTestCases))] - public void Ctor_PopulatesProperties(string value, bool isNumber, float number) - { - var expected = new { String = value, IsNumber = isNumber, Number = number }; - - var token = new Token(value); - - token.Should().BeEquivalentTo(expected); - } - - public static TheoryData TokenTestCases() => new() - { - { "", false, float.NaN }, - { "abcde", false, float.NaN }, - { "123 ", true, 123 }, - { "+42 ", true, 42 }, - { "-42 ", true, -42 }, - { "+3.14159 ", true, 3.14159F }, - { "-3.14159 ", true, -3.14159F }, - { " 123", false, float.NaN }, - { "1.2e4", true, 12000 }, - { "2.3e-5", true, 0.000023F }, - { "1e100", true, float.MaxValue }, - { "-1E100", true, float.MinValue }, - { "1E-100", true, 0 }, - { "-1e-100", true, 0 }, - { "100abc", true, 100 }, - { "1,2,3", true, 1 }, - { "42,a,b", true, 42 }, - { "1.2.3", true, 1.2F }, - { "12e.5", false, float.NaN }, - { "12e0.5", true, 12 } - }; -} diff --git a/00_Common/dotnet/Games.Common.Test/IO/TokenizerTests.cs b/00_Common/dotnet/Games.Common.Test/IO/TokenizerTests.cs deleted file mode 100644 index 30e54b0f4..000000000 --- a/00_Common/dotnet/Games.Common.Test/IO/TokenizerTests.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System.Linq; -using FluentAssertions; -using Xunit; - -namespace Games.Common.IO; - -public class TokenizerTests -{ - [Theory] - [MemberData(nameof(TokenizerTestCases))] - public void ParseTokens_SplitsStringIntoExpectedTokens(string input, string[] expected) - { - var result = Tokenizer.ParseTokens(input); - - result.Select(t => t.ToString()).Should().BeEquivalentTo(expected); - } - - public static TheoryData TokenizerTestCases() => new() - { - { "", new[] { "" } }, - { "aBc", new[] { "aBc" } }, - { " Foo ", new[] { "Foo" } }, - { " \" Foo \" ", new[] { " Foo " } }, - { " \" Foo ", new[] { " Foo " } }, - { "\"\"abc", new[] { "" } }, - { "a\"\"bc", new[] { "a\"\"bc" } }, - { "\"\"", new[] { "" } }, - { ",", new[] { "", "" } }, - { " foo ,bar", new[] { "foo", "bar" } }, - { "\"a\"bc,de", new[] { "a" } }, - { "a\"b,\" c,d\", f ,,g", new[] { "a\"b", " c,d", "f", "", "g" } } - }; -} diff --git a/00_Common/dotnet/Games.Common.sln b/00_Common/dotnet/Games.Common.sln deleted file mode 100644 index e0f51d4b9..000000000 --- a/00_Common/dotnet/Games.Common.sln +++ /dev/null @@ -1,28 +0,0 @@ - -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}") = "Games.Common", "Games.Common\Games.Common.csproj", "{005F2A3E-4E45-418B-8D19-E735B3BD4535}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Games.Common.Test", "Games.Common.Test\Games.Common.Test.csproj", "{8369DA66-0414-4A14-B5BE-73B0159498A2}" -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 - {005F2A3E-4E45-418B-8D19-E735B3BD4535}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {005F2A3E-4E45-418B-8D19-E735B3BD4535}.Debug|Any CPU.Build.0 = Debug|Any CPU - {005F2A3E-4E45-418B-8D19-E735B3BD4535}.Release|Any CPU.ActiveCfg = Release|Any CPU - {005F2A3E-4E45-418B-8D19-E735B3BD4535}.Release|Any CPU.Build.0 = Release|Any CPU - {8369DA66-0414-4A14-B5BE-73B0159498A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8369DA66-0414-4A14-B5BE-73B0159498A2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8369DA66-0414-4A14-B5BE-73B0159498A2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8369DA66-0414-4A14-B5BE-73B0159498A2}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection -EndGlobal diff --git a/00_Common/dotnet/Games.Common/Games.Common.csproj b/00_Common/dotnet/Games.Common/Games.Common.csproj deleted file mode 100644 index 74c8445fc..000000000 --- a/00_Common/dotnet/Games.Common/Games.Common.csproj +++ /dev/null @@ -1,10 +0,0 @@ - - - - net6.0 - 10 - enable - enable - - - diff --git a/00_Common/dotnet/Games.Common/IO/ConsoleIO.cs b/00_Common/dotnet/Games.Common/IO/ConsoleIO.cs deleted file mode 100644 index a1f770831..000000000 --- a/00_Common/dotnet/Games.Common/IO/ConsoleIO.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace Games.Common.IO; - -/// -/// An implementation of with input begin read for STDIN and output being written to -/// STDOUT. -/// -public sealed class ConsoleIO : TextIO -{ - public ConsoleIO() - : base(Console.In, Console.Out) - { - } - - public override char ReadCharacter() => Console.ReadKey(intercept: true).KeyChar; -} diff --git a/00_Common/dotnet/Games.Common/IO/IReadWrite.cs b/00_Common/dotnet/Games.Common/IO/IReadWrite.cs deleted file mode 100644 index b4c533f87..000000000 --- a/00_Common/dotnet/Games.Common/IO/IReadWrite.cs +++ /dev/null @@ -1,120 +0,0 @@ -using Games.Common.Numbers; - -namespace Games.Common.IO; - -/// -/// Provides for input and output of strings and numbers. -/// -public interface IReadWrite -{ - /// - /// Reads a character from input. - /// - /// The character read. - char ReadCharacter(); - - /// - /// Reads a value from input. - /// - /// The text to display to prompt for the value. - /// A , being the value entered. - float ReadNumber(string prompt); - - /// - /// Reads 2 values from input. - /// - /// The text to display to prompt for the values. - /// A , being the values entered. - (float, float) Read2Numbers(string prompt); - - /// - /// Reads 3 values from input. - /// - /// The text to display to prompt for the values. - /// A , being the values entered. - (float, float, float) Read3Numbers(string prompt); - - /// - /// Reads 4 values from input. - /// - /// The text to display to prompt for the values. - /// A , being the values entered. - (float, float, float, float) Read4Numbers(string prompt); - - /// - /// Read numbers from input to fill an array. - /// - /// The text to display to prompt for the values. - /// A to be filled with values from input. - void ReadNumbers(string prompt, float[] values); - - /// - /// Reads a value from input. - /// - /// The text to display to prompt for the value. - /// A , being the value entered. - string ReadString(string prompt); - - /// - /// Reads 2 values from input. - /// - /// The text to display to prompt for the values. - /// A , being the values entered. - (string, string) Read2Strings(string prompt); - - /// - /// Writes a to output. - /// - /// The to be written. - void Write(string message); - - /// - /// Writes a to output, followed by a new-line. - /// - /// The to be written. - void WriteLine(string message = ""); - - /// - /// Writes a to output. - /// - /// The to be written. - void Write(Number value); - - /// - /// Writes a to output. - /// - /// The to be written. - void WriteLine(Number value); - - /// - /// Writes an to output. - /// - /// The to be written. - void Write(object value); - - /// - /// Writes an to output. - /// - /// The to be written. - void WriteLine(object value); - - /// - /// Writes a formatted string to output. - /// - /// The format to be written. - /// The values to be inserted into the format. - void Write(string format, params object[] values); - - /// - /// Writes a formatted string to output followed by a new-line. - /// - /// The format to be written. - /// The values to be inserted into the format. - void WriteLine(string format, params object[] values); - - /// - /// Writes the contents of a to output. - /// - /// The to be written. - void Write(Stream stream, bool keepOpen = false); -} diff --git a/00_Common/dotnet/Games.Common/IO/InsufficientInputException.cs b/00_Common/dotnet/Games.Common/IO/InsufficientInputException.cs deleted file mode 100644 index 77100dc1f..000000000 --- a/00_Common/dotnet/Games.Common/IO/InsufficientInputException.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Games.Common.IO; - -public class InsufficientInputException : Exception -{ - public InsufficientInputException() - : base("Insufficient input was supplied") - { - } -} diff --git a/00_Common/dotnet/Games.Common/IO/Strings.cs b/00_Common/dotnet/Games.Common/IO/Strings.cs deleted file mode 100644 index cf7d0f43b..000000000 --- a/00_Common/dotnet/Games.Common/IO/Strings.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Games.Common.IO; - -internal static class Strings -{ - internal const string NumberExpected = "!Number expected - retry input line"; - internal const string ExtraInput = "!Extra input ignored"; -} diff --git a/00_Common/dotnet/Games.Common/IO/TextIO.cs b/00_Common/dotnet/Games.Common/IO/TextIO.cs deleted file mode 100644 index 33a5b7ca6..000000000 --- a/00_Common/dotnet/Games.Common/IO/TextIO.cs +++ /dev/null @@ -1,124 +0,0 @@ -using Games.Common.Numbers; - -namespace Games.Common.IO; - -/// -/// -/// Implements with input read from a and output written to a -/// . -/// -/// -/// This implementation reproduces the Vintage BASIC input experience, prompting multiple times when partial input -/// supplied, rejecting non-numeric input as needed, warning about extra input being ignored, etc. -/// -public class TextIO : IReadWrite -{ - private readonly TextReader _input; - private readonly TextWriter _output; - private readonly TokenReader _stringTokenReader; - private readonly TokenReader _numberTokenReader; - - public TextIO(TextReader input, TextWriter output) - { - _input = input ?? throw new ArgumentNullException(nameof(input)); - _output = output ?? throw new ArgumentNullException(nameof(output)); - _stringTokenReader = TokenReader.ForStrings(this); - _numberTokenReader = TokenReader.ForNumbers(this); - } - - public virtual char ReadCharacter() - { - while(true) - { - var ch = _input.Read(); - if (ch != -1) { return (char)ch; } - } - } - - public float ReadNumber(string prompt) => ReadNumbers(prompt, 1)[0]; - - public (float, float) Read2Numbers(string prompt) - { - var numbers = ReadNumbers(prompt, 2); - return (numbers[0], numbers[1]); - } - - public (float, float, float) Read3Numbers(string prompt) - { - var numbers = ReadNumbers(prompt, 3); - return (numbers[0], numbers[1], numbers[2]); - } - - public (float, float, float, float) Read4Numbers(string prompt) - { - var numbers = ReadNumbers(prompt, 4); - return (numbers[0], numbers[1], numbers[2], numbers[3]); - } - - public void ReadNumbers(string prompt, float[] values) - { - if (values.Length == 0) - { - throw new ArgumentException($"'{nameof(values)}' must have a non-zero length.", nameof(values)); - } - - var numbers = _numberTokenReader.ReadTokens(prompt, (uint)values.Length).Select(t => t.Number).ToArray(); - numbers.CopyTo(values.AsSpan()); - } - - private IReadOnlyList ReadNumbers(string prompt, uint quantity) => - (quantity > 0) - ? _numberTokenReader.ReadTokens(prompt, quantity).Select(t => t.Number).ToList() - : throw new ArgumentOutOfRangeException( - nameof(quantity), - $"'{nameof(quantity)}' must be greater than zero."); - - public string ReadString(string prompt) - { - return ReadStrings(prompt, 1)[0]; - } - - public (string, string) Read2Strings(string prompt) - { - var values = ReadStrings(prompt, 2); - return (values[0], values[1]); - } - - private IReadOnlyList ReadStrings(string prompt, uint quantityRequired) => - _stringTokenReader.ReadTokens(prompt, quantityRequired).Select(t => t.String).ToList(); - - internal string ReadLine(string prompt) - { - Write(prompt + "? "); - return _input.ReadLine() ?? throw new InsufficientInputException(); - } - - public void Write(string value) => _output.Write(value); - - public void WriteLine(string value = "") => _output.WriteLine(value); - - public void Write(Number value) => _output.Write(value.ToString()); - - public void WriteLine(Number value) => _output.WriteLine(value.ToString()); - - public void Write(object value) => _output.Write(value.ToString()); - - public void WriteLine(object value) => _output.WriteLine(value.ToString()); - - public void Write(string format, params object[] values) => _output.Write(format, values); - - public void WriteLine(string format, params object[] values) => _output.WriteLine(format, values); - - public void Write(Stream stream, bool keepOpen = false) - { - using var reader = new StreamReader(stream); - while (!reader.EndOfStream) - { - _output.WriteLine(reader.ReadLine()); - } - - if (!keepOpen) { stream?.Dispose(); } - } - - private string GetString(float value) => value < 0 ? $"{value} " : $" {value} "; -} diff --git a/00_Common/dotnet/Games.Common/IO/Token.cs b/00_Common/dotnet/Games.Common/IO/Token.cs deleted file mode 100644 index dc432e0c8..000000000 --- a/00_Common/dotnet/Games.Common/IO/Token.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System.Text; -using System.Text.RegularExpressions; - -namespace Games.Common.IO; - -internal class Token -{ - private static readonly Regex _numberPattern = new(@"^[+\-]?\d*(\.\d*)?([eE][+\-]?\d*)?"); - - internal Token(string value) - { - String = value; - - var match = _numberPattern.Match(String); - - IsNumber = float.TryParse(match.Value, out var number); - Number = (IsNumber, number) switch - { - (false, _) => float.NaN, - (true, float.PositiveInfinity) => float.MaxValue, - (true, float.NegativeInfinity) => float.MinValue, - (true, _) => number - }; - } - - public string String { get; } - public bool IsNumber { get; } - public float Number { get; } - - public override string ToString() => String; - - internal class Builder - { - private readonly StringBuilder _builder = new(); - private bool _isQuoted; - private int _trailingWhiteSpaceCount; - - public Builder Append(char character) - { - _builder.Append(character); - - _trailingWhiteSpaceCount = char.IsWhiteSpace(character) ? _trailingWhiteSpaceCount + 1 : 0; - - return this; - } - - public Builder SetIsQuoted() - { - _isQuoted = true; - return this; - } - - public Token Build() - { - if (!_isQuoted) { _builder.Length -= _trailingWhiteSpaceCount; } - return new Token(_builder.ToString()); - } - } -} diff --git a/00_Common/dotnet/Games.Common/IO/TokenReader.cs b/00_Common/dotnet/Games.Common/IO/TokenReader.cs deleted file mode 100644 index 04e7ad41d..000000000 --- a/00_Common/dotnet/Games.Common/IO/TokenReader.cs +++ /dev/null @@ -1,112 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using static Games.Common.IO.Strings; - -namespace Games.Common.IO; - -/// -/// Reads from input and assembles a given number of values, or tokens, possibly over a number of input lines. -/// -internal class TokenReader -{ - private readonly TextIO _io; - private readonly Predicate _isTokenValid; - - private TokenReader(TextIO io, Predicate isTokenValid) - { - _io = io; - _isTokenValid = isTokenValid ?? (t => true); - } - - /// - /// Creates a which reads string tokens. - /// - /// A instance. - /// The new instance. - public static TokenReader ForStrings(TextIO io) => new(io, t => true); - - /// - /// Creates a which reads tokens and validates that they can be parsed as numbers. - /// - /// A instance. - /// The new instance. - public static TokenReader ForNumbers(TextIO io) => new(io, t => t.IsNumber); - - /// - /// Reads valid tokens from one or more input lines and builds a list with the required quantity. - /// - /// The string used to prompt the user for input. - /// The number of tokens required. - /// The sequence of tokens read. - public IEnumerable ReadTokens(string prompt, uint quantityNeeded) - { - if (quantityNeeded == 0) - { - throw new ArgumentOutOfRangeException( - nameof(quantityNeeded), - $"'{nameof(quantityNeeded)}' must be greater than zero."); - } - - var tokens = new List(); - - while (tokens.Count < quantityNeeded) - { - tokens.AddRange(ReadValidTokens(prompt, quantityNeeded - (uint)tokens.Count)); - prompt = "?"; - } - - return tokens; - } - - /// - /// Reads a line of tokens, up to , and rejects the line if any are invalid. - /// - /// The string used to prompt the user for input. - /// The maximum number of tokens to read. - /// The sequence of tokens read. - private IEnumerable ReadValidTokens(string prompt, uint maxCount) - { - while (true) - { - var tokensValid = true; - var tokens = new List(); - foreach (var token in ReadLineOfTokens(prompt, maxCount)) - { - if (!_isTokenValid(token)) - { - _io.WriteLine(NumberExpected); - tokensValid = false; - prompt = ""; - break; - } - - tokens.Add(token); - } - - if (tokensValid) { return tokens; } - } - } - - /// - /// Lazily reads up to tokens from an input line. - /// - /// The string used to prompt the user for input. - /// The maximum number of tokens to read. - /// - private IEnumerable ReadLineOfTokens(string prompt, uint maxCount) - { - var tokenCount = 0; - - foreach (var token in Tokenizer.ParseTokens(_io.ReadLine(prompt))) - { - if (++tokenCount > maxCount) - { - _io.WriteLine(ExtraInput); - break; - } - - yield return token; - } - } -} diff --git a/00_Common/dotnet/Games.Common/IO/Tokenizer.cs b/00_Common/dotnet/Games.Common/IO/Tokenizer.cs deleted file mode 100644 index dc6a4d798..000000000 --- a/00_Common/dotnet/Games.Common/IO/Tokenizer.cs +++ /dev/null @@ -1,104 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Games.Common.IO; - -/// -/// A simple state machine which parses tokens from a line of input. -/// -internal class Tokenizer -{ - private const char Quote = '"'; - private const char Separator = ','; - - private readonly Queue _characters; - - private Tokenizer(string input) => _characters = new Queue(input); - - public static IEnumerable ParseTokens(string input) - { - if (input is null) { throw new ArgumentNullException(nameof(input)); } - - return new Tokenizer(input).ParseTokens(); - } - - private IEnumerable ParseTokens() - { - while (true) - { - var (token, isLastToken) = Consume(_characters); - yield return token; - - if (isLastToken) { break; } - } - } - - public (Token, bool) Consume(Queue characters) - { - var tokenBuilder = new Token.Builder(); - var state = ITokenizerState.LookForStartOfToken; - - while (characters.TryDequeue(out var character)) - { - (state, tokenBuilder) = state.Consume(character, tokenBuilder); - if (state is AtEndOfTokenState) { return (tokenBuilder.Build(), false); } - } - - return (tokenBuilder.Build(), true); - } - - private interface ITokenizerState - { - public static ITokenizerState LookForStartOfToken { get; } = new LookForStartOfTokenState(); - - (ITokenizerState, Token.Builder) Consume(char character, Token.Builder tokenBuilder); - } - - private struct LookForStartOfTokenState : ITokenizerState - { - public (ITokenizerState, Token.Builder) Consume(char character, Token.Builder tokenBuilder) => - character switch - { - Separator => (new AtEndOfTokenState(), tokenBuilder), - Quote => (new InQuotedTokenState(), tokenBuilder.SetIsQuoted()), - _ when char.IsWhiteSpace(character) => (this, tokenBuilder), - _ => (new InTokenState(), tokenBuilder.Append(character)) - }; - } - - private struct InTokenState : ITokenizerState - { - public (ITokenizerState, Token.Builder) Consume(char character, Token.Builder tokenBuilder) => - character == Separator - ? (new AtEndOfTokenState(), tokenBuilder) - : (this, tokenBuilder.Append(character)); - } - - private struct InQuotedTokenState : ITokenizerState - { - public (ITokenizerState, Token.Builder) Consume(char character, Token.Builder tokenBuilder) => - character == Quote - ? (new ExpectSeparatorState(), tokenBuilder) - : (this, tokenBuilder.Append(character)); - } - - private struct ExpectSeparatorState : ITokenizerState - { - public (ITokenizerState, Token.Builder) Consume(char character, Token.Builder tokenBuilder) => - character == Separator - ? (new AtEndOfTokenState(), tokenBuilder) - : (new IgnoreRestOfLineState(), tokenBuilder); - } - - private struct IgnoreRestOfLineState : ITokenizerState - { - public (ITokenizerState, Token.Builder) Consume(char character, Token.Builder tokenBuilder) => - (this, tokenBuilder); - } - - private struct AtEndOfTokenState : ITokenizerState - { - public (ITokenizerState, Token.Builder) Consume(char character, Token.Builder tokenBuilder) => - throw new InvalidOperationException(); - } -} diff --git a/00_Common/dotnet/Games.Common/Numbers/Number.cs b/00_Common/dotnet/Games.Common/Numbers/Number.cs deleted file mode 100644 index 3001009fc..000000000 --- a/00_Common/dotnet/Games.Common/Numbers/Number.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace Games.Common.Numbers; - -/// -/// A single-precision floating-point number with string formatting equivalent to the BASIC interpreter. -/// -public struct Number -{ - private readonly float _value; - - public Number (float value) - { - _value = value; - } - - public static implicit operator float(Number value) => value._value; - - public static implicit operator Number(float value) => new Number(value); - - public override string ToString() => _value < 0 ? $"{_value} " : $" {_value} "; -} diff --git a/00_Common/dotnet/Games.Common/Randomness/IRandom.cs b/00_Common/dotnet/Games.Common/Randomness/IRandom.cs deleted file mode 100644 index 9db4c12f9..000000000 --- a/00_Common/dotnet/Games.Common/Randomness/IRandom.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace Games.Common.Randomness; - -/// -/// Provides access to a random number generator -/// -public interface IRandom -{ - /// - /// Gets a random such that 0 <= n < 1. - /// - /// The random number. - float NextFloat(); - - /// - /// Gets the returned by the previous call to . - /// - /// The previous random number. - float PreviousFloat(); - - /// - /// Reseeds the random number generator. - /// - /// The seed. - void Reseed(int seed); -} diff --git a/00_Common/dotnet/Games.Common/Randomness/IRandomExtensions.cs b/00_Common/dotnet/Games.Common/Randomness/IRandomExtensions.cs deleted file mode 100644 index 155a9cc59..000000000 --- a/00_Common/dotnet/Games.Common/Randomness/IRandomExtensions.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System; - -namespace Games.Common.Randomness; - -/// -/// Provides extension methods to providing random numbers in a given range. -/// -/// -public static class IRandomExtensions -{ - /// - /// Gets a random such that 0 <= n < exclusiveMaximum. - /// - /// The random number. - public static float NextFloat(this IRandom random, float exclusiveMaximum) => - Scale(random.NextFloat(), exclusiveMaximum); - - /// - /// Gets a random such that inclusiveMinimum <= n < exclusiveMaximum. - /// - /// The random number. - public static float NextFloat(this IRandom random, float inclusiveMinimum, float exclusiveMaximum) => - Scale(random.NextFloat(), inclusiveMinimum, exclusiveMaximum); - - /// - /// Gets a random such that 0 <= n < exclusiveMaximum. - /// - /// The random number. - public static int Next(this IRandom random, int exclusiveMaximum) => ToInt(random.NextFloat(exclusiveMaximum)); - - /// - /// Gets a random such that inclusiveMinimum <= n < exclusiveMaximum. - /// - /// The random number. - public static int Next(this IRandom random, int inclusiveMinimum, int exclusiveMaximum) => - ToInt(random.NextFloat(inclusiveMinimum, exclusiveMaximum)); - - /// - /// Gets the previous unscaled (between 0 and 1) scaled to a new range: - /// 0 <= x < . - /// - /// The random number. - public static float PreviousFloat(this IRandom random, float exclusiveMaximum) => - Scale(random.PreviousFloat(), exclusiveMaximum); - - /// - /// Gets the previous unscaled (between 0 and 1) scaled to a new range: - /// <= n < . - /// - /// The random number. - public static float PreviousFloat(this IRandom random, float inclusiveMinimum, float exclusiveMaximum) => - Scale(random.PreviousFloat(), inclusiveMinimum, exclusiveMaximum); - - /// - /// Gets the previous unscaled (between 0 and 1) scaled to an in a new - /// range: 0 <= n < . - /// - /// The random number. - public static int Previous(this IRandom random, int exclusiveMaximum) => - ToInt(random.PreviousFloat(exclusiveMaximum)); - - /// - /// Gets the previous unscaled (between 0 and 1) scaled to an in a new - /// range: <= n < . - /// The random number. - public static int Previous(this IRandom random, int inclusiveMinimum, int exclusiveMaximum) => - ToInt(random.PreviousFloat(inclusiveMinimum, exclusiveMaximum)); - - private static float Scale(float zeroToOne, float exclusiveMaximum) - { - if (exclusiveMaximum <= 0) - { - throw new ArgumentOutOfRangeException(nameof(exclusiveMaximum), "Must be greater than 0."); - } - - return Scale(zeroToOne, 0, exclusiveMaximum); - } - - private static float Scale(float zeroToOne, float inclusiveMinimum, float exclusiveMaximum) - { - if (exclusiveMaximum <= inclusiveMinimum) - { - throw new ArgumentOutOfRangeException(nameof(exclusiveMaximum), "Must be greater than inclusiveMinimum."); - } - - var range = exclusiveMaximum - inclusiveMinimum; - return zeroToOne * range + inclusiveMinimum; - } - - private static int ToInt(float value) => (int)Math.Floor(value); -} diff --git a/00_Common/dotnet/Games.Common/Randomness/RandomNumberGenerator.cs b/00_Common/dotnet/Games.Common/Randomness/RandomNumberGenerator.cs deleted file mode 100644 index d46f72e7f..000000000 --- a/00_Common/dotnet/Games.Common/Randomness/RandomNumberGenerator.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; - -namespace Games.Common.Randomness; - -/// -public class RandomNumberGenerator : IRandom -{ - private Random _random; - private float _previous; - - public RandomNumberGenerator() - { - // The BASIC RNG is seeded based on time with a 1 second resolution - _random = new Random((int)(DateTime.UtcNow.Ticks / TimeSpan.TicksPerSecond)); - } - - public float NextFloat() => _previous = (float)_random.NextDouble(); - - public float PreviousFloat() => _previous; - - public void Reseed(int seed) => _random = new Random(seed); -} diff --git a/00_Common/dotnet/Games.Common/_InternalsVisibleTo.cs b/00_Common/dotnet/Games.Common/_InternalsVisibleTo.cs deleted file mode 100644 index bbdda9627..000000000 --- a/00_Common/dotnet/Games.Common/_InternalsVisibleTo.cs +++ /dev/null @@ -1,3 +0,0 @@ -using System.Runtime.CompilerServices; - -[assembly:InternalsVisibleTo("Games.Common.Test")] diff --git a/00_Common/dotnet/README.md b/00_Common/dotnet/README.md deleted file mode 100644 index c44f210bd..000000000 --- a/00_Common/dotnet/README.md +++ /dev/null @@ -1,181 +0,0 @@ -# Games.Common - -This is the common library for C# and VB.Net ports of the games. - -## Overview - -### Game Input/Output - -* `TextIO` is the main class which manages text input and output for a game. It take a `TextReader` and a `TextWriter` in -its constructor so it can be wired up in unit tests to test gameplay scenarios. -* `ConsoleIO` derives from `TextIO` and binds it to `System.Console.In` and `System.Console.Out`. -* `IReadWrite` is an interface implemented by `TextIO` which may be useful in some test scenarios. - -```csharp -public interface IReadWrite -{ - // Reads a float value from input. - float ReadNumber(string prompt); - - // Reads 2 float values from input. - (float, float) Read2Numbers(string prompt); - - // Reads 3 float values from input. - (float, float, float) Read3Numbers(string prompt); - - // Reads 4 float values from input. - (float, float, float, float) Read4Numbers(string prompt); - - // Read numbers from input to fill an array. - void ReadNumbers(string prompt, float[] values); - - // Reads a string value from input. - string ReadString(string prompt); - - // Reads 2 string values from input. - (string, string) Read2Strings(string prompt); - - // Writes a string to output. - void Write(string message); - - // Writes a string to output, followed by a new-line. - void WriteLine(string message = ""); - - // Writes a float to output, formatted per the BASIC interpreter, with leading and trailing spaces. - void Write(float value); - - // Writes a float to output, formatted per the BASIC interpreter, with leading and trailing spaces, - // followed by a new-line. - void WriteLine(float value); - - // Writes the contents of a Stream to output. - void Write(Stream stream);} -``` - -### Random Number Generation - -* `IRandom` is an interface that provides basic methods that parallel the 3 uses of BASIC's `RND(float)` function. -* `RandomNumberGenerator` is an implementation of `IRandom` built around `System.Random`. -* `IRandomExtensions` provides convenience extension methods for obtaining random numbers as `int` and also within a - given range. - -```csharp -public interface IRandom -{ - // Like RND(1), gets a random float such that 0 <= n < 1. - float NextFloat(); - - // Like RND(0), Gets the float returned by the previous call to NextFloat. - float PreviousFloat(); - - // Like RND(-x), Reseeds the random number generator. - void Reseed(int seed); -} -``` - -Extension methods on `IRandom`: - -```csharp -// Gets a random float such that 0 <= n < exclusiveMaximum. -float NextFloat(this IRandom random, float exclusiveMaximum); - -// Gets a random float such that inclusiveMinimum <= n < exclusiveMaximum. -float NextFloat(this IRandom random, float inclusiveMinimum, float exclusiveMaximum); - -// Gets a random int such that 0 <= n < exclusiveMaximum. -int Next(this IRandom random, int exclusiveMaximum); - -// Gets a random int such that inclusiveMinimum <= n < exclusiveMaximum. -int Next(this IRandom random, int inclusiveMinimum, int exclusiveMaximum); - -// Gets the previous unscaled float (between 0 and 1) scaled to a new range: -// 0 <= x < exclusiveMaximum. -float PreviousFloat(this IRandom random, float exclusiveMaximum); - -// Gets the previous unscaled float (between 0 and 1) scaled to a new range: -// inclusiveMinimum <= n < exclusiveMaximum. -float PreviousFloat(this IRandom random, float inclusiveMinimum, float exclusiveMaximum); - -// Gets the previous unscaled float (between 0 and 1) scaled to an int in a new range: -// 0 <= n < exclusiveMaximum. -int Previous(this IRandom random, int exclusiveMaximum); - -// Gets the previous unscaled float (between 0 and 1) scaled to an int in a new range: -// inclusiveMinimum <= n < exclusiveMaximum. -int Previous(this IRandom random, int inclusiveMinimum, int exclusiveMaximum); -``` - -## C\# Usage - -### Add Project Reference - -Add the `Games.Common` project as a reference to the game project. For example, here's the reference from the C\# port -of `86_Target`: - -```xml - - - -``` - -### C# Game Input/Output usage - -A game can be encapsulated in a class which takes a `TextIO` instance in it's constructor: - -```csharp -public class Game -{ - private readonly TextIO _io; - - public Game(TextIO io) => _io = io; - - public void Play() - { - var name = _io.ReadString("What is your name"); - var (cats, dogs) = _io.Read2Number($"Hello, {name}, how many pets do you have (cats, dogs)"); - _io.WriteLine($"So, {cats + dogs} pets in total, huh?"); - } -} -``` - -Then the entry point of the game program would look something like: - -```csharp -var game = new Game(new ConsoleIO()); -game.Play(); -``` - -### C# Random Number Generator usage - -```csharp -var io = new ConsoleIO(); -var rng = new RandomNumberGenerator(); -io.WriteLine(rng.NextFloat()); // 0.1234, for example -io.WriteLine(rng.NextFloat()); // 0.6, for example -io.WriteLine(rng.PreviousFloat()); // 0.6, repeats previous -io.WriteLine(rng.PreviousFloat(0, 10)); // 6, repeats previous value, but scaled to new range -``` - -### C# Unit Test usage - -`TextIO` can be initialised with a `StringReader` and `StringWriter` to enable testing. For example, given the `Game` -class above: - -```csharp -var reader = new StringReader("Joe Bloggs\r\n4\n\r5"); -var writer = new StringWriter(); -var game = new Game(new TextIO(reader, writer)) - -game.Play(); - -writer.ToString().Should().BeEquivalentTo( - "What is your name? Hello, Joe Bloggs, how many pets do you have (cats, dogs)? ?? So, 9 pets in total, huh?"); -``` - -Note the lack of line breaks in the expected output, because during game play the line breaks come from the text input. - -Of course, `IReadWrite` can also be mocked for simple test scenarios. - -## VB.Net Usage - -*To be provided* diff --git a/00_Common/javascript/WebTerminal/HtmlTerminal.css b/00_Common/javascript/WebTerminal/HtmlTerminal.css deleted file mode 100644 index eaeea9662..000000000 --- a/00_Common/javascript/WebTerminal/HtmlTerminal.css +++ /dev/null @@ -1,78 +0,0 @@ -:root { - --terminal-font: 1rem "Lucida Console", "Courier New", monospace; - --background-color: transparent; - --text-color: var(--text); - --prompt-char: '$ '; - --cursor-char: '_'; -} - -/* Basic terminal style. - * If you wan t to overwrite them use custom properties (variables). - */ -.terminal { - display: block; - font: var(--terminal-font); - background-color: var(--background-color); - color: var(--text-color); - - overflow-y: scroll; - width: 100%; - max-width: 640px; - margin: 0 auto; -} - -/* The terminal consits of multiple "line" elements - * Because sometimes we want to add a simulates "prompt" at the end of a line - * we need to make it an "inline" element and handle line-breaks - * by adding
elements */ -.terminal pre.line { - display: inline-block; - font: var(--terminal-font); - margin: 0; - padding: 0; -} - -/* The "terminal" has one "prompt" input-element. */ -@keyframes prompt-blink { - 100% { - opacity: 0; - } -} -.terminal #prompt { - display: inline-block; -} -.terminal #prompt:before { - display: inline-block; - content: var(--prompt-char); - font: var(--terminal-font); -} -.terminal #prompt:after { - display: inline-block; - content: var(--cursor-char); - background: var(--text); - animation: prompt-blink 1s steps(2) infinite; - width: 0.75rem; - opacity: 1; -} -.terminal input#prompt { - text-transform: uppercase; - background: none; - border: none; - outline: none; - caret-color: var(--text); - color: var(--text); - font: var(--terminal-font); -} - - -/* Terminal scrollbar */ -::-webkit-scrollbar { - width: 3px; - height: 3px; -} -::-webkit-scrollbar-track { - background: var(--background-color); -} -::-webkit-scrollbar-thumb { - background: var(--text-color); -} diff --git a/00_Common/javascript/WebTerminal/HtmlTerminal.js b/00_Common/javascript/WebTerminal/HtmlTerminal.js deleted file mode 100644 index a2aa2365b..000000000 --- a/00_Common/javascript/WebTerminal/HtmlTerminal.js +++ /dev/null @@ -1,180 +0,0 @@ -/** - * @class HtmlTerminal - * - * This class is a very basic implementation of a "terminal" in the browser. - * It provides simple functions like "write" and an "input" Callback. - * - * @license AGPL-2.0 - * @author Alexaner Wunschik - */ -class HtmlTerminal { - - /** - * Input callback. - * If the prompt is activated by calling the input function - * a callback is defined. If this member is not set this means - * the prompt is not active. - * - * @private - * @type {function} - */ - #inputCallback = undefined; - - /** - * A html element to show a "prompt". - * - * @private - * @type {HTMLElement} - */ - #$prompt; - - /** - * Constructor - * Creates a basic terminal simulation on the provided HTMLElement. - * - * @param {HTMLElement} $output - a dom element - */ - constructor($output) { - // Store the output DOM element in a local variable. - this.$output = $output; - - // Clear terminal. - this.clear(); - - // Add the call "terminal" to the $output element. - this.$output.classList.add('terminal'); - - // Create a prompt element. - // This element gets added if input is needed. - this.#$prompt = document.createElement("input"); - this.#$prompt.setAttribute("id", "prompt"); - this.#$prompt.setAttribute("type", "text"); - this.#$prompt.setAttribute("length", "50"); - this.#$prompt.addEventListener("keydown", this.#handleKey.bind(this)); - - // Force focus on the promt on each click. - // This is needed for mobile support. - document.body.addEventListener('click', () => { - this.#$prompt.focus(); - }); - } - - /** - * Creates a new HTMLElement with the given text content. - * This element than gets added to the $output as a new "line". - * - * @private - * @memberof MinimalTerminal - * @param {String} text - text that should be displayed in the new "line". - * @returns {HTMLElement} return a new DOM Element

-   */
-  #newLine(text) {
-    const $lineNode = document.createElement("pre");
-    $lineNode.classList.add("line");
-    $lineNode.innerText = text;
-    return $lineNode;
-  }
-
-  /**
-   * TODO
-   * 
-   * @private
-   * @param {*} e 
-   */
-  #handleKey(e) {
-    // if no input-callback is defined just return
-    if (!this.#inputCallback) {
-      return;
-    }
-
-    if (e.keyCode == 13) {
-      const text = this.#$prompt.value;
-      this.#$prompt.value = '';
-      this.#$prompt.remove();
-      this.#inputCallback(text + '\n');
-    }
-  }
-
-  /**
-   * Clear the terminal.
-   * Remove all lines.
-   * 
-   * @public
-   */
-  clear() {
-    this.$output.innerText = "";
-  }
-
-  /**
-   * Create a new div and add html content.
-   * 
-   * @public
-   * @param {*} htmlContent 
-   */
-  inserHtml(htmlContent) {
-    const $htmlNode = document.createElement("div");
-    $htmlNode.innerHTML = htmlContent;
-    this.$output.appendChild($htmlNode);
-    document.body.scrollTo(0, document.body.scrollHeight);
-  }
-
-  /**
-   * Write a text to the terminal.
-   * By default there is no linebreak at the end of a new line
-   * except the line ensd with a "\n".
-   * If the given text has multible linebreaks, multibe lines are inserted.
-   * 
-   * @public
-   * @param {string} text 
-   */
-  write(text) {
-    if (!text || text.length <= 0) {
-      // empty line
-      this.$output.appendChild(document.createElement("br"));
-    } else if (text.endsWith("\n")) {
-      // single line with linebrank
-      const $lineNode = this.#newLine(text);
-      this.$output.appendChild(this.#newLine(text));
-      this.$output.appendChild(document.createElement("br"));
-    } else if (text.includes("\n")) {
-      // multible lines
-      const lines = text.split("\n");
-      lines.forEach((line) => {
-        this.write(line);
-      });
-    } else {
-      // single line
-      this.$output.appendChild(this.#newLine(text));
-    }
-
-    // scroll to the buttom of the page
-    document.body.scrollTo(0, document.body.scrollHeight);
-  }
-
-  /**
-   * Like "write" but with a newline at the end.
-   * 
-   * @public
-   * @param {*} text 
-   */
-  writeln(text) {
-    this.write(text + "\n");
-  }
-
-  /**
-   * Query from user input.
-   * This is done by adding a input-element at the end of the terminal,
-   * that showes a prompt and a blinking cursor.
-   * If a key is pressed the input is added to the prompt element.
-   * The input ends with a linebreak.
-   * 
-   * @public
-   * @param {*} callback 
-   */
-  input(callback) {
-    // show prompt with a blinking prompt
-    this.#inputCallback = callback;
-    this.$output.appendChild(this.#$prompt);
-    this.#$prompt.focus();
-  }
-}
diff --git a/00_Common/javascript/WebTerminal/terminal.html b/00_Common/javascript/WebTerminal/terminal.html
deleted file mode 100644
index ae68bedb7..000000000
--- a/00_Common/javascript/WebTerminal/terminal.html
+++ /dev/null
@@ -1,129 +0,0 @@
-
-  
-    Minimal node.js terminal
-    
-    
-    
-    
-  
-  
-    
-

BASIC Computer Games

-
-
- - - - diff --git a/00_Common/javascript/WebTerminal/terminal_tests.mjs b/00_Common/javascript/WebTerminal/terminal_tests.mjs deleted file mode 100644 index d2470c958..000000000 --- a/00_Common/javascript/WebTerminal/terminal_tests.mjs +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env node - -import { print, println, tab, input } from '../common.mjs'; - -async function main() { - println(tab(30), "Minimal node.js terminal emulator"); - println(); - println(tab(0), "tab 0"); - println(tab(5), "tab 5"); - println(tab(10), "tab 10"); - println(tab(15), "tab 15"); - println(tab(20), "tab 20"); - println(tab(25), "tab 25"); - println(); - println("1234567890", " _ ", "ABCDEFGHIJKLMNOPRSTUVWXYZ"); - println(); - print("\nHallo"); print(" "); print("Welt!\n"); - println(""); - println("Line 1\nLine 2\nLine 3\nLine 4"); - println("----------------------------------------------"); - - const value = await input("input"); - println(`input value was "${value}"`); - - println("End of script"); - - // 320 END - process.exit(0); -} -main(); diff --git a/00_Common/javascript/common.mjs b/00_Common/javascript/common.mjs deleted file mode 100644 index 5f489990c..000000000 --- a/00_Common/javascript/common.mjs +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Print multible strings to the terminal. - * Strings get concatinated (add together) without any space betweent them. - * There will be no newline at the end! - * If you want a linebrak at the end use `println`. - * - * This function is normally used if you want to put something on the screen - * and later add some content to the same line. - * For normal output (similar to `console.log`) use `println`! - * - * @param {...string} messages - the strings to print to the terminal. - */ -export function print(...messages) { - process.stdout.write(messages.join("")); -} - -/** - * Add multible strings as a new line to the terminal. - * Strings get concatinated (add together) without any space betweent them. - * There will be a newline at the end! - * If you want the terminal to stay active on the current line use `print`. - * - * @param {...any} messages - the strings to print to the terminal. - */ -export function println(...messages) { - process.stdout.write(messages.join("") + "\n"); -} - -/** - * Create an empty string with a given length - * - * @param {number} length - the length of the string in space-characters. - * @returns {string} returns a string containing only ampty spaces with a length of `count`. - */ -export function tab(length) { - return " ".repeat(length); -} - -/** - * Read input from the keyboard and return it as a string. - * TODO: to would be very helpfull to only allow a certain class of input (numbers, letters) - * TODO: also we could convert all inputs to uppercase (where it makes sence). - * - * @param {string=''} message - a message or question to print befor the input. - * @returns {Promise} - returns the entered text as a string - * @async - */ -export async function input(message = '') { - /* First we need to print the mesage - * We append a space by default to seperate the message from the imput. - * TODO: If the message already contains a space at the end this is not needed! */ - process.stdout.write(message + ' '); - - return new Promise(resolve => { - process.stdin.on('data', (input) => { - /* onData returns a Buffer. - * First we need to convert it into a string. */ - const data = input.toString(); - - /* add input to terminal - * The data should end with a newline! */ - process.stdout.write(data); - - /* The result fo onData is a string ending with an `\n`. - * We just need the actual content so let's remove the newline at the end: */ - const content = data.endsWith('\n') ? data.slice(0, -1) : data; - - resolve(content); - }); - }); -} diff --git a/00_Common/rust/Cargo.lock b/00_Common/rust/Cargo.lock deleted file mode 100644 index 2c85bc520..000000000 --- a/00_Common/rust/Cargo.lock +++ /dev/null @@ -1,7 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "basic_input" -version = "0.1.0" diff --git a/00_Common/rust/Cargo.toml b/00_Common/rust/Cargo.toml deleted file mode 100644 index 23c680f4e..000000000 --- a/00_Common/rust/Cargo.toml +++ /dev/null @@ -1,7 +0,0 @@ -# -# Although there is currently only the `basic_input` crate here, I am anticipating -# more utility crates for rust ports, as well as proc macro crates. -# -[workspace] -resolver = "2" -members = [ "crates/basic_input" ] diff --git a/00_Common/rust/crates/basic_input/Cargo.toml b/00_Common/rust/crates/basic_input/Cargo.toml deleted file mode 100644 index d32bdb628..000000000 --- a/00_Common/rust/crates/basic_input/Cargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "basic_input" -version = "0.1.0" -edition = "2024" - -[dependencies] diff --git a/00_Common/rust/crates/basic_input/src/input.rs b/00_Common/rust/crates/basic_input/src/input.rs deleted file mode 100644 index 0955d8ec4..000000000 --- a/00_Common/rust/crates/basic_input/src/input.rs +++ /dev/null @@ -1,354 +0,0 @@ -mod input_state; -mod io_layer; - -use input_state::InputState; -use io_layer::IoLayer; - -/// Main entrypoint for this module. Display a prompt and read one or more values from the user. -/// See [the crate docs](module@crate) -pub fn get_input>(prompt: S) -> BI { - let mut io = IoLayer::get_io(); - get_input_from_io(prompt, &mut io) -} - -// This is the trait that we return to the user, which allows us to have -// a different function for each return type. -// let one_input : f32 = get_input("..."); -// let (x, y) : (f32, f32) = get_input("..."); -// let (a, b, c) : (f32, f32, f32) = get_input("..."); -pub trait BasicInput { - fn from_string>(s: S, state: &mut InputState) -> Result - where - Self: Sized; -} - -// -------------------------------------------------------------------------------- - -impl BasicInput for f32 { - fn from_string>(s: S, state: &mut InputState) -> Result { - state.input_f32s(s, 1)?; - Ok(state.data[0].as_f32()) - } -} - -impl BasicInput for (f32, f32) { - fn from_string>(s: S, state: &mut InputState) -> Result { - state.input_f32s(s, 2)?; - - Ok((state.data[0].as_f32(), state.data[1].as_f32())) - } -} - -impl BasicInput for (f32, f32, f32) { - fn from_string>(s: S, state: &mut InputState) -> Result { - state.input_f32s(s, 3)?; - - Ok(( - state.data[0].as_f32(), - state.data[1].as_f32(), - state.data[2].as_f32(), - )) - } -} - -impl BasicInput for (f32, f32, f32, f32) { - fn from_string>(s: S, state: &mut InputState) -> Result { - state.input_f32s(s, 4)?; - - Ok(( - state.data[0].as_f32(), - state.data[1].as_f32(), - state.data[2].as_f32(), - state.data[3].as_f32(), - )) - } -} - -impl BasicInput for (f32, f32, f32, f32, f32, f32, f32, f32, f32, f32) { - fn from_string>(s: S, state: &mut InputState) -> Result { - state.input_f32s(s, 10)?; - - Ok(( - state.data[0].as_f32(), - state.data[1].as_f32(), - state.data[2].as_f32(), - state.data[3].as_f32(), - state.data[4].as_f32(), - state.data[5].as_f32(), - state.data[6].as_f32(), - state.data[7].as_f32(), - state.data[8].as_f32(), - state.data[9].as_f32(), - )) - } -} - -impl BasicInput for String { - fn from_string>(s: S, state: &mut InputState) -> Result { - state.input_strings(s, 1)?; - Ok(state.data[0].as_string()) - } -} - -impl BasicInput for (String, String) { - fn from_string>(s: S, state: &mut InputState) -> Result { - state.input_strings(s, 2)?; - Ok((state.data[0].as_string(), state.data[1].as_string())) - } -} - -// -------------------------------------------------------------------------------- - -fn get_input_from_io>(prompt: S, io: &mut IoLayer) -> BI { - let mut state = InputState { - io, - data: Vec::new(), - }; - - state.io.raw_output_string(format!("{}? ", prompt.as_ref())); - - loop { - let buffer = state.io.raw_input_string(); - match BI::from_string(buffer, &mut state) { - Ok(result) => return result, - Err(e) => match e { - BasicInputError::ParseFailed => { - state.io.raw_output_string("?REENTER\n"); - state.io.raw_output_string(format!("{}? ", prompt.as_ref())); - state.data.clear(); - } - BasicInputError::MissingInput => { - state.io.raw_output_string("??? "); - } - }, - } - } -} - -#[derive(Debug)] -pub enum BasicInputError { - ParseFailed, - MissingInput, -} - -#[cfg(test)] -mod test { - use crate::input::get_input_from_io; - use crate::input::io_layer::{IoLayer, TextInput, TextOutput}; - use std::collections::VecDeque; - - fn getio() -> IoLayer { - IoLayer { - output: Box::new(WriteTestLayer::new()), - input: Box::new(ReadTestLayer::new()), - } - } - - #[test] - fn test_trait_single_input() { - let mut testio = getio(); - testio.input.set_input_text("2"); - let result: f32 = get_input_from_io("prompt", &mut testio); - assert_eq!(2.0, result); - } - - #[test] - fn test_trait_dual_input() { - let mut testio = getio(); - testio.input.set_input_text("2,3"); - let result: (f32, f32) = get_input_from_io("prompt", &mut testio); - assert_eq!( - "prompt? ".to_string(), - testio.output.get_last_line().unwrap() - ); - assert_eq!(2.0, result.0); - assert_eq!(3.0, result.1); - } - - #[test] - fn test_invalid_input() { - let mut testio = getio(); - testio.input.set_input_text("abc"); - testio.input.set_input_text("2"); - let result: f32 = get_input_from_io("prompt", &mut testio); - assert_eq!( - "prompt? ".to_string(), - testio.output.get_last_line().unwrap() - ); - assert_eq!( - "?REENTER\n".to_string(), - testio.output.get_last_line().unwrap() - ); - assert_eq!(2.0, result); - } - - #[test] - fn test_multiple_invalid_input() { - let mut testio = getio(); - testio.input.set_input_text("abc"); - testio.input.set_input_text("2,a"); - testio.input.set_input_text("2,3"); - let result: (f32, f32) = get_input_from_io("prompt", &mut testio); - assert_eq!( - "prompt? ".to_string(), - testio.output.get_last_line().unwrap() - ); - assert_eq!( - "?REENTER\n".to_string(), - testio.output.get_last_line().unwrap() - ); - assert_eq!( - "prompt? ".to_string(), - testio.output.get_last_line().unwrap() - ); - assert_eq!( - "?REENTER\n".to_string(), - testio.output.get_last_line().unwrap() - ); - assert_eq!( - "prompt? ".to_string(), - testio.output.get_last_line().unwrap() - ); - assert_eq!(2.0, result.0); - assert_eq!(3.0, result.1); - } - - #[test] - fn two_inputs_over_multiple_lines() { - let mut testio = getio(); - testio.input.set_input_text("2"); - testio.input.set_input_text("3"); - let result: (f32, f32) = get_input_from_io("prompt", &mut testio); - assert_eq!( - "prompt? ".to_string(), - testio.output.get_last_line().unwrap() - ); - assert_eq!("??? ".to_string(), testio.output.get_last_line().unwrap()); - assert_eq!(2.0, result.0); - assert_eq!(3.0, result.1); - } - - #[test] - fn test_triple_f32() { - let mut testio = getio(); - testio.input.set_input_text("1, 2, 3"); - let result: (f32, f32, f32) = get_input_from_io("enter 3 numbers", &mut testio); - assert_eq!(1.0, result.0); - assert_eq!(2.0, result.1); - assert_eq!(3.0, result.2); - } - - #[test] - fn test_input_string() { - let mut testio = getio(); - testio.input.set_input_text("hello"); - let result: String = get_input_from_io("String prompt", &mut testio); - assert_eq!("hello".to_string(), result); - } - - #[test] - fn test_two_input_strings() { - let mut testio = getio(); - testio.input.set_input_text("hello, world"); - let result: (String, String) = get_input_from_io("Double string prompt", &mut testio); - assert_eq!("hello".to_string(), result.0); - assert_eq!("world".to_string(), result.1); - } - - #[test] - fn test_four_nums() { - let mut testio = getio(); - testio.input.set_input_text("1, 2, 3, 4"); - let result: (f32, f32, f32, f32) = get_input_from_io("whatever", &mut testio); - assert_eq!(4.0, result.3); - } - - #[test] - fn test_extra_ignored() { - let mut testio = getio(); - testio.input.set_input_text("1, 2, 3, 4"); - let result: (f32, f32) = get_input_from_io("whatever", &mut testio); - assert_eq!(Some("whatever? "), testio.output.get_last_line().as_deref()); - assert_eq!( - Some("?EXTRA IGNORED\n"), - testio.output.get_last_line().as_deref() - ); - assert_eq!(2.0, result.1); - } - - #[test] - fn test_extra_ignored_bad_parse() { - let mut testio = getio(); - testio.input.set_input_text("1, 2, hello"); - let result: (f32, f32) = get_input_from_io("whatever", &mut testio); - assert_eq!(Some("whatever? "), testio.output.get_last_line().as_deref()); - assert_eq!( - Some("?EXTRA IGNORED\n"), - testio.output.get_last_line().as_deref() - ); - assert_eq!(2.0, result.1); - } - - #[test] - fn test_ten_nums() { - let mut testio = getio(); - testio.input.set_input_text("1, 2, 3, 4, 5, 6, 7, 8, 9, 10"); - let result: (f32, f32, f32, f32, f32, f32, f32, f32, f32, f32) = - get_input_from_io("whatever", &mut testio); - assert_eq!(Some("whatever? "), testio.output.get_last_line().as_deref()); - assert_eq!(None, testio.output.get_last_line()); - assert_eq!(10.0, result.9); - } - - // - // Helpers for test i/o - // - pub struct ReadTestLayer { - next_line: VecDeque, - } - - impl ReadTestLayer { - pub fn new() -> Self { - Self { - next_line: VecDeque::new(), - } - } - } - - impl TextInput for ReadTestLayer { - fn read(&mut self) -> String { - if let Some(line) = self.next_line.pop_front() { - println!(">> returning {line}"); - line - } else { - panic!("Test tried to read too much input"); - } - } - - fn set_input_text(&mut self, text: &str) { - self.next_line.push_back(text.to_string()); - } - } - - pub struct WriteTestLayer { - last_items_written: VecDeque, - } - - impl WriteTestLayer { - pub fn new() -> Self { - Self { - last_items_written: VecDeque::new(), - } - } - } - - impl TextOutput for WriteTestLayer { - fn write(&mut self, to_write: &str) { - self.last_items_written.push_back(to_write.into()); - } - - fn get_last_line(&mut self) -> Option { - self.last_items_written.pop_front() - } - } -} diff --git a/00_Common/rust/crates/basic_input/src/input/input_state.rs b/00_Common/rust/crates/basic_input/src/input/input_state.rs deleted file mode 100644 index 58c19e88f..000000000 --- a/00_Common/rust/crates/basic_input/src/input/input_state.rs +++ /dev/null @@ -1,77 +0,0 @@ -use crate::{BasicInputError, input::io_layer::IoLayer}; - -pub struct InputState<'a> { - pub(crate) io: &'a mut IoLayer, - pub(crate) data: Vec, -} - -impl<'a> InputState<'a> { - pub(crate) fn input_f32s>( - &mut self, - s: S, - count: usize, - ) -> Result<(), BasicInputError> { - let vals = crate::parse::parse(s); - - for v in vals { - if self.data.len() >= count { - self.io.raw_output_string("?EXTRA IGNORED\n"); - return Ok(()); - } - - let value = v - .trim() - .parse::() - .map_err(|_| BasicInputError::ParseFailed)?; - self.data.push(Value::Num(value)); - } - - if self.data.len() < count { - return Err(BasicInputError::MissingInput); - } - - Ok(()) - } - - pub(crate) fn input_strings>( - &mut self, - s: S, - count: usize, - ) -> Result<(), BasicInputError> { - let vals = crate::parse::parse(s); - - for v in vals { - let value = v.trim(); - self.data.push(Value::Str(value.to_string())); - } - if self.data.len() < count { - return Err(BasicInputError::MissingInput); - } - if self.data.len() > count { - self.io.raw_output_string("?EXTRA IGNORED\n"); - } - Ok(()) - } -} - -#[derive(Clone, Debug)] -pub enum Value { - Num(f32), - Str(String), -} - -impl Value { - pub(crate) fn as_f32(&self) -> f32 { - match self { - Value::Num(num) => *num, - Value::Str(_) => panic!("tried to extract a number, but Value was a String"), - } - } - - pub(crate) fn as_string(&self) -> String { - match self { - Value::Num(_) => panic!("tried to extract a string, but Value was a Num"), - Value::Str(s) => s.clone(), - } - } -} diff --git a/00_Common/rust/crates/basic_input/src/input/io_layer.rs b/00_Common/rust/crates/basic_input/src/input/io_layer.rs deleted file mode 100644 index 5939da31f..000000000 --- a/00_Common/rust/crates/basic_input/src/input/io_layer.rs +++ /dev/null @@ -1,80 +0,0 @@ -use std::io::{BufRead, StdoutLock, Write}; - -pub struct IoLayer { - pub(super) output: Box, - pub(super) input: Box, -} - -impl IoLayer { - pub(crate) fn get_io() -> Self { - Self { - output: StdoutLayer::new(), - input: StdinLayer::new(), - } - } - - pub(crate) fn raw_output_string>(&mut self, s: S) { - self.output.write(s.as_ref()); - } - - pub(crate) fn raw_input_string(&mut self) -> String { - self.input.read() - } -} - -pub(crate) trait TextOutput { - fn write(&mut self, to_write: &str); - #[cfg(test)] - fn get_last_line(&mut self) -> Option; -} - -pub(crate) trait TextInput { - fn read(&mut self) -> String; - #[cfg(test)] - fn set_input_text(&mut self, text: &str); -} - -struct StdoutLayer<'a> { - stdout: StdoutLock<'a>, -} - -impl<'a> TextOutput for StdoutLayer<'a> { - fn write(&mut self, to_write: &str) { - print!("{to_write}"); - let _ = self.stdout.flush(); - } - - #[cfg(test)] - fn get_last_line(&mut self) -> Option { - unreachable!(); - } -} - -struct StdinLayer; -impl TextInput for StdinLayer { - fn read(&mut self) -> String { - let mut buffer = String::new(); - let stdin = std::io::stdin(); - let mut handle = stdin.lock(); - let _ = handle.read_line(&mut buffer); - buffer - } - - #[cfg(test)] - fn set_input_text(&mut self, _text: &str) { - unreachable!(); - } -} - -impl<'a> StdoutLayer<'a> { - fn new() -> Box { - Box::new(Self { - stdout: std::io::stdout().lock(), - }) - } -} -impl StdinLayer { - fn new() -> Box { - Box::new(Self) - } -} diff --git a/00_Common/rust/crates/basic_input/src/lib.rs b/00_Common/rust/crates/basic_input/src/lib.rs deleted file mode 100644 index 8d14d9a5f..000000000 --- a/00_Common/rust/crates/basic_input/src/lib.rs +++ /dev/null @@ -1,42 +0,0 @@ -//! A library for reading input from a basic program. -//! -//! In BASIC, you can have a statement like -//! ```basic -//! 10 INPUT "PROMPT";A$ -//! ``` -//! This crate emulates this with: -//! ```no_run -//! let a_value: String = basic_input::get_input("PROMPT"); -//! ``` -//! -//! BASIC also allows programmers to read multiple values at a time. For example, to -//! read two numbers, the program will have `INPUT "PROMPT";X1,Y1`. This can be done -//! in Rust with a tuple: -//! ```no_run -//! let (x1, y1): (f32, f32) = basic_input::get_input("Enter coordinates"); -//! ``` -//! The code will automatically re-prompt if the user doesn't enter all the values. -//! -//! Guided by the README.md under 00_Common, we know that there are `INPUT` statements -//! in the various games which ask for -//! -//! * 1 or 2 strings, -//! * 1-4 floating-point numbers, or 10(!) floating-point numbers -//! -//! and there are no other kinds of input required. All of these have been accounted -//! for in the `input` module (see `impl BasicInput for `) but they are easy -//! enough to extend/enhance for different kinds of input. -//! -//! To use this in your Rust code, you can reference the local crate by adding the -//! following line to your `Cargo.toml`: -//! -//! ```toml -//! basic_input = { path = "../../00_Common/rust/crates/basic_input" } -//! ``` -//! -//! (adjust the number of `../` for the depth of your own subdirectory) - -pub mod input; -mod parse; - -pub use input::*; diff --git a/00_Common/rust/crates/basic_input/src/parse.rs b/00_Common/rust/crates/basic_input/src/parse.rs deleted file mode 100644 index fa2ac9eff..000000000 --- a/00_Common/rust/crates/basic_input/src/parse.rs +++ /dev/null @@ -1,85 +0,0 @@ -pub(crate) fn parse>(buffer: B) -> Vec { - let mut result = Vec::new(); - let mut in_quote = false; - let mut need_comma = false; - - let mut current = String::new(); - for ch in buffer.as_ref().chars() { - match (ch, in_quote) { - (',', false) => { - result.push(current.trim().to_string()); - current.clear(); - } - ('"', true) => { - need_comma = true; - result.push(current.trim().to_string()); - current.clear(); - } - ('"', false) => { - in_quote = true; - } - - (',', true) if need_comma => { - need_comma = false; - in_quote = false; - } - (',', true) => current.push(ch), - - _ => { - current.push(ch); - } - } - } - if !current.is_empty() { - result.push(current.trim().to_string()); - } - - result -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn parse_single_value() { - let result = parse("123"); - assert_eq!("123".to_string(), result[0]); - assert_eq!(1, result.len()); - } - - #[test] - fn parse_two_values() { - let result = parse("123, 456"); - assert_eq!("123".to_string(), result[0]); - assert_eq!("456".to_string(), result[1]); - assert_eq!(2, result.len()); - } - - #[test] - fn parse_quoted_value() { - let result = parse("123, \"456,789\", 10"); - assert_eq!("123".to_string(), result[0]); - assert_eq!("456,789".to_string(), result[1]); - assert_eq!("10".to_string(), result[2]); - assert_eq!(3, result.len()); - } - - #[test] - fn parse_missing_closing_quote() { - let result = parse("123, \"456,789, 10"); - assert_eq!("123".to_string(), result[0]); - assert_eq!("456,789, 10".to_string(), result[1]); - assert_eq!(2, result.len()); - } - - #[test] - fn parse_quoted_value_twice() { - let result = parse("123, \"456,789\", 10, 11"); - assert_eq!("123".to_string(), result[0]); - assert_eq!("456,789".to_string(), result[1]); - assert_eq!("10".to_string(), result[2]); - assert_eq!("11".to_string(), result[3]); - assert_eq!(4, result.len()); - } -} diff --git a/00_Utilities/DotnetUtils/.editorconfig b/00_Utilities/DotnetUtils/.editorconfig index f48cda0a2..9e7a90d56 100644 --- a/00_Utilities/DotnetUtils/.editorconfig +++ b/00_Utilities/DotnetUtils/.editorconfig @@ -65,11 +65,11 @@ dotnet_naming_rule.private_members_should_be_pascal_case.style = camel_case 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.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.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 @@ -80,19 +80,19 @@ 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.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.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.required_prefix = +dotnet_naming_style.camel_case.required_suffix = +dotnet_naming_style.camel_case.word_separator = dotnet_naming_style.camel_case.capitalization = camel_case diff --git a/00_Utilities/DotnetUtils/DotnetUtils/Extensions.cs b/00_Utilities/DotnetUtils/DotnetUtils/Extensions.cs index 11f051771..82ff95327 100644 --- a/00_Utilities/DotnetUtils/DotnetUtils/Extensions.cs +++ b/00_Utilities/DotnetUtils/DotnetUtils/Extensions.cs @@ -1,5 +1,4 @@ using System.Diagnostics.CodeAnalysis; -using static System.IO.Path; namespace DotnetUtils; @@ -10,11 +9,6 @@ public static IEnumerable SelectT(this IEnumerable 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")] @@ -24,7 +18,10 @@ predicate is null ? rootPath.IsNullOrWhitespace() ) { return path; } - path = path.TrimEnd('\\'); // remove trailing backslash, if present - return GetRelativePath(rootPath, path.TrimEnd('\\')); + 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/Functions.cs b/00_Utilities/DotnetUtils/DotnetUtils/Functions.cs deleted file mode 100644 index cc31170e1..000000000 --- a/00_Utilities/DotnetUtils/DotnetUtils/Functions.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Xml.Linq; -using static System.Console; - -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; - } - - 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/Methods.cs b/00_Utilities/DotnetUtils/DotnetUtils/Methods.cs deleted file mode 100644 index a8d3532b4..000000000 --- a/00_Utilities/DotnetUtils/DotnetUtils/Methods.cs +++ /dev/null @@ -1,88 +0,0 @@ -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 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) { - 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 c7a96147c..894c88345 100644 --- a/00_Utilities/DotnetUtils/DotnetUtils/PortInfo.cs +++ b/00_Utilities/DotnetUtils/DotnetUtils/PortInfo.cs @@ -1,55 +1,47 @@ -using static System.IO.Directory; +using System.Reflection; +using static System.IO.Directory; using static System.IO.Path; using static DotnetUtils.Globals; namespace DotnetUtils; public record PortInfo( - string GamePath, string FolderName, int Index, string GameName, + 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 }; - // .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", "Plot" }, - { "3-D_Tic-Tac-Toe", "ThreeDTicTacToe" }, - { "23_Matches", "TwentyThreeMatches"} - }; - - public static PortInfo? Create(string gamePath, string langKeyword) { - var folderName = GetFileName(gamePath); + public static PortInfo? Create(string fullPath, string langKeyword) { + var folderName = GetFileName(fullPath); var parts = folderName.Split('_', 2); - if (parts.Length <= 1) { return null; } - - var (index, gameName) = ( - int.TryParse(parts[0], out var n) && n > 0 ? // ignore utilities folder + var index = + parts.Length > 0 && int.TryParse(parts[0], out var n) ? n : - (int?)null, - specialGameNames.TryGetValue(parts[1], out var specialName) ? - specialName : - parts[1].Replace("_", "").Replace("-", "") - ); + (int?)null; + + var gameName = + parts.Length > 1 ? + parts[1].Replace("_", "") : + null; - if (index is null || gameName is null) { return null; } + if (index is 0 or null || gameName is null) { return null; } var (ext, projExt) = LangData[langKeyword]; - var langPath = Combine(gamePath, langKeyword); + var langPath = Combine(fullPath, langKeyword); var codeFiles = GetFiles(langPath, $"*.{ext}", enumerationOptions) .Where(x => !x.Contains("\\bin\\") && !x.Contains("\\obj\\")) .ToArray(); return new PortInfo( - gamePath, folderName, index.Value, gameName, + fullPath, 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 af824b338..b8c1afd3a 100644 --- a/00_Utilities/DotnetUtils/DotnetUtils/PortInfos.cs +++ b/00_Utilities/DotnetUtils/DotnetUtils/PortInfos.cs @@ -12,8 +12,8 @@ static PortInfos() { Root = Root[..Root.IndexOf(@"\00_Utilities")]; Get = GetDirectories(Root) - .SelectMany(gamePath => LangData.Keys.Select(keyword => (gamePath, keyword))) - .SelectT((gamePath, keyword) => PortInfo.Create(gamePath, keyword)) + .SelectMany(fullPath => LangData.Keys.Select(keyword => (fullPath, keyword))) + .SelectT((fullPath, keyword) => PortInfo.Create(fullPath, 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 a9f5cac1d..6d4594b73 100644 --- a/00_Utilities/DotnetUtils/DotnetUtils/Program.cs +++ b/00_Utilities/DotnetUtils/DotnetUtils/Program.cs @@ -1,9 +1,6 @@ -using System.Xml.Linq; -using DotnetUtils; +using DotnetUtils; using static System.Console; using static System.IO.Path; -using static DotnetUtils.Methods; -using static DotnetUtils.Functions; var infos = PortInfos.Get; @@ -14,14 +11,7 @@ (multipleSlns, "Output multiple sln files"), (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"), - (noCodeFiles, "Output ports without any code files"), - (printPortInfo, "Print info about a single port"), - - (generateMissingSlns, "Generate solution files when missing"), - (generateMissingProjs, "Generate project files when missing") + (multipleProjs, "Output multiple project files") }; foreach (var (_, description, index) in actions.WithIndex()) { @@ -32,6 +22,15 @@ 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: @@ -66,6 +65,7 @@ void printProjs(PortInfo pi) { } break; } + WriteLine(); } void printInfos() { @@ -88,7 +88,7 @@ void printInfos() { } void missingSln() { - var data = infos.Where(x => x.Slns.None()).ToArray(); + var data = infos.Where(x => !x.Slns.Any()).ToArray(); foreach (var item in data) { WriteLine(item.LangPath); } @@ -99,10 +99,10 @@ void missingSln() { void unexpectedSlnName() { var counter = 0; foreach (var item in infos) { - if (item.Slns.None()) { continue; } + if (!item.Slns.Any()) { continue; } var expectedSlnName = $"{item.GameName}.sln"; - if (item.Slns.Contains(Combine(item.LangPath, expectedSlnName), StringComparer.InvariantCultureIgnoreCase)) { continue; } + if (item.Slns.Contains(Combine(item.LangPath, expectedSlnName))) { continue; } counter += 1; WriteLine(item.LangPath); @@ -126,7 +126,7 @@ void multipleSlns() { } void missingProj() { - var data = infos.Where(x => x.Projs.None()).ToArray(); + var data = infos.Where(x => !x.Projs.Any()).ToArray(); foreach (var item in data) { WriteLine(item.LangPath); } @@ -137,7 +137,7 @@ void missingProj() { void unexpectedProjName() { var counter = 0; foreach (var item in infos) { - if (item.Projs.None()) { continue; } + if (!item.Projs.Any()) { continue; } var expectedProjName = $"{item.GameName}.{item.ProjExt}"; if (item.Projs.Contains(Combine(item.LangPath, expectedProjName))) { continue; } @@ -159,205 +159,8 @@ void multipleProjs() { WriteLine(item.LangPath); WriteLine(); printProjs(item); - } - WriteLine(); - WriteLine($"Count: {data.Length}"); -} - -void generateMissingSlns() { - foreach (var item in infos.Where(x => x.Slns.None())) { - 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.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. - - var projText = item.Lang switch { - "csharp" => @" - - Exe - net6.0 - 10 - enable - enable - - -", - "vbnet" => @$" - - Exe - {item.GameName} - net6.0 - 16.9 - - -", - _ => throw new InvalidOperationException() - }; - 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); - } - } -} - -void checkProjects() { - foreach (var info in infos) { - WriteLine(info.LangPath); - printProjectWarnings(info); - } -} - -void printProjectWarnings(PortInfo info) { - foreach (var proj in info.Projs) { - var warnings = new List(); - var parent = XDocument.Load(proj).Element("Project")?.Element("PropertyGroup"); - - var ( - framework, - nullable, - implicitUsing, - rootNamespace, - langVersion, - optionStrict - ) = ( - getValue(parent, "TargetFramework", "TargetFrameworks"), - getValue(parent, "Nullable"), - getValue(parent, "ImplicitUsings"), - getValue(parent, "RootNamespace"), - getValue(parent, "LangVersion"), - getValue(parent, "OptionStrict") - ); - - if (framework != "net6.0") { - warnings.Add($"Target: {framework}"); - } - - if (info.Lang == "csharp") { - if (nullable != "enable") { - warnings.Add($"Nullable: {nullable}"); - } - if (implicitUsing != "enable") { - warnings.Add($"ImplicitUsings: {implicitUsing}"); - } - if (rootNamespace != null && rootNamespace != info.GameName) { - warnings.Add($"RootNamespace: {rootNamespace}"); - } - if (langVersion != "10") { - warnings.Add($"LangVersion: {langVersion}"); - } - } - - if (info.Lang == "vbnet") { - if (rootNamespace != info.GameName) { - warnings.Add($"RootNamespace: {rootNamespace}"); - } - if (langVersion != "16.9") { - warnings.Add($"LangVersion: {langVersion}"); - } - if (optionStrict != "On") { - warnings.Add($"OptionStrict: {optionStrict}"); - } - } - - if (warnings.Any()) { - WriteLine(proj.RelativePath(info.LangPath)); - 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 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 -} - -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 + WriteLine($"Count: {data.Length}"); } diff --git a/00_Utilities/README.md b/00_Utilities/README.md deleted file mode 100644 index a69ef2e1d..000000000 --- a/00_Utilities/README.md +++ /dev/null @@ -1,3 +0,0 @@ -#### Utilities - -These are global helper / utility programs to assist us in maintaining all the ports. \ No newline at end of file diff --git a/00_Utilities/TODO.md b/00_Utilities/TODO.md deleted file mode 100644 index 714807486..000000000 --- a/00_Utilities/TODO.md +++ /dev/null @@ -1,101 +0,0 @@ -# TODO list - game | C# | Java | JS | Kotlin | Lua | Perl | Python | Ruby | Rust | VB.NET ------------------------------- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- -01_Acey_Ducey | ✅ | ✅ | ✅ | ⬜️ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ -[02_Amazing](../02_Amazing) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ✅ | ✅ | ✅ -[03_Animal](../03_Animal) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⬜️ -[04_Awari](../04_Awari) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ✅ | ✅ | ⬜️ -[05_Bagels](../05_Bagels) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⬜️ -[06_Banner](../06_Banner) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ✅ | ⬜️ | ✅ -[07_Basketball](../07_Basketball) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ✅ | ⬜️ | ⬜️ -[08_Batnum](../08_Batnum) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ✅ | ✅ | ✅ -[09_Battle](../09_Battle) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ⬜️ | ✅ | ⬜️ | ✅ | ⬜️ -[10_Blackjack](../10_Blackjack) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ⬜️ | ✅ | ✅ | ✅ | ⬜️ -[11_Bombardment](../11_Bombardment) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ✅ | ✅ | ⬜️ -[12_Bombs_Away](../12_Bombs_Away) | ⬜️ | ✅ | ✅ | ⬜️ | ✅ | ✅ | ✅ | ⬜️ | ✅ | ⬜️ -[13_Bounce](../13_Bounce) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ✅ | ⬜️ | ⬜️ -[14_Bowling](../14_Bowling) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ⬜️ | ⬜️ | ⬜️ -[15_Boxing](../15_Boxing) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ⬜️ | ⬜️ | ⬜️ -[16_Bug](../16_Bug) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ⬜️ | ✅ | ✅ | ⬜️ | ⬜️ -[17_Bullfight](../17_Bullfight) | ✅ | ⬜️ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ⬜️ | ⬜️ | ⬜️ -[18_Bullseye](../18_Bullseye) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ⬜️ | ✅ | ⬜️ -[19_Bunny](../19_Bunny) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ✅ | ⬜️ | ⬜️ -[20_Buzzword](../20_Buzzword) | ✅ | ✅ | ✅ | ⬜️ | ✅ | ✅ | ✅ | ✅ | ✅ | ⬜️ -[21_Calendar](../21_Calendar) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ✅ | ✅ | ⬜️ -[22_Change](../22_Change) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ⬜️ | ✅ | ⬜️ -[23_Checkers](../23_Checkers) | ✅ | ⬜️ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ✅ | ⬜️ | ⬜️ -[24_Chemist](../24_Chemist) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ⬜️ | ✅ | ⬜️ -[25_Chief](../25_Chief) | ✅ | ✅ | ✅ | ⬜️ | ✅ | ✅ | ✅ | ✅ | ✅ | ⬜️ -[26_Chomp](../26_Chomp) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ⬜️ | ⬜️ | ⬜️ -[27_Civil_War](../27_Civil_War) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ⬜️ | ✅ | ⬜️ | ⬜️ | ⬜️ -[28_Combat](../28_Combat) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ⬜️ | ⬜️ | ⬜️ -[29_Craps](../29_Craps) | ⬜️ | ✅ | ✅ | ⬜️ | ✅ | ✅ | ✅ | ✅ | ✅ | ⬜️ -[30_Cube](../30_Cube) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ⬜️ | ✅ | ✅ | ✅ | ⬜️ -[31_Depth_Charge](../31_Depth_Charge) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ✅ | ⬜️ | ⬜️ -[32_Diamond](../32_Diamond) | ✅ | ✅ | ✅ | ✅ | ⬜️ | ✅ | ✅ | ✅ | ✅ | ⬜️ -[33_Dice](../33_Dice) | ✅ | ✅ | ✅ | ⬜️ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ -[34_Digits](../34_Digits) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ⬜️ | ⬜️ | ⬜️ -[35_Even_Wins](../35_Even_Wins) | ⬜️ | ⬜️ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ⬜️ | ✅ | ⬜️ -[36_Flip_Flop](../36_Flip_Flop) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ✅ | ✅ | ⬜️ -[37_Football](../37_Football) | ⬜️ | ⬜️ | ✅ | ⬜️ | ⬜️ | ⬜️ | ✅ | ⬜️ | ⬜️ | ⬜️ -[38_Fur_Trader](../38_Fur_Trader) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ⬜️ | ⬜️ | ⬜️ -[39_Golf](../39_Golf) | ✅ | ⬜️ | ✅ | ⬜️ | ⬜️ | ⬜️ | ✅ | ⬜️ | ⬜️ | ⬜️ -[40_Gomoko](../40_Gomoko) | ⬜️ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ⬜️ | ⬜️ | ⬜️ -[41_Guess](../41_Guess) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ✅ | ✅ | ⬜️ -[42_Gunner](../42_Gunner) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ⬜️ | ⬜️ | ⬜️ -[43_Hammurabi](../43_Hammurabi) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ⬜️ | ✅ | ⬜️ -[44_Hangman](../44_Hangman) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ✅ | ⬜️ | ⬜️ -[45_Hello](../45_Hello) | ⬜️ | ✅ | ✅ | ⬜️ | ✅ | ✅ | ✅ | ✅ | ⬜️ | ⬜️ -[46_Hexapawn](../46_Hexapawn) | ✅ | ⬜️ | ✅ | ⬜️ | ⬜️ | ⬜️ | ✅ | ⬜️ | ⬜️ | ⬜️ -[47_Hi-Lo](../47_Hi-Lo) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⬜️ -[48_High_IQ](../48_High_IQ) | ⬜️ | ✅ | ✅ | ⬜️ | ⬜️ | ⬜️ | ✅ | ⬜️ | ⬜️ | ⬜️ -[49_Hockey](../49_Hockey) | ⬜️ | ⬜️ | ✅ | ⬜️ | ⬜️ | ⬜️ | ✅ | ⬜️ | ⬜️ | ⬜️ -[50_Horserace](../50_Horserace) | ⬜️ | ⬜️ | ✅ | ⬜️ | ⬜️ | ⬜️ | ✅ | ⬜️ | ✅ | ⬜️ -[51_Hurkle](../51_Hurkle) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ✅ | ✅ | ⬜️ -[52_Kinema](../52_Kinema) | ⬜️ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ✅ | ⬜️ | ⬜️ -[53_King](../53_King) | ✅ | ⬜️ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ⬜️ | ✅ | ⬜️ -[54_Letter](../54_Letter) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ✅ | ✅ | ⬜️ -[55_Life](../55_Life) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ✅ | ✅ | ⬜️ -[56_Life_for_Two](../56_Life_for_Two) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ⬜️ | ⬜️ | ⬜️ -[57_Literature_Quiz](../57_Literature_Quiz) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ⬜️ | ✅ | ⬜️ -[58_Love](../58_Love) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ✅ | ✅ | ⬜️ -[59_Lunar_LEM_Rocket](../59_Lunar_LEM_Rocket) | ⬜️ | ⬜️ | ✅ | ⬜️ | ⬜️ | ⬜️ | ✅ | ⬜️ | ✅ | ⬜️ -[60_Mastermind](../60_Mastermind) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ⬜️ | ✅ | ⬜️ -[61_Math_Dice](../61_Math_Dice) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ✅ | ✅ | ⬜️ -[62_Mugwump](../62_Mugwump) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ⬜️ | ✅ | ⬜️ -[63_Name](../63_Name) | ✅ | ✅ | ✅ | ⬜️ | ✅ | ✅ | ✅ | ✅ | ⬜️ | ⬜️ -[64_Nicomachus](../64_Nicomachus) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ⬜️ | ✅ | ⬜️ -[65_Nim](../65_Nim) | ⬜️ | ⬜️ | ✅ | ⬜️ | ⬜️ | ⬜️ | ✅ | ✅ | ✅ | ⬜️ -[66_Number](../66_Number) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ⬜️ | ✅ | ⬜️ -[67_One_Check](../67_One_Check) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ⬜️ | ⬜️ | ⬜️ -[68_Orbit](../68_Orbit) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ✅ | ✅ | ⬜️ -[69_Pizza](../69_Pizza) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ✅ | ✅ | ⬜️ -[70_Poetry](../70_Poetry) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ✅ | ⬜️ | ⬜️ -[71_Poker](../71_Poker) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ⬜️ | ⬜️ | ⬜️ | ⬜️ | ⬜️ -[72_Queen](../72_Queen) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ⬜️ | ✅ | ⬜️ -[73_Reverse](../73_Reverse) | ⬜️ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ✅ | ⬜️ | ✅ -[74_Rock_Scissors_Paper](../74_Rock_Scissors_Paper) | ✅ | ✅ | ✅ | ⬜️ | ✅ | ✅ | ✅ | ✅ | ✅ | ⬜️ -[75_Roulette](../75_Roulette) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ⬜️ | ✅ | ⬜️ -[76_Russian_Roulette](../76_Russian_Roulette) | ✅ | ✅ | ✅ | ⬜️ | ✅ | ✅ | ✅ | ✅ | ✅ | ⬜️ -[77_Salvo](../77_Salvo) | ✅ | ⬜️ | ✅ | ⬜️ | ⬜️ | ⬜️ | ✅ | ⬜️ | ⬜️ | ⬜️ -[78_Sine_Wave](../78_Sine_Wave) | ✅ | ✅ | ✅ | ⬜️ | ✅ | ✅ | ✅ | ✅ | ✅ | ⬜️ -[79_Slalom](../79_Slalom) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ⬜️ | ✅ | ⬜️ | ⬜️ | ⬜️ -[80_Slots](../80_Slots) | ⬜️ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ✅ | ⬜️ | ⬜️ -[81_Splat](../81_Splat) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ⬜️ | ✅ | ⬜️ -[82_Stars](../82_Stars) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ✅ | ✅ | ⬜️ -[83_Stock_Market](../83_Stock_Market) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ⬜️ | ✅ | ⬜️ | ⬜️ | ⬜️ -[84_Super_Star_Trek](../84_Super_Star_Trek) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ⬜️ | ✅ | ⬜️ | ✅ | ⬜️ -[85_Synonym](../85_Synonym) | ✅ | ✅ | ✅ | ✅ | ⬜️ | ✅ | ✅ | ✅ | ✅ | ⬜️ -[86_Target](../86_Target) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ⬜️ | ⬜️ | ⬜️ -[87_3-D_Plot](../87_3-D_Plot) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ✅ | ⬜️ | ⬜️ -[88_3-D_Tic-Tac-Toe](../88_3-D_Tic-Tac-Toe) | ✅ | ⬜️ | ✅ | ⬜️ | ⬜️ | ⬜️ | ✅ | ⬜️ | ⬜️ | ⬜️ -[89_Tic-Tac-Toe](../89_Tic-Tac-Toe) | ⬜️ | ✅ | ✅ | ✅ | ⬜️ | ✅ | ✅ | ⬜️ | ✅ | ⬜️ -[90_Tower](../90_Tower) | ✅ | ✅ | ✅ | ⬜️ | ✅ | ✅ | ✅ | ⬜️ | ✅ | ⬜️ -[91_Train](../91_Train) | ⬜️ | ✅ | ✅ | ⬜️ | ✅ | ✅ | ✅ | ✅ | ✅ | ⬜️ -[92_Trap](../92_Trap) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ✅ | ✅ | ⬜️ -[93_23_Matches](../93_23_Matches) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ✅ | ✅ | ⬜️ -[94_War](../94_War) | ⬜️ | ✅ | ✅ | ✅ | ⬜️ | ✅ | ✅ | ✅ | ✅ | ⬜️ -[95_Weekday](../95_Weekday) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ⬜️ | ✅ | ⬜️ -[96_Word](../96_Word) | ✅ | ✅ | ✅ | ⬜️ | ⬜️ | ✅ | ✅ | ✅ | ✅ | ✅ ------------------------------- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- -Sum of 96 | 79 | 83 | 96 | 9 | 16 | 75 | 95 | 51 | 58 | 7 diff --git a/00_Utilities/bas2perl.pl b/00_Utilities/bas2perl.pl deleted file mode 100755 index 8ad136e37..000000000 --- a/00_Utilities/bas2perl.pl +++ /dev/null @@ -1,377 +0,0 @@ -#!/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; - } diff --git a/00_Utilities/build-index.js b/00_Utilities/build-index.js deleted file mode 100644 index 1ed862efe..000000000 --- a/00_Utilities/build-index.js +++ /dev/null @@ -1,153 +0,0 @@ -#!/usr/bin/env node -/** - * This script creates an "index.html" file in the root of the directory. - * - * Call this from the root of the project with - * `node ./00_Utilities/build-index.js` - * - * @author Alexander Wunschik - */ - -const fs = require('fs'); -const path = require('path'); - -const TITLE = 'BASIC Computer Games'; -const JAVASCRIPT_FOLDER = 'javascript'; -const IGNORE_FOLDERS_START_WITH = ['.', '00_', 'buildJvm', 'Sudoku']; -const IGNORE_FILES = [ - // "84 Super Star Trek" has it's own node/js implementation (using xterm) - 'cli.mjs', 'superstartrek.mjs' -]; - -function createGameLinks(game) { - const creatFileLink = (file, name = path.basename(file)) => { - if (file.endsWith('.html')) { - return ` -
  • ${name.replace('.html', '')}
  • - `; - } else if (file.endsWith('.mjs')) { - return ` -
  • ${name.replace('.mjs', '')} (node.js)
  • - `; - } else { - throw new Error(`Unknown file-type found: ${file}`); - } - } - - if (game.files.length > 1) { - const entries = game.files.map(file => { - return creatFileLink(file); - }); - return ` -
  • - ${game.name} -
      ${entries.map(e => `\t\t\t${e}`).join('\n')}
    -
  • - `; - } else { - return creatFileLink(game.files[0], game.name); - } -} - -function createIndexHtml(title, games) { - const listEntries = games.map(game => - createGameLinks(game) - ).map(entry => `\t\t\t${entry}`).join('\n'); - - const head = ` - - - ${title} - - - `; - - const body = ` - -
    -
    -

    ${title}

    -
    -
    -
      - ${listEntries} -
    -
    -
    - - `; - - return ` - - - ${head} - ${body} - - `.trim().replace(/\s\s+/g, ''); -} - -function findJSFilesInFolder(folder) { - // filter folders that do not include a subfolder called "javascript" - const hasJavascript = fs.existsSync(`${folder}/${JAVASCRIPT_FOLDER}`); - if (!hasJavascript) { - throw new Error(`Game "${folder}" is missing a javascript folder`); - } - - // get all files in the javascript folder - const files = fs.readdirSync(`${folder}/${JAVASCRIPT_FOLDER}`); - - // filter files only allow .html files - const htmlFiles = files.filter(file => file.endsWith('.html')); - const mjsFiles = files.filter(file => file.endsWith('.mjs')); - const entries = [ - ...htmlFiles, - ...mjsFiles - ].filter(file => !IGNORE_FILES.includes(file)); - - if (entries.length == 0) { - throw new Error(`Game "${folder}" is missing a HTML or node.js file in the folder "${folder}/${JAVASCRIPT_FOLDER}"`); - } - - return entries.map(file => path.join(folder, JAVASCRIPT_FOLDER, file)); -} - -function main() { - // Get the list of all folders in the current director - let folders = fs.readdirSync(process.cwd()); - - // filter files only allow folders - folders = folders.filter(folder => fs.statSync(folder).isDirectory()); - - // filter out the folders that start with a dot or 00_ - folders = folders.filter(folder => { - return !IGNORE_FOLDERS_START_WITH.some(ignore => folder.startsWith(ignore)); - }); - - // sort the folders alphabetically (by number) - folders = folders.sort(); - - // get name and javascript file from folder - const games = folders.map(folder => { - const name = folder.replace('_', ' '); - let files; - - try { - files = findJSFilesInFolder(folder); - } catch (error) { - console.warn(`Game "${name}" is missing a javascript implementation: ${error.message}`); - return null; - } - - return { - name, - files - } - }).filter(game => game !== null); - - // create a index.html file with a list of all games - const htmlContent = createIndexHtml(TITLE, games); - fs.writeFileSync('index.html', htmlContent); - console.log(`index.html successfully created!`); -} - -main(); \ No newline at end of file diff --git a/00_Utilities/find-missing-implementations.js b/00_Utilities/find-missing-implementations.js index a458f190e..61d849feb 100644 --- a/00_Utilities/find-missing-implementations.js +++ b/00_Utilities/find-missing-implementations.js @@ -16,13 +16,10 @@ const languages = [ { name: "csharp", extension: "cs" }, { name: "java", extension: "java" }, { name: "javascript", extension: "html" }, - { name: "kotlin", extension: "kt" }, - { name: "lua", extension: "lua" }, { name: "pascal", extension: "pas" }, { name: "perl", extension: "pl" }, { name: "python", extension: "py" }, { name: "ruby", extension: "rb" }, - { name: "rust", extension: "rs" }, { name: "vbnet", extension: "vb" }, ]; diff --git a/00_Utilities/find-unimplemented.js b/00_Utilities/find-unimplemented.js deleted file mode 100644 index fb88fdbe2..000000000 --- a/00_Utilities/find-unimplemented.js +++ /dev/null @@ -1,76 +0,0 @@ -/** - * 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: "kotlin", extension: "kt" }, - { name: "lua", extension: "lua" }, - { name: "pascal", extension: "pas" }, - { name: "perl", extension: "pl" }, - { name: "python", extension: "py" }, - { name: "ruby", extension: "rb" }, - { name: "vbnet", extension: "vb" }, - { name: "rust", extension: "rs" }, -]; - -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; diff --git a/00_Utilities/javascript/style_terminal.css b/00_Utilities/javascript/style_terminal.css deleted file mode 100644 index c0a23ac57..000000000 --- a/00_Utilities/javascript/style_terminal.css +++ /dev/null @@ -1,117 +0,0 @@ -/** - * Old school terminal style - * - * @see https://codepen.io/cvan/pen/Zarmry - * @see http://aleclownes.com/2017/02/01/crt-display.html - */ - - /* define the main color theme */ -:root { - --background: rgb(1, 24, 1); - --text: rgb(51, 251, 51); - --input: yellow; - --font: 600 1rem/1.3 Consolas, Andale Mono, monospace; -} - -/* reset some styles */ -* { - box-sizing: border-box; - margin: 0; - padding: 0; -} -html { - font-size: 16px; -} - -header { - margin-bottom: 2rem; -} - -body { - background-color: var(--background); - color: var(--text); - font: var(--font); - margin: 0; -} - -#output { - padding: 1rem; -} - -/* format input fields */ -/* TODO: a simple blinking cursor would even better than this! */ -input { - display: inline-block; - position: relative; - caret-color: var(--input); - background: none; - border: none; - outline: none; - border-bottom: 1px solid var(--input); - border-style: none none dashed none; - color: var(--input); - font: 900 1rem/1.3 Consolas, Andale Mono, monospace; - animation: textShadow 1.6s infinite; - text-transform: uppercase; -} - -/* format the link list */ -ul { - margin: 0; - list-style: none; -} -li { - margin: 0; -} -/* format the sub-lists */ -ul > li > ul { - margin-left: 1.75rem; -} -ul > li > ul > li::before { - content: "├── "; -} -ul > li > ul > li:last-child::before { - content: "└── "; -} - -/* overwrite the default (blue) link styles */ -a, a:visited { - color: var(--text); - text-decoration: none; -} -a:hover { - text-decoration: underline; -} - -/* add all the face flicker effects (only on desktop) */ -@media not screen and (max-width: 960px) and (prefers-reduced-motion) { - main { - padding: 3rem; - } - #output::before { - content: " "; - display: block; - position: fixed; - top: 0; - left: 0; - bottom: 0; - right: 0; - background: linear-gradient(rgba(18, 16, 16, 0) 50%, rgba(0, 0, 0, 0.25) 50%), linear-gradient(90deg, rgba(255, 0, 0, 0.06), rgba(0, 255, 0, 0.02), rgba(0, 0, 255, 0.06)); - z-index: 2; - background-size: 100% 2px, 3px 100%; - pointer-events: none; - } - #output::after { - content: " "; - display: block; - position: fixed; - top: 0; - left: 0; - bottom: 0; - right: 0; - background: rgba(18, 16, 16, 0.1); - opacity: 0; - z-index: 2; - pointer-events: none; - } -} \ No newline at end of file diff --git a/00_Utilities/jvmTestUtils/kotlin/test/ConsoleTest.kt b/00_Utilities/jvmTestUtils/kotlin/test/ConsoleTest.kt deleted file mode 100644 index eba584d96..000000000 --- a/00_Utilities/jvmTestUtils/kotlin/test/ConsoleTest.kt +++ /dev/null @@ -1,37 +0,0 @@ -package com.pcholt.console.testutils - -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(), " ") -} diff --git a/00_Utilities/markdown_todo.py b/00_Utilities/markdown_todo.py index fa5d14c50..74e358c09 100644 --- a/00_Utilities/markdown_todo.py +++ b/00_Utilities/markdown_todo.py @@ -1,118 +1,50 @@ import os -from typing import Dict, List -def has_implementation(lang: str, file_list: List[str], subdir_list: List[str]) -> bool: - if lang == "csharp": - return any(file.endswith(".cs") for file in file_list) - elif lang == "vbnet": - return any(file.endswith(".vb") for file in file_list) - else: - return len(file_list) > 1 or len(subdir_list) > 0 +lang_pos = { + "csharp": 1, "java": 2, "javascript": 3, + "pascal": 4, "perl": 5, "python": 6, "ruby": 7, "vbnet": 8 +} +write_string = "# TODO list \n game | csharp | java | javascript | pascal | perl | python | ruby | vbnet \n --- | --- | --- | --- | --- | --- | --- | --- | --- \n" +# Set the directory you want to start from +rootDir = '..' -def get_data(checklist_orig: List[str], root_dir: str = "..") -> List[List[str]]: - """ +strings_done = [] - Parameters - ---------- - root_dir : str - The root directory you want to start from. - """ - lang_pos: Dict[str, int] = { - lang: i for i, lang in enumerate(checklist_orig[1:], start=1) - } - strings_done: List[List[str]] = [] +checklist = ["game", "csharp", "java", "javascript", + "pascal", "perl", "python", "ruby", "vbnet"] - ignore_folders = [ - ".git", - "00_Utilities", - ".github", - ".mypy_cache", - ".pytest_cache", - "00_Alternate_Languages", - "00_Common", - "buildJvm", - "htmlcov", - ] +prev_game = "" - prev_game = "" +for dirName, subdirList, fileList in os.walk(rootDir): + split_dir = dirName.split("/") - empty_boxes = ["⬜️" for _ in checklist_orig] - checklist = empty_boxes[:] + if len(split_dir) == 2 and not split_dir[1] in ['.git', '00_Utilities']: + if prev_game == "": + prev_game = split_dir[1] + checklist[0] = split_dir[1] - for dir_name, subdir_list, file_list in sorted(os.walk(root_dir)): - # split_dir[1] is the game - # split_dir[2] is the language - split_dir = dir_name.split(os.path.sep) + if prev_game != split_dir[1]: + # it's a new dir + strings_done.append(checklist) + checklist = [split_dir[1], "csharp", "java", "javascript", + "pascal", "perl", "python", "ruby", "vbnet"] + prev_game = split_dir[1] - if len(split_dir) == 2 and split_dir[1] not in ignore_folders: - if prev_game == "": - prev_game = split_dir[1] - checklist[0] = f"{split_dir[1]:<30}" - - if prev_game != split_dir[1]: - # it's a new dir - strings_done.append(checklist) - checklist = [ - f"{f'[{split_dir[1]}](../{split_dir[1]})':<30}", - ] + empty_boxes[1:] - prev_game = split_dir[1] - elif ( - len(split_dir) == 3 and split_dir[1] != ".git" and split_dir[2] in lang_pos - ): - out = ( - "✅" - if has_implementation(split_dir[2], file_list, subdir_list) - else "⬜️" - ) - if split_dir[2] not in lang_pos or lang_pos[split_dir[2]] >= len(checklist): - print(f"Could not find {split_dir[2]}: {dir_name}") + elif len(split_dir) == 3 and split_dir[1] != '.git': + if split_dir[2] in lang_pos.keys(): + if len(fileList) > 1 or len(subdirList) > 0: + # there is more files than the readme + checklist[lang_pos[split_dir[2]]] = "✅" + else: checklist[lang_pos[split_dir[2]]] = "⬜️" - continue - checklist[lang_pos[split_dir[2]]] = out - return strings_done - -def write_file(path: str, languages: List[str], strings_done: List[List[str]]) -> None: - dashes_arr = ["---"] * (len(languages) + 1) - dashes_arr[0] = "-" * 30 - dashes = " | ".join(dashes_arr) - write_string = f"# TODO list\n {'game':<30}| {' | '.join(languages)}\n{dashes}\n" - sorted_strings = list( - map(lambda l: " | ".join(l) + "\n", sorted(strings_done, key=lambda x: x[0])) - ) - write_string += "".join(sorted_strings) - write_string += f"{dashes}\n" - language_indices = range(1, len(languages) + 1) - nb_games = len(strings_done) - write_string += ( - f"{f'Sum of {nb_games}':<30} | " - + " | ".join( - [ - f"{sum(row[lang] == '✅' for row in strings_done)}" - for lang in language_indices - ] - ) - + "\n" - ) - with open(path, "w", encoding="utf-8") as f: - f.write(write_string) +sorted_strings = list(map(lambda l: " | ".join(l) + "\n", + sorted(strings_done, key=lambda x: x[0]))) +write_string += ''.join(sorted_strings) -if __name__ == "__main__": - languages = { - "csharp": "C#", - "java": "Java", - "javascript": "JS", - "kotlin": "Kotlin", - "lua": "Lua", - "perl": "Perl", - "python": "Python", - "ruby": "Ruby", - "rust": "Rust", - "vbnet": "VB.NET", - } - strings_done = get_data(["game"] + list(languages.keys())) - write_file("TODO.md", list(languages.values()), strings_done) +with open("README.md", "w") as f: + f.write(write_string) diff --git a/00_Utilities/markdown_todo_rust/Cargo.toml b/00_Utilities/markdown_todo_rust/Cargo.toml deleted file mode 100644 index ff21c377b..000000000 --- a/00_Utilities/markdown_todo_rust/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "markdown_todo_rust" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] diff --git a/00_Utilities/markdown_todo_rust/src/main.rs b/00_Utilities/markdown_todo_rust/src/main.rs deleted file mode 100644 index 9df645677..000000000 --- a/00_Utilities/markdown_todo_rust/src/main.rs +++ /dev/null @@ -1,277 +0,0 @@ -use std::ffi::OsStr; -use std::{fs, io}; -use std::fs::metadata; -use std::path::{Path, PathBuf}; -/** - * todo list generator for this repository, coded in rust - * - * @author Anthony Rubick - */ - -//DATA -const ROOT_DIR: &str = "../../"; -const LANGUAGES: [(&str,&str); 10] = [ //first element of tuple is the language name, second element is the file extension - ("csharp", "cs"), - ("java", "java"), - ("javascript", "html"), - ("kotlin", "kt"), - ("lua", "lua"), - ("perl", "pl"), - ("python", "py"), - ("ruby", "rb"), - ("rust", "rs"), - ("vbnet", "vb") -]; -const OUTPUT_PATH: &str = "../../todo.md"; - -fn main() { - //DATA - let mut root_folders:Vec; - let mut output_string: String = String::new(); - let format_game_first: bool; - let ingore: [PathBuf;5] = [ - PathBuf::from(r"../../.git"), - PathBuf::from(r"../../.github"), - PathBuf::from(r"../../00_Alternate_Languages"), - PathBuf::from(r"../../00_Utilities"), - PathBuf::from(r"../../00_Common"), - ]; //folders to ignore - - //print welcome message - println!(" - Markdown TODO list maker - by Anthony Rubick for the basic-computer-games repo - - - "); - - - //ask user how they want the todo list formatted - format_game_first = get_yn_from_user("\n\t---====FORMATS====---\ngame first:\n\tGame\n\t\tLanguage ✅/⬜️\n\nlang first:\n\tLanguage\n\t\tGame ✅/⬜️\n\nmake todo list using the game first format? (y/n | default No) "); - - //get all folders in ROOT_DIR - root_folders = Vec::new(); - match fs::read_dir(ROOT_DIR) { - Err(why) => { - println!("! {:?}", why.kind()); - panic!("error"); - }, - Ok(paths) => { - for path in paths { - let full_path = path.unwrap().path(); - if metadata(&full_path).unwrap().is_dir() { - root_folders.push(full_path); - } - } - }, - } - - //for i in root_folders {println!("> {:?}", &i);} - - //for all folders, search for the languages and extensions - root_folders = root_folders.into_iter().filter(|path| { - //not one of the ignored folders - !ingore.contains(path) - }).collect(); - root_folders.sort(); - - //create todo list - if format_game_first { - //being forming output string - // for every game - // every language + ✅/⬜️ - for g in root_folders.into_iter() { - //DATA - let mut num_done:u8 = 0; //number of languages implemented - let mut total:u8 = 0; //number of languages - - let game = g.clone().into_os_string().into_string().unwrap().chars().filter(|c| !(*c=='.' || *c=='/')).collect::();//get the game name - - - //find all the lanuages the game is coded in - let languages_list_for_game = { - let mut s:String = String::new(); - //every language + ✅/⬜️ - LANGUAGES.iter().for_each(|lang| { - s+="- "; - s += lang.0; - // + ✅/⬜️ - let paths:Vec<_> = list_files(&g).into_iter().map(|path| path.into_os_string().into_string().unwrap()).collect(); - let paths:Vec = paths.into_iter().filter_map(|s| { - match Path::new(s.as_str()).extension().and_then(OsStr::to_str) { - None => None, - Some(s) => Some(s.to_string()), - } - }).collect(); //get all the extensions - if paths.into_iter().any(|f| f.eq(lang.1)) {//list_files(&game).iter().map(|path| path.into_os_string().into_string().unwrap()).any(|s| LANGUAGES.iter().map(|tup| Some(tup.1)).collect::>().contains(&s.split('.').next())) { - s+="✅"; - num_done += 1; //increment number done - } else { - s += "⬜️"; - } - total += 1; //increment total - - s += "\n"; - }); - s - }; - - //format message - output_string += format!( - "### {}\t{}\n\n{}\n", //message format - game, - format!("coded in {}/{} languages", num_done, total), - languages_list_for_game, - ).as_str(); - } - - //print the whole list - println!("\n\n{}", output_string); - } - else { - //figure out what langauges the user wants printed - - //print language - extension table - println!("\n\t---====LANGUAGES TO PRINT====---\na complete todo list will be output to todo-list.md\n"); - print_lang_extension_table(); - - //prompt user to input the file extensions of the languages they want the todo-lists for printed to console - //parse input for valid languages, store them in langs_to_print - let langs_to_print = get_str_from_user("\nenter the file extensions, from the table above,\nfor the languages you want printed to standard output\nFile extensions: (separated by spaces)") - .chars().filter(|c| c.is_ascii_alphabetic() || c.is_whitespace()).collect::();//filter out everything but ascii letters and spaces - let langs_to_print: Vec<_> = langs_to_print.split(' ')//create an iterator with all the words - .filter(|s| LANGUAGES.iter().any(|tup| tup.1.eq_ignore_ascii_case(*s))) //filter out words that aren't valid extensions (in languages) - .collect(); //collect words into vector - println!("\nwill print: {:#?}\n\n", langs_to_print); - - - //being forming output string - // for every language - // every game + ✅/⬜️ - for lang in LANGUAGES.iter() { - //DATA - let mut num_done = 0; - let mut total = 0; - let games_list_for_language = { //list - //DATA - let mut s:String = String::new(); - - //go through every game and check if it's coded in the language - for g in (&root_folders).into_iter() { - //data - let game = g.clone(); - let game_name = game.into_os_string().into_string().unwrap().chars().filter(|c| !(*c=='.' || *c=='/')).collect::(); //get the game name - let paths:Vec<_> = list_files(g).into_iter().map(|path| path.into_os_string().into_string().unwrap()).collect(); //all subpaths of game - let paths:Vec = paths.into_iter().filter_map(|s| { - match Path::new(s.as_str()).extension().and_then(OsStr::to_str) { - None => None, - Some(s) => Some(s.to_string()), - } - }).collect(); //get all the extensions - - //add game name - s+="- "; - s+= game_name.as_str(); - - //every game + ✅/⬜️ - if paths.into_iter().any(|f| f.eq(lang.1)) { - s+="✅"; - num_done += 1; //increment num done - } else { - s += "⬜️"; - } - total += 1; //increment total - - //new line - s += "\n"; - } - - //print desired languages only, what's output to std_out, also not markdown formatted - if langs_to_print.contains(&lang.1) { - print!("### {}\t{} ###\n{}\n\n", lang.0, format!("{}/{} games ported", num_done, total), s); - } - s - }; - - //format message, what's output to the file - output_string += format!( - "### {}\t{}\n\n{}\n\n", //message format - lang.0, //language - format!("{}/{} games ported", num_done, total),//number done / total number - games_list_for_language, - ).as_str(); - } - } - - //write output to file - fs::write(OUTPUT_PATH, output_string).expect("failed to write todo list"); -} - -/** - * print language - extension table - */ -fn print_lang_extension_table() { - println!("LANGUAGE\tFILE EXTENSION"); - println!("========\t=============="); - for tup in LANGUAGES.iter() { - match tup.0 { - "javascript" => println!("{}\t{}", tup.0,tup.1), //long ones - _ => println!("{}\t\t{}", tup.0,tup.1), - }; - } -} - -/** - * gets a string from user input - */ -fn get_str_from_user(prompt:&str) -> String { - //DATA - let mut raw_input = String::new(); - - //print prompt - println!("{}",prompt); - - //get input and trim whitespaces - io::stdin().read_line(&mut raw_input).expect("Failed to read input"); - - //return raw input - return raw_input.trim().to_string(); -} -/** - * gets a boolean from user - */ -fn get_yn_from_user(prompt:&str) -> bool { - //DATA - let input = get_str_from_user(prompt); - - //default in case of error - if input.is_empty() {return false;} - - //get and parse input - match &input[0..1] { //get first character - "y" | "Y" => return true, - _ => return false, - } -} - -/** - * returns a vector containing paths to all files in path and subdirectories of path - */ -fn list_files(path: &Path) -> Vec { - let mut vec = Vec::new(); - _list_files(&mut vec,&path); - vec -} -fn _list_files(vec: &mut Vec, path: &Path) { - if metadata(&path).unwrap().is_dir() { - let paths = fs::read_dir(&path).unwrap(); - for path_result in paths { - let full_path = path_result.unwrap().path(); - if metadata(&full_path).unwrap().is_dir() { - _list_files(vec, &full_path); - } else { - vec.push(full_path); - } - } - } -} diff --git a/00_Utilities/python/ci-requirements.in b/00_Utilities/python/ci-requirements.in deleted file mode 100644 index eaa0bc146..000000000 --- a/00_Utilities/python/ci-requirements.in +++ /dev/null @@ -1,5 +0,0 @@ -flake8 -flake8-bugbear -flake8-comprehensions -flake8_implicit_str_concat -mypy diff --git a/00_Utilities/python/ci-requirements.txt b/00_Utilities/python/ci-requirements.txt deleted file mode 100644 index 0ba583b15..000000000 --- a/00_Utilities/python/ci-requirements.txt +++ /dev/null @@ -1,37 +0,0 @@ -# -# This file is autogenerated by pip-compile with python 3.10 -# To update, run: -# -# pip-compile ci-requirements.in -# -attrs==20.3.0 - # via - # flake8-bugbear - # flake8-implicit-str-concat -flake8==4.0.1 - # via - # -r ci-requirements.in - # flake8-bugbear - # flake8-comprehensions -flake8-bugbear==22.1.11 - # via -r ci-requirements.in -flake8-comprehensions==3.8.0 - # via -r ci-requirements.in -flake8-implicit-str-concat==0.2.0 - # via -r ci-requirements.in -mccabe==0.6.1 - # via flake8 -more-itertools==8.12.0 - # via flake8-implicit-str-concat -mypy==0.931 - # via -r ci-requirements.in -mypy-extensions==0.4.3 - # via mypy -pycodestyle==2.8.0 - # via flake8 -pyflakes==2.4.0 - # via flake8 -tomli==2.0.1 - # via mypy -typing-extensions==4.1.1 - # via mypy diff --git a/00_Utilities/yatol.pl b/00_Utilities/yatol.pl deleted file mode 100755 index 11825a65d..000000000 --- a/00_Utilities/yatol.pl +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/perl -#YATOL: Yet Another TOdo List -use strict; - -#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; - -my $Row=25; -my $Tab=7; - -printf("%-$Row\s", "PATH"); -printf("%$Tab\s", "BAS"); - -foreach my $Dir (@Langs) { - printf("%$Tab\s", $Dir); - } -print "\n"; - -my $Count; -foreach my $Lin (@Ret) { - $Count++; - chomp $Lin; - my ($Num, $File)= split (" ", $Lin); - my @Parts= split(/\//, $File); - my $Base= $Parts[1]; - - 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) { printf("%$Tab\s", "YES"); $Sum{$Dir}++; } - else { printf("%$Tab\s", " ");} - } - print "\n"; - } - - -printf("%$Row\s", "FILES:"); -printf("%$Tab\s", " "); -foreach my $Dir (@Dirs) { - printf("%$Tab\s", "$Sum{$Dir}"); - } -print "\n"; - -printf("%$Row\s", "ADVANCE:"); -printf("%$Tab\s", " "); -foreach my $Dir (@Dirs) { - my $Per= int($Sum{$Dir}/$Count*100)."%"; - printf("%$Tab\s", "$Per"); - } -print "\n"; diff --git a/01_Acey_Ducey/README.md b/01_Acey_Ducey/README.md index 0fabfb087..f8e16312b 100644 --- a/01_Acey_Ducey/README.md +++ b/01_Acey_Ducey/README.md @@ -15,14 +15,6 @@ As published in Basic Computer Games (1978): Downloaded from Vintage Basic at http://www.vintage-basic.net/games.html -#### Known Bugs - -- Entering a negative bet allows you to gain arbitrarily large amounts of money upon losing the round. - -#### Porting Notes - -- The assignment `N = 100` in line 100 has no effect; variable `N` is not used anywhere else in the program. - #### 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 diff --git a/01_Acey_Ducey/csharp/GameState.cs b/01_Acey_Ducey/csharp/GameState.cs index 0a4c587d7..5f8ccbcf8 100644 --- a/01_Acey_Ducey/csharp/GameState.cs +++ b/01_Acey_Ducey/csharp/GameState.cs @@ -9,7 +9,7 @@ namespace AceyDucey ///
    internal class GameState { - + /// /// How much money does the player have at the moment? /// diff --git a/00_Alternate_Languages/01_Acey_Ducey/d/.gitignore b/01_Acey_Ducey/d/.gitignore similarity index 100% rename from 00_Alternate_Languages/01_Acey_Ducey/d/.gitignore rename to 01_Acey_Ducey/d/.gitignore diff --git a/00_Alternate_Languages/01_Acey_Ducey/d/README.md b/01_Acey_Ducey/d/README.md similarity index 100% rename from 00_Alternate_Languages/01_Acey_Ducey/d/README.md rename to 01_Acey_Ducey/d/README.md diff --git a/00_Alternate_Languages/01_Acey_Ducey/d/aceyducey.d b/01_Acey_Ducey/d/aceyducey.d similarity index 99% rename from 00_Alternate_Languages/01_Acey_Ducey/d/aceyducey.d rename to 01_Acey_Ducey/d/aceyducey.d index a2c6ba3f8..036786c56 100644 --- a/00_Alternate_Languages/01_Acey_Ducey/d/aceyducey.d +++ b/01_Acey_Ducey/d/aceyducey.d @@ -55,7 +55,7 @@ void main() { writeln("YOU WIN!!!"); cash += bet; - } + } else { writeln("Sorry, you lose."); diff --git a/00_Alternate_Languages/01_Acey_Ducey/d/aceyducey_literal.d b/01_Acey_Ducey/d/aceyducey_literal.d similarity index 100% rename from 00_Alternate_Languages/01_Acey_Ducey/d/aceyducey_literal.d rename to 01_Acey_Ducey/d/aceyducey_literal.d diff --git a/01_Acey_Ducey/elixir/acey_ducey.exs b/01_Acey_Ducey/elixir/acey_ducey.exs deleted file mode 100644 index 31308df78..000000000 --- a/01_Acey_Ducey/elixir/acey_ducey.exs +++ /dev/null @@ -1,97 +0,0 @@ -######################################################## -# -# Acey Ducey -# -# From: BASIC Computer Games (1978) -# Edited by David Ahl -# -# "This is a simulation of the Acey Ducey card game. -# In the game, the dealer (the computer) deals two -# cards face up. You have an option to bet or not to -# bet depending on whether or not you feel the next -# card dealt will have a value between the first two. -# -# "Your initial money is set to $100. The game keeps -# going on until you lose all your money or interrupt -# the program. -# -# "The original BASIC program author was Bill Palmby -# of Prairie View, Illinois." -# -# To run this file: -# > mix run acey_ducey.exs --no-mix-exs -# -# This uses the following techniques: -# -# - The `Game` module uses a recursive `play/1` function. -# - The `Game` module stores the game state in a `%Game{}` struct. -# - The classic 52 playing card deck is set as a module attribute generated via a comprehension. -# - The deck is automatically shuffled when there are less than 3 cards remaining in the deck. -# - The initial deck defaults to an empty list which triggers a shuffle when the game begins. -# - The initial funds defaults to 100 but it can be explicitly set in the `%Game{}` struct. -# - The prompt to place a bet will automatically re-prompt when given an invalid input. -# - The bets are assumed to be the whole integers for simplicity. -# -######################################################## - -defmodule Game do - @deck for suit <- [:spades, :hearts, :clubs, :diamonds], value <- 1..13, do: {suit, value} - - defstruct funds: 100, deck: [] - - def play(), do: play(%__MODULE__{}) # for convenience - - def play(%__MODULE__{funds: funds}) when funds <= 0, do: IO.puts("~~~ game over ~~~") - def play(%__MODULE__{deck: deck} = game) when length(deck) < 3, do: play(%{game | deck: Enum.shuffle(@deck)}) - def play(%__MODULE__{deck: deck, funds: funds} = game) do - IO.gets("\n") - - [first_card, second_card, third_card | remaining_deck] = deck - - IO.puts("~~~ new round ~~~") - IO.puts("first card: #{format(first_card)}") - IO.puts("second card: #{format(second_card)}\n") - IO.puts("funds: $#{funds}") - - bet = prompt_to_place_bet(funds) - new_funds = if win?(first_card, second_card, third_card), do: funds + bet, else: funds - bet - - IO.puts("\nthird card: #{format(third_card)}") - IO.puts("funds: $#{funds} => $#{new_funds}") - IO.puts("~~~ end round ~~~\n") - - play(%{game | deck: remaining_deck, funds: new_funds}) - end - - # re-prompt if invalid integer and/or out of bounds - defp prompt_to_place_bet(funds) do - input = IO.gets("place your bet: $") - case Integer.parse(input) do - {bet, _} when bet in 0..funds -> bet - _ -> prompt_to_place_bet(funds) - end - end - - # for a stricter win condition (non-inclusive) - defp win?({_, first}, {_, second}, {_, third}) do - [floor, ceiling] = Enum.sort([first, second]) - (floor < third) && (third < ceiling) - end - # for a looser win condition (inclusive) - #defp win?({_, first}, {_, second}, {_, third}) do - #[_, middle, _] = Enum.sort([first, second, third]) - #middle == third - #end - - defp format({suit, value}) do - case value do - 1 -> "ace of #{suit}" - 11 -> "prince of #{suit}" - 12 -> "queen of #{suit}" - 13 -> "king of #{suit}" - value -> "#{value} of #{suit}" - end - end -end - -Game.play() # equivalent to Game.play(%Game{funds: 100, deck: 100}) diff --git a/01_Acey_Ducey/java/src/AceyDucey.java b/01_Acey_Ducey/java/src/AceyDucey.java index d0cccb0a9..d53c0d050 100644 --- a/01_Acey_Ducey/java/src/AceyDucey.java +++ b/01_Acey_Ducey/java/src/AceyDucey.java @@ -169,4 +169,4 @@ public void intro() { System.out.println("A VALUE BETWEEN THE FIRST TWO."); System.out.println("IF YOU DO NOT WANT TO BET, INPUT: 0"); } -} +} \ No newline at end of file diff --git a/01_Acey_Ducey/java/src/AceyDucey17.java b/01_Acey_Ducey/java/src/AceyDucey17.java index bb62fdafe..6192fc14a 100644 --- a/01_Acey_Ducey/java/src/AceyDucey17.java +++ b/01_Acey_Ducey/java/src/AceyDucey17.java @@ -15,8 +15,8 @@ public static void main(String[] args) { 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 diff --git a/01_Acey_Ducey/java/src/AceyDuceyGame.java b/01_Acey_Ducey/java/src/AceyDuceyGame.java index 787c92e67..1ce08c284 100644 --- a/01_Acey_Ducey/java/src/AceyDuceyGame.java +++ b/01_Acey_Ducey/java/src/AceyDuceyGame.java @@ -18,4 +18,4 @@ public static void main(String[] args) { keepPlaying = game.playAgain(); } while (keepPlaying); } -} +} \ No newline at end of file diff --git a/01_Acey_Ducey/javascript/aceyducey.html b/01_Acey_Ducey/javascript/aceyducey.html index c3c4ef451..61c362a70 100644 --- a/01_Acey_Ducey/javascript/aceyducey.html +++ b/01_Acey_Ducey/javascript/aceyducey.html @@ -1,9 +1,7 @@ - + + ACEY DUCEY - - - +
    
     
    -
    \ No newline at end of file
    diff --git a/01_Acey_Ducey/javascript/aceyducey.js b/01_Acey_Ducey/javascript/aceyducey.js
    index 89838f0a6..9969ebbf5 100644
    --- a/01_Acey_Ducey/javascript/aceyducey.js
    +++ b/01_Acey_Ducey/javascript/aceyducey.js
    @@ -99,7 +99,7 @@ async function main() {
                     }
                 }
             }
    -        if (bet == 0)
    +        if (bet == 0) 
             {
                 // User chose not to bet.
                 print('CHICKEN!!');
    diff --git a/01_Acey_Ducey/kotlin/aceyducey.kt b/01_Acey_Ducey/kotlin/aceyducey.kt
    deleted file mode 100644
    index fe7c32c7e..000000000
    --- a/01_Acey_Ducey/kotlin/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!")
    -}
    diff --git a/01_Acey_Ducey/lua/README.md b/01_Acey_Ducey/lua/README.md
    deleted file mode 100644
    index 6fa5c47c8..000000000
    --- a/01_Acey_Ducey/lua/README.md
    +++ /dev/null
    @@ -1,6 +0,0 @@
    -As published in Basic Computer Games (1978), as found at Annarchive:
    -- [Annarchive](https://annarchive.com/files/Basic_Computer_Games_Microcomputer_Edition.pdf#page=17)
    -
    -
    -Conversion to Lua
    -- [Lua.org](https://www.lua.org)
    diff --git a/01_Acey_Ducey/lua/acey_ducey.lua b/01_Acey_Ducey/lua/acey_ducey.lua
    deleted file mode 100644
    index 7a96edde0..000000000
    --- a/01_Acey_Ducey/lua/acey_ducey.lua
    +++ /dev/null
    @@ -1,100 +0,0 @@
    -print [[
    -            ACEY DUCEY CARD GAME
    - CREATIVE COMPUTING  MORRISTOWN, NEW JERSY
    -
    -
    -
    -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 OF NOT YOU FEEL THE CARD WILL HAVE
    -A VALUE BETWEEN THE FIRST TWO.
    -IF YOU DO NOT WANT TO BET INPUT A 0]]
    -
    -local starting_cash = 100
    -
    -local card_names = {[11] = "JACK", [12] = "QUEEN", [13] = "KING", [14] = "ACE"}
    -for i = 2, 10 do
    -  card_names[i] = string.format(" %d", i)
    -end
    -
    -function play_round(player_cash, skip_total)
    -  assert(player_cash > 0, "can't play with nothing to bet")
    -
    -  if not skip_total then
    -    print(string.format("YOU NOW HAVE %u DOLLARS", player_cash))
    -  end
    -
    -  print "\nHERE ARE YOUR NEXT TWO CARDS"
    -
    -  local first_card, second_card;
    -
    -  repeat
    -    first_card = math.random(2, 14)
    -    second_card = math.random(2, 14)
    -  until first_card < second_card
    -
    -  print(card_names[first_card])
    -  print(card_names[second_card])
    -  print("")
    -
    -  local bet = get_bet(player_cash)
    -
    -  if bet == 0 then
    -    print "CHICKEN!!"
    -    return play_round(player_cash, "skip total")
    -  end
    -
    -  local third_card = math.random(2, 14)
    -  print(card_names[third_card])
    -
    -  if first_card < third_card and third_card < second_card then
    -    print "YOU WIN!!!"
    -    return play_round(player_cash + bet)
    -  end
    -
    -  print "SORRY, YOU LOSE"
    -  if bet < player_cash then
    -    return play_round(player_cash - bet)
    -  end
    -
    -  print "SORRY, FRIEND BUT YOU BLEW YOUR WAD"
    -  io.write "TRY AGAIN (YES OR NO)? "
    -  local keep_playing = io.read("l")
    -  if keep_playing:upper():match("%f[%a]YES%f[^%a]") then
    -    return play_round(starting_cash)
    -  end
    -
    -  print "OK HOPE YOU HAD FUN"
    -end
    -
    -function get_bet(player_cash)
    -  assert(player_cash > 0, "can't play with nothing to bet")
    -
    -  io.write("WHAT IS YOUR BET? ")
    -  local input = io.read("l")
    -  if not input then
    -    print "GOODBYE"
    -    os.exit(0)
    -  end
    -
    -  local digits = input:match("(%d+)")
    -  if not digits then
    -    print "I DON'T UNDERSTAND THAT NUMBER"
    -    return get_bet(player_cash)
    -  end
    -
    -  local bet = tonumber(digits)
    -  assert(bet, "pattern matched something that doesn't convert to number")
    -
    -  if bet > player_cash then
    -    print "SORRY, MY FRIEND BUT YOU BET TOO MUCH"
    -    print(string.format("YOU HAVE ONLY %u DOLLARS TO BET", player_cash))
    -    return get_bet(player_cash)
    -  end
    -
    -  assert(0 <= bet and bet <= player_cash, "invalid bet")
    -  return bet
    -end
    -
    -play_round(starting_cash)
    diff --git a/00_Alternate_Languages/01_Acey_Ducey/pascal/.gitattributes b/01_Acey_Ducey/pascal/.gitattributes
    similarity index 100%
    rename from 00_Alternate_Languages/01_Acey_Ducey/pascal/.gitattributes
    rename to 01_Acey_Ducey/pascal/.gitattributes
    diff --git a/00_Alternate_Languages/01_Acey_Ducey/pascal/.gitignore b/01_Acey_Ducey/pascal/.gitignore
    similarity index 100%
    rename from 00_Alternate_Languages/01_Acey_Ducey/pascal/.gitignore
    rename to 01_Acey_Ducey/pascal/.gitignore
    diff --git a/00_Alternate_Languages/01_Acey_Ducey/pascal/README.md b/01_Acey_Ducey/pascal/README.md
    similarity index 100%
    rename from 00_Alternate_Languages/01_Acey_Ducey/pascal/README.md
    rename to 01_Acey_Ducey/pascal/README.md
    diff --git a/00_Alternate_Languages/01_Acey_Ducey/pascal/object-pascal/aceyducey.lpi b/01_Acey_Ducey/pascal/object-pascal/aceyducey.lpi
    similarity index 100%
    rename from 00_Alternate_Languages/01_Acey_Ducey/pascal/object-pascal/aceyducey.lpi
    rename to 01_Acey_Ducey/pascal/object-pascal/aceyducey.lpi
    diff --git a/01_Acey_Ducey/pascal/object-pascal/aceyducey.pas b/01_Acey_Ducey/pascal/object-pascal/aceyducey.pas
    new file mode 100644
    index 000000000..9e72952b6
    --- /dev/null
    +++ b/01_Acey_Ducey/pascal/object-pascal/aceyducey.pas
    @@ -0,0 +1,19 @@
    +program aceyducey;
    +
    +{$IFDEF FPC}
    +{$mode objfpc}{$H+}
    +{$ENDIF}
    +
    +uses
    +  Game
    +, Deck
    +;
    +
    +var
    +  Acey_Ducey: TGame;
    +
    +begin
    +  Acey_Ducey:= TGame.Create;
    +  Acey_Ducey.Run;
    +end.
    +
    diff --git a/00_Alternate_Languages/01_Acey_Ducey/pascal/object-pascal/deck.pas b/01_Acey_Ducey/pascal/object-pascal/deck.pas
    similarity index 99%
    rename from 00_Alternate_Languages/01_Acey_Ducey/pascal/object-pascal/deck.pas
    rename to 01_Acey_Ducey/pascal/object-pascal/deck.pas
    index c2f603c86..d5940fe28 100644
    --- a/00_Alternate_Languages/01_Acey_Ducey/pascal/object-pascal/deck.pas
    +++ b/01_Acey_Ducey/pascal/object-pascal/deck.pas
    @@ -108,3 +108,4 @@ function TDeck.PlayerWins: Boolean;
     end;
     
     end.
    +
    diff --git a/00_Alternate_Languages/01_Acey_Ducey/pascal/object-pascal/game.pas b/01_Acey_Ducey/pascal/object-pascal/game.pas
    similarity index 99%
    rename from 00_Alternate_Languages/01_Acey_Ducey/pascal/object-pascal/game.pas
    rename to 01_Acey_Ducey/pascal/object-pascal/game.pas
    index e49615419..1e983f7c0 100644
    --- a/00_Alternate_Languages/01_Acey_Ducey/pascal/object-pascal/game.pas
    +++ b/01_Acey_Ducey/pascal/object-pascal/game.pas
    @@ -133,3 +133,4 @@ procedure TGame.Run;
     end;
     
     end.
    +
    diff --git a/00_Alternate_Languages/01_Acey_Ducey/pascal/simple/aceyducey.lpi b/01_Acey_Ducey/pascal/simple/aceyducey.lpi
    similarity index 100%
    rename from 00_Alternate_Languages/01_Acey_Ducey/pascal/simple/aceyducey.lpi
    rename to 01_Acey_Ducey/pascal/simple/aceyducey.lpi
    diff --git a/01_Acey_Ducey/pascal/simple/aceyducey.pas b/01_Acey_Ducey/pascal/simple/aceyducey.pas
    new file mode 100644
    index 000000000..fa049eb0a
    --- /dev/null
    +++ b/01_Acey_Ducey/pascal/simple/aceyducey.pas
    @@ -0,0 +1,152 @@
    +program aceyducey;
    +
    +{$IFDEF FPC}
    +{$mode objfpc}{$H+}
    +{$ENDIF}
    +
    +uses
    + Crt;
    +
    +var
    +  Stash: Integer;
    +  CardA: Integer;
    +  CardB: Integer;
    +  CardC: Integer;
    +  Bet: Integer;
    +
    +procedure PrintGreeting;
    +begin
    +  WriteLN(' ':26, 'ACEY DUCEY CARD GAME');
    +  WriteLN(' ':15, 'CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY');
    +  WriteLN;
    +  WriteLN;
    +  WriteLN('ACEY-DUCEY IS PLAYED IN THE FOLLOWING MANNER ');
    +  WriteLN('THE DEALER (COMPUTER) DEALS TWO CARDS FACE UP');
    +  WriteLN('YOU HAVE AN OPTION TO BET OR NOT BET DEPENDING');
    +  WriteLN('ON WHETHER OR NOT YOU FEEL THE CARD WILL HAVE');
    +  WriteLN('A VALUE BETWEEN THE FIRST TWO.');
    +  WriteLN('IF YOU DO NOT WANT TO BET, INPUT A 0');
    +  WriteLN;
    +end;
    +
    +procedure PrintBalance;
    +begin
    +  WriteLN('YOU NOW HAVE ', Stash,' DOLLARS.');
    +  WriteLN;
    +end;
    +
    +procedure PrintCard(const ACard: Integer);
    +begin
    +  if ACard < 11 then
    +  begin
    +    Write(ACard);
    +  end;
    +  if ACard = 11 then
    +  begin
    +    Write('JACK');
    +  end;
    +  if ACard = 12 then
    +  begin
    +    Write('QUEEN');
    +  end;
    +  if ACard = 13 then
    +  begin
    +    Write('KING');
    +  end;
    +  if ACard = 14 then
    +  begin
    +    Write('ACE');
    +  end;
    +end;
    +
    +procedure DrawDealerCards;
    +var
    +  tmp: Integer;
    +begin
    +  Write('HERE ARE YOUR NEXT TWO CARDS: ');
    +  repeat
    +    CardA:= Random(14) + 2;
    +  until (CardA >= 2) and (CardA <= 14);
    +  repeat
    +    CardB:= Random(14) + 2;
    +  until (CardB >= 2) and (CardB <= 14) and (CardA <> CardB);
    +  if CardA > CardB then
    +  begin
    +    tmp:= CardB;
    +    CardB:= CardA;
    +    CardA:= tmp;
    +  end;
    +  PrintCard(CardA);
    +  Write(' ');
    +  PrintCard(CardB);
    +  WriteLN;
    +  WriteLN;
    +end;
    +
    +procedure DrawPlayerCard;
    +begin
    +  repeat
    +    CardC:= Random(14) + 2;
    +  until (CardC >= 2) and (CardC <= 14);
    +  PrintCard(CardC);
    +  WriteLN;
    +  WriteLN;
    +end;
    +
    +function GetBet: Integer;
    +begin
    +  Result:= 0;
    +  repeat
    +    Write('WHAT IS YOUR BET: ');
    +    ReadLN(Result);
    +    if Result > Stash then
    +    begin
    +      WriteLn('SORRY, MY FRIEND, BUT YOU BET TOO MUCH.');
    +      WriteLn('YOU HAVE ONLY ', Stash,' DOLLARS TO BET.');
    +    end;
    +  until (Result >=0) and (Result <= Stash);
    +end;
    +
    +function TryAgain: Boolean;
    +var
    +  answer: String;
    +begin
    +  Result:= False;
    +  Write('TRY AGAIN (YES OR NO)');
    +  ReadLn(answer);
    +  Result:= (LowerCase(answer)='yes') or (LowerCase(answer)='y');
    +end;
    +
    +begin
    +  Randomize;
    +  ClrScr;
    +  PrintGreeting;
    +  repeat
    +    Stash:= 100;
    +    repeat
    +      PrintBalance;
    +      DrawDealerCards;
    +      Bet:= GetBet;
    +      if Bet = 0 then
    +      begin
    +        WriteLN('CHICKEN!!');
    +        continue;
    +      end;
    +      DrawPlayerCard;
    +      if (CardC > CardA) and (CardC < CardB) then
    +      begin
    +        WriteLN('YOU WIN!!!');
    +        Inc(Stash, Bet)
    +      end
    +      else
    +      begin
    +        WriteLN('SORRY, YOU LOSE');
    +        Dec(Stash, Bet)
    +      end;
    +    until Stash = 0;
    +    WriteLN('SORRY, FRIEND, BUT YOU BLEW YOUR WAD.');
    +    WriteLN;
    +  until not TryAgain;
    +  WriteLN('O.K., HOPE YOU HAD FUN!');
    +end.
    +
    diff --git a/01_Acey_Ducey/python/acey_ducey.py b/01_Acey_Ducey/python/acey_ducey.py
    old mode 100755
    new mode 100644
    index e6dca6f21..8461dad1c
    --- a/01_Acey_Ducey/python/acey_ducey.py
    +++ b/01_Acey_Ducey/python/acey_ducey.py
    @@ -7,6 +7,7 @@
     import random
     
     cards = {
    +    1: "1",
         2: "2",
         3: "3",
         4: "4",
    @@ -15,26 +16,23 @@
         7: "7",
         8: "8",
         9: "9",
    -    10: "10",
    -    11: "Jack",
    -    12: "Queen",
    -    13: "King",
    -    14: "Ace",
    +    10: "Jack",
    +    11: "Queen",
    +    12: "King",
    +    13: "Ace",
     }
     
     
    -def play_game() -> None:
    +def play_game():
    +    """Play the game"""
         cash = 100
         while cash > 0:
             print(f"You now have {cash} dollars\n")
    -        print("Here are your next two cards")
    -        round_cards = list(cards.keys())  # gather cards from dictionary
    -        card_a = random.choice(round_cards)  # choose a card
    -        card_b = card_a  # clone the first card, so we avoid the same number for the second card
    -        while (card_a == card_b):  # if the cards are the same, choose another card
    -            card_b = random.choice(round_cards)
    -        card_c = random.choice(round_cards)  # choose last card
    -        if card_a > card_b:  # swap cards if card_a is greater than card_b
    +        print("Here are you next two cards")
    +        round_cards = list(cards.keys())
    +        random.shuffle(round_cards)
    +        card_a, card_b, card_c = round_cards.pop(), round_cards.pop(), round_cards.pop()
    +        if card_a > card_b:
                 card_a, card_b = card_b, card_a
             print(f" {cards[card_a]}")
             print(f" {cards[card_b]}\n")
    @@ -56,7 +54,7 @@ def play_game() -> None:
                     print("Please enter a positive number")
             print(f" {cards[card_c]}")
             if bet > 0:
    -            if card_a <= card_c <= card_b:
    +            if card_a < card_c < card_b:
                     print("You win!!!")
                     cash += bet * 2
                 else:
    @@ -65,7 +63,17 @@ def play_game() -> None:
         print("Sorry, friend, but you blew your wad")
     
     
    -def main() -> None:
    +def main():
    +    """Main"""
    +    keep_playing = True
    +
    +    while keep_playing:
    +        play_game()
    +        keep_playing = input("Try again? (yes or no) ").lower().startswith("y")
    +    print("Ok hope you had fun")
    +
    +
    +if __name__ == "__main__":
         print(
             """
     Acey-Ducey is played in the following manner
    @@ -76,14 +84,4 @@ def main() -> None:
     If you do not want to bet, input a 0
       """
         )
    -    keep_playing = True
    -
    -    while keep_playing:
    -        play_game()
    -        keep_playing = input("Try again? (yes or no) ").lower().startswith("y")
    -    print("Ok hope you had fun")
    -
    -
    -if __name__ == "__main__":
    -    random.seed()
         main()
    diff --git a/01_Acey_Ducey/python/acey_ducey_oo.py b/01_Acey_Ducey/python/acey_ducey_oo.py
    index cd5cad76f..3e05387f8 100644
    --- a/01_Acey_Ducey/python/acey_ducey_oo.py
    +++ b/01_Acey_Ducey/python/acey_ducey_oo.py
    @@ -1,48 +1,54 @@
    -"""
    -AceyDuchy
    -From: BASIC Computer Games (1978)
    -      Edited by David Ahl
    -"The original BASIC program author was Bill Palmby
    - of Prairie View, Illinois."
    -Python port by Aviyam Fischer, 2022
    -"""
    -
    -from typing import List, Literal, NamedTuple, TypeAlias, get_args
    -import random
    -
    -Suit: TypeAlias = Literal["\u2665", "\u2666", "\u2663", "\u2660"]
    -Rank: TypeAlias = Literal[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
    -
    -
    -class Card(NamedTuple):
    -    suit: Suit
    -    rank: Rank
    -
    -    def __str__(self) -> str:
    -        r = str(self.rank)
    -        r = {"11": "J", "12": "Q", "13": "K", "14": "A"}.get(r, r)
    -        return f"{r}{self.suit}"
    +#
    +# AceyDuchy
    +#
    +# From: BASIC Computer Games (1978)
    +#       Edited by David Ahl
    +#
    +# "The original BASIC program author was Bill Palmby
    +#  of Prairie View, Illinois."
    +#
    +# Python port by Aviyam Fischer, 2022
    +#
    +######################################################
    +
    +class Card:
    +    def __init__(self, suit, rank):
    +        self.suit = suit
    +        self.rank = rank
    +
    +    def __str__(self):
    +        r = self.rank
    +        if r == 11:
    +            r = 'J'
    +        elif r == 12:
    +            r = 'Q'
    +        elif r == 13:
    +            r = 'K'
    +        elif r == 14:
    +            r = 'A'
    +        return f'{r}{self.suit}'
     
     
     class Deck:
    -    def __init__(self) -> None:
    -        self.cards: List[Card] = []
    +    def __init__(self):
    +        self.cards = []
             self.build()
     
    -    def build(self) -> None:
    -        for suit in get_args(Suit):
    -            for rank in get_args(Rank):
    +    def build(self):
    +        for suit in ['\u2665', '\u2666', '\u2663', '\u2660']:
    +            for rank in range(2, 15):
                     self.cards.append(Card(suit, rank))
     
    -    def shuffle(self) -> None:
    +    def shuffle(self):
    +        import random
             random.shuffle(self.cards)
     
    -    def deal(self) -> Card:
    +    def deal(self):
             return self.cards.pop()
     
     
     class Game:
    -    def __init__(self) -> None:
    +    def __init__(self):
             self.deck = Deck()
             self.deck.shuffle()
             self.card_a = self.deck.deal()
    @@ -50,7 +56,7 @@ def __init__(self) -> None:
             self.money = 100
             self.not_done = True
     
    -    def play(self) -> None:
    +    def play(self):
             while self.not_done:
                 while self.money > 0:
                     card_a = self.card_a
    @@ -63,31 +69,34 @@ def play(self) -> None:
                         self.card_b = self.deck.deal()
                         card_b = self.card_b
     
    -                print(f"You have:\t ${self.money} ")
    -                print(f"Your cards:\t {card_a} {card_b}")
    +                print(f'You have:\t ${self.money} ')
    +                print(f'Your cards:\t {card_a} {card_b}')
     
    -                bet = int(input("What is your bet? "))
    +                bet = int(input('What is your bet? '))
                     player_card = self.deck.deal()
                     if 0 < bet <= self.money:
     
    -                    print(f"Your deal:\t {player_card}")
    -                    if card_a.rank <= player_card.rank <= card_b.rank:
    -                        print("You Win!")
    +                    print(f'Your deal:\t {player_card}')
    +                    if card_a.rank < player_card.rank < card_b.rank:
    +                        print('You Win!')
                             self.money += bet
                         else:
    -                        print("You Lose!")
    +                        print('You Lose!')
                             self.money -= bet
                             self.not_done = False
                     else:
    -                    print("Chicken!")
    -                    print(f"Your deal should have been: {player_card}")
    +                    print('Chicken!')
    +                    print(f'Your deal should have been: {player_card}')
                         if card_a.rank < player_card.rank < card_b.rank:
    -                        print("You could have won!")
    +                        print(f'You could have won!')
                         else:
    -                        print("You would lose, so it was wise of you to chicken out!")
    +                        print(f'You would lose, so it was wise of you to chicken out!')
    +
    +                    self.not_done = False
    +                    break
     
                     if len(self.deck.cards) <= 3:
    -                    print("You ran out of cards. Game over.")
    +                    print('You ran out of cards. Game over.')
                         self.not_done = False
                         break
     
    @@ -98,32 +107,22 @@ def play(self) -> None:
                 self.not_done = False
     
     
    -def game_loop() -> None:
    -    game_over = False
    -
    -    while not game_over:
    -        game = Game()
    -        game.play()
    -        print(f"You have ${game.money} left")
    -        print("Would you like to play again? (y/n)")
    -        if input() == "n":
    -            game_over = True
    -
    -
    -def main() -> None:
    -    print(
    -        """
    +if __name__ == '__main__':
    +    print(''' 
         Acey Ducey is a card game where you play against the computer.
         The Dealer(computer) will deal two cards facing up.
    -    You have an option to bet or not bet depending on whether or not you
    +    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
    -    """
    -    )
    -    game_loop()
    -    print("\nThanks for playing!")
    +    ''')
    +    GAME_OVER = False
     
    +    while not GAME_OVER:
    +        game = Game()
    +        game.play()
    +        print(f'You have ${game.money} left')
    +        print('Would you like to play again? (y/n)')
    +        if input() == 'n':
    +            GAME_OVER = True
     
    -if __name__ == "__main__":
    -    random.seed()
    -    main()
    +    print('\nThanks for playing!')
    diff --git a/01_Acey_Ducey/python/aceyducey.py b/01_Acey_Ducey/python/aceyducey.py
    new file mode 100644
    index 000000000..871471811
    --- /dev/null
    +++ b/01_Acey_Ducey/python/aceyducey.py
    @@ -0,0 +1,206 @@
    +"""aceyducey.py contains game code"""
    +########################################################
    +#
    +# Acey Ducey
    +#
    +# From: BASIC Computer Games (1978)
    +#       Edited by David Ahl
    +#
    +# "This is a simulation of the Acey Ducey card game.
    +#  In the game, the dealer (the computer) deals two
    +#  cards face up.  You have an option to bet or not to
    +#  bet depending on whether or not you feel the next
    +#  card dealt will have a value between the first two.
    +#
    +# "Your initial money is set to $100. The game keeps
    +#  going on until you lose all your money or interrupt
    +#  the program.
    +#
    +# "The original BASIC program author was Bill Palmby
    +#  of Prairie View, Illinois."
    +#
    +# Python port by Jeff Jetton, 2019
    +#
    +########################################################
    +
    +
    +import random
    +
    +# "You may alter [the following statement] if you want
    +#  to start with more or less than $100."
    +DEFAULT_BANKROLL = 100
    +
    +# functions
    +def deal_card_num():
    +    """Get card number"""
    +    return random.randint(0, 12)
    +
    +
    +def get_card_name(number):
    +    """Get card name"""
    +    card_names = (
    +        " 2",
    +        " 3",
    +        " 4",
    +        " 5",
    +        " 6",
    +        " 7",
    +        " 8",
    +        " 9",
    +        " 10",
    +        "Jack",
    +        "Queen",
    +        "King",
    +        "Ace",
    +    )
    +    return card_names[number]
    +
    +
    +def display_bankroll(bank_roll):
    +    """Print current bankroll"""
    +    if BANK_ROLL > 0:
    +        print("You now have %s dollars\n" % bank_roll)
    +
    +
    +# Display initial title and instructions
    +print("\n           Acey Ducey Card Game")
    +print("Creative Computing  Morristown, New Jersey")
    +print("\n\n")
    +print("Acey-Ducey is played in the following manner")
    +print("The dealer (computer) deals two cards face up")
    +print("You have an option to bet or not bet depending")
    +print("on whether or not you feel the card will have")
    +print("a value between the first two.")
    +print("If you do not want to bet, input a 0")
    +
    +
    +# Loop for series of multiple games
    +KEEP_PLAYING = True
    +while KEEP_PLAYING:
    +
    +    # Initialize bankroll at start of each game
    +    BANK_ROLL = DEFAULT_BANKROLL
    +    display_bankroll(BANK_ROLL)
    +
    +    # Loop for a single round.  Repeat until out of money.
    +    while BANK_ROLL > 0:
    +
    +        # Deal out dealer cards
    +        print("Here are your next two cards")
    +        dealer1 = deal_card_num()
    +        # If the cards match, we redeal 2nd card until they don't
    +        dealer2 = dealer1
    +        while dealer1 == dealer2:
    +            dealer2 = deal_card_num()
    +        # Organize the cards in order if they're not already
    +        if dealer1 >= dealer2:
    +            (dealer1, dealer2) = (dealer2, dealer1)  # Ya gotta love Python!
    +        # Show dealer cards to the player
    +        # (use card name rather than internal number)
    +        print(get_card_name(dealer1))
    +        print(get_card_name(dealer2) + "\n")
    +
    +        # Get and handle player bet choice
    +        BET_IS_VALID = False
    +        while not BET_IS_VALID:
    +            curr_bet = input("What is your bet? ")
    +            try:
    +                curr_bet = int(curr_bet)
    +            except ValueError:
    +                # Bad input? Just loop back up and ask again...
    +                pass
    +            else:
    +                if curr_bet == 0:
    +                    BET_IS_VALID = True
    +                    print("Chicken!!\n")
    +                elif curr_bet > BANK_ROLL:
    +                    print("Sorry, my friend but you bet too much")
    +                    print("You have only %s dollars to bet\n" % BANK_ROLL)
    +                else:
    +                    # Deal player card
    +                    BET_IS_VALID = True
    +                    player = deal_card_num()
    +                    print(get_card_name(player))
    +
    +                    # Did we win?
    +                    if dealer1 < player < dealer2:
    +                        print("You win!!!")
    +                        BANK_ROLL += curr_bet
    +                    else:
    +                        print("Sorry, you lose")
    +                        BANK_ROLL -= curr_bet
    +
    +                    # Update player on new bankroll level
    +                    display_bankroll(BANK_ROLL)
    +
    +    # End of loop for a single round
    +
    +    print("\n\nSorry, friend but you blew your wad")
    +    player_response = input("Try again (yes or no) ")
    +    if player_response.lower() == "yes":
    +        print()
    +    else:
    +        KEEP_PLAYING = False
    +
    +# End of multiple game loop
    +
    +print("OK Hope you had fun\n")
    +
    +
    +########################################################
    +#
    +# Porting notes:
    +#
    +#   The original BASIC version had a variable named N
    +#   that was initialized to 100 and then never used.
    +#   Maybe it did something in feature that was edited
    +#   out of the final version used in the book?
    +#
    +#   The original program simply generated random numbers
    +#   for each card.  It did not simulate a true card deck,
    +#   where the dealing of a card eliminates it from the
    +#   deck and reduces the chances of the same value
    +#   being drawn.  This "infinite deck" logic (or "deal,
    +#   with replacement after") has NOT been changed.
    +#
    +#   In the interests of historical fidelity, the bug
    +#   in the original BASIC listing that let you input a
    +#   negative bet value has been faithfully reproduced.
    +#   This lets the player lose money when they win and
    +#   earn money when they lose! :-)
    +#
    +#
    +# Ideas for Modifications
    +#
    +#   Give the user the ability to quit the game, perhaps
    +#   by typing "quit" instead of making a bet.  Provide a
    +#   final assessment based on how much of the original
    +#   bankroll they have left.
    +#
    +#   Or have the game run for a set number of rounds or
    +#   until a certain bankroll goal is attained.
    +#
    +#   Implement an "ante"--a set amount the player has to
    +#   bet each time rather than having the option to lay
    +#   out entirely.
    +#
    +#   See "porting notes" above about negative bet values.
    +#   How would you fix this?
    +#
    +#   When the player "chickens out", show them what the
    +#   next card would've been and point out whether they
    +#   made a good or bad decision.
    +#
    +#   In what situations are the odds of winning high
    +#   enough to justify making a bet? Create a cheat mode
    +#   where the program identifies these situations and
    +#   lets the player know.
    +#
    +#   Change the card dealing to simulate deals from a
    +#   single deck (or a user-selectable number of decks).
    +#
    +#   Implement a two-player mode where players take turns
    +#   betting (or both bet on the same dealer cards and
    +#   get their own player card dealt).
    +#
    +########################################################
    diff --git a/01_Acey_Ducey/rust/Cargo.lock b/01_Acey_Ducey/rust/Cargo.lock
    deleted file mode 100644
    index 4fe2abbea..000000000
    --- a/01_Acey_Ducey/rust/Cargo.lock
    +++ /dev/null
    @@ -1,75 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.10"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.147"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/01_Acey_Ducey/rust/Cargo.toml b/01_Acey_Ducey/rust/Cargo.toml
    deleted file mode 100644
    index 3b1d02f52..000000000
    --- a/01_Acey_Ducey/rust/Cargo.toml
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -[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/README.md b/01_Acey_Ducey/rust/README.md
    deleted file mode 100644
    index 916a737b9..000000000
    --- a/01_Acey_Ducey/rust/README.md
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -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
    deleted file mode 100644
    index 8df9f3270..000000000
    --- a/01_Acey_Ducey/rust/src/main.rs
    +++ /dev/null
    @@ -1,139 +0,0 @@
    -use rand::{prelude::ThreadRng, Rng};
    -use std::{fmt, io, mem};
    -
    -#[derive(PartialEq, Eq, PartialOrd, Ord)]
    -struct Card(u8);
    -
    -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;
    -
    -    loop {
    -        println!("YOU NOW HAVE {} DOLLARS.", &mut user_bank);
    -        println!("\nHERE ARE YOUR NEXT TWO CARDS:");
    -        // get new random cards
    -        let cards = CardsPool::new();
    -
    -        println!("{}", cards.0);
    -        println!("{}", cards.1);
    -
    -        let user_bet: u16 = get_bet(user_bank);
    -
    -        if user_bet == 0 {
    -            println!("CHICKEN!!!\n");
    -            continue;
    -        } else {
    -            println!("THANK YOU! YOUR BET IS {} DOLLARS.", user_bet);
    -        }
    -
    -        println!("\nTHE THIRD CARD IS:");
    -        println!("{}", cards.2);
    -
    -        if cards.is_in_win_range() {
    -            println!("\nYOU WIN!!!");
    -            user_bank += user_bet;
    -        } else {
    -            println!("\nSORRY, YOU LOSE");
    -            user_bank -= user_bet;
    -        }
    -
    -        if user_bank == 0 {
    -            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 input.trim().to_lowercase() == "yes" {
    -                user_bank = 100;
    -                println!();
    -            } else {
    -                println!("\nO.K., HOPE YOU HAD FUN!");
    -                break;
    -            }
    -        }
    -    }
    -}
    -
    -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");
    -    println!("\n\n");
    -}
    -
    -fn get_bet(user_bank: u16) -> u16 {
    -    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("CANNOT READ INPUT!");
    -
    -        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);
    -            }
    -        };
    -    }
    -}
    diff --git a/01_Acey_Ducey/vbnet/AceyDucey.sln b/01_Acey_Ducey/vbnet/AceyDucey.sln
    deleted file mode 100644
    index 1c5cafb68..000000000
    --- a/01_Acey_Ducey/vbnet/AceyDucey.sln
    +++ /dev/null
    @@ -1,25 +0,0 @@
    -
    -Microsoft Visual Studio Solution File, Format Version 12.00
    -# Visual Studio Version 17
    -VisualStudioVersion = 17.0.31903.59
    -MinimumVisualStudioVersion = 10.0.40219.1
    -Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "AceyDucey", "AceyDucey.vbproj", "{54C05475-238D-4A82-A67B-B6C1BF2CA337}"
    -EndProject
    -Global
    -	GlobalSection(SolutionConfigurationPlatforms) = preSolution
    -		Debug|Any CPU = Debug|Any CPU
    -		Release|Any CPU = Release|Any CPU
    -	EndGlobalSection
    -	GlobalSection(ProjectConfigurationPlatforms) = postSolution
    -		{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
    -	EndGlobalSection
    -	GlobalSection(ExtensibilityGlobals) = postSolution
    -		SolutionGuid = {C01D9DAE-644C-455F-8365-E14E49074BC3}
    -	EndGlobalSection
    -EndGlobal
    diff --git a/01_Acey_Ducey/vbnet/AceyDucey.vb b/01_Acey_Ducey/vbnet/AceyDucey.vb
    deleted file mode 100644
    index 528d92750..000000000
    --- a/01_Acey_Ducey/vbnet/AceyDucey.vb
    +++ /dev/null
    @@ -1,242 +0,0 @@
    -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/AceyDucey.vbproj b/01_Acey_Ducey/vbnet/AceyDucey.vbproj deleted file mode 100644 index 88e8cd5ef..000000000 --- a/01_Acey_Ducey/vbnet/AceyDucey.vbproj +++ /dev/null @@ -1,10 +0,0 @@ - - - - Exe - AceyDucey - net6.0 - 16.9 - - - diff --git a/01_Acey_Ducey/vbnet/AceyDucy.sln b/01_Acey_Ducey/vbnet/AceyDucy.sln new file mode 100644 index 000000000..881d7c9c7 --- /dev/null +++ b/01_Acey_Ducey/vbnet/AceyDucy.sln @@ -0,0 +1,25 @@ + +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}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + 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 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C01D9DAE-644C-455F-8365-E14E49074BC3} + EndGlobalSection +EndGlobal diff --git a/01_Acey_Ducey/vbnet/AceyDucy/AceyDucy.vbproj b/01_Acey_Ducey/vbnet/AceyDucy/AceyDucy.vbproj new file mode 100644 index 000000000..98a070018 --- /dev/null +++ b/01_Acey_Ducey/vbnet/AceyDucy/AceyDucy.vbproj @@ -0,0 +1,9 @@ + + + + Exe + AceyDucy + net6.0 + + + diff --git a/01_Acey_Ducey/vbnet/AceyDucy/Program.vb b/01_Acey_Ducey/vbnet/AceyDucy/Program.vb new file mode 100644 index 000000000..bfa518ca2 --- /dev/null +++ b/01_Acey_Ducey/vbnet/AceyDucy/Program.vb @@ -0,0 +1,178 @@ +Imports System + +''' +''' This is a modern adapation of Acey Ducey from BASIC Computer Games. +''' +''' 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 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. +''' +''' 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!") + + 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 diff --git a/01_Acey_Ducey/vbnet/Program.vb b/01_Acey_Ducey/vbnet/Program.vb deleted file mode 100644 index 3275187c5..000000000 --- a/01_Acey_Ducey/vbnet/Program.vb +++ /dev/null @@ -1,21 +0,0 @@ -Imports System - -''' -''' This is a modern adapation of Acey Ducey from BASIC Computer Games. -''' -''' The structural changes primarily consist of replacing the many GOTOs with -''' Do/Loop constructs to force the continual execution of the program. -''' -''' 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. -''' -''' 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() - Call New AceyDucey().Play() - End Sub -End Module diff --git a/02_Amazing/README.md b/02_Amazing/README.md index b8e4b9b41..e94949bdb 100644 --- a/02_Amazing/README.md +++ b/02_Amazing/README.md @@ -13,10 +13,6 @@ As published in Basic Computer Games (1978): Downloaded from Vintage Basic at http://www.vintage-basic.net/games.html -#### Known Bugs - -- The input dimensions are checked for values of 1, but not for values of 0 or less. Such inputs will cause the program to break. - -#### Porting Notes +--- **2022-01-04:** patched original source in [#400](https://github.com/coding-horror/basic-computer-games/pull/400) to fix a minor bug where a generated maze may be missing an exit, particularly at small maze sizes. diff --git a/02_Amazing/csharp/Amazing.cs b/02_Amazing/csharp/Amazing.cs index c556901b9..995b58d68 100644 --- a/02_Amazing/csharp/Amazing.cs +++ b/02_Amazing/csharp/Amazing.cs @@ -1,8 +1,8 @@ -using System; -using System.Collections.Generic; - -namespace Amazing -{ +using System; +using System.Collections.Generic; + +namespace Amazing +{ class AmazingGame { private const int FIRST_COL = 0; @@ -35,9 +35,9 @@ public static int Random(int min, int max) } public void Play() - { - Console.WriteLine(Tab(28) + "AMAZING PROGRAM"); - Console.WriteLine(Tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + { + Console.WriteLine(Tab(28) + "AMAZING PROGRAM"); + Console.WriteLine(Tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); Console.WriteLine(); int width = 0; @@ -113,25 +113,25 @@ private void WriteMaze(int width, Grid grid, int enterCol) { if (i == enterCol) Console.Write(". "); else Console.Write(".--"); - } - Console.WriteLine("."); + } + Console.WriteLine("."); for (int i = 0; i < grid.Length; i++) - { + { Console.Write("I"); for (int j = 0; j < grid.Width; j++) { if (grid.Cells[i,j].ExitType == EXIT_UNSET || grid.Cells[i, j].ExitType == EXIT_DOWN) Console.Write(" I"); else Console.Write(" "); - } - Console.WriteLine(); + } + Console.WriteLine(); for (int j = 0; j < grid.Width; j++) { if (grid.Cells[i,j].ExitType == EXIT_UNSET || grid.Cells[i, j].ExitType == EXIT_RIGHT) Console.Write(":--"); else Console.Write(": "); - } + } Console.WriteLine("."); } } @@ -164,7 +164,7 @@ private List GetPossibleDirs(Grid grid, Cell cell) } private String DisplayTextAndGetInput(String text) - { + { Console.WriteLine(text); return Console.ReadLine(); } @@ -308,13 +308,13 @@ public Cell GetFirstUnset(Cell cell) return newCell; } } - } - - class Program - { - static void Main(string[] args) + } + + class Program + { + static void Main(string[] args) { - new AmazingGame().Play(); - } - } -} + new AmazingGame().Play(); + } + } +} diff --git a/02_Amazing/java/Amazing.java b/02_Amazing/java/Amazing.java index c5963715d..5188f14f5 100644 --- a/02_Amazing/java/Amazing.java +++ b/02_Amazing/java/Amazing.java @@ -259,4 +259,4 @@ public Cell getFirstUnset(Cell cell) { return newCell; } } -} +} \ No newline at end of file diff --git a/02_Amazing/javascript/amazing.html b/02_Amazing/javascript/amazing.html index 475bc4eef..c066a3e9e 100644 --- a/02_Amazing/javascript/amazing.html +++ b/02_Amazing/javascript/amazing.html @@ -1,10 +1,9 @@ AMAZING - -
    
    +
    
     
     
     
    diff --git a/02_Amazing/javascript/amazing.js b/02_Amazing/javascript/amazing.js
    index ee06816ee..427e07935 100644
    --- a/02_Amazing/javascript/amazing.js
    +++ b/02_Amazing/javascript/amazing.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/02_Amazing/kotlin/README.md b/02_Amazing/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/02_Amazing/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/02_Amazing/lua/README.md b/02_Amazing/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/02_Amazing/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/00_Alternate_Languages/02_Amazing/pascal/.gitattributes b/02_Amazing/pascal/.gitattributes
    similarity index 100%
    rename from 00_Alternate_Languages/02_Amazing/pascal/.gitattributes
    rename to 02_Amazing/pascal/.gitattributes
    diff --git a/00_Alternate_Languages/02_Amazing/pascal/.gitignore b/02_Amazing/pascal/.gitignore
    similarity index 100%
    rename from 00_Alternate_Languages/02_Amazing/pascal/.gitignore
    rename to 02_Amazing/pascal/.gitignore
    diff --git a/00_Alternate_Languages/02_Amazing/pascal/README.md b/02_Amazing/pascal/README.md
    similarity index 100%
    rename from 00_Alternate_Languages/02_Amazing/pascal/README.md
    rename to 02_Amazing/pascal/README.md
    diff --git a/00_Alternate_Languages/02_Amazing/pascal/object-pascal/amazing.lpi b/02_Amazing/pascal/object-pascal/amazing.lpi
    similarity index 100%
    rename from 00_Alternate_Languages/02_Amazing/pascal/object-pascal/amazing.lpi
    rename to 02_Amazing/pascal/object-pascal/amazing.lpi
    diff --git a/02_Amazing/pascal/object-pascal/amazing.pas b/02_Amazing/pascal/object-pascal/amazing.pas
    new file mode 100644
    index 000000000..716bd1da3
    --- /dev/null
    +++ b/02_Amazing/pascal/object-pascal/amazing.pas
    @@ -0,0 +1,17 @@
    +program amazing;
    +
    +{$IFDEF FPC}
    +{$mode ObjFPC}{$H+}
    +{$ENDIF}
    +
    +uses
    +  AmazingApplication, maze, Room;
    +
    +var
    +  AmazingApp: TAmazingApplication;
    +
    +begin
    +  AmazingApp:= TAmazingApplication.Create;
    +  AmazingApp.Run;
    +end.
    +
    diff --git a/00_Alternate_Languages/02_Amazing/pascal/object-pascal/amazingapplication.pas b/02_Amazing/pascal/object-pascal/amazingapplication.pas
    similarity index 99%
    rename from 00_Alternate_Languages/02_Amazing/pascal/object-pascal/amazingapplication.pas
    rename to 02_Amazing/pascal/object-pascal/amazingapplication.pas
    index 4dc791bf8..1431fd67b 100644
    --- a/00_Alternate_Languages/02_Amazing/pascal/object-pascal/amazingapplication.pas
    +++ b/02_Amazing/pascal/object-pascal/amazingapplication.pas
    @@ -101,3 +101,4 @@ procedure TAmazingApplication.Run;
     end;
     
     end.
    +
    diff --git a/00_Alternate_Languages/02_Amazing/pascal/object-pascal/maze.pas b/02_Amazing/pascal/object-pascal/maze.pas
    similarity index 99%
    rename from 00_Alternate_Languages/02_Amazing/pascal/object-pascal/maze.pas
    rename to 02_Amazing/pascal/object-pascal/maze.pas
    index e4355c49c..1f5b32474 100644
    --- a/00_Alternate_Languages/02_Amazing/pascal/object-pascal/maze.pas
    +++ b/02_Amazing/pascal/object-pascal/maze.pas
    @@ -277,3 +277,4 @@ procedure TMaze.Print;
     end;
     
     end.
    +
    diff --git a/00_Alternate_Languages/02_Amazing/pascal/object-pascal/room.pas b/02_Amazing/pascal/object-pascal/room.pas
    similarity index 99%
    rename from 00_Alternate_Languages/02_Amazing/pascal/object-pascal/room.pas
    rename to 02_Amazing/pascal/object-pascal/room.pas
    index 201f40937..f0b741032 100644
    --- a/00_Alternate_Languages/02_Amazing/pascal/object-pascal/room.pas
    +++ b/02_Amazing/pascal/object-pascal/room.pas
    @@ -68,3 +68,4 @@ procedure TRoom.PrintWall;
     end;
     
     end.
    +
    diff --git a/00_Alternate_Languages/02_Amazing/pascal/simple/amazing.lpi b/02_Amazing/pascal/simple/amazing.lpi
    similarity index 100%
    rename from 00_Alternate_Languages/02_Amazing/pascal/simple/amazing.lpi
    rename to 02_Amazing/pascal/simple/amazing.lpi
    diff --git a/02_Amazing/pascal/simple/amazing.pas b/02_Amazing/pascal/simple/amazing.pas
    new file mode 100644
    index 000000000..dc5d7610b
    --- /dev/null
    +++ b/02_Amazing/pascal/simple/amazing.pas
    @@ -0,0 +1,284 @@
    +program Amazing;
    +
    +{$IFDEF FPC}
    +{$mode objfpc}{$H+}
    +{$ENDIF}
    +
    +uses
    +  Crt;
    +
    +type
    +  TDirection = (dUp, dRight, dDown, dLeft);
    +  TDirections = set of TDirection;
    +
    +var
    +  Width: Integer;   // H
    +  Length: Integer;  // V
    +  Entry: Integer;
    +  MatrixWalls: Array of Array of Integer;
    +  MatrixVisited: Array of Array of Integer;
    +
    +const
    +  EXIT_DOWN  = 1;
    +  EXIT_RIGHT = 2;
    +
    +procedure PrintGreeting;
    +begin
    +  WriteLN(' ':28, 'AMAZING PROGRAM');
    +  WriteLN(' ':15, 'CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY');
    +  WriteLN;
    +  WriteLN;
    +  WriteLN;
    +  WriteLN;
    +end;
    +
    +procedure GetDimensions;
    +begin
    +  repeat
    +    Write('WHAT ARE YOUR WIDTH AND LENGTH (SPACE IN BETWEEN): ');
    +    ReadLN(Width, Length);
    +    if (Width = 1) or (Length = 1) then
    +    begin
    +      WriteLN('MEANINGLESS DIMENSIONS.  TRY AGAIN.');
    +    end;
    +  until (Width > 1) and (Length > 1);
    +  WriteLN;
    +  WriteLN;
    +  WriteLN;
    +  WriteLN;
    +end;
    +
    +procedure ClearMatrices;
    +var
    +  indexW: Integer;
    +  indexL: Integer;
    +begin
    +  SetLength(MatrixWalls, Width, Length);
    +  SetLength(MatrixVisited, Width, Length);
    +  for indexW:= 0 to Pred(Width) do
    +  begin
    +    for indexL:= 0 to Pred(Length) do
    +    begin
    +      MatrixWalls[indexW][indexL]:= 0;
    +      MatrixVisited[indexW][indexL]:= 0;
    +    end;
    +  end;
    +end;
    +
    +function GetRandomDirection(const ADirections: TDirections): TDirection;
    +var
    +  count: Integer;
    +  position: Integer;
    +  directions: array [0..3] of TDirection;
    +begin
    +  count:= 0;
    +  position:= 0;
    +  if dUp in ADirections then
    +  begin
    +    Inc(count);
    +    directions[position]:= dUp;
    +    Inc(position);
    +  end;
    +  if dRight in ADirections then
    +  begin
    +    Inc(count);
    +    directions[position]:= dRight;
    +    Inc(position);
    +  end;
    +  if dDown in ADirections then
    +  begin
    +    Inc(count);
    +    directions[position]:= dDown;
    +    Inc(position);
    +  end;
    +  if dLeft in ADirections then
    +  begin
    +    Inc(count);
    +    directions[position]:= dLeft;
    +    Inc(position);
    +  end;
    +  Result:= directions[Random(count)];
    +end;
    +
    +procedure BuildMaze;
    +var
    +  indexW: Integer;
    +  indexL: Integer;
    +  direction: TDirection;
    +  directions: TDirections;
    +  count: Integer;
    +begin
    +  Entry:= Random(Width);
    +  indexW:= Entry;
    +  indexL:= 0;
    +  count:= 1;
    +  MatrixVisited[indexW][indexL]:= count;
    +  Inc(count);
    +  repeat
    +    directions:= [dUp, dRight, dDown, dLeft];
    +    if (indexW = 0) or (MatrixVisited[Pred(indexW)][indexL] <> 0) then
    +    begin
    +      Exclude(directions, dLeft);
    +    end;
    +    if (indexL = 0) or (MatrixVisited[indexW][Pred(indexL)] <> 0) then
    +    begin
    +      Exclude(directions, dUp);
    +    end;
    +    if (indexW = Pred(Width)) or (MatrixVisited[Succ(indexW)][indexL] <> 0) then
    +    begin
    +      Exclude(directions, dRight);
    +    end;
    +    if (indexL = Pred(Length)) or (MatrixVisited[indexW][Succ(indexL)] <> 0) then
    +    begin
    +      Exclude(directions, dDown);
    +    end;
    +
    +    if directions <> [] then
    +    begin
    +      direction:= GetRandomDirection(directions);
    +      case direction of
    +        dLeft:begin
    +          Dec(indexW);
    +          MatrixWalls[indexW][indexL]:= EXIT_RIGHT;
    +        end;
    +        dUp:begin
    +          Dec(indexL);
    +          MatrixWalls[indexW][indexL]:= EXIT_DOWN;
    +        end;
    +        dRight:begin
    +          Inc(MatrixWalls[indexW][indexL], EXIT_RIGHT);
    +          Inc(indexW);
    +        end;
    +        dDown:begin
    +          Inc(MatrixWalls[indexW][indexL], EXIT_DOWN);
    +          Inc(indexL);
    +        end;
    +      end;
    +      MatrixVisited[indexW][indexL]:= count;
    +      Inc(count);
    +    end
    +    else
    +    begin
    +      while True do
    +      begin
    +        if indexW <> Pred(Width) then
    +        begin
    +          Inc(indexW);
    +        end
    +        else if indexL <> Pred(Length) then
    +        begin
    +          Inc(indexL);
    +          indexW:= 0;
    +        end
    +        else
    +        begin
    +          indexW:= 0;
    +          indexL:= 0;
    +        end;
    +        if MatrixVisited[indexW][indexL] <> 0 then
    +        begin
    +          break;
    +        end;
    +      end;
    +    end;
    +  until count = (Width * Length) + 1;
    +  indexW:= Random(Width);
    +  indexL:= Pred(Length);
    +  Inc(MatrixWalls[indexW][indexL]);
    +end;
    +
    +procedure DegubVisited;
    +var
    +  indexW: Integer;
    +  indexL: Integer;
    +begin
    +  WriteLN('Visited');
    +  for indexL:= 0 to Pred(Length) do
    +  begin
    +    for indexW:= 0 to Pred(Width) do
    +    begin
    +      Write(MatrixVisited[indexW][indexL]:2,' ');
    +    end;
    +    WriteLN;
    +  end;
    +  WriteLN;
    +end;
    +
    +procedure DebugWalls;
    +var
    +  indexW: Integer;
    +  indexL: Integer;
    +begin
    +  WriteLN('Walls');
    +  for indexL:= 0 to Pred(Length) do
    +  begin
    +    for indexW:= 0 to Pred(Width) do
    +    begin
    +      Write(MatrixWalls[indexW, indexL]:2, ' ');
    +    end;
    +    WriteLN;
    +  end;
    +  WriteLN;
    +end;
    +
    +procedure PrintMaze;
    +var
    +  indexW: Integer;
    +  indexL: Integer;
    +begin
    +
    +  for indexW:= 0 to Pred(Width) do
    +  begin
    +    if indexW = Entry then
    +    begin
    +      Write('.  ');
    +    end
    +    else
    +    begin
    +      Write('.--');
    +    end;
    +  end;
    +  WriteLN('.');
    +  for indexL:= 0 to Pred(Length) do
    +  begin
    +    Write('I');
    +    for indexW:= 0 to Pred(Width) do
    +    begin
    +      if MatrixWalls[indexW, indexL] < 2 then
    +      begin
    +        Write('  I');
    +      end
    +      else
    +      begin
    +        Write('   ');
    +      end;
    +    end;
    +    WriteLN;
    +    for indexW:= 0 to Pred(Width) do
    +    begin
    +      if (MatrixWalls[indexW, indexL] = 0) or (MatrixWalls[indexW, indexL] = 2) then
    +      begin
    +        Write(':--');
    +      end
    +      else
    +      begin
    +        Write(':  ');
    +      end;
    +    end;
    +    WriteLN('.');
    +  end;
    +  WriteLN;
    +end;
    +
    +begin
    +  Randomize;
    +  ClrScr;
    +  PrintGreeting;
    +  GetDimensions;
    +  ClearMatrices;
    +  BuildMaze;
    +  //DegubVisited;
    +  //DebugWalls;
    +  PrintMaze;
    +end.
    +
    diff --git a/02_Amazing/perl/amazing.pl b/02_Amazing/perl/amazing.pl
    index 70b1c2321..c7cb5f44e 100755
    --- a/02_Amazing/perl/amazing.pl
    +++ b/02_Amazing/perl/amazing.pl
    @@ -79,7 +79,7 @@ sub input_dimensions {
             print 'WHAT ARE YOUR WIDTH AND LENGTH? ';
     
             ($w, $h) =  =~ / \d+ /xg;
    -
    +        
             if ($w < 1 || $h < 1) {
                 say "MEANINGLESS DIMENSIONS.  TRY AGAIN."
             }
    diff --git a/02_Amazing/python/amazing.py b/02_Amazing/python/amazing.py
    index 22f141c9f..dc9da3806 100644
    --- a/02_Amazing/python/amazing.py
    +++ b/02_Amazing/python/amazing.py
    @@ -1,187 +1,121 @@
    -import enum
     import random
    -from dataclasses import dataclass
    -from typing import List, Tuple
    -
    +            
     # Python translation by Frank Palazzolo - 2/2021
    -
    -
    -class Maze:
    -    def __init__(self, width: int, length: int) -> None:
    -        assert width >= 2 and length >= 2
    -        used: List[List[int]] = []
    -        walls: List[List[int]] = []
    -        for _ in range(length):
    -            used.append([0] * width)
    -            walls.append([0] * width)
    -
    -        # Pick a random entrance, mark as used
    -        enter_col = random.randint(0, width - 1)
    -        used[0][enter_col] = 1
    -
    -        self.used = used
    -        self.walls = walls
    -        self.enter_col = enter_col
    -        self.width = width
    -        self.length = length
    -
    -    def add_exit(self) -> None:
    -        """Modifies 'walls' to add an exit to the maze."""
    -        col = random.randint(0, self.width - 1)
    -        row = self.length - 1
    -        self.walls[row][col] = self.walls[row][col] + 1
    -
    -    def display(self) -> None:
    -        for col in range(self.width):
    -            if col == self.enter_col:
    -                print(".  ", end="")
    -            else:
    -                print(".--", end="")
    -        print(".")
    -        for row in range(self.length):
    -            print("I", end="")
    -            for col in range(self.width):
    -                if self.walls[row][col] < 2:
    -                    print("  I", end="")
    -                else:
    -                    print("   ", end="")
    -            print()
    -            for col in range(self.width):
    -                if self.walls[row][col] in [0, 2]:
    -                    print(":--", end="")
    -                else:
    -                    print(":  ", end="")
    -            print(".")
    -
    -
    -class Direction(enum.Enum):
    -    LEFT = 0
    -    UP = 1
    -    RIGHT = 2
    -    DOWN = 3
    -
    -
    -@dataclass
    -class Position:
    -    row: int
    -    col: int
    -
    -
    +    
    +print(' '*28+'AMAZING PROGRAM')
    +print(' '*15+'CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY')
    +print()
    +print()
    +print()
    +
    +while True:
    +    width, length = input('What are your width and length?').split(',')
    +    width = int(width)
    +    length = int(length)
    +    if width != 1 and length != 1:
    +        break
    +    print('Meaningless dimensions. Try again.')
    +
    +# Build two 2D arrays
    +#
    +# used:
    +#   Initially set to zero, unprocessed cells
    +#   Filled in with consecutive non-zero numbers as cells are processed
    +#
    +# walls:
    +#   Initially set to zero, (all paths blocked)
    +#   Remains 0 if there is no exit down or right
    +#   Set to 1 if there is an exit down
    +#   Set to 2 if there is an exit right
    +#   Set to 3 if there are exits down and right
    +
    +used = []
    +walls = []
    +for i in range(length):
    +    used.append([0]*width)
    +    walls.append([0]*width)
    +
    +# Use direction variables with nice names
    +GO_LEFT,GO_UP,GO_RIGHT,GO_DOWN=[0,1,2,3]
     # Give Exit directions nice names
     EXIT_DOWN = 1
     EXIT_RIGHT = 2
     
    -
    -def main() -> None:
    -    print_intro()
    -    width, length = get_maze_dimensions()
    -    maze = build_maze(width, length)
    -    maze.display()
    -
    -
    -def print_intro() -> None:
    -    print(" " * 28 + "AMAZING PROGRAM")
    -    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n")
    -
    -
    -def build_maze(width: int, length: int) -> Maze:
    -    """Build two 2D arrays."""
    -    #
    -    # used:
    -    #   Initially set to zero, unprocessed cells
    -    #   Filled in with consecutive non-zero numbers as cells are processed
    -    #
    -    # walls:
    -    #   Initially set to zero, (all paths blocked)
    -    #   Remains 0 if there is no exit down or right
    -    #   Set to 1 if there is an exit down
    -    #   Set to 2 if there is an exit right
    -    #   Set to 3 if there are exits down and right
    -    assert width >= 2 and length >= 2
    -
    -    maze = Maze(width, length)
    -    position = Position(row=0, col=maze.enter_col)
    -    count = 2
    -
    -    while count != width * length + 1:
    -        possible_dirs = get_possible_directions(maze, position)
    -
    -        # If we can move in a direction, move and make opening
    -        if len(possible_dirs) != 0:
    -            position, count = make_opening(maze, possible_dirs, position, count)
    -        # otherwise, move to the next used cell, and try again
    -        else:
    -            while True:
    -                if position.col != width - 1:
    -                    position.col += 1
    -                elif position.row != length - 1:
    -                    position.row, position.col = position.row + 1, 0
    -                else:
    -                    position.row, position.col = 0, 0
    -                if maze.used[position.row][position.col] != 0:
    -                    break
    -
    -    maze.add_exit()
    -    return maze
    -
    -
    -def make_opening(
    -    maze: Maze,
    -    possible_dirs: List[Direction],
    -    pos: Position,
    -    count: int,
    -) -> Tuple[Position, int]:
    -    """
    -    Attention! This modifies 'used' and 'walls'
    -    """
    -    direction = random.choice(possible_dirs)
    -    if direction == Direction.LEFT:
    -        pos.col = pos.col - 1
    -        maze.walls[pos.row][pos.col] = EXIT_RIGHT
    -    elif direction == Direction.UP:
    -        pos.row = pos.row - 1
    -        maze.walls[pos.row][pos.col] = EXIT_DOWN
    -    elif direction == Direction.RIGHT:
    -        maze.walls[pos.row][pos.col] = maze.walls[pos.row][pos.col] + EXIT_RIGHT
    -        pos.col = pos.col + 1
    -    elif direction == Direction.DOWN:
    -        maze.walls[pos.row][pos.col] = maze.walls[pos.row][pos.col] + EXIT_DOWN
    -        pos.row = pos.row + 1
    -    maze.used[pos.row][pos.col] = count
    -    count += 1
    -    return pos, count
    -
    -
    -def get_possible_directions(maze: Maze, pos: Position) -> List[Direction]:
    -    """
    -    Get a list of all directions that are not blocked.
    -
    -    Also ignore hit cells that we have already processed
    -    """
    -    possible_dirs = list(Direction)
    -    if pos.col == 0 or maze.used[pos.row][pos.col - 1] != 0:
    -        possible_dirs.remove(Direction.LEFT)
    -    if pos.row == 0 or maze.used[pos.row - 1][pos.col] != 0:
    -        possible_dirs.remove(Direction.UP)
    -    if pos.col == maze.width - 1 or maze.used[pos.row][pos.col + 1] != 0:
    -        possible_dirs.remove(Direction.RIGHT)
    -    if pos.row == maze.length - 1 or maze.used[pos.row + 1][pos.col] != 0:
    -        possible_dirs.remove(Direction.DOWN)
    -    return possible_dirs
    -
    -
    -def get_maze_dimensions() -> Tuple[int, int]:
    -    while True:
    -        input_str = input("What are your width and length?")
    -        if input_str.count(",") == 1:
    -            width_str, length_str = input_str.split(",")
    -            width = int(width_str)
    -            length = int(length_str)
    -            if width > 1 and length > 1:
    +# Pick a random entrance, mark as used
    +enter_col=random.randint(0,width-1)
    +row,col=0,enter_col
    +count=1
    +used[row][col]=count
    +count=count+1
    +
    +while count!=width*length+1:
    +    # remove possible directions that are blocked or
    +    # hit cells that we have already processed
    +    possible_dirs = [GO_LEFT,GO_UP,GO_RIGHT,GO_DOWN]
    +    if col==0 or used[row][col-1]!=0:
    +        possible_dirs.remove(GO_LEFT)
    +    if row==0 or used[row-1][col]!=0:
    +        possible_dirs.remove(GO_UP)
    +    if col==width-1 or used[row][col+1]!=0: 
    +        possible_dirs.remove(GO_RIGHT)
    +    if row==length-1 or used[row+1][col]!=0:
    +        possible_dirs.remove(GO_DOWN)   
    +
    +    # If we can move in a direction, move and make opening
    +    if len(possible_dirs)!=0:
    +        direction=random.choice(possible_dirs) 
    +        if direction==GO_LEFT:
    +            col=col-1
    +            walls[row][col]=EXIT_RIGHT
    +        elif direction==GO_UP:
    +            row=row-1 
    +            walls[row][col]=EXIT_DOWN
    +        elif direction==GO_RIGHT:
    +            walls[row][col]=walls[row][col]+EXIT_RIGHT    
    +            col=col+1
    +        elif direction==GO_DOWN:
    +            walls[row][col]=walls[row][col]+EXIT_DOWN
    +            row=row+1
    +        used[row][col]=count
    +        count=count+1
    +    # otherwise, move to the next used cell, and try again
    +    else:
    +        while True:
    +            if col!=width-1:
    +                col=col+1
    +            elif row!=length-1:
    +                row,col=row+1,0
    +            else:
    +                row,col=0,0
    +            if used[row][col]!=0:
                     break
    -        print("Meaningless dimensions. Try again.")
    -    return width, length
     
    +# Add a random exit
    +col=random.randint(0,width-1)
    +row=length-1
    +walls[row][col]=walls[row][col]+1
    +    
    +# Print the maze
    +for col in range(width):
    +    if col==enter_col:
    +        print('.  ',end='')
    +    else:
    +        print('.--',end='')
    +print('.')
    +for row in range(length):
    +    print('I',end='')
    +    for col in range(width):
    +        if walls[row][col]<2:
    +            print('  I',end='')
    +        else:
    +            print('   ',end='')
    +    print()
    +    for col in range(width):
    +        if walls[row][col]==0 or walls[row][col]==2:
    +            print(':--',end='')
    +        else:
    +            print(':  ',end='')    
    +    print('.')
     
    -if __name__ == "__main__":
    -    main()
    +        
    +        
    \ No newline at end of file
    diff --git a/02_Amazing/ruby/amazing.rb b/02_Amazing/ruby/amazing.rb
    index e8325bbc2..d9a4f9d09 100644
    --- a/02_Amazing/ruby/amazing.rb
    +++ b/02_Amazing/ruby/amazing.rb
    @@ -213,4 +213,4 @@ def ask_dimensions
       end
     end
     
    -Amazing.new.run
    +Amazing.new.run
    \ No newline at end of file
    diff --git a/02_Amazing/rust/Cargo.lock b/02_Amazing/rust/Cargo.lock
    deleted file mode 100644
    index 4fe2abbea..000000000
    --- a/02_Amazing/rust/Cargo.lock
    +++ /dev/null
    @@ -1,75 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.10"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.147"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/02_Amazing/rust/Cargo.toml b/02_Amazing/rust/Cargo.toml
    deleted file mode 100644
    index 127b2c635..000000000
    --- a/02_Amazing/rust/Cargo.toml
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -[package]
    -name = "rust"
    -version = "0.1.0"
    -edition = "2018"
    -
    -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
    -
    -[dependencies]
    -rand = "0.8.5"
    diff --git a/02_Amazing/rust/README.md b/02_Amazing/rust/README.md
    deleted file mode 100644
    index 7e85f9a15..000000000
    --- a/02_Amazing/rust/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Rust](https://www.rust-lang.org/) by Anthony Rubick [AnthonyMichaelTDM](https://github.com/AnthonyMichaelTDM)
    diff --git a/02_Amazing/rust/src/main.rs b/02_Amazing/rust/src/main.rs
    deleted file mode 100644
    index 2e71e7ab7..000000000
    --- a/02_Amazing/rust/src/main.rs
    +++ /dev/null
    @@ -1,202 +0,0 @@
    -use rand::{Rng, thread_rng, prelude::SliceRandom};
    -use  std::{io, collections::HashSet};
    -
    -fn main() {
    -    //DATA
    -    enum Direction {
    -        LEFT=0,
    -        UP=1,
    -        RIGHT=2,
    -        DOWN=3,
    -    }
    -    impl Direction {
    -        fn val(&self) -> usize {
    -            match self {
    -                Direction::LEFT=>0,
    -                Direction::UP=>1,
    -                Direction::RIGHT=>2,
    -                Direction::DOWN=>3,
    -            }
    -        }
    -    }
    -    const EXIT_DOWN:usize = 1;
    -    const EXIT_RIGHT:usize = 2;
    -    let mut rng = thread_rng(); //rng
    -    /*
    -    vector of:
    -        vectors of:
    -            integers
    -                Initially set to 0, unprocessed cells.
    -                Filled in with consecutive non-zero numbers as cells are processed
    -    */
    -    let mut used; //2d vector
    -    /*
    -    vector of:
    -        vectors of:
    -            integers
    -                Remains 0 if there is no exit down or right
    -                Set to 1 if there is an exit down
    -                Set to 2 if there is an exit right
    -                Set to 3 if there are exits down and right
    -    */
    -    let mut walls; //2d vector
    -    let width;
    -    let height;
    -    let entrance_column; //rng, column of entrance
    -    let mut row;
    -    let mut col;
    -    let mut count;
    -
    -
    -
    -    //print welcome message
    -    println!("
    -                 AMAZING PROGRAM
    -    CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n\n");
    -
    -    //prompt for input
    -    width = get_user_input("What is your width?");
    -    print!("\n"); //one blank line below
    -    height = get_user_input("What is your height?");
    -    print!("\n\n\n\n");//4 blank lines below
    -
    -    //generate maze
    -    //initialize used and wall vectors
    -    //2d vectors when you don't know the sizes at compile time are wierd, but here's how it's done :)
    -    used = vec![0; (width * height) as usize];
    -    let mut used: Vec<_> = used.as_mut_slice().chunks_mut(width as usize).collect();
    -    let used = used.as_mut_slice(); //accessible as used[][]
    -    //2d vectors when you don't know the sizes at compile time are wierd, but here's how it's done :)
    -    walls = vec![0; (width * height) as usize];
    -    let mut walls: Vec<_> = walls.as_mut_slice().chunks_mut(width as usize).collect();
    -    let walls = walls.as_mut_slice(); //accessible as walls[][]
    -
    -    entrance_column=rng.gen_range(0..width-1);
    -    row = 0;
    -    col = entrance_column;
    -    count = 1;
    -    used[row][col] = count;
    -    count += 1;
    -
    -    while count != width*height + 1 {
    -        //remove possible directions that are blocked or
    -        //hit cells already processed
    -        let mut possible_directions: HashSet = vec![Direction::LEFT.val(),Direction::UP.val(),Direction::RIGHT.val(),Direction::DOWN.val()].into_iter().collect(); //create it as a vector bc that's easy, then convert it to a hashset
    -        if col==0 || used[row][col-1]!=0 {
    -            possible_directions.remove(&Direction::LEFT.val());
    -        }
    -        if row==0 || used[row-1][col]!=0 {
    -            possible_directions.remove(&Direction::UP.val());
    -        }
    -        if col==width-1 || used[row][col+1]!=0 {
    -            possible_directions.remove(&Direction::RIGHT.val());
    -        }
    -        if row==height-1 || used[row+1][col]!=0 {
    -            possible_directions.remove(&Direction::DOWN.val());
    -        }
    -
    -        //If we can move in a direction, move and make opening
    -        if possible_directions.len() != 0 { //all values in possible_directions are not NONE
    -            let pos_dir_vec: Vec<_> = possible_directions.into_iter().collect(); // convert the set to a vector to get access to the choose method
    -            //select a random direction
    -            match pos_dir_vec.choose(&mut rng).expect("error") {
    -                0=> {
    -                    col -= 1;
    -                    walls[row][col] = EXIT_RIGHT;
    -                },
    -                1=> {
    -                    row -= 1;
    -                    walls[row][col] = EXIT_DOWN;
    -                },
    -                2=>{
    -                    walls[row][col] = walls[row][col] + EXIT_RIGHT;
    -                    col += 1;
    -                },
    -                3=>{
    -                    walls[row][col] = walls[row][col] + EXIT_DOWN;
    -                    row += 1;
    -                },
    -                _=>{},
    -            }
    -            used[row][col]=count;
    -            count += 1;
    -        }
    -        //otherwise, move to the next used cell, and try again
    -        else {
    -            loop {
    -                if col != width-1 {col += 1;}
    -                else if row != height-1 {row+=1; col=0;}
    -                else {row=0;col=0;}
    -
    -                if used[row][col] != 0 {break;}
    -            }
    -        }
    -    }
    -    // Add a random exit
    -    col=rng.gen_range(0..width);
    -    row=height-1;
    -    walls[row][col]+=1;
    -
    -    //print maze
    -    //first line
    -    for c in 0..width {
    -        if c == entrance_column {
    -            print!(".  ");
    -        }
    -        else {
    -            print!(".--");
    -        }
    -    }
    -    println!(".");
    -    //rest of maze
    -    for r in 0..height {
    -        print!("I");
    -        for c in 0..width {
    -            if walls[r][c]<2 {print!("  I");}
    -            else {print!("   ");}
    -        }
    -        println!();
    -        for c in 0..width {
    -            if walls[r][c] == 0 || walls[r][c]==2 {print!(":--");}
    -            else {print!(":  ");}
    -        }
    -        println!(".");
    -    }
    -
    -    //stops the program from ending until you give input, useful when running a compiled .exe
    -    println!("\n\npress ENTER to exit");
    -    io::stdin().read_line(&mut String::new()).expect("closing");
    -}
    -
    -fn get_user_input(prompt: &str) -> usize {
    -    //DATA
    -    let mut raw_input = String::new(); // temporary variable for user input that can be parsed later
    -
    -    //input loop
    -    return loop {
    -
    -        //print prompt
    -        println!("{}", prompt);
    -
    -        //read user input from standard input, and store it to raw_input
    -        raw_input.clear(); //clear input
    -        io::stdin().read_line(&mut raw_input).expect( "CANNOT READ INPUT!");
    -
    -        //from input, try to read a number
    -        match raw_input.trim().parse::() {
    -            Ok(i) => {
    -                if i>1 { //min size 1
    -                    break i; // this escapes the loop, returning i
    -                }
    -                else {
    -                    println!("INPUT OUT OF RANGE.  TRY AGAIN.");
    -                    continue;// run the loop again
    -                }
    -            }
    -            Err(e) => {
    -                println!("MEANINGLESS DIMENSION.  TRY AGAIN.  {}", e.to_string().to_uppercase());
    -                continue; // run the loop again
    -            }
    -        };
    -    }
    -}
    diff --git a/02_Amazing/vbnet/Amazing.sln b/02_Amazing/vbnet/Amazing.sln
    deleted file mode 100644
    index 81309fe0c..000000000
    --- a/02_Amazing/vbnet/Amazing.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index c619d3fac..000000000
    --- a/02_Amazing/vbnet/Amazing.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Amazing
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/02_Amazing/vbnet/program.vb b/02_Amazing/vbnet/program.vb
    index 0983c5b28..d39eb4508 100644
    --- a/02_Amazing/vbnet/program.vb
    +++ b/02_Amazing/vbnet/program.vb
    @@ -145,7 +145,7 @@ Module Program
                     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
    +            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 ==
    diff --git a/03_Animal/README.md b/03_Animal/README.md
    index a8ab0e45b..defaa7351 100644
    --- a/03_Animal/README.md
    +++ b/03_Animal/README.md
    @@ -20,7 +20,3 @@ As published in Basic Computer Games (1978)
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/03_Animal/csharp/Branch.cs b/03_Animal/csharp/Branch.cs
    index ca7b66c57..52c130372 100644
    --- a/03_Animal/csharp/Branch.cs
    +++ b/03_Animal/csharp/Branch.cs
    @@ -15,4 +15,4 @@ public override string ToString()
                 return $"{Text} : IsEnd {IsEnd}";
             }
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/03_Animal/java/Animal.java b/03_Animal/java/Animal.java
    new file mode 100644
    index 000000000..11e9e8892
    --- /dev/null
    +++ b/03_Animal/java/Animal.java
    @@ -0,0 +1,160 @@
    +import java.util.ArrayList;
    +import java.util.List;
    +import java.util.Locale;
    +import java.util.Scanner;
    +
    +/**
    + * ANIMAL
    + * 

    + * Converted from BASIC to Java by Aldrin Misquitta (@aldrinm) + */ +public class Animal { + + 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")); + + 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++; + } + } + + if (!correctGuess) { + askForInformationAndSave(scan, questions); + } + } + } + } + + } + + 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); + } + + 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 + + Question newOption; + if (newAnswer) { + newOption = new Question(newQuestion, animal, lastAnimal); + } else { + newOption = new Question(newQuestion, lastAnimal, animal); + } + questions.add(newOption); + } + + private static boolean askQuestion(Question question, Scanner scanner) { + System.out.printf("%s ? ", question.question); + + 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 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)); + } + + 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."); + } + + + public static class Question { + String question; + String trueAnswer; + String falseAnswer; + + public Question(String question, String trueAnswer, String falseAnswer) { + this.question = question; + this.trueAnswer = trueAnswer; + this.falseAnswer = falseAnswer; + } + } + +} + diff --git a/03_Animal/java/src/Animal.java b/03_Animal/java/src/Animal.java deleted file mode 100644 index 0a3875430..000000000 --- a/03_Animal/java/src/Animal.java +++ /dev/null @@ -1,246 +0,0 @@ -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). - * - * Bonus option: TREE --> prints the game decision data as a tree to visualize/debug the state of the game - */ -public class Animal { - - public static void main(String[] args) { - printIntro(); - Scanner scan = new Scanner(System.in); - - 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 "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. - - 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); - } - } - } - } - } - } - } - - /** - * 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(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); - - if (previous != null) { - if (previousToCurrentDecisionChoice) { - previous.setTrueAnswer(questionNode); - } else { - previous.setFalseAnswer(questionNode); - } - } - } - - private static boolean askQuestionAndGetReply(QuestionNode questionNode, Scanner scanner) { - System.out.printf("%s ? ", questionNode.question); - return readYesOrNo(scanner); - } - - 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:"); - - List leafNodes = collectLeafNodes(root); - String allAnimalsString = leafNodes.stream().map(AnimalNode::getAnimal).collect(Collectors.joining("\t\t")); - - System.out.println(allAnimalsString); - } - - //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 + " "); - } - } - - - /** - * Base interface for all nodes in our question tree - */ - private interface Node { - } - - 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 + "'}"; - } - } - -} diff --git a/03_Animal/java/test/AnimalJavaTest.kt b/03_Animal/java/test/AnimalJavaTest.kt deleted file mode 100644 index 0327a1d61..000000000 --- a/03_Animal/java/test/AnimalJavaTest.kt +++ /dev/null @@ -1,54 +0,0 @@ -import com.pcholt.console.testutils.ConsoleTest -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/javascript/animal.html b/03_Animal/javascript/animal.html index ab65daa5b..d13d8c7ba 100644 --- a/03_Animal/javascript/animal.html +++ b/03_Animal/javascript/animal.html @@ -1,10 +1,9 @@ ANIMAL - -

    
    +
    
     
     
     
    diff --git a/03_Animal/javascript/animal.js b/03_Animal/javascript/animal.js
    index ed539d27c..a9deae8cd 100644
    --- a/03_Animal/javascript/animal.js
    +++ b/03_Animal/javascript/animal.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    @@ -70,7 +70,7 @@ n = animals.length;
     
     function show_animals() {
         var x;
    -
    +    
         print("\n");
         print("ANIMALS I ALREADY KNOW ARE:\n");
         str = "";
    @@ -108,7 +108,7 @@ async function main()
                 if (str[0] == "Y")
                     break;
             }
    -
    +        
             k = 0;
             do {
                 // Subroutine to print questions
    @@ -119,7 +119,7 @@ async function main()
                         if (q[z] == "\\")
                             break;
                         str += q[z];
    -                }
    +                }	
                     print(str);
                     c = await input();
                     if (c[0] == "Y" || c[0] == "N")
    @@ -127,9 +127,9 @@ async function main()
                 }
                 t = "\\" + c[0];
                 x = q.indexOf(t);
    -            k = parseInt(q.substr(x + 2));
    +            k = parseInt(q.substr(x + 2));	
             } while (animals[k].substr(0,2) == "\\Q") ;
    -
    +        
             print("IS IT A " + animals[k].substr(2));
             a = await input();
             if (a[0] == "Y") {
    diff --git a/03_Animal/kotlin/src/Animal.kt b/03_Animal/kotlin/Animal.kt
    similarity index 100%
    rename from 03_Animal/kotlin/src/Animal.kt
    rename to 03_Animal/kotlin/Animal.kt
    diff --git a/03_Animal/kotlin/test/AnimalKtTest.kt b/03_Animal/kotlin/test/AnimalKtTest.kt
    deleted file mode 100644
    index 354efad6a..000000000
    --- a/03_Animal/kotlin/test/AnimalKtTest.kt
    +++ /dev/null
    @@ -1,54 +0,0 @@
    -import com.pcholt.console.testutils.ConsoleTest
    -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/lua/Animal.lua b/03_Animal/lua/Animal.lua
    deleted file mode 100644
    index 293c53e41..000000000
    --- a/03_Animal/lua/Animal.lua
    +++ /dev/null
    @@ -1,181 +0,0 @@
    ---
    --- Animal.lua
    ---
    -
    --- maintain a flat table/list of all the known animals
    -local animals = {
    -    "FISH",
    -    "BIRD"
    -}
    -
    --- store the questions as a binary tree with each node having a 
    --- "y" or "n" branch
    --- if the node has a member named "a" it's an answer, with an index
    --- into the animals list.
    --- Otherwise, it's a question that leads to more nodes.
    -local questionTree = {
    -    q = "DOES IT SWIM",
    -    y = { a = 1 },
    -    n = { a = 2 }
    -}
    -
    --- print the given prompt string and then wait for input
    --- loops until a non-empty input is given
    --- returns the input as an upper-case string
    -function askPrompt(promptString)
    -    local answered = false 
    -    local a
    -    while (not answered) do 
    -        print(promptString)
    -        a = io.read()
    -        a = string.upper(a)
    -        if (string.len(a) > 0) then 
    -            answered = true 
    -        end
    -    end
    -    return a
    -end
    -
    --- print the given prompt string and then wait for the
    --- user to enter a string beginning with "Y" or "N"
    -function askYesOrNo(promptString)
    -    local a
    -    while ((a ~= "Y") and (a ~= "N")) do 
    -        a = askPrompt(promptString)
    -        a = a:sub(1,1)
    -    end
    -    return a
    -end
    -
    --- prints the introductory text from the original BASIC program
    -function printIntro()
    -    print(string.format("%32s", " ") .. "ANIMAL")
    -    print(string.format("%15s", " ") .. "CREATIVE COMPUTING   MORRISTOWN, NEW JERSEY")
    -    print()
    -    print()
    -    print()
    -    print("PLAY 'GUESS THE ANIMAL'")
    -    print("THINK OF AN ANIMAL AND THE COMPUTER WILL TRY TO GUESS IT.")
    -    print()
    -end
    -
    --- prints the animals known in the source list
    -function listKnownAnimals()
    -    print()
    -    print("ANIMALS I ALREADY KNOW ARE:")
    -
    -    local x
    -    local item
    -    for x = 1,#animals do 
    -        -- use string.format to space each animal in a 12-character-wide "cell"
    -        item = string.format("%-12s", animals[x])
    -
    -        -- io.write() works like print(), but doesn't automatically add a carriage return/newline
    -        io.write(item)
    -
    -        -- every fifth item, start a new line
    -        if ((x % 5) == 0) then 
    -            io.write("\n")
    -        end
    -    end
    -
    -    print()
    -    print()
    -end
    -
    --- Prompts the user for info about the animal they were thinking of, then
    --- uses that to add a new branch to the tree
    ---      curNode: the node in the tree where the computer made a wrong guess
    ---      branch: the answer the user gave to curNode's question
    -function addAnimalToTree(curNode, branch)
    -    local newAnimal 
    -    local curResponse = curNode[branch]
    -    local guessedIndex = curResponse.a
    -    local guessedAnimal = animals[guessedIndex]
    -    local newQuestion, newAnswer, newIndex
    -    local newNode
    -
    -    newAnimal = askPrompt("THE ANIMAL YOU WERE THINKING OF WAS A ?")
    -    newQuestion = askPrompt("PLEASE TYPE IN A QUESTION THAT WOULD DISTINGUISH A "..
    -        tostring(newAnimal).." FROM A "..tostring(guessedAnimal))
    -    newAnswer = askYesOrNo("FOR A "..tostring(newAnimal).." THE ANSWER WOULD BE?")
    -
    -    -- add the new animal to the master list at the end, and
    -    -- save off its index in the list
    -    table.insert(animals, newAnimal)
    -    newIndex = #animals
    -
    -    -- create a new node for the question we just learned
    -    newNode = {}
    -    newNode.q = newQuestion
    -    if (newAnswer == "Y") then 
    -        newNode.y = { a = newIndex }
    -        newNode.n = { a = guessedIndex }
    -    else 
    -        newNode.y = { a = guessedIndex }
    -        newNode.n = { a = newIndex }
    -    end 
    -
    -    -- replace the previous answer with our new node
    -    curNode[branch] = newNode
    -end
    -
    --- Starts at the root of the question tree and asks questions about
    --- the user's animal until the computer hits an "a" answer node and tries
    --- to make a guess
    -function askAboutAnimal()
    -    local curNode = questionTree
    -    local finished = false
    -    local response, responseIndex
    -    local nextNode, animalName
    -    while (not finished) do 
    -        response = askYesOrNo(curNode.q .. "?")
    -        
    -        -- convert the response "Y" or "N" to the lowercase "y" or "n" that we use to name our branches
    -        branch = string.lower(response)
    -        nextNode = curNode[branch]
    -        
    -        -- is the next node an answer node, or another question?
    -        if (nextNode.a ~= nil) then 
    -            -- it's an answer, so make a guess
    -            animalName = animals[nextNode.a]
    -            response = askYesOrNo("IS IT A "..tostring(animalName).."?")
    -            if (response == "Y") then
    -                -- we got the correct answer, so prompt for a new animal
    -                print()
    -                print("WHY NOT TRY ANOTHER ANIMAL?")
    -            else 
    -                -- incorrect answer, so add a new entry at this point in the tree
    -                addAnimalToTree(curNode, branch)
    -            end
    -
    -            -- whether we were right or wrong, we're finished with this round
    -            finished = true
    -        else 
    -            -- it's another question, so advance down the tree
    -            curNode = nextNode
    -        end
    -    end
    -end
    -
    --- MAIN CONTROL SECTION
    -
    -printIntro()
    -
    --- loop forever until the player requests an exit by entering a blank line
    -local exitRequested = false
    -local answer 
    -
    -while (not exitRequested) do
    -    print("ARE YOU THINKING OF AN ANIMAL?")
    -    answer = io.read()
    -    answer = string.upper(answer)
    -
    -    if (string.len(answer) == 0) then
    -        exitRequested = true
    -    elseif (answer:sub(1,4) == "LIST") then
    -        listKnownAnimals()
    -    elseif (answer:sub(1,1) == "Y") then
    -        askAboutAnimal()
    -    end
    -end
    diff --git a/03_Animal/lua/README.md b/03_Animal/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/03_Animal/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/00_Alternate_Languages/10_Blackjack/pascal/README.md b/03_Animal/pascal/README.md
    similarity index 100%
    rename from 00_Alternate_Languages/10_Blackjack/pascal/README.md
    rename to 03_Animal/pascal/README.md
    diff --git a/03_Animal/python/animal.py b/03_Animal/python/animal.py
    index 1c29f2faf..65263917e 100644
    --- a/03_Animal/python/animal.py
    +++ b/03_Animal/python/animal.py
    @@ -1,46 +1,46 @@
    -"""
    -Animal
    -
    -From: Basic computer Games(1978)
    -
    -   Unlike other computer games in which the computer
    -  picks a number or letter and you must guess what it is,
    -  in this game you think of an animal and the computer asks
    -  you questions and tries to guess the name of your animal.
    -  If the computer guesses incorrectly, it will ask you for a
    -  question that differentiates the animal it guessed
    -  from the one you were thinking of. In this way the
    -  computer "learns" new animals. Questions to differentiate
    -  new animals should be input without a question mark.
    -   This version of the game does not have a SAVE feature.
    -  If your sistem allows, you may modify the program to
    -  save array A$, then reload the array  when you want
    -  to play the game again. This way you can save what the
    -  computer learns over a series of games.
    -   At any time if you reply 'LIST' to the question "ARE YOU
    -  THINKING OF AN ANIMAL", the computer will tell you all the
    -  animals it knows so far.
    -   The program starts originally by knowing only FISH and BIRD.
    -  As you build up a file of animals you should use broad,
    -  general questions first and then narrow down to more specific
    -  ones with later animals. For example, If an elephant was to be
    -  your first animal, the computer would ask for a question to distinguish
    -  an elephant from a bird. Naturally there are hundreds of possibilities,
    -  however, if you plan to build a large file of animals a good question
    -  would be "IS IT A MAMAL".
    -   This program can be easily modified to deal with categories of
    -  things other than animals by simply modifying the initial data
    -  in Line 530 and the dialogue references to animal in Lines 10,
    -  40, 50, 130, 230, 240 and 600. In an educational environment, this
    -  would be a valuable program to teach the distinguishing chacteristics
    -  of many classes of objects -- rock formations, geography, marine life,
    -  cell structures, etc.
    -   Originally developed by Arthur Luehrmann at Dartmouth College,
    -  Animal was subsequently shortened and modified by Nathan Teichholtz at
    -  DEC and Steve North at Creative Computing
    -"""
    -
    -from typing import Optional
    +########################################################
    +#
    +# Animal
    +#
    +# From: Basic computer Games(1978)
    +#
    +#    Unlike other computer games in which the computer
    +#   picks a number or letter and you must guess what it is,
    +#   in this game you think of an animal and the computer asks
    +#   you questions and tries to guess the name of your animal.
    +#   If the computer guesses incorrectly, it will ask you for a
    +#   question that differentiates the animal it guessed
    +#   from the one you were thinking of. In this way the
    +#   computer "learns" new animals. Questions to differentiate
    +#   new animals should be input without a question mark.
    +#    This version of the game does not have a SAVE feature.
    +#   If your sistem allows, you may modify the program to
    +#   save array A$, then reload the array  when you want
    +#   to play the game again. This way you can save what the
    +#   computer learns over a series of games.
    +#    At any time if you reply 'LIST' to the question "ARE YOU
    +#   THINKING OF AN ANIMAL", the computer will tell you all the
    +#   animals it knows so far.
    +#    The program starts originally by knowing only FISH and BIRD.
    +#   As you build up a file of animals you should use broad,
    +#   general questions first and then narrow down to more specific
    +#   ones with later animals. For example, If an elephant was to be
    +#   your first animal, the computer would ask for a question to distinguish
    +#   an elephant from a bird. Naturally there are hundreds of possibilities,
    +#   however, if you plan to build a large file of animals a good question
    +#   would be "IS IT A MAMAL".
    +#    This program can be easily modified to deal with categories of
    +#   things other than animals by simply modifying the initial data
    +#   in Line 530 and the dialogue references to animal in Lines 10,
    +#   40, 50, 130, 230, 240 and 600. In an educational environment, this
    +#   would be a valuable program to teach the distinguishing chacteristics
    +#   of many classes of objects -- rock formations, geography, marine life,
    +#   cell structures, etc.
    +#    Originally developed by Arthur Luehrmann at Dartmouth College,
    +#   Animal was subsequently shortened and modified by Nathan Teichholtz at
    +#   DEC and Steve North at Creative Computing
    +#
    +########################################################
     
     
     class Node:
    @@ -48,24 +48,20 @@ class Node:
         Node of the binary tree of questions.
         """
     
    -    def __init__(
    -        self, text: str, yes_node: Optional["Node"], no_node: Optional["Node"]
    -    ):
    +    def __init__(self, text, yes_node, no_node):
             # the nodes that are leafs have as text the animal's name, otherwise
             # a yes/no question
             self.text = text
             self.yes_node = yes_node
             self.no_node = no_node
     
    -    def update_node(
    -        self, new_question: str, answer_new_ques: str, new_animal: str
    -    ) -> None:
    +    def update_node(self, new_question, answer_new_ques, new_animal):
             # update the leaf with a question
             old_animal = self.text
             # we replace the animal with a new question
             self.text = new_question
     
    -        if answer_new_ques == "y":
    +        if answer_new_ques == 'y':
                 self.yes_node = Node(new_animal, None, None)
                 self.no_node = Node(old_animal, None, None)
             else:
    @@ -73,17 +69,17 @@ def update_node(
                 self.no_node = Node(new_animal, None, None)
     
         # the leafs have as children None
    -    def is_leaf(self) -> bool:
    -        return self.yes_node is None and self.no_node is None
    +    def is_leaf(self):
    +        return self.yes_node == None and self.no_node == None
     
     
    -def list_known_animals(root_node: Optional[Node]) -> None:
    -    """Traversing the tree by recursion until we reach the leafs."""
    -    if root_node is None:
    +def list_known_animals(root_node):
    +    # Traversing the tree by recursion until we reach the leafs
    +    if root_node == None:
             return
     
         if root_node.is_leaf():
    -        print(root_node.text, end=" " * 11)
    +        print(root_node.text, end=' '*11)
             return
     
         if root_node.yes_node:
    @@ -93,89 +89,88 @@ def list_known_animals(root_node: Optional[Node]) -> None:
             list_known_animals(root_node.no_node)
     
     
    -def parse_input(message: str, check_list: bool, root_node: Optional[Node]) -> str:
    -    """only accepts yes or no inputs and recognizes list operation"""
    -    token = ""
    -    while token not in ["y", "n"]:
    -        inp = input(message)
    +def parse_input(message, check_list, root_node):
    +    # only accepts yes or no inputs and recognizes list operation
    +    correct_input = False
    +    while not correct_input:
    +        try:
    +            inp = input(message)
     
    -        if check_list and inp.lower() == "list":
    -            print("Animals I already know are:")
    -            list_known_animals(root_node)
    -            print("\n")
    +            if check_list and inp.lower() == 'list':
    +                print('Animals I already know are:')
    +                list_known_animals(root_node)
    +                print('\n')
    +
    +            token = inp[0].lower()
    +            if token == 'y' or token == 'n':
    +                correct_input = True
    +        except IndexError:
    +            pass
     
    -        token = inp[0].lower() if len(inp) > 0 else ""
         return token
     
     
    -def avoid_void_input(message: str) -> str:
    -    answer = ""
    -    while not answer:
    +def avoid_void_input(message):
    +    answer = ''
    +    while answer == '':
             answer = input(message)
         return answer
     
     
    -def print_intro() -> None:
    -    print(" " * 32 + "Animal")
    -    print(" " * 15 + "Creative Computing Morristown, New Jersey\n")
    -    print("Play ´Guess the Animal´")
    -    print("Think of an animal and the computer will try to guess it.\n")
    -
    -
    -def main() -> None:
    -    # Initial tree
    -    yes_child = Node("Fish", None, None)
    -    no_child = Node("Bird", None, None)
    -    root = Node("Does it swim?", yes_child, no_child)
    -
    -    # Main loop of game
    -    print_intro()
    -    while (
    -        parse_input(
    -            "Are you thinking of an animal? ", True, root
    -        )
    -        == "y"
    -    ):
    -        keep_asking = True
    -        # Start traversing the tree by the root
    -        actual_node: Node = root
    -
    -        while keep_asking:
    -
    -            if not actual_node.is_leaf():
    -
    -                # we have to keep asking i.e. traversing nodes
    -                answer = parse_input(actual_node.text, False, None)
    -
    -                # As this is an inner node, both children are not None
    -                if answer == "y":
    -                    assert actual_node.yes_node is not None
    -                    actual_node = actual_node.yes_node
    -                else:
    -                    assert actual_node.no_node is not None
    -                    actual_node = actual_node.no_node
    +def initial_message():
    +    print(' '*32 + 'Animal')
    +    print(' '*15 + 'Creative Computing Morristown, New Jersey\n')
    +    print('Play ´Guess the Animal´')
    +    print('Think of an animal and the computer will try to guess it.\n')
    +
    +
    +# Initial tree
    +yes_child = Node('Fish', None, None)
    +no_child = Node('Bird', None, None)
    +root = Node('Does it swim?', yes_child, no_child)
    +
    +# Main loop of game
    +initial_message()
    +keep_playing = parse_input(
    +    'Are you thinking of an animal? ', True, root) == 'y'
    +while keep_playing:
    +    keep_asking = True
    +    # Start traversing the tree by the root
    +    actual_node = root
    +
    +    while keep_asking:
    +
    +        if not actual_node.is_leaf():
    +            # we have to keep asking i.e. traversing nodes
    +            answer = parse_input(actual_node.text, False, None)
    +
    +            if answer == 'y':
    +                actual_node = actual_node.yes_node
                 else:
    -                # we have reached a possible answer
    -                answer = parse_input(f"Is it a {actual_node.text}? ", False, None)
    -                if answer == "n":
    -                    # add the new animal to the tree
    -                    new_animal = avoid_void_input(
    -                        "The animal you were thinking of was a ? "
    -                    )
    -                    new_question = avoid_void_input(
    -                        "Please type in a question that would distinguish a "
    -                        f"{new_animal} from a {actual_node.text}: "
    -                    )
    -                    answer_new_question = parse_input(
    -                        f"for a {new_animal} the answer would be: ", False, None
    -                    )
    +                actual_node = actual_node.no_node
    +        else:
    +            # we have reached a possible answer
    +            answer = parse_input('Is it a {}? '.format(
    +                actual_node.text), False, None)
    +            if answer == 'n':
    +                # add the new animal to the tree
    +                new_animal = avoid_void_input(
    +                    'The animal you were thinking of was a ? ')
    +                new_question = avoid_void_input(
    +                    'Please type in a question that would distinguish a {} from a {}: '.format(new_animal, actual_node.text))
    +                answer_new_question = parse_input(
    +                    'for a {} the answer would be: '.format(new_animal), False, None)
    +
    +                actual_node.update_node(
    +                    new_question+'?', answer_new_question, new_animal)
     
    -                    actual_node.update_node(f"{new_question}?", answer_new_question, new_animal)
    +            else:
    +                print("Why not try another animal?")
     
    -                else:
    -                    print("Why not try another animal?")
    +            keep_asking = False
     
    -                keep_asking = False
    +    keep_playing = parse_input(
    +        'Are you thinking of an animal? ', True, root) == 'y'
     
     
     ########################################################
    @@ -195,6 +190,3 @@ def main() -> None:
     #   function  (Lines 120 to 130, 135, 158, 160, 168, 173)
     
     ########################################################
    -
    -if __name__ == "__main__":
    -    main()
    diff --git a/03_Animal/ruby/animal.rb b/03_Animal/ruby/animal.rb
    index bedf55248..5100b2aa3 100644
    --- a/03_Animal/ruby/animal.rb
    +++ b/03_Animal/ruby/animal.rb
    @@ -92,4 +92,4 @@ def main
     
     trap "SIGINT" do puts; exit 130 end
     
    -main
    +main
    \ No newline at end of file
    diff --git a/03_Animal/rust/Cargo.lock b/03_Animal/rust/Cargo.lock
    deleted file mode 100644
    index 9c4ba014c..000000000
    --- a/03_Animal/rust/Cargo.lock
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "animal"
    -version = "0.1.0"
    diff --git a/03_Animal/rust/Cargo.toml b/03_Animal/rust/Cargo.toml
    deleted file mode 100644
    index bf553e329..000000000
    --- a/03_Animal/rust/Cargo.toml
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -[package]
    -name = "animal"
    -version = "0.1.0"
    -edition = "2021"
    -
    -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
    -
    -[dependencies]
    diff --git a/03_Animal/rust/README.md b/03_Animal/rust/README.md
    deleted file mode 100644
    index 8b8ed57e0..000000000
    --- a/03_Animal/rust/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Rust](https://www.rust-lang.org/) by [Anton Kaiukov](https://github.com/batk0)
    diff --git a/03_Animal/rust/src/main.rs b/03_Animal/rust/src/main.rs
    deleted file mode 100644
    index a48c32689..000000000
    --- a/03_Animal/rust/src/main.rs
    +++ /dev/null
    @@ -1,291 +0,0 @@
    -/*******************************************************************************
    - * Animal
    - * 
    - * From: Basic computer Games(1978)
    - * 
    - *    Unlike other computer games in which the computer
    - *   picks a number or letter and you must guess what it is,
    - *   in this game you think of an animal and the computer asks
    - *   you questions and tries to guess the name of your animal.
    - *   If the computer guesses incorrectly, it will ask you for a
    - *   question that differentiates the animal it guessed
    - *   from the one you were thinking of. In this way the
    - *   computer "learns" new animals. Questions to differentiate
    - *   new animals should be input without a question mark.
    - *    This version of the game does not have a SAVE feature.
    - *   If your sistem allows, you may modify the program to
    - *   save array A$, then reload the array  when you want
    - *   to play the game again. This way you can save what the
    - *   computer learns over a series of games.
    - *    At any time if you reply 'LIST' to the question "ARE YOU
    - *   THINKING OF AN ANIMAL", the computer will tell you all the
    - *   animals it knows so far.
    - *    The program starts originally by knowing only FISH and BIRD.
    - *   As you build up a file of animals you should use broad,
    - *   general questions first and then narrow down to more specific
    - *   ones with later animals. For example, If an elephant was to be
    - *   your first animal, the computer would ask for a question to distinguish
    - *   an elephant from a bird. Naturally there are hundreds of possibilities,
    - *   however, if you plan to build a large file of animals a good question
    - *   would be "IS IT A MAMAL".
    - *    This program can be easily modified to deal with categories of
    - *   things other than animals by simply modifying the initial data
    - *   in Line 530 and the dialogue references to animal in Lines 10,
    - *   40, 50, 130, 230, 240 and 600. In an educational environment, this
    - *   would be a valuable program to teach the distinguishing chacteristics
    - *   of many classes of objects -- rock formations, geography, marine life,
    - *   cell structures, etc.
    - *    Originally developed by Arthur Luehrmann at Dartmouth College,
    - *   Animal was subsequently shortened and modified by Nathan Teichholtz at
    - *   DEC and Steve North at Creative Computing
    - ******************************************************************************/
    -/*******************************************************************************
    - * Porting notes:
    - * 
    - * The data structure used for the game is B-Tree where each leaf is an animal
    - * and non-leaf node is a question.
    - * 
    - * B-Tree is implemented in non-traditional way. It uses HashMap for string
    - * nodes data and use determenistic method to calculate keys for left (yes) and 
    - * right (no) nodes. (See comments in the code.)
    - * 
    - * The logic of the game mostly kept in `main` function with the use of some
    - * helper functions.
    - ******************************************************************************/
    -use std::collections::HashMap;
    -use std::io;
    -
    -/// Main function that contains all the logic.
    -fn main() {
    -    println!("{: ^80}", "Animal");
    -    println!("{: ^80}\n", "Creative Computing Morristown, New Jersey");
    -    println!("Play ´Guess the Animal´");
    -    println!("Think of an animal and the computer will try to guess it.\n");
    -
    -    // Initial game data
    -    let mut animal = BTree::new(
    -        "Does it swim".to_string(),
    -        "Fish".to_string(),
    -        "Bird".to_string(),
    -    );
    -    
    -    // Main game loop
    -    while keep_playing() {
    -        animal.restart();
    -        // Ask questions until player reaches an animal.
    -        while ! animal.is_leaf() {
    -            println!("{}? ", animal.get());
    -            if yes_no() {
    -                animal.yes();
    -            } else {
    -                animal.no();
    -            }
    -        }
    -        // Ask if this is the animal player is thinking of.
    -        println!("Is it a {}? ", animal.get());
    -        if ! yes_no() {
    -            // Add a new animal if it's not, and distiguish it from the existing
    -            // one with a question.
    -            println!("The animal you were thinking of was a ? ");
    -            let new_animal = read_input();
    -            let old_animal = animal.get();
    -            println!("Please type in a question that would distinguish a {} from a {}: ",
    -                new_animal, old_animal );
    -            let new_question = read_input();
    -                println!("for a {} the answer would be: ", new_animal);
    -            if yes_no() {
    -                animal.set(new_question, new_animal, old_animal)
    -            } else {
    -                animal.set(new_question, old_animal, new_animal)
    -            }
    -        }
    -        println!("Why not try another animal?");
    -    }
    -}
    -
    -/// Reads the input line from [`io::stdin`] and returns it as a [`String`].
    -fn read_input() -> String {
    -    let mut input = String::new();
    -    io::stdin().read_line(&mut input).unwrap();
    -    input.trim().parse::().unwrap()
    -}
    -
    -/// Asks the player whether the player wants to continue playing. Returns 
    -/// [`true`] if the answer is yes.
    -fn keep_playing() -> bool {
    -    println!("Are you thinking of an animal? ");
    -    yes_no()
    -}
    -
    -/// Checks whether given answer is `yes` or `no`, returns [`true`] if yes.
    -fn yes_no() -> bool {
    -    loop {
    -        let answer = read_input().to_lowercase();
    -        if answer != "y" && answer != "yes" && answer != "n" && answer != "no" {
    -            println!("Please type `yes` or `no`");
    -            continue;
    -        }
    -        return answer == "y" || answer == "yes";
    -    }
    -}
    -
    -/// Binary Tree data structure. Implemented the similar way to Max/Min Heap.
    -struct BTree {
    -    /// contains all nodes data (questions and animals).
    -    nodes: HashMap,
    -    /// contains the key to current node in the game.
    -    cursor: usize,
    -}
    -
    -impl BTree {
    -    /// Creates new [`BTree`] with one root node (question) and two childs 
    -    /// (animals).
    -    fn new(value: String, yes: String, no: String) -> BTree {
    -        let nodes: HashMap = HashMap::from([
    -            (0, value),
    -            (1, yes),
    -            (2, no),
    -        ]);
    -        BTree { nodes: nodes, cursor: 0 }
    -    }
    -    
    -    /// Returns the key for left node (yes) based on the postition of the 
    -    /// [`BTree::cursor`].
    -    fn get_yes_key(&self) -> usize {
    -        &self.cursor * 2 + 1
    -    }
    -
    -    /// Returns the key for right node (no) based on the postition of the 
    -    /// [`BTree::cursor`].
    -    fn get_no_key(&self) -> usize {
    -        &self.cursor * 2 + 2
    -    }
    -    
    -    /// Check if current node is a leaf (has no children).
    -    fn is_leaf(&self) -> bool {
    -        ! ( self.nodes.contains_key(&self.get_yes_key()) || 
    -            self.nodes.contains_key(&self.get_no_key()) )
    -    }
    -
    -    /// Moves cursor to `yes` (left node) if the node exists.
    -    fn yes(&mut self) {
    -        if self.nodes.contains_key(&self.get_yes_key()) {
    -            self.cursor = self.get_yes_key();   
    -        }
    -    }
    -
    -    /// Moves cursor to `no` (right node) if the node exists.
    -    fn no(&mut self) {
    -        if self.nodes.contains_key(&self.get_no_key()) {
    -            self.cursor = self.get_no_key();   
    -        }
    -    }
    -    
    -    /// Sets new value (question) and two children (animals) at current position
    -    /// of the [`BTree::cursor`].
    -    fn set(&mut self, value: String, yes: String, no: String) {
    -        if let Some(v) = self.nodes.get_mut(&self.cursor) {
    -            *v = value;
    -        }
    -        self.nodes.insert(self.get_yes_key(), yes);
    -        self.nodes.insert(self.get_no_key(), no);
    -    }
    -    
    -    /// Returns the value (question or animal) of the current node.
    -    fn get(&self) -> String {
    -        if let Some(t) = self.nodes.get(&self.cursor) {
    -            return t.to_string();
    -        }
    -        "".to_string()
    -    }
    -
    -    /// Reset cursor to 0 (root node).
    -    fn restart(&mut self) {
    -        self.cursor = 0;
    -    }
    -}
    -
    -#[cfg(test)]
    -mod tests {
    -    use super::*;
    -    
    -    #[test]
    -    fn test_new() {
    -        let got = BTree::new("root".to_string(), "yes".to_string(), "no".to_string());
    -        let want = BTree{nodes: HashMap::from([
    -            (0, "root".to_string()),
    -            (1, "yes".to_string()),
    -            (2, "no".to_string()),
    -        ]), cursor: 0};
    -        assert_eq!(got.nodes, want.nodes);
    -        assert_eq!(got.cursor, want.cursor);
    -    }
    -
    -    #[test]
    -    fn test_get() {
    -        let got = BTree::new("root".to_string(), "yes".to_string(), "no".to_string());
    -        let want = "root".to_string();
    -        assert_eq!(got.get(), want);
    -    }
    -
    -    #[test]
    -    fn test_set() {
    -        let mut got = BTree::new("root".to_string(), "yes".to_string(), "no".to_string());
    -        got.set("Root".to_string(), "Yes".to_string(), "No".to_string());
    -        let want = BTree{nodes: HashMap::from([
    -                (0, "Root".to_string()),
    -                (1, "Yes".to_string()),
    -                (2, "No".to_string()),
    -            ]), cursor: 0};
    -        assert_eq!(got.nodes, want.nodes);
    -        assert_eq!(got.cursor, want.cursor);
    -    }
    -
    -    #[test]
    -    fn test_yes() {
    -        let mut got = BTree::new("root".to_string(), "yes".to_string(), "no".to_string());
    -        let want = "yes".to_string();
    -        let want_cursor = 1;
    -        got.yes();
    -        assert_eq!(got.get(), want);
    -        assert_eq!(got.cursor, want_cursor);
    -    }
    -
    -    #[test]
    -    fn test_no() {
    -        let mut got = BTree::new("root".to_string(), "yes".to_string(), "no".to_string());
    -        let want = "no".to_string();
    -        let want_cursor = 2;
    -        got.no();
    -        assert_eq!(got.get(), want);
    -        assert_eq!(got.cursor, want_cursor);
    -    }
    -
    -    #[test]
    -    fn test_is_leaf() {
    -        let mut got = BTree::new("root".to_string(), "yes".to_string(), "no".to_string());
    -        assert!(!got.is_leaf(), "should not be leaf");
    -        got.yes();
    -        assert!(got.is_leaf(), "should be leaf");
    -    }
    -
    -    #[test]
    -    fn test_get_key() {
    -        let mut got = BTree::new("root".to_string(), "yes".to_string(), "no".to_string());
    -        assert_eq!(got.get_yes_key(), 1);
    -        assert_eq!(got.get_no_key(), 2);
    -        got.yes();
    -        assert_eq!(got.get_yes_key(), 3);
    -        assert_eq!(got.get_no_key(), 4);
    -    }
    -
    -    #[test]
    -    fn test_restart() {
    -        let mut got = BTree::new("root".to_string(), "yes".to_string(), "no".to_string());
    -        assert_eq!(got.cursor, 0);
    -        got.yes();
    -        assert_eq!(got.cursor, 1);
    -        got.restart();
    -        assert_eq!(got.cursor, 0);
    -    }
    -}
    diff --git a/03_Animal/vbnet/Animal.Tests/Animal.Tests.vbproj b/03_Animal/vbnet/Animal.Tests/Animal.Tests.vbproj
    deleted file mode 100644
    index 62a341e98..000000000
    --- a/03_Animal/vbnet/Animal.Tests/Animal.Tests.vbproj
    +++ /dev/null
    @@ -1,27 +0,0 @@
    -
    -
    -  
    -    Animal.Tests
    -    net6.0
    -    false
    -    On
    -  
    -
    -  
    -    
    -    
    -    
    -      runtime; build; native; contentfiles; analyzers; buildtransitive
    -      all
    -    
    -    
    -      runtime; build; native; contentfiles; analyzers; buildtransitive
    -      all
    -    
    -  
    -
    -  
    -    
    -  
    -
    -
    diff --git a/03_Animal/vbnet/Animal.Tests/EndOfInputsException.vb b/03_Animal/vbnet/Animal.Tests/EndOfInputsException.vb
    deleted file mode 100644
    index b584e451d..000000000
    --- a/03_Animal/vbnet/Animal.Tests/EndOfInputsException.vb
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -''' 
    -''' 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
    deleted file mode 100644
    index 7b21dfe20..000000000
    --- a/03_Animal/vbnet/Animal.Tests/MockConsole.vb
    +++ /dev/null
    @@ -1,60 +0,0 @@
    -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()
    -        Lines.Add(("", False))
    -    End Sub
    -
    -    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 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 EndOfInputsException
    -
    -        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
    deleted file mode 100644
    index f3d0c4943..000000000
    --- a/03_Animal/vbnet/Animal.Tests/TestContainer.vb
    +++ /dev/null
    @@ -1,118 +0,0 @@
    -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 EndOfInputsException)(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 EndOfInputsException)(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 EndOfInputsException)(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
    -
    -    ''' 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.sln b/03_Animal/vbnet/Animal.sln
    deleted file mode 100644
    index f3b48076d..000000000
    --- a/03_Animal/vbnet/Animal.sln
    +++ /dev/null
    @@ -1,31 +0,0 @@
    -
    -Microsoft Visual Studio Solution File, Format Version 12.00
    -# Visual Studio Version 17
    -VisualStudioVersion = 17.0.32112.339
    -MinimumVisualStudioVersion = 10.0.40219.1
    -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(ExtensibilityGlobals) = postSolution
    -		SolutionGuid = {88469A47-E30C-4763-A325-074101D16608}
    -	EndGlobalSection
    -EndGlobal
    diff --git a/03_Animal/vbnet/Animal/Animal.vbproj b/03_Animal/vbnet/Animal/Animal.vbproj
    deleted file mode 100644
    index f01d7b62b..000000000
    --- a/03_Animal/vbnet/Animal/Animal.vbproj
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -
    -  
    -    Exe
    -    Animal
    -    net6.0
    -    16.9
    -    On
    -  
    -
    diff --git a/03_Animal/vbnet/Animal/Branch.vb b/03_Animal/vbnet/Animal/Branch.vb
    deleted file mode 100644
    index 4af369bb1..000000000
    --- a/03_Animal/vbnet/Animal/Branch.vb
    +++ /dev/null
    @@ -1,29 +0,0 @@
    -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
    -
    -    ' Allows walking all the descendants recursively
    -    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/Animal/Game.vb b/03_Animal/vbnet/Animal/Game.vb
    deleted file mode 100644
    index 2da0bbb14..000000000
    --- a/03_Animal/vbnet/Animal/Game.vb
    +++ /dev/null
    @@ -1,158 +0,0 @@
    -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},
    -        {"true", True},
    -        {"t", True},
    -        {"1", True},
    -        {"no", False},
    -        {"n", False},
    -        {"false", False},
    -        {"f", False},
    -        {"0", False}
    -    }
    -
    -    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"},
    -        .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() - ' Print the program heading - console.WriteCenteredLines( -"ANIMAL -CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") - - ' Print the program description - 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 - ' List all the stored animals - console.Write( -" -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) - console.Write( -" - -") - 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 - ' 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, - currentBranch.No - ) - Loop - - ' 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 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 from the user - console.Write("THE ANIMAL YOU WERE THINKING OF WAS A ? ") - Dim newAnimal = console.ReadLine.ToUpperInvariant - - ' Get the question used to distinguish the new animal from the current end branch - 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 will 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 - 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/Animal/Program.vb b/03_Animal/vbnet/Animal/Program.vb deleted file mode 100644 index adb34932f..000000000 --- a/03_Animal/vbnet/Animal/Program.vb +++ /dev/null @@ -1,6 +0,0 @@ -Module Program - Sub Main() - Dim game As New Game(New ConsoleAdapter) - game.BeginLoop() - End Sub -End Module diff --git a/03_Animal/vbnet/Animal/Shared/ConsoleAdapter.vb b/03_Animal/vbnet/Animal/Shared/ConsoleAdapter.vb deleted file mode 100644 index b5b98d2fd..000000000 --- a/03_Animal/vbnet/Animal/Shared/ConsoleAdapter.vb +++ /dev/null @@ -1,28 +0,0 @@ -Public Class ConsoleAdapter - Inherits ConsoleAdapterBase - - Public Overrides Sub Write(value As Object) - Console.Write(value) - End Sub - - Public Overrides Sub WriteLine() - Console.WriteLine() - End Sub - - Public Overrides Sub WriteCenteredLines(value As Object) - If Console.CursorLeft <> 0 Then WriteLine() - Dim toWrite = If(value?.ToString, "") - 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 - 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/Animal/Shared/ConsoleAdapterBase.vb b/03_Animal/vbnet/Animal/Shared/ConsoleAdapterBase.vb deleted file mode 100644 index b08a59ce9..000000000 --- a/03_Animal/vbnet/Animal/Shared/ConsoleAdapterBase.vb +++ /dev/null @@ -1,13 +0,0 @@ -Public MustInherit Class ConsoleAdapterBase - Public MustOverride Sub Write(value As Object) - Public MustOverride Sub WriteLine() - 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/Animal/Shared/Extensions.vb b/03_Animal/vbnet/Animal/Shared/Extensions.vb deleted file mode 100644 index e10df441a..000000000 --- a/03_Animal/vbnet/Animal/Shared/Extensions.vb +++ /dev/null @@ -1,50 +0,0 @@ -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 - 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 - - 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 diff --git a/03_Animal/vbnet/README.md b/03_Animal/vbnet/README.md index 5d8a43bfb..98b702c7e 100644 --- a/03_Animal/vbnet/README.md +++ b/03_Animal/vbnet/README.md @@ -1,9 +1,3 @@ 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. diff --git a/04_Awari/README.md b/04_Awari/README.md index 173e86b36..a4b4d2da9 100644 --- a/04_Awari/README.md +++ b/04_Awari/README.md @@ -36,8 +36,3 @@ As published in Basic Computer Games (1978) Downloaded from Vintage Basic at http://www.vintage-basic.net/games.html - -#### Porting Notes - -(please note any difficulties or challenges in porting here) - diff --git a/04_Awari/csharp/Awari.sln b/04_Awari/csharp/Awari.sln deleted file mode 100644 index 492aa5801..000000000 --- a/04_Awari/csharp/Awari.sln +++ /dev/null @@ -1,25 +0,0 @@ - -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}") = "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(ExtensibilityGlobals) = postSolution - SolutionGuid = {7F5C288A-A6C6-4AC0-96E3-6A3B482A0947} - EndGlobalSection -EndGlobal diff --git a/04_Awari/csharp/Game.cs b/04_Awari/csharp/Game.cs index f4325cf78..8a673dea2 100644 --- a/04_Awari/csharp/Game.cs +++ b/04_Awari/csharp/Game.cs @@ -261,4 +261,4 @@ public enum GameWinner Draw, } -public record struct GameOutcome(GameWinner Winner, int Difference); +public record struct GameOutcome(GameWinner Winner, int Difference); \ No newline at end of file diff --git a/04_Awari/csharp/Program.cs b/04_Awari/csharp/Program.cs index e97cfdfef..750787e79 100644 --- a/04_Awari/csharp/Program.cs +++ b/04_Awari/csharp/Program.cs @@ -95,4 +95,4 @@ void ComputerTurn() Console.WriteLine($"MY MOVE IS {movesString}"); } -string Tab(int n) => new(' ', n); +string Tab(int n) => new(' ', n); \ No newline at end of file diff --git a/04_Awari/csharp/Awari.csproj b/04_Awari/csharp/csharp.csproj similarity index 100% rename from 04_Awari/csharp/Awari.csproj rename to 04_Awari/csharp/csharp.csproj diff --git a/04_Awari/javascript/awari.html b/04_Awari/javascript/awari.html index 4749690ab..1d3c62085 100644 --- a/04_Awari/javascript/awari.html +++ b/04_Awari/javascript/awari.html @@ -1,10 +1,9 @@ AWARI - -
    
    +
    
     
     
     
    diff --git a/04_Awari/javascript/awari.js b/04_Awari/javascript/awari.js
    index 0a6b47c2e..cda27c08b 100644
    --- a/04_Awari/javascript/awari.js
    +++ b/04_Awari/javascript/awari.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    @@ -65,7 +65,7 @@ function show_number(number)
     function show_board()
     {
         var i;
    -
    +    
         print("\n");
         print("   ");
         for (i = 12; i >= 7; i--)
    @@ -184,12 +184,12 @@ async function main()
             e = 0;
             for (i = 0; i <= 12; i++)
                 b[i] = 3;
    -
    +        
             c = 0;
             f[n] = 0;
             b[13] = 0;
             b[6] = 0;
    -
    +        
             while (1) {
                 show_board();
                 print("YOUR MOVE");
    diff --git a/04_Awari/kotlin/README.md b/04_Awari/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/04_Awari/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/04_Awari/lua/README.md b/04_Awari/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/04_Awari/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/00_Alternate_Languages/89_Tic-Tac-Toe/go/README.md b/04_Awari/pascal/README.md
    similarity index 100%
    rename from 00_Alternate_Languages/89_Tic-Tac-Toe/go/README.md
    rename to 04_Awari/pascal/README.md
    diff --git a/04_Awari/python/awari.py b/04_Awari/python/awari.py
    index df4906f58..c04cce263 100644
    --- a/04_Awari/python/awari.py
    +++ b/04_Awari/python/awari.py
    @@ -6,90 +6,114 @@
     Ported by Dave LeCompte
     """
     
    -# PORTING NOTES
    -#
    -# This game started out as 70 lines of BASIC, and I have ported it
    -# before. I find it somewhat amazing how efficient (densely packed) the
    -# original code is. Of course, the original code has fairly cryptic
    -# variable names (as was forced by BASIC's limitation on long (2+
    -# character) variable names). I have done my best here to interpret what
    -# each variable is doing in context, and rename them appropriately.
    -#
    -# I have endeavored to leave the logic of the code in place, as it's
    -# interesting to see a 2-ply game tree evaluation written in BASIC,
    -# along with what a reader in 2021 would call "machine learning".
    -#
    -# As each game is played, the move history is stored as base-6
    -# digits stored losing_book[game_number]. If the human player wins or
    -# draws, the computer increments game_number, effectively "recording"
    -# that loss to be referred to later. As the computer evaluates moves, it
    -# checks the potential game state against these losing game records, and
    -# if the potential move matches with the losing game (up to the current
    -# number of moves), that move is evaluated at a two point penalty.
    -#
    -# Compare this, for example with MENACE, a mechanical device for
    -# "learning" tic-tac-toe:
    -# https://en.wikipedia.org/wiki/Matchbox_Educable_Noughts_and_Crosses_Engine
    -#
    -# The base-6 representation allows game history to be VERY efficiently
    -# represented. I considered whether to rewrite this representation to be
    -# easier to read, but I elected to TRY to document it, instead.
    -#
    -# Another place where I have made a difficult decision between accuracy
    -# and correctness is inside the "wrapping" code where it considers
    -# "while human_move_end > 13". The original BASIC code reads:
    -#
    -# 830 IF L>13 THEN L=L-14:R=1:GOTO 830
    -#
    -# I suspect that the intention is not to assign 1 to R, but to increment
    -# R. I discuss this more in a porting note comment next to the
    -# translated code. If you wish to play a more accurate version of the
    -# game as written in the book, you can convert the increment back to an
    -# assignment.
    -#
    -# I continue to be impressed with this jewel of a game; as soon as I had
    -# the AI playing against me, it was beating me. I've been able to score
    -# a few wins against the computer, but even at its 2-ply lookahead, it
    -# beats me nearly always. I would like to become better at this game to
    -# explore the effectiveness of the "losing book" machine learning.
    -#
    -#
    -# EXERCISES FOR THE READER
    -# One could go many directions with this game:
    -# - change the initial number of stones in each pit
    -# - change the number of pits
    -# - only allow capturing if you end on your side of the board
    -# - don't allow capturing at all
    -# - don't drop a stone into the enemy "home"
    -# - go clockwise, instead
    -# - allow the player to choose to go clockwise or counterclockwise
    -# - instead of a maximum of two moves, allow each move that ends on the
    -#   "home" to be followed by a free move.
    -# - increase the AI lookahead
    -# - make the scoring heuristic a little more nuanced
    -# - store history to a file on disk (or in the cloud!) to allow the AI
    -#   to learn over more than a single session
    -
    -from typing import Dict, List, Tuple
    -
    -game_number: int = 0
    -move_count: int = 0
    -losing_book: List[int] = []
    +"""
    +
    +PORTING NOTES
    +
    +This game started out as 70 lines of BASIC, and I have ported it
    +before. I find it somewhat amazing how efficient (densely packed) the
    +original code is. Of course, the original code has fairly cryptic
    +variable names (as was forced by BASIC's limitation on long (2+
    +character) variable names). I have done my best here to interpret what
    +each variable is doing in context, and rename them appropriately.
    +
    +I have endeavored to leave the logic of the code in place, as it's
    +interesting to see a 2-ply game tree evaluation written in BASIC,
    +along with what a reader in 2021 would call "machine learning".
    +
    +As each game is played, the move history is stored as base-6
    +digits stored losing_book[game_number]. If the human player wins or
    +draws, the computer increments game_number, effectively "recording"
    +that loss to be referred to later. As the computer evaluates moves, it
    +checks the potential game state against these losing game records, and
    +if the potential move matches with the losing game (up to the current
    +number of moves), that move is evaluated at a two point penalty.  
    +
    +Compare this, for example with MENACE, a mechanical device for
    +"learning" tic-tac-toe:
    +https://en.wikipedia.org/wiki/Matchbox_Educable_Noughts_and_Crosses_Engine
    +
    +The base-6 representation allows game history to be VERY efficiently
    +represented. I considered whether to rewrite this representation to be
    +easier to read, but I elected to TRY to document it, instead.
    +
    +Another place where I have made a difficult decision between accuracy
    +and correctness is inside the "wrapping" code where it considers
    +"while human_move_end > 13". The original BASIC code reads:
    +
    +830 IF L>13 THEN L=L-14:R=1:GOTO 830
    +
    +I suspect that the intention is not to assign 1 to R, but to increment
    +R. I discuss this more in a porting note comment next to the
    +translated code. If you wish to play a more accurate version of the
    +game as written in the book, you can convert the increment back to an
    +assignment.
    +
    +
    +I continue to be impressed with this jewel of a game; as soon as I had
    +the AI playing against me, it was beating me. I've been able to score
    +a few wins against the computer, but even at its 2-ply lookahead, it
    +beats me nearly always. I would like to become better at this game to
    +explore the effectiveness of the "losing book" machine learning.
    +
    +
    +EXERCISES FOR THE READER
    +One could go many directions with this game:
    +
    +- change the initial number of stones in each pit
    +
    +- change the number of pits
    +
    +- only allow capturing if you end on your side of the board
    +
    +- don't allow capturing at all
    +
    +- don't drop a stone into the enemy "home"
    +
    +- go clockwise, instead
    +
    +- allow the player to choose to go clockwise or counterclockwise
    +
    +- instead of a maximum of two moves, allow each move that ends on the
    +  "home" to be followed by a free move.
    +
    +- increase the AI lookahead
    +
    +- make the scoring heuristic a little more nuanced
    +
    +- store history to a file on disk (or in the cloud!) to allow the AI
    +  to learn over more than a single session
    +
    +"""
    +
    +
    +game_number = 0
    +move_count = 0
    +losing_book = []
     n = 0
     
     MAX_HISTORY = 9
     LOSING_BOOK_SIZE = 50
     
     
    -def draw_pit(line: str, board, pit_index) -> str:
    +def print_with_tab(space_count, msg):
    +    if space_count > 0:
    +        spaces = " " * space_count
    +    else:
    +        spaces = ""
    +    print(spaces + msg)
    +
    +
    +def draw_pit(line, board, pit_index):
         val = board[pit_index]
    -    line += " "
    +    line = line + " "
         if val < 10:
    -        line += " "
    -    return line + str(val) + " "
    +        line = line + " "
    +    line = line + str(val) + " "
    +    return line
     
     
    -def draw_board(board) -> None:
    +def draw_board(board):
         print()
     
         # Draw the top (computer) pits
    @@ -113,7 +137,7 @@ def draw_board(board) -> None:
         print()
     
     
    -def play_game(board: List[int]) -> None:
    +def play_game(board):
         # Place the beginning stones
         for i in range(0, 13):
             board[i] = 3
    @@ -147,7 +171,7 @@ def play_game(board: List[int]) -> None:
                 print(msg)
                 break
             if landing_spot == home:
    -            landing_spot, is_still_going, home, msg = computer_move(f"{msg} , ", board)
    +            landing_spot, is_still_going, home, msg = computer_move(msg + " , ", board)
             if not is_still_going:
                 print(msg)
                 break
    @@ -156,7 +180,7 @@ def play_game(board: List[int]) -> None:
         game_over(board)
     
     
    -def computer_move(msg: str, board) -> Tuple[int, bool, int, str]:
    +def computer_move(msg, board):
         # This function does a two-ply lookahead evaluation; one computer
         # move plus one human move.
         #
    @@ -231,7 +255,7 @@ def computer_move(msg: str, board) -> Tuple[int, bool, int, str]:
                 # penalize that move.
                 for prev_game_number in range(game_number):
                     if losing_book[game_number] * 6 + move_digit == int(
    -                    losing_book[prev_game_number] / 6 ^ (7 - move_count) + 0.1  # type: ignore
    +                    losing_book[prev_game_number] / 6 ^ (7 - move_count) + 0.1
                     ):
                         computer_move_quality -= 2
     
    @@ -247,7 +271,7 @@ def computer_move(msg: str, board) -> Tuple[int, bool, int, str]:
     
         move_str = chr(42 + selected_move)
         if msg:
    -        msg += f", {move_str}"
    +        msg += ", " + move_str
         else:
             msg = move_str
     
    @@ -256,7 +280,7 @@ def computer_move(msg: str, board) -> Tuple[int, bool, int, str]:
         return move_number, is_still_going, home, msg
     
     
    -def game_over(board) -> None:
    +def game_over(board):
         print()
         print("GAME OVER")
     
    @@ -274,35 +298,43 @@ def game_over(board) -> None:
                 print(f"YOU WIN BY {pit_difference} POINTS")
     
     
    -def do_capture(m, home, board) -> None:
    +def do_capture(m, home, board):
         board[home] += board[12 - m] + 1
         board[m] = 0
         board[12 - m] = 0
     
     
    -def do_move(m, home, board) -> int:
    +def do_move(m, home, board):
         move_stones = board[m]
         board[m] = 0
     
    -    for _stones in range(move_stones, 0, -1):
    +    for stones in range(move_stones, 0, -1):
             m = m + 1
             if m > 13:
                 m = m - 14
             board[m] += 1
    -    if board[m] == 1 and (m != 6) and (m != 13) and (board[12 - m] != 0):
    -        do_capture(m, home, board)
    +    if board[m] == 1:
    +        # capture
    +        if (m != 6) and (m != 13) and (board[12 - m] != 0):
    +            do_capture(m, home, board)
         return m
     
     
    -def player_has_stones(board) -> bool:
    -    return any(board[i] > 0 for i in range(6))
    +def player_has_stones(board):
    +    for i in range(6):
    +        if board[i] > 0:
    +            return True
    +    return False
     
     
    -def computer_has_stones(board: Dict[int, int]) -> bool:
    -    return any(board[i] > 0 for i in range(7, 13))
    +def computer_has_stones(board):
    +    for i in range(7, 13):
    +        if board[i] > 0:
    +            return True
    +    return False
     
     
    -def execute_move(move, home: int, board) -> Tuple[int, bool, int]:
    +def execute_move(move, home, board):
         move_digit = move
         last_location = do_move(move, home, board)
     
    @@ -322,16 +354,19 @@ def execute_move(move, home: int, board) -> Tuple[int, bool, int]:
             # losses.
             losing_book[game_number] = losing_book[game_number] * 6 + move_digit
     
    -    is_still_going = bool(player_has_stones(board) and computer_has_stones(board))
    +    if player_has_stones(board) and computer_has_stones(board):
    +        is_still_going = True
    +    else:
    +        is_still_going = False
         return last_location, is_still_going, home
     
     
    -def player_move_again(board) -> Tuple[int, bool, int]:
    +def player_move_again(board):
         print("AGAIN")
         return player_move(board)
     
     
    -def player_move(board) -> Tuple[int, bool, int]:
    +def player_move(board):
         while True:
             print("SELECT MOVE 1-6")
             m = int(input()) - 1
    @@ -349,9 +384,11 @@ def player_move(board) -> Tuple[int, bool, int]:
         return ending_spot, is_still_going, home
     
     
    -def main() -> None:
    -    print(" " * 34 + "AWARI")
    -    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n")
    +def main():
    +    print_with_tab(34, "AWARI")
    +    print_with_tab(15, "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
    +    print()
    +    print()
     
         board = [0] * 14  # clear the board representation
         global losing_book
    diff --git a/04_Awari/rust/Cargo.lock b/04_Awari/rust/Cargo.lock
    deleted file mode 100644
    index 4fe2abbea..000000000
    --- a/04_Awari/rust/Cargo.lock
    +++ /dev/null
    @@ -1,75 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.10"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.147"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/04_Awari/rust/Cargo.toml b/04_Awari/rust/Cargo.toml
    deleted file mode 100644
    index 1c2935d47..000000000
    --- a/04_Awari/rust/Cargo.toml
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -[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"
    \ No newline at end of file
    diff --git a/04_Awari/rust/src/main.rs b/04_Awari/rust/src/main.rs
    deleted file mode 100644
    index 7aa008313..000000000
    --- a/04_Awari/rust/src/main.rs
    +++ /dev/null
    @@ -1,214 +0,0 @@
    -use std::{thread, time::Duration};
    -
    -use rand::Rng;
    -
    -// AI "learning" is not implemented. Don't have the time. - Ugur
    -
    -fn main() {
    -    loop {
    -        let mut game = Game::default();
    -
    -        loop {
    -            game.draw();
    -            if game.play_turn(false) {
    -                break;
    -            }
    -        }
    -    }
    -}
    -
    -enum DistributeResult {
    -    Normal,
    -    // Leftover beans
    -    EndOnHomePit(bool),
    -    // "true" if ended on Player Home Pit
    -    EndOnEmptyPit(usize),
    -    // "index" of the empty pit within the Row
    -    ChosenEmpty,
    -}
    -
    -struct Game {
    -    pits: [u8; 14],
    -    player_turn: bool,
    -}
    -
    -impl Default for Game {
    -    fn default() -> Self {
    -        println!("\n\n\t\t AWARI");
    -        println!("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
    -
    -        Self {
    -            pits: [3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 0],
    -            player_turn: true,
    -        }
    -    }
    -}
    -
    -impl Game {
    -    fn step_through(&mut self, mut index: usize) -> usize {
    -        let mut bean_amount = self.pits[index];
    -        self.pits[index] = 0;
    -
    -        loop {
    -            index += 1;
    -
    -            if index > self.pits.len() - 1 {
    -                index = 0;
    -            }
    -
    -            self.pits[index] += 1;
    -
    -            bean_amount -= 1;
    -            if bean_amount == 0 {
    -                return index;
    -            }
    -        }
    -    }
    -
    -    fn play_turn(&mut self, is_repeat: bool) -> bool {
    -        use DistributeResult::*;
    -
    -        if self.is_game_over() {
    -            println!("\nGame Over!");
    -            let (player_beans, ai_beans) = (self.pits[6], self.pits[13]);
    -            if player_beans == ai_beans {
    -                println!("It's a draw")
    -            } else if player_beans > ai_beans {
    -                println!("You win by {}", player_beans - ai_beans);
    -            } else {
    -                println!("I win by {}", ai_beans - player_beans);
    -            }
    -            return true;
    -        }
    -
    -        let chosen_index = if self.player_turn {
    -            player_prompt(if is_repeat { "Again?" } else { "Your move?" }) - 1
    -        } else {
    -            println!("========================");
    -
    -            thread::sleep(Duration::from_secs(1));
    -
    -            let non_empty_pits: Vec = self
    -                .pits
    -                .iter()
    -                .enumerate()
    -                .filter(|&(i, p)| (7..13).contains(&i) && *p > 0)
    -                .map(|(i, _)| i)
    -                .collect();
    -            let random_index = rand::thread_rng().gen_range(0..non_empty_pits.len());
    -            let ai_move = non_empty_pits[random_index];
    -
    -            println!("My move is {}", ai_move - 6);
    -
    -            println!("========================");
    -            ai_move
    -        };
    -
    -        match self.process_choice(chosen_index) {
    -            Normal => (),
    -            EndOnHomePit(player) => {
    -                self.draw();
    -
    -                if player == self.player_turn && !is_repeat {
    -                    self.play_turn(true);
    -                }
    -            }
    -            EndOnEmptyPit(last_index) => {
    -                let opposite_index = 12 - last_index;
    -                let home_index = if self.player_turn { 6 } else { 13 };
    -                let won_beans = 1 + self.pits[opposite_index];
    -
    -                self.pits[last_index] = 0;
    -                self.pits[opposite_index] = 0;
    -                self.pits[home_index] += won_beans;
    -            }
    -            ChosenEmpty => {
    -                println!("Chosen pit is empty");
    -                return self.play_turn(is_repeat);
    -            }
    -        }
    -
    -        if !is_repeat {
    -            self.player_turn = !self.player_turn;
    -        }
    -
    -        false
    -    }
    -
    -    pub fn process_choice(&mut self, index: usize) -> DistributeResult {
    -        use DistributeResult::*;
    -
    -        if self.pits[index] == 0 {
    -            return ChosenEmpty;
    -        }
    -
    -        let last_index = self.step_through(index);
    -
    -        if last_index == 6 && self.player_turn {
    -            return EndOnHomePit(true);
    -        } else if last_index == 13 && !self.player_turn {
    -            return EndOnHomePit(false);
    -        } else if self.pits[last_index] == 1 {
    -            return EndOnEmptyPit(last_index);
    -        }
    -
    -        Normal
    -    }
    -
    -    fn is_game_over(&self) -> bool {
    -        let player_empty = !(0..6).any(|i| self.pits[i] > 0);
    -        let ai_empty = !(7..13).any(|i| self.pits[i] > 0);
    -        player_empty || ai_empty
    -    }
    -
    -    fn draw(&self) {
    -        let row_as_string = |player: bool| -> String {
    -            let mut row_as_string = String::new();
    -
    -            let range = if player { 0..6 } else { 7..13 };
    -
    -            range.for_each(|i| {
    -                let mut bean_amount_as_string = self.pits[i].to_string();
    -                bean_amount_as_string.push_str("  ");
    -
    -                if player {
    -                    row_as_string.push_str(&bean_amount_as_string);
    -                } else {
    -                    row_as_string.insert_str(0, &bean_amount_as_string);
    -                }
    -            });
    -
    -            row_as_string
    -        };
    -
    -        println!(
    -            "\n  {}\n{}                  {}\n  {}\n",
    -            row_as_string(false),
    -            self.pits[13].to_string(),
    -            self.pits[6].to_string(),
    -            row_as_string(true)
    -        );
    -    }
    -}
    -
    -pub fn player_prompt(message: &str) -> usize {
    -    loop {
    -        let mut input = String::new();
    -        println!("{}", message);
    -
    -        if let Ok(_) = std::io::stdin().read_line(&mut input) {
    -            match input.trim().parse::() {
    -                Ok(n) => {
    -                    if (1..=6).contains(&n) {
    -                        return n;
    -                    } else {
    -                        println!("Enter a number between 1 and 6")
    -                    }
    -                }
    -                Err(e) => {
    -                    println!("{}", e);
    -                }
    -            }
    -        }
    -    }
    -}
    diff --git a/04_Awari/vbnet/Awari.sln b/04_Awari/vbnet/Awari.sln
    deleted file mode 100644
    index ef0fd0cf0..000000000
    --- a/04_Awari/vbnet/Awari.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 368d6f02c..000000000
    --- a/04_Awari/vbnet/Awari.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Awari
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/05_Bagels/README.md b/05_Bagels/README.md
    index 0a13accef..51d324bbc 100644
    --- a/05_Bagels/README.md
    +++ b/05_Bagels/README.md
    @@ -18,7 +18,3 @@ As published in Basic Computer Games (1978)
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/05_Bagels/csharp/BagelNumber.cs b/05_Bagels/csharp/BagelNumber.cs
    index 86a048f24..2fd660e9a 100644
    --- a/05_Bagels/csharp/BagelNumber.cs
    +++ b/05_Bagels/csharp/BagelNumber.cs
    @@ -54,7 +54,7 @@ public BagelNumber(string number)
     
     			_digits = number.Select(d => d - '0').ToArray();
     		}
    -
    +			
     		//public BagelNumber(long number)
     		//{
     		//	var digits = new List();
    @@ -118,4 +118,4 @@ private static void Shuffle(int[] digits)
     			return (pico, fermi);
     		}
     	}
    -}
    +}
    \ No newline at end of file
    diff --git a/05_Bagels/csharp/Bagels.csproj b/05_Bagels/csharp/Bagels.csproj
    index 54cdbe422..68fa11ec0 100644
    --- a/05_Bagels/csharp/Bagels.csproj
    +++ b/05_Bagels/csharp/Bagels.csproj
    @@ -3,6 +3,7 @@
       
         Exe
         net5.0
    +    BasicComputerGames.Bagels
       
     
       
    diff --git a/05_Bagels/csharp/Bagels.sln b/05_Bagels/csharp/Bagels.sln
    deleted file mode 100644
    index 3aaa718ba..000000000
    --- a/05_Bagels/csharp/Bagels.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/csharp/Game.cs b/05_Bagels/csharp/Game.cs
    index 7015d20f6..f6885464d 100644
    --- a/05_Bagels/csharp/Game.cs
    +++ b/05_Bagels/csharp/Game.cs
    @@ -121,4 +121,4 @@ private void DisplayIntroText()
     			Console.ReadKey(true);
     		}
     	}
    -}
    +}
    \ No newline at end of file
    diff --git a/05_Bagels/csharp/GameBase.cs b/05_Bagels/csharp/GameBase.cs
    index 2591c0f97..db8af5ae3 100644
    --- a/05_Bagels/csharp/GameBase.cs
    +++ b/05_Bagels/csharp/GameBase.cs
    @@ -36,4 +36,4 @@ protected bool TryAgain()
     		}
     
     	}
    -}
    +}
    \ No newline at end of file
    diff --git a/05_Bagels/java/BagelGame.java b/05_Bagels/java/BagelGame.java
    index d299dec5e..19a621c93 100644
    --- a/05_Bagels/java/BagelGame.java
    +++ b/05_Bagels/java/BagelGame.java
    @@ -16,34 +16,34 @@
     import java.util.Set;
     
     public class BagelGame {
    -
    +  
       public static final String CORRECT = "FERMI FERMI FERMI";
       public static final int MAX_GUESSES = 20;
    -
    +  
       enum GameState {
           RUNNING,
           WON,
           LOST
         }
    -
    +    
       private GameState      state = GameState.RUNNING;
       private List  secretNum;
       private int            guessNum = 1;
    -
    +  
       public BagelGame() {
         // No-arg constructor for when you don't need to set the seed
         this(new Random());
       }
    -
    +  
       public BagelGame(long seed) {
         // Setting the seed as a long value
         this(new Random(seed));
       }
    -
    +  
       public BagelGame(Random rand) {
         // This is the "real" constructor, which expects an instance of
         // Random to use for shuffling the digits of the secret number.
    -
    +    
         // Since the digits cannot repeat in our "number", we can't just
         // pick three random 0-9 integers. Instead, we'll treat it like
         // a deck of ten cards, numbered 0-9.
    @@ -57,23 +57,23 @@ public BagelGame(Random rand) {
         // uses a fresh Random class PRNG, but we're supplying our own
         // to give us controll over whether or not we set the seed
         Collections.shuffle(digits, rand);
    -
    +    
         // Just take the first three digits
         secretNum = digits.subList(0, 3);
       }
    -
    +  
       public boolean isOver() {
         return state != GameState.RUNNING;
       }
    -
    +  
       public boolean isWon() {
         return state == GameState.WON;
       }
    -
    +    
       public int getGuessNum() {
         return guessNum;
       }
    -
    +  
       public String getSecretAsString() {
         // Convert the secret number to a three-character string
         String secretString = "";
    @@ -82,7 +82,7 @@ public String getSecretAsString() {
         }
         return secretString;
       }
    -
    +  
       @Override
       public String toString() {
         // Quick report of game state for debugging purposes
    @@ -91,13 +91,13 @@ public String toString() {
         s += "Secret Number: " + secretNum;
         return s;
       }
    -
    +  
       public String validateGuess(String guess) {
         // Checks the passed string and returns null if it's a valid guess
         // (i.e., exactly three numeric characters)
         // If not valid, returns an "error" string to display to user.
         String error = "";
    -
    +    
         if (guess.length() == 3) {
           // Correct length. Are all the characters numbers?
           try {
    @@ -122,20 +122,20 @@ public String validateGuess(String guess) {
     
         return error;
       }
    -
    +  
       public String makeGuess(String s) throws IllegalArgumentException {
         // Processes the passed guess string (which, ideally, should be
         // validated by previously calling validateGuess)
         // Return a response string (PICO, FERMI, etc.) if valid
         // Also sets game state accordingly (sets win state or increments
         // number of guesses)
    -
    +    
         // Convert string to integer list, just to keep things civil
         List guess = new ArrayList(3);
         for (int i = 0; i < 3; i++) {
           guess.add((int)s.charAt(i) - 48);
         }
    -
    +    
         // Build response string...
         String response = "";
         // Correct digit, but in wrong place?
    @@ -177,5 +177,5 @@ public String makeGuess(String s) throws IllegalArgumentException {
         }
         return response;
       }
    -
    -}
    +    
    +}
    \ No newline at end of file
    diff --git a/05_Bagels/java/Bagels.java b/05_Bagels/java/Bagels.java
    index 8b4174ac3..435b5644c 100644
    --- a/05_Bagels/java/Bagels.java
    +++ b/05_Bagels/java/Bagels.java
    @@ -35,7 +35,7 @@
     public class Bagels {
     
       public static void main(String[] args) {
    -
    +    
         int gamesWon = 0;
     
         // Intro text
    @@ -43,7 +43,7 @@ public static void main(String[] args) {
         System.out.println("Creative Computing  Morristown, New Jersey");
         System.out.println("\n\n");
         System.out.print("Would you like the rules (Yes or No)? ");
    -
    +    
         // Need instructions?
         Scanner scan = new Scanner(System.in);
         String s = scan.nextLine();
    @@ -55,15 +55,15 @@ public static void main(String[] args) {
           System.out.println("   FERMI  - One digit correct and in the right position");
           System.out.println("   BAGELS - No digits correct");
         }
    -
    +    
         // Loop for playing multiple games
         boolean stillPlaying = true;
         while(stillPlaying) {
    -
    +      
           // Set up a new game
           BagelGame game = new BagelGame();
           System.out.println("\nO.K.  I have a number in mind.");
    -
    +    
           // Loop guess and responsses until game is over
           while (!game.isOver()) {
             String guess = getValidGuess(game);
    @@ -73,7 +73,7 @@ public static void main(String[] args) {
               System.out.println(response);
             }
           }
    -
    +    
           // Game is over. But did we win or lose?
           if (game.isWon()) {
             System.out.println("You got it!!!\n");
    @@ -83,24 +83,24 @@ public static void main(String[] args) {
             System.out.print("That's " + BagelGame.MAX_GUESSES + " guesses.  ");
             System.out.println("My number was " + game.getSecretAsString());
           }
    -
    +      
           stillPlaying = getReplayResponse();
         }
    -
    +    
         // Print goodbye message
         if (gamesWon > 0) {
           System.out.println("\nA " + gamesWon + " point Bagels buff!!");
         }
         System.out.println("Hope you had fun.  Bye.\n");
       }
    -
    +  
       private static String getValidGuess(BagelGame game) {
         // Keep asking for a guess until valid
         Scanner scan = new Scanner(System.in);
         boolean valid = false;
         String guess = "";
         String error;
    -
    +    
         while (!valid) {
           System.out.print("Guess # " + game.getGuessNum() + "     ? ");
           guess = scan.nextLine().trim();
    @@ -113,7 +113,7 @@ private static String getValidGuess(BagelGame game) {
         }
         return guess;
       }
    -
    +  
       private static boolean getReplayResponse() {
         // keep asking for response until valid
         Scanner scan = new Scanner(System.in);
    @@ -126,5 +126,8 @@ private static boolean getReplayResponse() {
           }
         }
       }
    -
    +  
     }
    +
    +
    +
    diff --git a/05_Bagels/javascript/bagels.html b/05_Bagels/javascript/bagels.html
    index 25224a9fd..714c3c9a9 100644
    --- a/05_Bagels/javascript/bagels.html
    +++ b/05_Bagels/javascript/bagels.html
    @@ -1,10 +1,9 @@
     
     
     BAGELS
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/05_Bagels/javascript/bagels.js b/05_Bagels/javascript/bagels.js
    index c0d519e2b..37fa36652 100644
    --- a/05_Bagels/javascript/bagels.js
    +++ b/05_Bagels/javascript/bagels.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    @@ -84,7 +84,7 @@ async function main()
                 } while (j >= 1) ;
             }
             print("\n");
    -        print("OK.  I HAVE A NUMBER IN MIND.\n");
    +        print("O.K.  I HAVE A NUMBER IN MIND.\n");
             for (i = 1; i <= 20; i++) {
                 while (1) {
                     print("GUESS #" + i);
    @@ -142,7 +142,7 @@ async function main()
                 print("\n");
             } else {
                 print("OH WELL.\n");
    -            print("THAT'S YOUR TWENTIETH GUESS.  MY NUMBER WAS " + a[1] + a[2] + a[3]);
    +            print("THAT'S A TWENTY GUESS.  MY NUMBER WAS " + a[1] + a[2] + a[3]);
             }
             y++;
             print("PLAY AGAIN (YES OR NO)");
    @@ -154,7 +154,7 @@ async function main()
             print("HOPE YOU HAD FUN.  BYE.\n");
         else
             print("\nA " + y + " POINT BAGELS BUFF!!\n");
    -
    +    
     }
     
     main();
    diff --git a/05_Bagels/kotlin/README.md b/05_Bagels/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/05_Bagels/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/05_Bagels/kotlin/bagels.kt b/05_Bagels/kotlin/bagels.kt
    deleted file mode 100644
    index 5948b42bd..000000000
    --- a/05_Bagels/kotlin/bagels.kt
    +++ /dev/null
    @@ -1,118 +0,0 @@
    -import java.util.Random
    -
    -fun main() {
    -    println("BAGELS")
    -    println("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
    -    var a = mutableListOf(0, 0, 0)
    -    var y = 0
    -    var t = 255
    -    println()
    -    println()
    -    println()
    -    println("WOULD YOU LIKE THE RULES (YES OR NO)? ")
    -    var astring = readLine()
    -    if (astring?.substring(0, 1) != "N") {
    -        println()
    -        println()
    -        println("I AM THINKING OF A THREE-DIGIT NUMBER.  TRY TO GUESS")
    -        println("MY NUMBER AND I WILL GIVE YOU CLUES AS FOLLOWS:")
    -        println("   PICO   - ONE DIGIT CORRECT BUT IN THE WRONG POSITION")
    -        println("   FERMI  - ONE DIGIT CORRECT AND IN THE RIGHT POSITION")
    -        println("   BAGELS - NO DIGITS CORRECT")
    -    }
    -    var i = 0
    -    var random = Random()
    -    while (i < 3) {
    -        a[i] = random.nextInt(9) + 1
    -        if (i > 0) {
    -            for (j in 0 until i) {
    -                if (a[i] == a[j])
    -                {
    -                    a[i] = random.nextInt(9) + 1
    -                    i--
    -                }
    -            }
    -        }
    -        i++
    -    }
    -    println()
    -    println("O.K.  I HAVE A NUMBER IN MIND.")
    -    do {
    -        var i = 1
    -        while (i <= 20) {
    -            do {
    -                var repeatGuess = false
    -                println("GUESS #" + i)
    -                astring = readLine()
    -                if (astring?.length != 3) {
    -                    println("TRY GUESSING A THREE-DIGIT NUMBER.")
    -                    repeatGuess = true
    -                } else {
    -                    for (j in 0..2) {
    -                        if (astring[j].toInt() < 48 || astring[j].toInt() > 57) {
    -                            println("WHAT?")
    -                            repeatGuess = true
    -                        }
    -                    }
    -
    -                    if (astring[0] == astring[1] ||
    -                        astring[1] == astring[2] ||
    -                        astring[2] == astring[0]
    -                    ) {
    -                        println("OH, I FORGOT TO TELL YOU THAT THE NUMBER I HAVE IN MIND")
    -                        println("HAS NO TWO DIGITS THE SAME.")
    -                        repeatGuess = true
    -                    }
    -                }
    -            } while (repeatGuess);
    -
    -            var c = 0
    -            var d = 0
    -            for (j in 0..2) {
    -                if (astring!![j]?.toInt() - 48 == a[j]) {
    -                    c++
    -                    d++
    -                }
    -                if (j < 2 && astring!![j]?.toInt() - 48 == a[j + 1]) c++
    -            }
    -            if (astring!![2]?.toInt() - 48 == a[0]) c++
    -            if (astring!![0]?.toInt() - 48 == a[2]) c++
    -
    -            if (d == 3) {
    -                break;
    -            }
    -            if (c != 0) {
    -                for (j in 1..c) {
    -                    print("PICO ")
    -                }
    -            }
    -            if (d != 0) {
    -                for (j in 1..d) {
    -                    print("FERMI ")
    -                }
    -            }
    -            if (c + d == 0) {
    -                print("BAGELS ")
    -            }
    -            println()
    -            i++
    -        }
    -
    -        if (i == 21) {
    -            println("OH WELL.")
    -            println("THAT'S TWENTY GUESSES.  MY NUMBER WAS " + a[0] + a[1] + a[2])
    -        }
    -        else {
    -            println("YOU GOT IT!!!")
    -            println()
    -            y++
    -        }
    -        println("PLAY AGAIN (YES OR NO)?")
    -        astring = readLine()
    -    } while (astring?.substring(0, 1) == "Y");
    -    if (y != 0) {
    -        println()
    -        println("A $y POINT BAGELS BUFF!!")
    -    }
    -    println ("HOPE YOU HAD FUN.  BYE.")
    -}
    diff --git a/05_Bagels/lua/Bagels.lua b/05_Bagels/lua/Bagels.lua
    deleted file mode 100644
    index 57c352977..000000000
    --- a/05_Bagels/lua/Bagels.lua
    +++ /dev/null
    @@ -1,121 +0,0 @@
    ----
    ---- Bagels
    ---- Ported by Joe Nellis.
    ---- Text displayed is altered slightly from the original program to allow for
    ---- more (or less) than three digits to be guessed. Change the difficulty to
    ---- the number of digits you wish in the secret code.
    ----
    -
    ---- difficult is number of digits to use
    -local difficulty = 3
    -
    -print [[
    -                                BAGELS
    -              CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY
    -
    -]]
    -
    -function getInput(prompt)
    -    io.write(prompt)
    -    io.flush()
    -    local input = io.read("l") 
    -    if not input then  --- test for EOF
    -        print("GOODBYE")
    -        os.exit(0)
    -    end
    -    return input
    -end
    -
    -local needsRules = getInput("WOULD YOU LIKE THE RULES? (YES OR NO) ")
    -print()
    -if needsRules:match("[yY].*") then
    -    print(string.format( [[
    -I AM THINKING OF A %u DIGIT NUMBER.  TRY TO GUESS
    -MY NUMBER AND I WILL GIVE YOU CLUES AS FOLLOWS:
    -   PICO   - ONE DIGIT CORRECT BUT IN THE WRONG POSITION
    -   FERMI  - ONE DIGIT CORRECT AND IN THE RIGHT POSITION
    -   BAGELS - NO DIGITS
    -   ]], difficulty))
    -end
    -
    -function play(numDigits, score)
    -    local digits = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" }
    -    --- secret number must not have duplicate digits
    -    --- randomly swap numDigits at the head of this list to create secret number
    -    for i = 1, numDigits do
    -        local j = math.random(1, 10)
    -        digits[i], digits[j] = digits[j], digits[i]
    -    end
    -
    -    print "O.K.  I HAVE A NUMBER IN MIND."
    -    for guessNum = 1, 20 do
    -        :: GUESS_AGAIN :: --- 0) then
    -            print("A", score, "POINT BAGELS BUFF!!")
    -        end
    -        print "HOPE YOU HAD FUN. BYE."
    -    end
    -end
    -
    -play(difficulty, 0) --- default is numDigits=3, score=0
    -
    diff --git a/05_Bagels/lua/README.md b/05_Bagels/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/05_Bagels/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/00_Alternate_Languages/89_Tic-Tac-Toe/pascal/README.md b/05_Bagels/pascal/README.md
    similarity index 100%
    rename from 00_Alternate_Languages/89_Tic-Tac-Toe/pascal/README.md
    rename to 05_Bagels/pascal/README.md
    diff --git a/05_Bagels/perl/bagels.pl b/05_Bagels/perl/bagels.pl
    index 94a7744bd..739ded0e0 100755
    --- a/05_Bagels/perl/bagels.pl
    +++ b/05_Bagels/perl/bagels.pl
    @@ -20,7 +20,7 @@ sub yes_input {
     print ' 'x32; print "Bagels\n";
     print ' 'x14; print "Creative Computing  Morristown, New Jersey\n\n";
     
    -# Provide instructions if requested
    +# Provide instructions if requested 
     print "Would you like the rules (yes or no)? ";
     if (yes_input()) {
     
    @@ -39,7 +39,7 @@ sub yes_input {
     # There are three code loops here. The outermost one, labeled 'PLAY',
     # performs one game start to finish every time it runs.
     # The next loop is a for loop that implements the required 20 guesses.
    -# And the innermost loop, labeled 'CHECK', does the game logic of
    +# And the innermost loop, labeled 'CHECK', does the game logic of 
     # checking the user's guess to make sure it's valid, figuring out
     # the response, and rewarding the user if they won.
     
    @@ -59,7 +59,7 @@ sub yes_input {
     
             # Note that the CHECK loop will automatically loop to ask
             # for the user's input, and it's only with the 'next' and
    -        # 'last' statements that this loop is exited. So if the
    +        # 'last' statements that this loop is exited. So if the 
             # user's input is somehow invalid, we just print out an
             # appropriate message. Execution will by default return
             # to the start of the loop, and only leaves the loop if
    @@ -75,15 +75,15 @@ sub yes_input {
                 if ($A !~ m{^(\d)(\d)(\d)$}) {
                     print "What?\n";
                     # Program execution will now pass through the rest
    -                # of the logic below and loop back to the start
    +                # of the logic below and loop back to the start 
                     # of the CHECK loop.
                 } else {
     
    -                # As a side effect of the regex match above, the
    +                # As a side effect of the regex match above, the 
                     # $1, $2, and $3 variables are each of the digits
                     # of the user's guess. Perl treats numbers and
                     # strings interchangably, so we will not have to
    -                # use the ASC() conversion functions required
    +                # use the ASC() conversion functions required 
                     # by the BASIC program.
                     my @B = ($1,$2,$3);
     
    @@ -134,11 +134,11 @@ sub yes_input {
     
                         # Print out the clues. The 'x' operator
                         # prints out the string the indicated number
    -                    # of times. The "BAGELS" line uses Perl's
    -                    # ternary operator to print the word if
    +                    # of times. The "BAGELS" line uses Perl's 
    +                    # ternary operator to print the word if 
                         # the expression ($C + $D) is equal to 0.
     
    -                    printf("%s%s%s\n",
    +                    printf("%s%s%s\n", 
                             "PICO " x$C,
                             "FERMI "x$D,
                             ($C+$D==0 ? "BAGELS" : '')
    @@ -152,11 +152,11 @@ sub yes_input {
                 } # end of regex match else block
     
                 # If program execution reaches this particular point,
    -            # then the user's input has not been accepted (the
    +            # then the user's input has not been accepted (the 
                 # only ways out of this loop are the "next PLAY" statement
                 # when the user wins, and the "last CHECK" statement
                 # when the user's input is successfully parsed).
    -            # So the program execution goes back to the top of the
    +            # So the program execution goes back to the top of the 
                 # CHECK loop, printing the request for user input
                 # again.
     
    @@ -183,7 +183,7 @@ sub yes_input {
     
         # This 'continue' loop is reached either when the PLAY loop has completed
         # or via the 'next PLAY' statement when the user wins a game. In either
    -    # case we ask if the player wants to go again, and use the 'last'
    +    # case we ask if the player wants to go again, and use the 'last' 
         # statement to exit the loop if the response is not yes.
         print "Play again (yes or no) ? ";
         last unless yes_input();
    diff --git a/05_Bagels/python/bagels.py b/05_Bagels/python/bagels.py
    index e0662d18c..b56a75d02 100644
    --- a/05_Bagels/python/bagels.py
    +++ b/05_Bagels/python/bagels.py
    @@ -1,42 +1,44 @@
    -"""
    -Bagels
    -
    -From: BASIC Computer Games (1978)
    -      Edited by David H. Ahl
    -
    -"In this game, the computer picks a 3-digit secret number using
    - the digits 0 to 9 and you attempt to guess what it is.  You are
    - allowed up to twenty guesses.  No digit is repeated.  After
    - each guess the computer will give you clues about your guess
    - as follows:
    -
    - PICO     One digit is correct, but in the wrong place
    - FERMI    One digit is in the correct place
    - BAGELS   No digit is correct
    -
    -"You will learn to draw inferences from the clues and, with
    - practice, you'll learn to improve your score.  There are several
    - good strategies for playing Bagels.  After you have found a good
    - strategy, see if you can improve it.  Or try a different strategy
    - altogether and see if it is any better.  While the program allows
    - up to twenty guesses, if you use a good strategy it should not
    - take more than eight guesses to get any number.
    -
    -"The original authors of this program are D. Resek and P. Rowe of
    - the Lawrence Hall of Science, Berkeley, California."
    -
    -
    -Python port by Jeff Jetton, 2019
    -"""
    +######################################################################
    +#
    +# Bagels
    +#
    +# From: BASIC Computer Games (1978)
    +#       Edited by David H. Ahl
    +#
    +# "In this game, the computer picks a 3-digit secret number using
    +#  the digits 0 to 9 and you attempt to guess what it is.  You are
    +#  allowed up to twenty guesses.  No digit is repeated.  After
    +#  each guess the computer will give you clues about your guess
    +#  as follows:
    +#
    +#  PICO     One digit is correct, but in the wrong place
    +#  FERMI    One digit is in the correct place
    +#  BAGELS   No digit is correct
    +#
    +# "You will learn to draw inferences from the clues and, with
    +#  practice, you'll learn to improve your score.  There are several
    +#  good strategies for playing Bagels.  After you have found a good
    +#  strategy, see if you can improve it.  Or try a different strategy
    +#  altogether and see if it is any better.  While the program allows
    +#  up to twenty guesses, if you use a good strategy it should not
    +#  take more than eight guesses to get any number.
    +#
    +# "The original authors of this program are D. Resek and P. Rowe of
    +#  the Lawrence Hall of Science, Berkeley, California."
    +#
    +#
    +# Python port by Jeff Jetton, 2019
    +#
    +######################################################################
     
     
     import random
    -from typing import List
     
     MAX_GUESSES = 20
     
     
    -def print_rules() -> None:
    +
    +def print_rules():
         print("\nI am thinking of a three-digit number.  Try to guess")
         print("my number and I will give you clues as follows:")
         print("   PICO   - One digit correct but in the wrong position")
    @@ -44,16 +46,19 @@ def print_rules() -> None:
         print("   BAGELS - No digits correct")
     
     
    -def pick_number() -> List[str]:
    +
    +def pick_number():
         # Note that this returns a list of individual digits
         # as separate strings, not a single integer or string
    -    numbers = list(range(10))
    +    numbers = [i for i in range(10)]
         random.shuffle(numbers)
    -    num = numbers[:3]
    -    return [str(i) for i in num]
    +    num = numbers[0:3]
    +    num = [str(i) for i in num] 
    +    return num
    +
     
     
    -def get_valid_guess(guesses: int) -> str:
    +def get_valid_guess():
         valid = False
         while not valid:
             guess = input(f"Guess # {guesses}     ? ")
    @@ -66,7 +71,8 @@ def get_valid_guess(guesses: int) -> str:
                     if len(set(guess)) == 3:
                         valid = True
                     else:
    -                    print("Oh, I forgot to tell you that the number I have in mind")
    +                    print("Oh, I forgot to tell you that " +
    +                          "the number I have in mind")
                         print("has no two digits the same.")
                 else:
                     print("What?")
    @@ -76,14 +82,16 @@ def get_valid_guess(guesses: int) -> str:
         return guess
     
     
    -def build_result_string(num: List[str], guess: str) -> str:
    +
    +def build_result_string(num, guess):
    +
         result = ""
     
         # Correct digits in wrong place
         for i in range(2):
    -        if num[i] == guess[i + 1]:
    +        if num[i] == guess[i+1]:
                 result += "PICO "
    -        if num[i + 1] == guess[i]:
    +        if num[i+1] == guess[i]:
                 result += "PICO "
         if num[0] == guess[2]:
             result += "PICO "
    @@ -102,62 +110,68 @@ def build_result_string(num: List[str], guess: str) -> str:
         return result
     
     
    -def main() -> None:
    -    # Intro text
    -    print("\n                Bagels")
    -    print("Creative Computing  Morristown, New Jersey\n\n")
     
    -    # Anything other than N* will show the rules
    -    response = input("Would you like the rules (Yes or No)? ")
    -    if len(response) > 0:
    -        if response.upper()[0] != "N":
    -            print_rules()
    -    else:
    +
    +######################################################################
    +
    +
    +# Intro text
    +print("\n                Bagels")
    +print("Creative Computing  Morristown, New Jersey")
    +print("\n\n")
    +
    +# Anything other than N* will show the rules
    +response = input("Would you like the rules (Yes or No)? ")
    +if len(response) > 0:
    +    if response.upper()[0] != 'N':
             print_rules()
    +else:
    +    print_rules()
     
    -    games_won = 0
    -    still_running = True
    -    while still_running:
    +games_won = 0
    +still_running = True
    +while still_running:
     
    -        # New round
    -        num = pick_number()
    -        num_str = "".join(num)
    -        guesses = 1
    +    # New round
    +    num = pick_number()
    +    num_str = ''.join(num)
    +    guesses = 1
     
    -        print("\nO.K.  I have a number in mind.")
    -        guessing = True
    -        while guessing:
    +    print("\nO.K.  I have a number in mind.")
    +    guessing = True
    +    while guessing:
     
    -            guess = get_valid_guess(guesses)
    +        guess = get_valid_guess()
     
    -            if guess == num_str:
    -                print("You got it!!!\n")
    -                games_won += 1
    -                guessing = False
    -            else:
    -                print(build_result_string(num, guess))
    -                guesses += 1
    -                if guesses > MAX_GUESSES:
    -                    print("Oh well")
    -                    print(f"That's {MAX_GUESSES} guesses.  My number was {num_str}")
    -                    guessing = False
    +        if guess == num_str:
    +            print("You got it!!!\n")
    +            games_won += 1
    +            guessing = False
    +        else: 
    +            print(build_result_string(num, guess))
    +            guesses += 1
    +            if guesses > MAX_GUESSES:
    +                print("Oh well")
    +                print(f"That's {MAX_GUESSES} guesses.  " +
    +                      "My number was " + num_str)
    +                guessing = False   
    +
    +
    +    valid_response = False
    +    while not valid_response:
    +        response = input("Play again (Yes or No)? ")
    +        if len(response) > 0:
    +            valid_response = True
    +            if response.upper()[0] != "Y":
    +                still_running = False
     
    -        valid_response = False
    -        while not valid_response:
    -            response = input("Play again (Yes or No)? ")
    -            if len(response) > 0:
    -                valid_response = True
    -                if response.upper()[0] != "Y":
    -                    still_running = False
     
    -    if games_won > 0:
    -        print(f"\nA {games_won} point Bagels buff!!")
    +if games_won > 0:
    +    print(f"\nA {games_won} point Bagels buff!!")
     
    -    print("Hope you had fun.  Bye.\n")
    +print("Hope you had fun.  Bye.\n")
     
     
    -if __name__ == "__main__":
    -    main()
     
     ######################################################################
     #
    @@ -166,7 +180,7 @@ def main() -> None:
     #   The original program did an unusually good job of validating the
     #   player's input (compared to many of the other programs in the
     #   book). Those checks and responses have been exactly reproduced.
    -#
    +#   
     #
     # Ideas for Modifications
     #
    @@ -178,3 +192,10 @@ def main() -> None:
     #   that creates the "result" string?
     #
     ######################################################################
    +
    +
    +            
    +        
    +    
    +
    +    
    diff --git a/05_Bagels/rust/Cargo.lock b/05_Bagels/rust/Cargo.lock
    deleted file mode 100644
    index 4fe2abbea..000000000
    --- a/05_Bagels/rust/Cargo.lock
    +++ /dev/null
    @@ -1,75 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.10"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.147"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/05_Bagels/rust/Cargo.toml b/05_Bagels/rust/Cargo.toml
    deleted file mode 100644
    index 3b1d02f52..000000000
    --- a/05_Bagels/rust/Cargo.toml
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -[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/05_Bagels/rust/README.md b/05_Bagels/rust/README.md
    deleted file mode 100644
    index 90780c4d2..000000000
    --- a/05_Bagels/rust/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Rust](https://www.rust-lang.org/) by Till Klister [tikste@github](https://github.com/tikste).
    diff --git a/05_Bagels/rust/src/main.rs b/05_Bagels/rust/src/main.rs
    deleted file mode 100644
    index 8a59ce7f1..000000000
    --- a/05_Bagels/rust/src/main.rs
    +++ /dev/null
    @@ -1,131 +0,0 @@
    -use std::io;
    -use std::io::{stdin, stdout, Write};
    -
    -use rand::prelude::SliceRandom;
    -
    -type Digits = [u8; 3];
    -
    -fn main() -> io::Result<()> {
    -    print_header();
    -    if !read_lowercase_input()?.starts_with('n') {
    -        print_rules();
    -    }
    -    let mut win_count = 0;
    -    loop {
    -        let solution = generate_random_digits();
    -        println!("\nO.K. I have a number in mind.");
    -        if guess(solution)? {
    -            win_count += 1;
    -            println!("You got it!!!");
    -        } else {
    -            println!(
    -                "\nOh well\nThat's twenty guesses: My number was {}{}{}",
    -                solution[0], solution[1], solution[2]
    -            );
    -        }
    -        println!("\nPlay again (yes or no)?");
    -        if read_lowercase_input()? != "yes" {
    -            println!();
    -            if win_count > 0 {
    -                println!("A {win_count} point bagels buff!!");
    -            }
    -            println!("Hope you had fun. Bye.");
    -            return Ok(());
    -        }
    -    }
    -}
    -
    -fn print_header() {
    -    println!("                  Bagels");
    -    println!("Creative-Computing  Morristown, New Jersey");
    -    println!();
    -    println!("Would you like the rules (yes or no)?");
    -}
    -
    -fn print_rules() {
    -    println!();
    -    println!("I am thinking of a three-digit number. Try to guess");
    -    println!("my number and I will give you clues as follows:");
    -    println!("   Pico   - one digit correct but in the wrong position");
    -    println!("   Fermi  - one digit correct and in the right position");
    -    println!("   Bagles - no digits correct");
    -}
    -
    -fn read_lowercase_input() -> io::Result {
    -    let mut input = String::new();
    -    stdin().read_line(&mut input)?;
    -    Ok(input.trim().to_lowercase())
    -}
    -
    -fn generate_random_digits() -> Digits {
    -    let range = 0..10;
    -    let mut numbers = range.into_iter().collect::>();
    -    numbers.shuffle(&mut rand::thread_rng());
    -    let mut digits = Digits::default();
    -    let len = digits.len();
    -    digits.copy_from_slice(&numbers[..len]);
    -    digits
    -}
    -
    -fn guess(solution: Digits) -> io::Result {
    -    for round in 1..21 {
    -        let guess = read_valid_guess(round)?;
    -        if guess == solution {
    -            return Ok(true);
    -        } else {
    -            let mut pico = 0;
    -            let mut fermi = 0;
    -            for i in 0..guess.len() {
    -                if guess[i] == solution[i] {
    -                    fermi += 1;
    -                } else if solution.contains(&guess[i]) {
    -                    pico += 1;
    -                }
    -            }
    -            let mut status = String::new();
    -            if pico == 0 && fermi == 0 {
    -                status += "Bagels";
    -            } else {
    -                for _ in 0..pico {
    -                    status += "Pico ";
    -                }
    -                for _ in 0..fermi {
    -                    status += "Fermi ";
    -                }
    -            };
    -            println!("{}", status.trim_end());
    -        }
    -    }
    -    Ok(false)
    -}
    -
    -fn read_valid_guess(round: u8) -> io::Result {
    -    let mut guess = Digits::default();
    -    loop {
    -        let space = " ".repeat(if round < 10 { 5 } else { 4 });
    -        print!("Guess #{round}{space}? ");
    -        stdout().flush()?;
    -        let input = read_lowercase_input()?;
    -        if input.len() == guess.len() {
    -            let mut i = 0;
    -            for c in input.chars() {
    -                if let Ok(digit) = c.to_string().parse::() {
    -                    if guess[..i].contains(&digit) {
    -                        println!("\nOh, I forgot to tell you that the number I have in mind\nhas no two digits the same.");
    -                        break;
    -                    }
    -                    guess[i] = digit;
    -                    i += 1;
    -                    if i == guess.len() {
    -                        return Ok(guess);
    -                    }
    -                } else {
    -                    println!("What?");
    -                    break;
    -                }
    -            }
    -        } else {
    -            println!("Try guessing a three-digit number.");
    -        }
    -    }
    -}
    diff --git a/05_Bagels/vbnet/Bagels.sln b/05_Bagels/vbnet/Bagels.sln
    deleted file mode 100644
    index ab6fa275e..000000000
    --- a/05_Bagels/vbnet/Bagels.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index c0d9d2d0c..000000000
    --- a/05_Bagels/vbnet/Bagels.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Bagels
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/06_Banner/README.md b/06_Banner/README.md
    index f01b876d1..960b76cb7 100644
    --- a/06_Banner/README.md
    +++ b/06_Banner/README.md
    @@ -12,12 +12,3 @@ As published in Basic Computer Games (1978)
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -- The "SET PAGE" input, stored in `O$`, has no effect.  It was probably meant as an opportunity for the user to set their pin-feed printer to the top of the page before proceeding.
    -
    -- The data values for each character are the bit representation of each horizontal row of the printout (vertical column of a character), plus one.  Perhaps because of this +1, the original code (and some of the ports here) are much more complicated than they need to be.
    -
    -(please note any difficulties or challenges in porting here)
    -
    diff --git a/06_Banner/csharp/banner.cs b/06_Banner/csharp/banner.cs
    index f037d489a..e3e59b4b2 100644
    --- a/06_Banner/csharp/banner.cs
    +++ b/06_Banner/csharp/banner.cs
    @@ -162,7 +162,7 @@ private void PrintChar(char ch)
                     // numSections decides how many 'sections' need to be printed
                     // for a given line of each character
                     int[] numSections = new int[7];
    -                // fillInSection decides whether each 'section' of the
    +                // fillInSection decides whether each 'section' of the 
                     // character gets filled in with the character or with blanks
                     int[] fillInSection = new int[9];
     
    diff --git a/06_Banner/csharp/banner.sln b/06_Banner/csharp/banner.sln
    index 9beeb9b3d..34f639846 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("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Banner", "Banner.csproj", "{7E8612AB-AFFD-4F72-855F-8172786F28FD}"
    +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "banner", "banner.csproj", "{9E24FA30-F2AC-4BF3-ADFB-92D3F796561C}"
     EndProject
     Global
     	GlobalSection(SolutionConfigurationPlatforms) = preSolution
    @@ -11,10 +11,10 @@ Global
     		Release|Any CPU = Release|Any CPU
     	EndGlobalSection
     	GlobalSection(ProjectConfigurationPlatforms) = postSolution
    -		{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
    +		{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
     	EndGlobalSection
     	GlobalSection(SolutionProperties) = preSolution
     		HideSolutionNode = FALSE
    diff --git a/06_Banner/java/Banner.java b/06_Banner/java/Banner.java
    index be1d74fc0..8c4e1c61d 100644
    --- a/06_Banner/java/Banner.java
    +++ b/06_Banner/java/Banner.java
    @@ -11,21 +11,21 @@
      * 

    * Note: The idea was to create a version of the 1970's BASIC game in Java, without introducing * new features - no additional text, error checking, etc has been added. - * + * * Converted from BASIC to Java by Darren Cardenas. */ - -public class Banner { + +public class Banner { private final Scanner scan; // For user input - + public Banner() { - + scan = new Scanner(System.in); + + } // End of constructor Banner - } // End of constructor Banner - - public void play() { + public void play() { int bitIndex = 0; int centerFlag = 0; @@ -38,19 +38,19 @@ public void play() { int vertical = 0; int vIndex = 0; int writeIndex = 0; - + int[] writerMap = new int[10]; - int[] writeLimit = new int[10]; - + int[] writeLimit = new int[10]; + String centerResponse = ""; String characters = ""; String letter = ""; - String lineContent = ""; + String lineContent = ""; String setPage = ""; String statement = ""; String token = ""; // Print token - - Map symbolData = new HashMap(); + + Map symbolData = new HashMap(); symbolData.put(" ", new int[]{0,0,0,0,0,0,0,0 }); symbolData.put("A", new int[]{0,505,37,35,34,35,37,505 }); symbolData.put("G", new int[]{0,125,131,258,258,290,163,101}); @@ -92,133 +92,133 @@ public void play() { symbolData.put("=", new int[]{0,41,41,41,41,41,41,41 }); symbolData.put("!", new int[]{0,1,1,1,384,1,1,1 }); symbolData.put("0", new int[]{0,57,69,131,258,131,69,57 }); - symbolData.put(".", new int[]{0,1,1,129,449,129,1,1 }); + symbolData.put(".", new int[]{0,1,1,129,449,129,1,1 }); - System.out.print("HORIZONTAL? "); + System.out.print("HORIZONTAL? "); horizontal = Integer.parseInt(scan.nextLine()); - System.out.print("VERTICAL? "); - vertical = Integer.parseInt(scan.nextLine()); - - System.out.print("CENTERED? "); + System.out.print("VERTICAL? "); + vertical = Integer.parseInt(scan.nextLine()); + + System.out.print("CENTERED? "); centerResponse = scan.nextLine().toUpperCase(); - + centerFlag = 0; - + // Lexicographical comparison if (centerResponse.compareTo("P") > 0) { - centerFlag = 1; + centerFlag = 1; } - - System.out.print("CHARACTER (TYPE 'ALL' IF YOU WANT CHARACTER BEING PRINTED)? "); + + System.out.print("CHARACTER (TYPE 'ALL' IF YOU WANT CHARACTER BEING PRINTED)? "); characters = scan.nextLine().toUpperCase(); - + System.out.print("STATEMENT? "); statement = scan.nextLine().toUpperCase(); - + // Initiates the print System.out.print("SET PAGE? "); - setPage = scan.nextLine(); - + setPage = scan.nextLine(); + // Begin loop through statement letters - for (letterIndex = 1; letterIndex <= statement.length(); letterIndex++) { - + for (letterIndex = 1; letterIndex <= statement.length(); letterIndex++) { + // Extract a letter letter = String.valueOf(statement.charAt(letterIndex - 1)); - - // Begin loop through all symbol data - for (String symbolString: symbolData.keySet()) { - + + // Begin loop through all symbol data + for (String symbolString: symbolData.keySet()) { + // Begin letter handling - if (letter.equals(" ")) { - for (index = 1; index <= (7 * horizontal); index++) { + if (letter.equals(" ")) { + for (index = 1; index <= (7 * horizontal); index++) { System.out.println(""); - } + } break; - - } else if (letter.equals(symbolString)) { + + } else if (letter.equals(symbolString)) { token = characters; - if (characters.equals("ALL")) { + if (characters.equals("ALL")) { token = symbolString; - } - + } + for (dataIndex = 1; dataIndex <= 7; dataIndex++) { - + // Avoid overwriting symbol data tempVal = symbolData.get(symbolString)[dataIndex]; - + for (bitIndex = 8; bitIndex >= 0; bitIndex--) { if (Math.pow(2, bitIndex) < tempVal) { writerMap[9 - bitIndex] = 1; tempVal -= Math.pow(2, bitIndex); - if (tempVal == 1) { - writeLimit[dataIndex] = 9 - bitIndex; + if (tempVal == 1) { + writeLimit[dataIndex] = 9 - bitIndex; break; } - + } else { - - writerMap[9 - bitIndex] = 0; + + writerMap[9 - bitIndex] = 0; } } // End of bitIndex loop - + for (hIndex = 1; hIndex <= horizontal; hIndex++) { - - // Add whitespace for centering + + // Add whitespace for centering lineContent = " ".repeat((int)((63 - 4.5 * vertical) * centerFlag / token.length())); - + for (writeIndex = 1; writeIndex <= writeLimit[dataIndex]; writeIndex++) { - - if (writerMap[writeIndex] == 0) { - - for (vIndex = 1; vIndex <= vertical; vIndex++) { - - for (index = 1; index <= token.length(); index++) { - lineContent += " "; - } - } - + + if (writerMap[writeIndex] == 0) { + + for (vIndex = 1; vIndex <= vertical; vIndex++) { + + for (index = 1; index <= token.length(); index++) { + lineContent += " "; + } + } + } else { - - for (vIndex = 1; vIndex <= vertical; vIndex++) { + + for (vIndex = 1; vIndex <= vertical; vIndex++) { lineContent += token; - } + } } } // End of writeIndex loop System.out.println(lineContent); - - } // End of hIndex loop + + } // End of hIndex loop } // End of dataIndex loop - + // Add padding between letters - for (index = 1; index <= 2 * horizontal; index++) { + for (index = 1; index <= 2 * horizontal; index++) { System.out.println(""); } - + } // End letter handling } // End loop through all symbol data - + } // End loop through statement letters // Add extra length to the banner - for (index = 1; index <= 75; index++) { + for (index = 1; index <= 75; index++) { System.out.println(""); - } - - } // End of method play + } + } // End of method play + public static void main(String[] args) { - + Banner game = new Banner(); game.play(); - + } // End of method main - + } // End of class Banner diff --git a/06_Banner/javascript/banner.html b/06_Banner/javascript/banner.html index 0745a640a..62f1bca8f 100644 --- a/06_Banner/javascript/banner.html +++ b/06_Banner/javascript/banner.html @@ -1,10 +1,9 @@ BANNER - -

    
    +
    
     
     
     
    diff --git a/06_Banner/javascript/banner.js b/06_Banner/javascript/banner.js
    index c67a81515..ca3604873 100644
    --- a/06_Banner/javascript/banner.js
    +++ b/06_Banner/javascript/banner.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    @@ -107,7 +107,7 @@ async function main()
         as = await input();
         print("SET PAGE");	// This means to prepare printer, just press Enter
         os = await input();
    -
    +    
         for (t = 0; t < as.length; t++) {
             ps = as.substr(t, 1);
             for (o = 0; o < 50 * 8; o += 8) {
    @@ -156,13 +156,13 @@ async function main()
                                     str += xs;
                             }
                         }
    -                    print(str + "\n");
    +                    print(str + "\n");	
                     }
                 }
    -            for (h = 1; h <= 2 * x; h++)
    +            for (h = 1; h <= 2 * x; h++) 
                     print("\n");
             }
    -    }
    +    }    
     }
     
     main();
    diff --git a/06_Banner/kotlin/README.md b/06_Banner/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/06_Banner/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/06_Banner/lua/README.md b/06_Banner/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/06_Banner/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/06_Banner/perl/banner.pl b/06_Banner/perl/banner.pl
    deleted file mode 100644
    index 2524ef00c..000000000
    --- a/06_Banner/perl/banner.pl
    +++ /dev/null
    @@ -1,150 +0,0 @@
    -#!/usr/bin/perl
    -
    -# Banner program in Perl
    -# Translated by Kevin Brannen (kbrannen)
    -
    -use strict;
    -use warnings;
    -
    -sub print_lines
    -{
    -    my $lines = shift;
    -    print "\n" x $lines;
    -}
    -
    -# each letter is made of 7 slices (or rows);
    -# the initial & unused 0 is to allow for Perl arrays being 0-based
    -#   but allow the algorithm to be 1-based (like Basic arrays);
    -# the numbers are essentially the dots/columns per slice in powers of 2.
    -my %data = (
    -    " " => [ 0,  0, 0, 0, 0, 0, 0, 0 ], 
    -    "." => [ 0,  1, 1, 129, 449, 129, 1, 1 ], 
    -    "!" => [ 0,  1, 1, 1, 384, 1, 1, 1 ], 
    -    "=" => [ 0,  41, 41, 41, 41, 41, 41, 41 ], 
    -    "?" => [ 0,  5, 3, 2, 354, 18, 11, 5 ], 
    -    "*" => [ 0,  69, 41, 17, 512, 17, 41, 69 ], 
    -    "0" => [ 0,  57, 69, 131, 258, 131, 69, 57 ], 
    -    "1" => [ 0,  0, 0, 261, 259, 512, 257, 257 ], 
    -    "2" => [ 0,  261, 387, 322, 290, 274, 267, 261 ], 
    -    "3" => [ 0,  66, 130, 258, 274, 266, 150, 100 ], 
    -    "4" => [ 0,  33, 49, 41, 37, 35, 512, 33 ], 
    -    "5" => [ 0,  160, 274, 274, 274, 274, 274, 226 ], 
    -    "6" => [ 0,  194, 291, 293, 297, 305, 289, 193 ], 
    -    "7" => [ 0,  258, 130, 66, 34, 18, 10, 8 ], 
    -    "8" => [ 0,  69, 171, 274, 274, 274, 171, 69 ], 
    -    "9" => [ 0,  263, 138, 74, 42, 26, 10, 7 ], 
    -    "A" => [ 0,  505, 37, 35, 34, 35, 37, 505 ], 
    -    "B" => [ 0,  512, 274, 274, 274, 274, 274, 239 ], 
    -    "C" => [ 0,  125, 131, 258, 258, 258, 131, 69 ], 
    -    "D" => [ 0,  512, 258, 258, 258, 258, 131, 125 ], 
    -    "E" => [ 0,  512, 274, 274, 274, 274, 258, 258 ], 
    -    "F" => [ 0,  512, 18, 18, 18, 18, 2, 2 ], 
    -    "G" => [ 0,  125, 131, 258, 258, 290, 163, 101 ], 
    -    "H" => [ 0,  512, 17, 17, 17, 17, 17, 512 ], 
    -    "I" => [ 0,  258, 258, 258, 512, 258, 258, 258 ], 
    -    "J" => [ 0,  65, 129, 257, 257, 257, 129, 128 ], 
    -    "K" => [ 0,  512, 17, 17, 41, 69, 131, 258 ], 
    -    "L" => [ 0,  512, 257, 257, 257, 257, 257, 257 ], 
    -    "M" => [ 0,  512, 7, 13, 25, 13, 7, 512 ], 
    -    "N" => [ 0,  512, 7, 9, 17, 33, 193, 512 ], 
    -    "O" => [ 0,  125, 131, 258, 258, 258, 131, 125 ], 
    -    "P" => [ 0,  512, 18, 18, 18, 18, 18, 15 ], 
    -    "Q" => [ 0,  125, 131, 258, 258, 322, 131, 381 ], 
    -    "R" => [ 0,  512, 18, 18, 50, 82, 146, 271 ], 
    -    "S" => [ 0,  69, 139, 274, 274, 274, 163, 69 ], 
    -    "T" => [ 0,  2, 2, 2, 512, 2, 2, 2 ], 
    -    "U" => [ 0,  128, 129, 257, 257, 257, 129, 128 ], 
    -    "V" => [ 0,  64, 65, 129, 257, 129, 65, 64 ], 
    -    "W" => [ 0,  256, 257, 129, 65, 129, 257, 256 ], 
    -    "X" => [ 0,  388, 69, 41, 17, 41, 69, 388 ], 
    -    "Y" => [ 0,  8, 9, 17, 481, 17, 9, 8 ], 
    -    "Z" => [ 0,  386, 322, 290, 274, 266, 262, 260 ], 
    -);
    -
    -my ($horz, $vert, $center, $char, $msg) = (0, 0, '', '', '');
    -
    -# get args to run with
    -while ($horz < 1)
    -{
    -    print "HORIZONTAL (1 or more): ";
    -    chomp($horz = <>);
    -    $horz = int($horz);
    -}
    -
    -while ($vert < 1)
    -{
    -    print "VERTICAL (1 or more): ";
    -    chomp($vert = <>);
    -    $vert = int($vert);
    -}
    -
    -print "CENTERED (Y/N): ";
    -chomp($center = <>);
    -$center = ($center =~ m/^Y/i) ? 1 : 0;
    -
    -# note you can enter multiple chars and the program will do the right thing
    -# thanks to the length() calls below, which was in the original Basic
    -print "CHARACTER TO PRINT (TYPE 'ALL' IF YOU WANT CHARACTER BEING PRINTED): ";
    -chomp($char = uc(<>));
    -
    -while (!$msg)
    -{
    -    print "STATEMENT: ";
    -    chomp($msg = uc(<>));
    -}
    -
    -print "SET PAGE TO PRINT, HIT RETURN WHEN READY";
    -$_ = <>;
    -print_lines(2 * $horz);
    -
    -# print the message
    -for my $letter ( split(//, $msg) )
    -{
    -    if (!exists($data{$letter}))
    -    {
    -        die "Cannot use letter '$letter'!";
    -    }
    -    my @s = @{$data{$letter}};
    -    #if ($letter eq " ") { print_lines(7 * $horz); next; }
    -
    -    my $print_letter = ($char eq "ALL") ? $letter : $char;
    -    for my $slice (1 .. 7)
    -    {
    -        my (@j, @f);
    -        for (my $k = 8; $k >= 0; $k--)
    -        {
    -            if (2**$k < $s[$slice])
    -            {
    -                $j[9 - $k] = 1;
    -                $s[$slice] = $s[$slice] - 2**$k;
    -                if ($s[$slice] == 1)
    -                {
    -                    $f[$slice] = 9 - $k;
    -                }
    -            }
    -            else
    -            {
    -                $j[9 - $k] = 0;
    -            }
    -        }
    -
    -        for my $t1 (1 .. $horz)
    -        {
    -            print " " x int((63 - 4.5 * $vert) * $center / (length($print_letter)) + 1);
    -            for my $b (1 .. (defined($f[$slice]) ? $f[$slice] : 0))
    -            {
    -                my $str = $j[$b] ? $print_letter : (" " x length($print_letter));
    -                print $str for (1 .. $vert);
    -            }
    -            print "\n";
    -        }
    -    }
    -
    -    # space between letters
    -    print_lines(2 * $horz);
    -}
    -
    -# while in the original code, this seems pretty excessive
    -#print_lines(75);
    -
    -exit(0);
    diff --git a/06_Banner/python/banner.py b/06_Banner/python/banner.py
    index d42a7763d..11f107666 100644
    --- a/06_Banner/python/banner.py
    +++ b/06_Banner/python/banner.py
    @@ -1,10 +1,8 @@
     #!/usr/bin/env python3
     
    -"""
    -BANNER
    -
    -Converted from BASIC to Python by Trevor Hobson
    -"""
    +# BANNER
    +#
    +# Converted from BASIC to Python by Trevor Hobson
     
     letters = {
         " ": [0, 0, 0, 0, 0, 0, 0],
    @@ -52,14 +50,16 @@
     }
     
     
    -def print_banner() -> None:
    +def print_banner():
    +    """Print the banner"""
    +
         f = [0] * 7
         j = [0] * 9
     
         while True:
             try:
    -            horizontal = int(input("Horizontal "))
    -            if horizontal < 1:
    +            x = int(input("Horizontal "))
    +            if x < 1:
                     raise ValueError("Horizontal must be greater than zero")
                 break
     
    @@ -67,51 +67,57 @@ def print_banner() -> None:
                 print("Please enter a number greater than zero")
         while True:
             try:
    -            vertical = int(input("Vertical "))
    -            if vertical < 1:
    +            y = int(input("Vertical "))
    +            if y < 1:
                     raise ValueError("Vertical must be greater than zero")
                 break
     
             except ValueError:
                 print("Please enter a number greater than zero")
    -    g1 = 1 if input("Centered ").lower().startswith("y") else 0
    -    character = input(
    -        "Character (type 'ALL' if you want character being printed) "
    -    ).upper()
    -    statement = input("Statement ")
    -
    -    input("Set page ")  # This means to prepare printer, just press Enter
    -
    -    for statement_char in statement:
    -        s = letters[statement_char].copy()
    -        x_str = character
    -        if x_str == "ALL":
    -            x_str = statement_char
    -        if x_str == " ":
    -            print("\n" * (7 * horizontal))
    +    g1 = 0
    +    if input("Centered ").lower().startswith("y"):
    +        g1 = 1
    +    mStr = input(
    +        "Character (type 'ALL' if you want character being printed) ").upper()
    +    aStr = input("Statement ")
    +    # This means to prepare printer, just press Enter
    +    oStr = input("Set page ")
    +    for lStr in aStr:
    +        s = letters[lStr].copy()
    +        xStr = mStr
    +        if mStr == "ALL":
    +            xStr = lStr
    +        if xStr == " ":
    +            print("\n" * (7 * x))
             else:
                 for u in range(0, 7):
                     for k in range(8, -1, -1):
    -                    if 2**k >= s[u]:
    +                    if 2 ** k >= s[u]:
                             j[8 - k] = 0
                         else:
                             j[8 - k] = 1
    -                        s[u] = s[u] - 2**k
    +                        s[u] = s[u] - 2 ** k
                             if s[u] == 1:
                                 f[u] = 8 - k
                                 break
    -                for _t1 in range(1, horizontal + 1):
    -                    line_str = " " * int((63 - 4.5 * vertical) * g1 / len(x_str) + 1)
    +                for t1 in range(1, x + 1):
    +                    lineStr = " " * int((63 - 4.5 * y) * g1 / len(xStr) + 1)
                         for b in range(0, f[u] + 1):
                             if j[b] == 0:
    -                            for _ in range(1, vertical + 1):
    -                                line_str = line_str + " " * len(x_str)
    +                            for i in range(1, y + 1):
    +                                lineStr = lineStr + " " * len(xStr)
                             else:
    -                            line_str = line_str + x_str * vertical
    -                    print(line_str)
    -            print("\n" * (2 * horizontal - 1))
    +                            lineStr = lineStr + xStr * y
    +                    print(lineStr)
    +            print("\n" * (2 * x - 1))
         # print("\n" * 75)  # Feed some more paper from the printer
     
     
    -if __name__ == "__main__":
    +def main():
    +    """Main"""
    +
         print_banner()
    +
    +
    +if __name__ == "__main__":
    +    main()
    diff --git a/06_Banner/ruby/banner.rb b/06_Banner/ruby/banner.rb
    deleted file mode 100755
    index 53136dbd5..000000000
    --- a/06_Banner/ruby/banner.rb
    +++ /dev/null
    @@ -1,92 +0,0 @@
    -#!/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 }
    diff --git a/06_Banner/vbnet/banner.sln b/06_Banner/vbnet/banner.sln
    index 8a782a2f8..5fdc87370 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("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "Banner", "Banner.vbproj", "{091ABE13-3E70-4848-B836-592F725915A3}"
    +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "banner", "banner.vbproj", "{1738D297-A04C-4E6E-8219-D9E72982C39D}"
     EndProject
     Global
     	GlobalSection(SolutionConfigurationPlatforms) = preSolution
    @@ -11,10 +11,10 @@ Global
     		Release|Any CPU = Release|Any CPU
     	EndGlobalSection
     	GlobalSection(ProjectConfigurationPlatforms) = postSolution
    -		{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
    +		{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
     	EndGlobalSection
     	GlobalSection(SolutionProperties) = preSolution
     		HideSolutionNode = FALSE
    diff --git a/06_Banner/vbnet/banner.vb b/06_Banner/vbnet/banner.vb
    index 8187c0bce..90e183b81 100644
    --- a/06_Banner/vbnet/banner.vb
    +++ b/06_Banner/vbnet/banner.vb
    @@ -146,7 +146,7 @@ Module Banner
                 ' numSections decides how many 'sections' need to be printed
                 ' for a given line of each character
                 Dim numSections(7) As Integer
    -            ' fillInSection decides whether each 'section' of the
    +            ' fillInSection decides whether each 'section' of the 
                 ' character gets filled in with the character Or with blanks
                 Dim fillInSection(9) As Integer
     
    diff --git a/06_Banner/vbnet/banner.vbproj b/06_Banner/vbnet/banner.vbproj
    index e825a636f..659fea7b8 100644
    --- a/06_Banner/vbnet/banner.vbproj
    +++ b/06_Banner/vbnet/banner.vbproj
    @@ -2,9 +2,8 @@
     
       
         Exe
    -    Banner
    +    banner
         netcoreapp3.1
    -    16.9
       
     
     
    diff --git a/07_Basketball/README.md b/07_Basketball/README.md
    index ac0662ddf..158cba435 100644
    --- a/07_Basketball/README.md
    +++ b/07_Basketball/README.md
    @@ -14,7 +14,7 @@ Both teams use the same defense, but you may call it:
     - Enter (7): Zone
     - Enter (7.5): None
     
    -To change defense, type "0" as your next shot.
    +To change defense, type “0” as your next shot.
     
     Note: The game is biased slightly in favor of Dartmouth. The average probability of a Dartmouth shot being good is 62.95% compared to a probability of 61.85% for their opponent. (This makes the sample run slightly remarkable in that Cornell won by a score of 45 to 42 Hooray for the Big Red!)
     
    @@ -28,24 +28,3 @@ As published in Basic Computer Games (1978)
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    -
    -##### Original bugs
    -
    -###### Initial defense selection
    -
    -If a number <6 is entered for the starting defense then the original code prompts again until a value >=6 is entered,
    -but then skips the opponent selection center jump.
    -
    -The C# port does not reproduce this behavior. It does prompt for a correct value, but will then go to opponent selection
    -followed by the center jump.
    -
    -###### Unvalidated defense selection
    -
    -The original code does not validate the value entered for the defense beyond checking that it is >=6. A large enough
    -defense value will guarantee that all shots are good, and the game gets rather predictable.
    -
    -This bug is preserved in the C# port.
    diff --git a/07_Basketball/csharp/Basketball.csproj b/07_Basketball/csharp/Basketball.csproj
    deleted file mode 100644
    index 91e759c0c..000000000
    --- a/07_Basketball/csharp/Basketball.csproj
    +++ /dev/null
    @@ -1,18 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    -  
    -    
    -  
    -
    -  
    -    
    -  
    -
    -
    diff --git a/07_Basketball/csharp/Basketball.sln b/07_Basketball/csharp/Basketball.sln
    deleted file mode 100644
    index 92f2de056..000000000
    --- a/07_Basketball/csharp/Basketball.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/csharp/Clock.cs b/07_Basketball/csharp/Clock.cs
    deleted file mode 100644
    index 250330523..000000000
    --- a/07_Basketball/csharp/Clock.cs
    +++ /dev/null
    @@ -1,25 +0,0 @@
    -using Basketball.Resources;
    -using Games.Common.IO;
    -
    -namespace Basketball;
    -
    -internal class Clock
    -{
    -    private readonly IReadWrite _io;
    -    private int time;
    -
    -    public Clock(IReadWrite io) => _io = io;
    -
    -    public bool IsHalfTime => time == 50;
    -    public bool IsFullTime => time >= 100;
    -    public bool TwoMinutesLeft => time == 92;
    -
    -    public void Increment(Scoreboard scoreboard)
    -    {
    -        time += 1;
    -        if (IsHalfTime) { scoreboard.Display(Resource.Formats.EndOfFirstHalf); }
    -        if (TwoMinutesLeft) { _io.Write(Resource.Streams.TwoMinutesLeft); }
    -    }
    -
    -    public void StartOvertime() => time = 93;
    -}
    \ No newline at end of file
    diff --git a/07_Basketball/csharp/Defense.cs b/07_Basketball/csharp/Defense.cs
    deleted file mode 100644
    index f447266fb..000000000
    --- a/07_Basketball/csharp/Defense.cs
    +++ /dev/null
    @@ -1,12 +0,0 @@
    -namespace Basketball;
    -
    -internal class Defense
    -{
    -    private float _value;
    -
    -    public Defense(float value) => Set(value);
    -
    -    public void Set(float value) => _value = value;
    -
    -    public static implicit operator float(Defense defense) => defense._value;
    -}
    diff --git a/07_Basketball/csharp/Game.cs b/07_Basketball/csharp/Game.cs
    deleted file mode 100644
    index 5a7d6ffad..000000000
    --- a/07_Basketball/csharp/Game.cs
    +++ /dev/null
    @@ -1,73 +0,0 @@
    -using Basketball.Plays;
    -using Basketball.Resources;
    -using Games.Common.IO;
    -using Games.Common.Randomness;
    -
    -namespace Basketball;
    -
    -internal class Game
    -{
    -    private readonly Clock _clock;
    -    private readonly Scoreboard _scoreboard;
    -    private readonly TextIO _io;
    -    private readonly IRandom _random;
    -
    -    private Game(Clock clock, Scoreboard scoreboard, TextIO io, IRandom random)
    -    {
    -        _clock = clock;
    -        _scoreboard = scoreboard;
    -        _io = io;
    -        _random = random;
    -    }
    -
    -    public static Game Create(TextIO io, IRandom random)
    -    {
    -        io.Write(Resource.Streams.Introduction);
    -
    -        var defense = new Defense(io.ReadDefense("Your starting defense will be"));
    -        var clock = new Clock(io);
    -
    -        io.WriteLine();
    -
    -        var scoreboard = new Scoreboard(
    -            new Team("Dartmouth", new HomeTeamPlay(io, random, clock, defense)),
    -            new Team(io.ReadString("Choose your opponent"), new VisitingTeamPlay(io, random, clock, defense)),
    -            io);
    -
    -        return new Game(clock, scoreboard, io, random);
    -    }
    -
    -    public void Play()
    -    {
    -        var ballContest = new BallContest(0.4f, "{0} controls the tap", _io, _random);
    -
    -        while (true)
    -        {
    -            _io.WriteLine("Center jump");
    -            ballContest.Resolve(_scoreboard);
    -
    -            _io.WriteLine();
    -
    -            while (true)
    -            {
    -                var isFullTime = _scoreboard.Offense.ResolvePlay(_scoreboard);
    -                if (isFullTime && IsGameOver()) { return; }
    -                if (_clock.IsHalfTime) { break; }
    -            }
    -        }
    -    }
    -
    -    private bool IsGameOver()
    -    {
    -        _io.WriteLine();
    -        if (_scoreboard.ScoresAreEqual)
    -        {
    -            _scoreboard.Display(Resource.Formats.EndOfSecondHalf);
    -            _clock.StartOvertime();
    -            return false;
    -        }
    -
    -        _scoreboard.Display(Resource.Formats.EndOfGame);
    -        return true;
    -    }
    -}
    diff --git a/07_Basketball/csharp/IRandomExtensions.cs b/07_Basketball/csharp/IRandomExtensions.cs
    deleted file mode 100644
    index 876e05a20..000000000
    --- a/07_Basketball/csharp/IRandomExtensions.cs
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -using Games.Common.Randomness;
    -
    -namespace Basketball;
    -
    -internal static class IRandomExtensions
    -{
    -    internal static Shot NextShot(this IRandom random) => Shot.Get(random.NextFloat(1, 3.5f));
    -}
    diff --git a/07_Basketball/csharp/IReadWriteExtensions.cs b/07_Basketball/csharp/IReadWriteExtensions.cs
    deleted file mode 100644
    index 6197ff977..000000000
    --- a/07_Basketball/csharp/IReadWriteExtensions.cs
    +++ /dev/null
    @@ -1,34 +0,0 @@
    -using Games.Common.IO;
    -
    -namespace Basketball;
    -
    -internal static class IReadWriteExtensions
    -{
    -    public static float ReadDefense(this IReadWrite io, string prompt)
    -    {
    -        while (true)
    -        {
    -            var defense = io.ReadNumber(prompt);
    -            if (defense >= 6) { return defense; }
    -        }
    -    }
    -
    -    private static bool TryReadInteger(this IReadWrite io, string prompt, out int intValue)
    -    {
    -        var floatValue = io.ReadNumber(prompt);
    -        intValue = (int)floatValue;
    -        return intValue == floatValue;
    -    }
    -
    -    public static Shot? ReadShot(this IReadWrite io, string prompt)
    -    {
    -        while (true)
    -        {
    -            if (io.TryReadInteger(prompt, out var value) && Shot.TryGet(value, out var shot))
    -            {
    -                return shot;
    -            }
    -            io.Write("Incorrect answer.  Retype it. ");
    -        }
    -    }
    -}
    diff --git a/07_Basketball/csharp/JumpShot.cs b/07_Basketball/csharp/JumpShot.cs
    deleted file mode 100644
    index 46ffc6d89..000000000
    --- a/07_Basketball/csharp/JumpShot.cs
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -namespace Basketball;
    -
    -public class JumpShot : Shot
    -{
    -    public JumpShot()
    -        : base("Jump shot")
    -    {
    -    }
    -}
    \ No newline at end of file
    diff --git a/07_Basketball/csharp/Plays/BallContest.cs b/07_Basketball/csharp/Plays/BallContest.cs
    deleted file mode 100644
    index a12ddc36b..000000000
    --- a/07_Basketball/csharp/Plays/BallContest.cs
    +++ /dev/null
    @@ -1,28 +0,0 @@
    -using Games.Common.IO;
    -using Games.Common.Randomness;
    -
    -namespace Basketball.Plays;
    -
    -internal class BallContest
    -{
    -    private readonly float _probability;
    -    private readonly string _messageFormat;
    -    private readonly IReadWrite _io;
    -    private readonly IRandom _random;
    -
    -    internal BallContest(float probability, string messageFormat, IReadWrite io, IRandom random)
    -    {
    -        _io = io;
    -        _probability = probability;
    -        _messageFormat = messageFormat;
    -        _random = random;
    -    }
    -
    -    internal bool Resolve(Scoreboard scoreboard)
    -    {
    -        var winner = _random.NextFloat() <= _probability ? scoreboard.Home : scoreboard.Visitors;
    -        scoreboard.Offense = winner;
    -        _io.WriteLine(_messageFormat, winner);
    -        return false;
    -    }
    -}
    diff --git a/07_Basketball/csharp/Plays/HomeTeamPlay.cs b/07_Basketball/csharp/Plays/HomeTeamPlay.cs
    deleted file mode 100644
    index 48ef249e5..000000000
    --- a/07_Basketball/csharp/Plays/HomeTeamPlay.cs
    +++ /dev/null
    @@ -1,93 +0,0 @@
    -using Games.Common.IO;
    -using Games.Common.Randomness;
    -
    -namespace Basketball.Plays;
    -
    -internal class HomeTeamPlay : Play
    -{
    -    private readonly TextIO _io;
    -    private readonly IRandom _random;
    -    private readonly Clock _clock;
    -    private readonly Defense _defense;
    -    private readonly BallContest _ballContest;
    -
    -    public HomeTeamPlay(TextIO io, IRandom random, Clock clock, Defense defense)
    -        : base(io, random, clock)
    -    {
    -        _io = io;
    -        _random = random;
    -        _clock = clock;
    -        _defense = defense;
    -        _ballContest = new BallContest(0.5f, "Shot is blocked.  Ball controlled by {0}.", _io, _random);
    -    }
    -
    -    internal override bool Resolve(Scoreboard scoreboard)
    -    {
    -        var shot = _io.ReadShot("Your shot");
    -
    -        if (_random.NextFloat() >= 0.5f && _clock.IsFullTime) { return true; }
    -
    -        if (shot is null)
    -        {
    -            _defense.Set(_io.ReadDefense("Your new defensive alignment is"));
    -            _io.WriteLine();
    -            return false;
    -        }
    -
    -        if (shot is JumpShot jumpShot)
    -        {
    -            if (ClockIncrementsToHalfTime(scoreboard)) { return false; }
    -            if (!Resolve(jumpShot, scoreboard)) { return false; }
    -        }
    -
    -        do
    -        {
    -            if (ClockIncrementsToHalfTime(scoreboard)) { return false; }
    -        } while (Resolve(shot, scoreboard));
    -
    -        return false;
    -    }
    -
    -    // The Resolve* methods resolve the probabilistic outcome of the current game state.
    -    // They return true if the Home team should continue the play and attempt a layup, false otherwise.
    -    private bool Resolve(JumpShot shot, Scoreboard scoreboard) =>
    -        Resolve(shot.ToString(), _defense / 8)
    -            .Do(0.341f, () => scoreboard.AddBasket("Shot is good"))
    -            .Or(0.682f, () => ResolveShotOffTarget(scoreboard))
    -            .Or(0.782f, () => _ballContest.Resolve(scoreboard))
    -            .Or(0.843f, () => ResolveFreeThrows(scoreboard, "Shooter is fouled.  Two shots."))
    -            .Or(() => scoreboard.Turnover($"Charging foul.  {scoreboard.Home} loses ball."));
    -
    -    private bool Resolve(Shot shot, Scoreboard scoreboard) =>
    -        Resolve(shot.ToString(), _defense / 7)
    -            .Do(0.4f, () => scoreboard.AddBasket("Shot is good.  Two points."))
    -            .Or(0.7f, () => ResolveShotOffTheRim(scoreboard))
    -            .Or(0.875f, () => ResolveFreeThrows(scoreboard, "Shooter fouled.  Two shots."))
    -            .Or(0.925f, () => scoreboard.Turnover($"Shot blocked. {scoreboard.Visitors}'s ball."))
    -            .Or(() => scoreboard.Turnover($"Charging foul.  {scoreboard.Home} loses ball."));
    -
    -    private bool ResolveShotOffTarget(Scoreboard scoreboard) =>
    -        Resolve("Shot is off target", 6 / _defense)
    -            .Do(0.45f, () => ResolveHomeRebound(scoreboard, ResolvePossibleSteal))
    -            .Or(() => scoreboard.Turnover($"Rebound to {scoreboard.Visitors}"));
    -
    -    private bool ResolveHomeRebound(Scoreboard scoreboard, Action endOfPlayAction) =>
    -        Resolve($"{scoreboard.Home} controls the rebound.")
    -            .Do(0.4f, () => true)
    -            .Or(() => endOfPlayAction.Invoke(scoreboard));
    -    private void ResolvePossibleSteal(Scoreboard scoreboard)
    -    {
    -        if (_defense == 6 && _random.NextFloat() > 0.6f)
    -        {
    -            scoreboard.Turnover();
    -            scoreboard.AddBasket($"Pass stolen by {scoreboard.Visitors} easy layup.");
    -            _io.WriteLine();
    -        }
    -        _io.Write("Ball passed back to you. ");
    -    }
    -
    -    private void ResolveShotOffTheRim(Scoreboard scoreboard) =>
    -        Resolve("Shot is off the rim.")
    -            .Do(2 / 3f, () => scoreboard.Turnover($"{scoreboard.Visitors} controls the rebound."))
    -            .Or(() => ResolveHomeRebound(scoreboard, _ => _io.WriteLine("Ball passed back to you.")));
    -}
    diff --git a/07_Basketball/csharp/Plays/Play.cs b/07_Basketball/csharp/Plays/Play.cs
    deleted file mode 100644
    index 9b82a74ea..000000000
    --- a/07_Basketball/csharp/Plays/Play.cs
    +++ /dev/null
    @@ -1,40 +0,0 @@
    -using Games.Common.IO;
    -using Games.Common.Randomness;
    -
    -namespace Basketball.Plays;
    -
    -internal abstract class Play
    -{
    -    private readonly IReadWrite _io;
    -    private readonly IRandom _random;
    -    private readonly Clock _clock;
    -
    -    public Play(IReadWrite io, IRandom random, Clock clock)
    -    {
    -        _io = io;
    -        _random = random;
    -        _clock = clock;
    -    }
    -
    -    protected bool ClockIncrementsToHalfTime(Scoreboard scoreboard)
    -    {
    -        _clock.Increment(scoreboard);
    -        return _clock.IsHalfTime;
    -    }
    -
    -    internal abstract bool Resolve(Scoreboard scoreboard);
    -
    -    protected void ResolveFreeThrows(Scoreboard scoreboard, string message) =>
    -        Resolve(message)
    -            .Do(0.49f, () => scoreboard.AddFreeThrows(2, "Shooter makes both shots."))
    -            .Or(0.75f, () => scoreboard.AddFreeThrows(1, "Shooter makes one shot and misses one."))
    -            .Or(() => scoreboard.AddFreeThrows(0, "Both shots missed."));
    -
    -    protected Probably Resolve(string message) => Resolve(message, 1f);
    -
    -    protected Probably Resolve(string message, float defenseFactor)
    -    {
    -        _io.WriteLine(message);
    -        return new Probably(defenseFactor, _random);
    -    }
    -}
    diff --git a/07_Basketball/csharp/Plays/VisitingTeamPlay.cs b/07_Basketball/csharp/Plays/VisitingTeamPlay.cs
    deleted file mode 100644
    index 3975a6ba7..000000000
    --- a/07_Basketball/csharp/Plays/VisitingTeamPlay.cs
    +++ /dev/null
    @@ -1,81 +0,0 @@
    -using Games.Common.IO;
    -using Games.Common.Randomness;
    -
    -namespace Basketball.Plays;
    -
    -internal class VisitingTeamPlay : Play
    -{
    -    private readonly TextIO _io;
    -    private readonly IRandom _random;
    -    private readonly Defense _defense;
    -
    -    public VisitingTeamPlay(TextIO io, IRandom random, Clock clock, Defense defense)
    -        : base(io, random, clock)
    -    {
    -        _io = io;
    -        _random = random;
    -        _defense = defense;
    -    }
    -
    -    internal override bool Resolve(Scoreboard scoreboard)
    -    {
    -        if (ClockIncrementsToHalfTime(scoreboard)) { return false; }
    -
    -        _io.WriteLine();
    -        var shot = _random.NextShot();
    -
    -        if (shot is JumpShot jumpShot)
    -        {
    -            var continuePlay = Resolve(jumpShot, scoreboard);
    -            _io.WriteLine();
    -            if (!continuePlay) { return false; }
    -        }
    -
    -        while (true)
    -        {
    -            var continuePlay = Resolve(shot, scoreboard);
    -            _io.WriteLine();
    -            if (!continuePlay) { return false; }
    -        }
    -    }
    -
    -    // The Resolve* methods resolve the probabilistic outcome of the current game state.
    -    // They return true if the Visiting team should continue the play and attempt a layup, false otherwise.
    -    private bool Resolve(JumpShot shot, Scoreboard scoreboard) =>
    -        Resolve(shot.ToString(), _defense / 8)
    -            .Do(0.35f, () => scoreboard.AddBasket("Shot is good."))
    -            .Or(0.75f, () => ResolveBadShot(scoreboard, "Shot is off the rim.", _defense * 6))
    -            .Or(0.9f, () => ResolveFreeThrows(scoreboard, "Player fouled.  Two shots."))
    -            .Or(() => _io.WriteLine($"Offensive foul.  {scoreboard.Home}'s ball."));
    -
    -    private bool Resolve(Shot shot, Scoreboard scoreboard) =>
    -        Resolve(shot.ToString(), _defense / 7)
    -            .Do(0.413f, () => scoreboard.AddBasket("Shot is good."))
    -            .Or(() => ResolveBadShot(scoreboard, "Shot is missed.", 6 / _defense));
    -
    -    private bool ResolveBadShot(Scoreboard scoreboard, string message, float defenseFactor) =>
    -        Resolve(message, defenseFactor)
    -            .Do(0.5f, () => scoreboard.Turnover($"{scoreboard.Home} controls the rebound."))
    -            .Or(() => ResolveVisitorsRebound(scoreboard));
    -
    -    private bool ResolveVisitorsRebound(Scoreboard scoreboard)
    -    {
    -        _io.Write($"{scoreboard.Visitors} controls the rebound.");
    -        if (_defense == 6 && _random.NextFloat() <= 0.25f)
    -        {
    -            _io.WriteLine();
    -            scoreboard.Turnover();
    -            scoreboard.AddBasket($"Ball stolen.  Easy lay up for {scoreboard.Home}.");
    -            return false;
    -        }
    -
    -        if (_random.NextFloat() <= 0.5f)
    -        {
    -            _io.WriteLine();
    -            _io.Write($"Pass back to {scoreboard.Visitors} guard.");
    -            return false;
    -        }
    -
    -        return true;
    -    }
    -}
    diff --git a/07_Basketball/csharp/Probably.cs b/07_Basketball/csharp/Probably.cs
    deleted file mode 100644
    index 0ba5864a0..000000000
    --- a/07_Basketball/csharp/Probably.cs
    +++ /dev/null
    @@ -1,50 +0,0 @@
    -using Games.Common.Randomness;
    -
    -namespace Basketball;
    -
    -/// 
    -/// Supports a chain of actions to be performed based on various probabilities. The original game code gets a new
    -/// random number for each probability check. Evaluating a set of probabilities against a single random number is
    -/// much simpler, but yield a very different outcome distribution. The purpose of this class is to simplify the code
    -/// to for the original probabilistic branch decisions.
    -/// 
    -internal struct Probably
    -{
    -    private readonly float _defenseFactor;
    -    private readonly IRandom _random;
    -    private readonly bool? _result;
    -
    -    internal Probably(float defenseFactor, IRandom random, bool? result = null)
    -    {
    -        _defenseFactor = defenseFactor;
    -        _random = random;
    -        _result = result;
    -    }
    -
    -    public Probably Do(float probability, Action action) =>
    -        ShouldResolveAction(probability)
    -            ? new Probably(_defenseFactor, _random, Resolve(action) ?? false)
    -            : this;
    -
    -    public Probably Do(float probability, Func action) =>
    -        ShouldResolveAction(probability)
    -            ? new Probably(_defenseFactor, _random, Resolve(action) ?? false)
    -            : this;
    -
    -    public Probably Or(float probability, Action action) => Do(probability, action);
    -
    -    public Probably Or(float probability, Func action) => Do(probability, action);
    -
    -    public bool Or(Action action) => _result ?? Resolve(action) ?? false;
    -
    -    private bool? Resolve(Action action)
    -    {
    -        action.Invoke();
    -        return _result;
    -    }
    -
    -    private bool? Resolve(Func action) => action.Invoke();
    -
    -    private readonly bool ShouldResolveAction(float probability) =>
    -        _result is null && _random.NextFloat() <= probability * _defenseFactor;
    -}
    diff --git a/07_Basketball/csharp/Program.cs b/07_Basketball/csharp/Program.cs
    deleted file mode 100644
    index 7a6103368..000000000
    --- a/07_Basketball/csharp/Program.cs
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -using Basketball;
    -using Games.Common.IO;
    -using Games.Common.Randomness;
    -
    -var game = Game.Create(new ConsoleIO(), new RandomNumberGenerator());
    -
    -game.Play();
    \ No newline at end of file
    diff --git a/07_Basketball/csharp/Resources/EndOfFirstHalf.txt b/07_Basketball/csharp/Resources/EndOfFirstHalf.txt
    deleted file mode 100644
    index 6a132a0ec..000000000
    --- a/07_Basketball/csharp/Resources/EndOfFirstHalf.txt
    +++ /dev/null
    @@ -1,5 +0,0 @@
    -
    -   ***** End of first half *****
    -
    -Score: {0}: {1}    {2}: {3}
    -
    diff --git a/07_Basketball/csharp/Resources/EndOfGame.txt b/07_Basketball/csharp/Resources/EndOfGame.txt
    deleted file mode 100644
    index fc65416c4..000000000
    --- a/07_Basketball/csharp/Resources/EndOfGame.txt
    +++ /dev/null
    @@ -1,2 +0,0 @@
    -   ***** End of game *****
    -Final score: {0}: {1}    {2}: {3}
    \ No newline at end of file
    diff --git a/07_Basketball/csharp/Resources/EndOfSecondHalf.txt b/07_Basketball/csharp/Resources/EndOfSecondHalf.txt
    deleted file mode 100644
    index c5f73218a..000000000
    --- a/07_Basketball/csharp/Resources/EndOfSecondHalf.txt
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -
    -   ***** End of second half *****
    -
    -Score at end of regulation time:
    -         {0}: {1}    {2}: {3}
    -
    -Begin two minute overtime period
    \ No newline at end of file
    diff --git a/07_Basketball/csharp/Resources/Introduction.txt b/07_Basketball/csharp/Resources/Introduction.txt
    deleted file mode 100644
    index b5ad510b6..000000000
    --- a/07_Basketball/csharp/Resources/Introduction.txt
    +++ /dev/null
    @@ -1,12 +0,0 @@
    -                               Basketball
    -               Creative Computing  Morristown, New Jersey
    -
    -
    -
    -This is Dartmouth College basketball.  You will be Dartmouth
    - captain and playmaker.  Call shots as follows:  1. Long
    - (30 ft.) jump shot; 2. Short (15 ft.) jump shot; 3. Lay
    - up; 4. Set shot.
    -Both teams will use the same defense.  Call defense as
    -follows:  6. Press; 6.5 Man-to-man; 7. Zone; 7.5 None.
    -To change defense, just type 0 as your next shot.
    \ No newline at end of file
    diff --git a/07_Basketball/csharp/Resources/Resource.cs b/07_Basketball/csharp/Resources/Resource.cs
    deleted file mode 100644
    index c442a3ff1..000000000
    --- a/07_Basketball/csharp/Resources/Resource.cs
    +++ /dev/null
    @@ -1,32 +0,0 @@
    -using System.Reflection;
    -using System.Runtime.CompilerServices;
    -
    -namespace Basketball.Resources;
    -
    -internal static class Resource
    -{
    -    internal static class Streams
    -    {
    -        public static Stream Introduction => GetStream();
    -        public static Stream TwoMinutesLeft => GetStream();
    -    }
    -
    -    internal static class Formats
    -    {
    -        public static string EndOfFirstHalf => GetString();
    -        public static string EndOfGame => GetString();
    -        public static string EndOfSecondHalf => GetString();
    -        public static string Score => GetString();
    -    }
    -
    -    private static string GetString([CallerMemberName] string? name = null)
    -    {
    -        using var stream = GetStream(name);
    -        using var reader = new StreamReader(stream);
    -        return reader.ReadToEnd();
    -    }
    -
    -    private static Stream GetStream([CallerMemberName] string? name = null) =>
    -        Assembly.GetExecutingAssembly().GetManifestResourceStream($"Basketball.Resources.{name}.txt")
    -            ?? throw new Exception($"Could not find embedded resource stream '{name}'.");
    -}
    \ No newline at end of file
    diff --git a/07_Basketball/csharp/Resources/Score.txt b/07_Basketball/csharp/Resources/Score.txt
    deleted file mode 100644
    index 7b317cb39..000000000
    --- a/07_Basketball/csharp/Resources/Score.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Score:  {1} to {3}
    \ No newline at end of file
    diff --git a/07_Basketball/csharp/Resources/TwoMinutesLeft.txt b/07_Basketball/csharp/Resources/TwoMinutesLeft.txt
    deleted file mode 100644
    index 0ad169930..000000000
    --- a/07_Basketball/csharp/Resources/TwoMinutesLeft.txt
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -
    -   *** Two minutes left in the game ***
    -
    diff --git a/07_Basketball/csharp/Scoreboard.cs b/07_Basketball/csharp/Scoreboard.cs
    deleted file mode 100644
    index 79068392f..000000000
    --- a/07_Basketball/csharp/Scoreboard.cs
    +++ /dev/null
    @@ -1,48 +0,0 @@
    -using Basketball.Resources;
    -using Games.Common.IO;
    -
    -namespace Basketball;
    -
    -internal class Scoreboard
    -{
    -    private readonly Dictionary _scores;
    -    private readonly IReadWrite _io;
    -
    -    public Scoreboard(Team home, Team visitors, IReadWrite io)
    -    {
    -        _scores = new() { [home] = 0, [visitors] = 0 };
    -        Home = home;
    -        Visitors = visitors;
    -        Offense = home;  // temporary value till first center jump
    -        _io = io;
    -    }
    -
    -    public bool ScoresAreEqual => _scores[Home] == _scores[Visitors];
    -    public Team Offense { get; set; }
    -    public Team Home { get; }
    -    public Team Visitors { get; }
    -
    -    public void AddBasket(string message) => AddScore(2, message);
    -
    -    public void AddFreeThrows(uint count, string message) => AddScore(count, message);
    -
    -    private void AddScore(uint score, string message)
    -    {
    -        if (Offense is null) { throw new InvalidOperationException("Offense must be set before adding to score."); }
    -
    -        _io.WriteLine(message);
    -        _scores[Offense] += score;
    -        Turnover();
    -        Display();
    -    }
    -
    -    public void Turnover(string? message = null)
    -    {
    -        if (message is not null) { _io.WriteLine(message); }
    -
    -        Offense = Offense == Home ? Visitors : Home;
    -    }
    -
    -    public void Display(string? format = null) =>
    -        _io.WriteLine(format ?? Resource.Formats.Score, Home, _scores[Home], Visitors, _scores[Visitors]);
    -}
    diff --git a/07_Basketball/csharp/Shot.cs b/07_Basketball/csharp/Shot.cs
    deleted file mode 100644
    index fb7c2f3e4..000000000
    --- a/07_Basketball/csharp/Shot.cs
    +++ /dev/null
    @@ -1,37 +0,0 @@
    -namespace Basketball;
    -
    -public class Shot
    -{
    -    private readonly string _name;
    -
    -    public Shot(string name)
    -    {
    -        _name = name;
    -    }
    -
    -    public static bool TryGet(int shotNumber, out Shot? shot)
    -    {
    -        shot = shotNumber switch
    -        {
    -            // Although the game instructions reference two different jump shots,
    -            // the original game code treats them both the same and just prints "Jump shot"
    -            0 => null,
    -            <= 2 => new JumpShot(),
    -            3 => new Shot("Lay up"),
    -            4 => new Shot("Set shot"),
    -            _ => null
    -        };
    -        return shotNumber == 0 || shot is not null;
    -    }
    -
    -    public static Shot Get(float shotNumber) =>
    -        shotNumber switch
    -        {
    -            <= 2 => new JumpShot(),
    -            > 3 => new Shot("Set shot"),
    -            > 2 => new Shot("Lay up"),
    -            _ => throw new Exception("Unexpected value")
    -        };
    -
    -    public override string ToString() => _name;
    -}
    diff --git a/07_Basketball/csharp/Team.cs b/07_Basketball/csharp/Team.cs
    deleted file mode 100644
    index 2cf262aa8..000000000
    --- a/07_Basketball/csharp/Team.cs
    +++ /dev/null
    @@ -1,10 +0,0 @@
    -using Basketball.Plays;
    -
    -namespace Basketball;
    -
    -internal record Team(string Name, Play PlayResolver)
    -{
    -    public override string ToString() => Name;
    -
    -    public bool ResolvePlay(Scoreboard scoreboard) => PlayResolver.Resolve(scoreboard);
    -}
    diff --git a/07_Basketball/java/Basketball.java b/07_Basketball/java/Basketball.java
    index 50ca95744..3ff9e7ab6 100644
    --- a/07_Basketball/java/Basketball.java
    +++ b/07_Basketball/java/Basketball.java
    @@ -1,5 +1,5 @@
     import java.lang.Math;
    -import java.util.*;
    +import java.util.*; 
     import java.util.Scanner;
     
     /* The basketball class is a computer game that allows you to play as
    @@ -15,7 +15,7 @@ public class Basketball {
         int shot = -1;
         List shot_choices = Arrays.asList(0, 1, 2, 3, 4);
         double opponent_chance = 0;
    -    String opponent = null;
    +    String opponent = null; 
     
         public Basketball() {
     
    @@ -41,7 +41,7 @@ public Basketball() {
             else {
                 scanner.next();
             }
    -
    +        
             // makes sure that input is legal
             while (!defense_choices.contains(defense)) {
                 System.out.print("Your new defensive allignment is? ");
    @@ -57,7 +57,7 @@ public Basketball() {
             // takes input for opponent's name
             System.out.print("\nChoose your opponent? ");
     
    -        opponent = scanner.next();
    +        opponent = scanner.next(); 
             start_of_period();
         }
     
    @@ -67,13 +67,13 @@ 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;
    @@ -82,13 +82,13 @@ private void change_defense() {
             while (!defense_choices.contains(defense)) {
                 System.out.println("Your new defensive allignment is? ");
                 if (scanner.hasNextDouble()) {
    -                defense = (double)(scanner.nextDouble());
    +                defense = (double)(scanner.nextDouble()); 
                 }
                 else {
    -                continue;
    +                continue; 
                 }
             }
    -
    +            
             dartmouth_ball();
         }
     
    @@ -102,15 +102,15 @@ private void foul_shots(int team) {
                 }
                 else {
                     System.out.println("Shooter makes one shot and misses one.");
    -                score[team] += 1;
    -            }
    +                score[team] += 1; 
    +            } 
             }
             else {
                 System.out.println("Shooter makes both shots.");
                 score[team] += 2;
             }
    -
    -        print_score();
    +        
    +        print_score(); 
         }
     
         // called when time = 50, starts a new period
    @@ -127,13 +127,13 @@ private void print_score() {
     
         // simulates a center jump for posession at the beginning of a period
         private void start_of_period() {
    -        System.out.println("Center jump");
    +        System.out.println("Center jump"); 
             if (Math.random() > .6) {
    -            System.out.println("Dartmouth controls the tap.\n");
    +            System.out.println("Dartmouth controls the tap.\n"); 
                 dartmouth_ball();
             }
             else {
    -            System.out.println(opponent + " controls the tap.\n");
    +            System.out.println(opponent + " controls the tap.\n"); 
                 opponent_ball();
             }
         }
    @@ -142,10 +142,10 @@ private void start_of_period() {
         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 ++;
    +        time ++;  
             if (time == 50) {
                 halftime();
             }
    @@ -171,135 +171,135 @@ else if (time == 92) {
                     else {
                         if (Math.random() > .5) {
                             System.out.println("Shot is blocked. Ball controlled by " +
    -                              opponent + ".\n");
    -                        opponent_ball();
    -                    }
    +                              opponent + ".\n"); 
    +                        opponent_ball(); 
    +                    } 
                         else {
    -                        System.out.println("Shot is blocked. Ball controlled by Dartmouth.");
    -                        dartmouth_ball();
    -                    }
    +                        System.out.println("Shot is blocked. Ball controlled by Dartmouth."); 
    +                        dartmouth_ball(); 
    +                    } 
                     }
                 }
                 else {
    -                System.out.println("Shot is off target.");
    +                System.out.println("Shot is off target."); 
                     if (defense / 6 * Math.random() > .45) {
    -                    System.out.println("Rebound to " + opponent + "\n");
    -                    opponent_ball();
    -                }
    +                    System.out.println("Rebound to " + opponent + "\n"); 
    +                    opponent_ball(); 
    +                } 
                     else {
    -                    System.out.println("Dartmouth controls the rebound.");
    +                    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();
    -                        }
    +                                  + ", easy lay up"); 
    +                            add_points(0, 2); 
    +                            dartmouth_ball(); 
    +                        }    
                             else {
                                 // ball is passed back to you
    -                            ball_passed_back();
    -                        }
    +                            ball_passed_back(); 
    +                        }  
                         }
                         else {
    -                        System.out.println("");
    -                        dartmouth_non_jump_shot();
    +                        System.out.println(""); 
    +                        dartmouth_non_jump_shot(); 
                         }
                     }
                 }
    -        }
    +        } 
             else {
    -            System.out.println("Shot is good.");
    -            add_points(1, 2);
    -            opponent_ball();
    +            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 ++;
    +        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.");
    +            System.out.println("Lay up."); 
             }
             else if (shot == 0) {
    -            change_defense();
    +            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();
    +                        System.out.println("Charging foul. Dartmouth loses the ball.\n"); 
    +                        opponent_ball(); 
                         }
                         else {
    -                        System.out.println("Shot blocked. " + opponent + "'s ball.\n");
    -                        opponent_ball();
    +                        System.out.println("Shot blocked. " + opponent + "'s ball.\n"); 
    +                        opponent_ball(); 
                         }
                     }
                     else {
    -                    foul_shots(1);
    -                    opponent_ball();
    +                    foul_shots(1); 
    +                    opponent_ball(); 
                     }
                 }
                 else {
    -                System.out.println("Shot is off the rim.");
    +                System.out.println("Shot is off the rim."); 
                     if (Math.random() > 2/3) {
    -                    System.out.println("Dartmouth controls the rebound.");
    +                    System.out.println("Dartmouth controls the rebound."); 
                         if (Math.random() > .4) {
    -                        System.out.println("Ball passed back to you.\n");
    -                        dartmouth_ball();
    +                        System.out.println("Ball passed back to you.\n"); 
    +                        dartmouth_ball(); 
                         }
                         else {
    -                        dartmouth_non_jump_shot();
    +                        dartmouth_non_jump_shot(); 
                         }
                     }
                     else {
    -                    System.out.println(opponent + " controls the rebound.\n");
    -                    opponent_ball();
    +                    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();
    +            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;
    +        System.out.print("Your shot? "); 
    +        shot = -1; 
             if (scanner.hasNextInt()) {
    -            shot = scanner.nextInt();
    +            shot = scanner.nextInt(); 
             }
             else {
                 System.out.println("");
    -            scanner.next();
    +            scanner.next(); 
             }
    -
    +        
             while (!shot_choices.contains(shot)) {
                 System.out.print("Incorrect answer. Retype it. Your shot?");
                 if (scanner.hasNextInt()) {
    -                shot = scanner.nextInt();
    +                shot = scanner.nextInt(); 
                 }
                 else {
                     System.out.println("");
    -                scanner.next();
    +                scanner.next(); 
                 }
             }
     
    @@ -308,154 +308,154 @@ private void dartmouth_ball() {
                     dartmouth_jump_shot();
                 }
                 else {
    -                dartmouth_non_jump_shot();
    +                dartmouth_non_jump_shot(); 
                 }
             }
             else {
                 if (score[0] != score[1]) {
    -                System.out.println("\n   ***** End Of Game *****");
    +                System.out.println("\n   ***** End Of Game *****"); 
                     System.out.println("Final Score: Dartmouth: " + score[1] + "  "
    -                      + opponent + ": " + score[0]);
    +                      + 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("\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();
    +                      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.");
    +        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();
    +                    System.out.println("Offensive foul. Dartmouth's ball.\n"); 
    +                    dartmouth_ball(); 
                     }
                     else {
    -                    foul_shots(0);
    -                    dartmouth_ball();
    +                    foul_shots(0); 
    +                    dartmouth_ball(); 
                     }
                 }
                 else {
    -                System.out.println("Shot is off the rim.");
    +                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();
    +                            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();
    +                                System.out.println(""); 
    +                                opponent_non_jumpshot(); 
                                 }
                                 else {
                                     System.out.println("Pass back to " + opponent +
    -                                      " guard.\n");
    -                                opponent_ball();
    +                                      " guard.\n"); 
    +                                opponent_ball(); 
                                 }
                             }
                         }
                         else {
                             if (Math.random() > .5) {
    -                            opponent_non_jumpshot();
    +                            opponent_non_jumpshot(); 
                             }
                             else {
                                 System.out.println("Pass back to " + opponent +
    -                                  " guard.\n");
    -                            opponent_ball();
    +                                  " guard.\n"); 
    +                            opponent_ball(); 
                             }
                         }
                     }
                     else {
    -                    System.out.println("Dartmouth controls the rebound.\n");
    -                    dartmouth_ball();
    +                    System.out.println("Dartmouth controls the rebound.\n"); 
    +                    dartmouth_ball(); 
                     }
                 }
    -        }
    +        } 
             else {
    -            System.out.println("Shot is good.");
    -            add_points(0, 2);
    -            dartmouth_ball();
    +            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.");
    +            System.out.println("Set shot."); 
             }
             else {
    -            System.out.println("Lay up");
    +            System.out.println("Lay up"); 
             }
             if (7/defense*Math.random() > .413) {
    -            System.out.println("Shot is missed.");
    +            System.out.println("Shot is missed."); 
                 if (defense/6*Math.random() > .5) {
    -                System.out.println(opponent + " controls the rebound.");
    +                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();
    +                        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();
    +                            System.out.println(""); 
    +                            opponent_non_jumpshot(); 
                             }
                             else {
                                 System.out.println("Pass back to " + opponent +
    -                                  " guard.\n");
    -                            opponent_ball();
    +                                  " guard.\n"); 
    +                            opponent_ball(); 
                             }
                         }
                     }
                     else {
                         if (Math.random() > .5) {
    -                        System.out.println("");
    -                        opponent_non_jumpshot();
    +                        System.out.println(""); 
    +                        opponent_non_jumpshot(); 
                         }
                         else {
    -                        System.out.println("Pass back to " + opponent + " guard\n");
    -                        opponent_ball();
    +                        System.out.println("Pass back to " + opponent + " guard\n"); 
    +                        opponent_ball(); 
                         }
                     }
                 }
                 else {
    -                System.out.println("Dartmouth controls the rebound.\n");
    -                dartmouth_ball();
    +                System.out.println("Dartmouth controls the rebound.\n"); 
    +                dartmouth_ball(); 
                 }
             }
             else {
    -            System.out.println("Shot is good.");
    -            add_points(0, 2);
    -            dartmouth_ball();
    +            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 ++;
    +        time ++; 
             if (time == 50) {
                 halftime();
             }
    -        opponent_chance = 10/4*Math.random()+1;
    +        opponent_chance = 10/4*Math.random()+1; 
             if (opponent_chance > 2) {
    -            opponent_non_jumpshot();
    +            opponent_non_jumpshot(); 
             }
             else {
    -            opponent_jumpshot();
    +            opponent_jumpshot(); 
             }
         }
     
    @@ -463,3 +463,7 @@ public static void main(String[] args) {
             Basketball new_game = new Basketball();
         }
     }
    +
    +
    +
    +
    diff --git a/07_Basketball/javascript/basketball.html b/07_Basketball/javascript/basketball.html
    index 03e1ae984..e9eedab37 100644
    --- a/07_Basketball/javascript/basketball.html
    +++ b/07_Basketball/javascript/basketball.html
    @@ -1,10 +1,9 @@
     
     
     BASKETBALL
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/07_Basketball/javascript/basketball.js b/07_Basketball/javascript/basketball.js
    index ed98fb0de..5b0b73e70 100644
    --- a/07_Basketball/javascript/basketball.js
    +++ b/07_Basketball/javascript/basketball.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/07_Basketball/kotlin/README.md b/07_Basketball/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/07_Basketball/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/07_Basketball/lua/README.md b/07_Basketball/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/07_Basketball/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/07_Basketball/perl/README.md b/07_Basketball/perl/README.md
    index 51373c0c8..e69c8b819 100644
    --- a/07_Basketball/perl/README.md
    +++ b/07_Basketball/perl/README.md
    @@ -1,21 +1,3 @@
     Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
     
     Conversion to [Perl](https://www.perl.org/)
    -
    -There are two version of the code here, a "faithful" translation (basketball-orig.pl) and
    -a "modern" translation (basketball.pl). The main difference between the 2 are is that the
    -faithful translation has 3 GOTOs in it while the modern version has no GOTO. I have added
    -a "TIME" print when the score is shown so the Clock is visible. Halftime is at "50" and
    -end of game is at 100 (per the Basic code).
    -
    -The 3 GOTOs in the faitful version are because of the way the original code jumped into
    -the "middle of logic" that has no obivious way to avoid ... that I can see, at least while
    -still maintaining something of the look and structure of the original Basic.
    -
    -The modern version avoided the GOTOs by restructuring the program in the 2 "play()" subs.
    -Despite the change, this should play the same way as the faithful version.
    -
    -All of the percentages remain the same. If writing this from scratch, we really should
    -have only a single play() sub which uses the same code for both teams, which would also
    -make the game more fair ... but that wasn't done so the percent edge to Darmouth has been
    -maintained here.
    diff --git a/07_Basketball/perl/basketball-orig.pl b/07_Basketball/perl/basketball-orig.pl
    deleted file mode 100755
    index 14627ffc6..000000000
    --- a/07_Basketball/perl/basketball-orig.pl
    +++ /dev/null
    @@ -1,415 +0,0 @@
    -#!/usr/bin/perl
    -
    -# Basketball program in Perl
    -#   This is fairly faithful translation from the original Basic.
    -#   This becomes apparent because there are actually 3 GOTOs still present
    -#   because of the way the original code jumped into the "middle of logic"
    -#   that has no obivious way to avoid ... that I can see.
    -#   For better structure and no GOTOs, see the other version of this program.
    -# Translated by Kevin Brannen (kbrannen)
    -
    -use strict;
    -use warnings;
    -
    -# globals
    -my $Defense=0;      # dartmouth defense value
    -my $Opponent;       # name of opponent
    -my @Score = (0, 0); # scores, dart is [0], opponent is [1]
    -my $Player = 0;     # player, 0 = dart, 1 = opp
    -my $Timer = 0;      # time tick, 100 ticks per game, 50 is end of first half, if tie at end then back to T=93
    -my $DoPlay = 1;     # true if game is still being played
    -my $ConTeam;        # controlling team, "dart" or "opp"
    -my $ShotType = 0;   # current shot type
    -
    -
    -print "\n";
    -print " " x 31, "BASKETBALL";
    -print " " x 15, "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY";
    -print "\n\n\n";
    -
    -print "THIS IS DARTMOUTH COLLEGE BASKETBALL.  YOU WILL BE DARTMOUTH\n";
    -print "CAPTAIN AND PLAYMAKER.  CALL SHOTS AS FOLLOWS:\n";
    -print "   1. LONG (30 FT.) JUMP SHOT;\n";
    -print "   2. SHORT (15 FT.) JUMP SHOT;\n";
    -print "   3. LAY UP;\n";
    -print "   4. SET SHOT.\n";
    -print "BOTH TEAMS WILL USE THE SAME DEFENSE.  CALL DEFENSE AS FOLLOWS:\n";
    -print "   6. PRESS;\n";
    -print "   6.5 MAN-TO MAN;\n";
    -print "   7. ZONE;\n";
    -print "   7.5 NONE.\n";
    -print "TO CHANGE DEFENSE, JUST TYPE 0 AS YOUR NEXT SHOT.\n\n";
    -get_defense();
    -print "\n";
    -print "CHOOSE YOUR OPPONENT: ";
    -chomp($Opponent = <>);
    -
    -$ConTeam = center_jump();
    -while ($DoPlay)
    -{
    -    print "\n";
    -    if ($ConTeam eq "dart")
    -    {
    -        $Player = 0;
    -        get_your_shot();
    -        dartmouth_play();
    -    }
    -    else
    -    {
    -        opponent_play();
    -    }
    -    if ($Timer >= 100)
    -    {
    -        check_end_game();
    -        last if (!$DoPlay);
    -        $Timer = 93;
    -        $ConTeam = center_jump();
    -    }
    -}
    -exit(0);
    -
    -###############################################################
    -
    -sub dartmouth_play
    -{
    -    if ($ShotType == 1 || $ShotType == 2)
    -    {
    -        $Timer++;
    -        if ($Timer == 50)
    -        {
    -            end_first_half();
    -            return;
    -        }
    -        if ($Timer == 92)
    -        {
    -            two_min_left();
    -        }
    -
    -        print "JUMP SHOT\n";
    -        if (rand(1) <= 0.341 * $Defense / 8)
    -        {
    -            print "SHOT IS GOOD.\n";
    -            dartmouth_score();
    -            $ConTeam = "opp";
    -            return;
    -        }
    -
    -        if (rand(1) <= 0.682*$Defense/8)
    -        {
    -            print "SHOT IS OFF TARGET.\n";
    -            if ($Defense/6*rand(1) > 0.45)
    -            {
    -                print "REBOUND TO ", $Opponent, "\n";
    -                $ConTeam = "opp";
    -                return;
    -            }
    -
    -            print "DARTMOUTH CONTROLS THE REBOUND.\n";
    -            if (rand(1) <= 0.4) { goto L1300; }
    -            if ($Defense == 6)
    -            {
    -                if (rand(1) <= 0.6)
    -                {
    -                    print "PASS STOLEN BY $Opponent, EASY LAYUP.\n";
    -                    opp_score();
    -                    $ConTeam = "dart"; return;
    -                    return;
    -                }
    -            }
    -            print "BALL PASSED BACK TO YOU.\n";
    -            $ConTeam = "dart";
    -            return;
    -        }
    -
    -        if (rand(1) <= 0.782*$Defense/8)
    -        {
    -            print "SHOT IS BLOCKED.  BALL CONTROLLED BY "; # no NL
    -            if (rand(1) > 0.5)
    -            {
    -                print "$Opponent.\n";
    -                $ConTeam = "opp";
    -                return;
    -            }
    -            else
    -            {
    -                print "DARTMOUTH.\n";
    -                $ConTeam = "dart";
    -                return;
    -            }
    -        }
    -
    -        if (rand(1) > 0.843*$Defense/8)
    -        {
    -            print "CHARGING FOUL.  DARTMOUTH LOSES BALL.\n";
    -            $ConTeam = "opp";
    -            return;
    -        }
    -        else
    -        {
    -            print "SHOOTER IS FOULED.  TWO SHOTS.\n";
    -            foul_shooting();
    -            $ConTeam = "opp";
    -            return;
    -        }
    -    }
    -
    -    L1300:
    -    while (1)
    -    {
    -        $Timer++;
    -        if ($Timer == 50)
    -        {
    -            end_first_half();
    -            return;
    -        }
    -        if ($Timer == 92) { two_min_left(); }
    -        if ($ShotType == 0) 
    -        {
    -            get_defense();
    -            return;
    -        }
    -        print '', ($ShotType > 3 ? "SET SHOT." : "LAY UP."), "\n";
    -        if (7 / $Defense * rand(1) <= 0.4)
    -        {
    -            print "SHOT IS GOOD.  TWO POINTS.\n";
    -            dartmouth_score();
    -            $ConTeam = "opp";
    -            return;
    -        }
    -
    -        if (7 / $Defense * rand(1) <= 0.7)
    -        {
    -            print "SHOT IS OFF THE RIM.\n";
    -            if (rand(1) <= 0.667)
    -            {
    -                print "$Opponent CONTROLS THE REBOUND.\n";
    -                $ConTeam = "opp";
    -                return;
    -            }
    -
    -            print "DARTMOUTH CONTROLS THE REBOUND.\n";
    -            next if (rand(1) <= 0.4);
    -
    -            print "BALL PASSED BACK TO YOU.\n";
    -            $ConTeam = "dart";
    -            return;
    -        }
    -
    -        if (7 / $Defense * rand(1) <= 0.875)
    -        {
    -            print "SHOOTER FOULED.  TWO SHOTS.\n";
    -            foul_shooting();
    -            $ConTeam = "opp";
    -            return;
    -        }
    -
    -        if (7 / $Defense * rand(1) <= 0.925)
    -        {
    -            print "SHOT BLOCKED. $Opponent\'S BALL.\n";
    -            $ConTeam = "opp";
    -            return;
    -        }
    -
    -        print "CHARGING FOUL.  DARTMOUTH LOSES THE BALL.\n";
    -        $ConTeam = "opp";
    -        return;
    -    }
    -}
    -
    -sub get_defense
    -{
    -    $Defense = 0;
    -    while ($Defense < 6 || $Defense > 7.5)
    -    {
    -        print "YOUR NEW DEFENSIVE ALLIGNMENT IS (6, 6.5, 7. 7.5): ";
    -        chomp($Defense = <>);
    -        ($Defense) =~ m/(\d(\.\d)?)/;
    -    }
    -}
    -
    -sub opponent_play
    -{
    -    $Player = 1;
    -    $Timer++;
    -    if ($Timer == 50)
    -    {
    -        end_first_half();
    -        $ConTeam = center_jump();
    -        return;
    -    }
    -
    -    print "\n";
    -    while (1)
    -    {
    -        my $shot = 10.0 / 4 * rand(1) + 1;
    -        if ($shot <= 2.0)
    -        {
    -            print "JUMP SHOT.\n";
    -            if (8.0 / $Defense * rand(1) <= 0.35)
    -            {
    -                print "SHOT IS GOOD.\n";
    -                opp_score();
    -                $ConTeam = "dart";
    -                return;
    -            }
    -
    -            if (8.0 / $Defense * rand(1) <=  0.75)
    -            {
    -                print "SHOT IS OFF RIM.\n";
    -
    -                L3110:
    -                if ($Defense / 6.0 * rand(1) <= 0.5)
    -                {
    -                    print "DARTMOUTH CONTROLS THE REBOUND.\n";
    -                    $ConTeam = "dart";
    -                    return;
    -                }
    -                print "$Opponent CONTROLS THE REBOUND.\n";
    -                if ($Defense == 6)
    -                {
    -                    if (rand(1) <= 0.75)
    -                    {
    -                        print "BALL STOLEN.  EASY LAY UP FOR DARTMOUTH.\n";
    -                        dartmouth_score();
    -                        $ConTeam = "opp";
    -                        return;
    -                    }
    -                }
    -                if (rand(1) <= 0.5)
    -                {
    -                    print "PASS BACK TO $Opponent GUARD.\n";
    -                    $ConTeam = "opp";
    -                    return;
    -                }
    -                goto L3500;
    -            }
    -
    -            if (8.0 / $Defense * rand(1) <= 0.9)
    -            {
    -                print "PLAYER FOULED.  TWO SHOTS.\n";
    -                foul_shooting();
    -                $ConTeam = "dart";
    -                return;
    -            }
    -            print "OFFENSIVE FOUL.  DARTMOUTH'S BALL.\n";
    -            $ConTeam = "dart";
    -            return;
    -        }
    -
    -        L3500:
    -        print ($shot > 3 ? "SET SHOT.\n" : "LAY UP.\n");
    -        if (7.0 / $Defense * rand(1) > 0.413)
    -        {
    -            print "SHOT IS MISSED.\n";
    -            {
    -            no warnings;
    -            goto L3110;
    -            }
    -        }
    -        else
    -        {
    -            print "SHOT IS GOOD.\n";
    -            opp_score();
    -            $ConTeam = "dart";
    -            return;
    -        }
    -    }
    -}
    -
    -sub opp_score
    -{
    -    $Score[0] += 2;
    -    print_score();
    -}
    -
    -sub dartmouth_score
    -{
    -    $Score[1] += 2;
    -    print_score();
    -}
    -
    -sub print_score
    -{
    -    print "SCORE: $Score[1] TO $Score[0]\n";
    -    print "TIME: $Timer\n";
    -}
    -
    -sub end_first_half
    -{
    -    print "\n   ***** END OF FIRST HALF *****\n\n";
    -    print "SCORE: DARTMOUTH: $Score[1]   $Opponent: $Score[0]\n\n\n";
    -    center_jump();
    -}
    -
    -sub get_your_shot
    -{
    -    $ShotType = -1;
    -    while ($ShotType < 0 || $ShotType > 4)
    -    {
    -        print "YOUR SHOT (0-4): ";
    -        chomp($ShotType = <>);
    -        $ShotType = int($ShotType);
    -        if ($ShotType < 0 || $ShotType > 4)
    -        {
    -            print "INCORRECT ANSWER.  RETYPE IT. ";
    -        }
    -    }
    -}
    -
    -sub center_jump
    -{
    -    print "CENTER JUMP\n";
    -    if (rand(1) <= 0.6)
    -    {
    -        print "$Opponent CONTROLS THE TAP.\n";
    -        return "opp";
    -    }
    -    print "DARTMOUTH CONTROLS THE TAP.\n";
    -    return "dart";
    -}
    -
    -sub check_end_game
    -{
    -    print "\n";
    -    if ($Score[1] != $Score[0])
    -    {
    -        print "   ***** END OF GAME *****\n";
    -        print "FINAL SCORE: DARTMOUTH: $Score[1]    $Opponent: $Score[0]\n\n";
    -        $DoPlay = 0;
    -    }
    -    else
    -    {
    -        print "\n   ***** END OF SECOND HALF *****\n";
    -        print "SCORE AT END OF REGULATION TIME:\n";
    -        print "        DARTMOUTH: $Score[1]    $Opponent: $Score[0]\n\n";
    -        print "BEGIN TWO MINUTE OVERTIME PERIOD\n";
    -    }
    -}
    -
    -sub two_min_left
    -{
    -    print "\n   *** TWO MINUTES LEFT IN THE GAME ***\n\n";
    -}
    -
    -sub foul_shooting
    -{
    -    if (rand(1) > 0.49)
    -    {
    -        if (rand(1) > 0.75)
    -        {
    -            print "BOTH SHOTS MISSED.\n";
    -        }
    -        else
    -        {
    -            print "SHOOTER MAKES ONE SHOT AND MISSES ONE.\n";
    -            $Score[1 - $Player]++;
    -        }
    -    }
    -    else
    -    {
    -        print "SHOOTER MAKES BOTH SHOTS.\n";
    -        $Score[1 - $Player] += 2;
    -    }
    -
    -    print_score();
    -}
    diff --git a/07_Basketball/perl/basketball.pl b/07_Basketball/perl/basketball.pl
    deleted file mode 100755
    index ac3483094..000000000
    --- a/07_Basketball/perl/basketball.pl
    +++ /dev/null
    @@ -1,393 +0,0 @@
    -#!/usr/bin/perl
    -
    -# Basketball program in Perl
    -#   While this should play the same way as the fairly faithful translation version,
    -#   there are no GOTOs in this code. That was achieved by restructuring the program
    -#   in the 2 *_play() subs. All of the percentages remain the same. If writing this
    -#   from scratch, we really should have only a play() sub which uses the same code
    -#   for both teams, but the percent edge to Darmouth has been maintained here.
    -# Translated by Kevin Brannen (kbrannen)
    -
    -use strict;
    -use warnings;
    -
    -# globals
    -my $Defense=0;      # dartmouth defense value
    -my $Opponent;       # name of opponent
    -my @Score = (0, 0); # scores, dart is [0], opponent is [1]
    -my $Player = 0;     # player, 0 = dart, 1 = opp
    -my $Timer = 0;      # time tick, 100 ticks per game, 50 is end of first half, if tie at end then back to T=93
    -my $DoPlay = 1;     # true if game is still being played
    -my $ConTeam;        # controlling team, "dart" or "opp"
    -my $ShotType = 0;   # current shot type
    -
    -
    -print "\n";
    -print " " x 31, "BASKETBALL";
    -print " " x 15, "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY";
    -print "\n\n\n";
    -
    -print "THIS IS DARTMOUTH COLLEGE BASKETBALL.  YOU WILL BE DARTMOUTH\n";
    -print "CAPTAIN AND PLAYMAKER.  CALL SHOTS AS FOLLOWS:\n";
    -print "   1. LONG (30 FT.) JUMP SHOT;\n";
    -print "   2. SHORT (15 FT.) JUMP SHOT;\n";
    -print "   3. LAY UP;\n";
    -print "   4. SET SHOT.\n";
    -print "BOTH TEAMS WILL USE THE SAME DEFENSE.  CALL DEFENSE AS FOLLOWS:\n";
    -print "   6. PRESS;\n";
    -print "   6.5 MAN-TO MAN;\n";
    -print "   7. ZONE;\n";
    -print "   7.5 NONE.\n";
    -print "TO CHANGE DEFENSE, JUST TYPE 0 AS YOUR NEXT SHOT.\n\n";
    -get_defense();
    -print "\n";
    -print "CHOOSE YOUR OPPONENT: ";
    -chomp($Opponent = <>);
    -
    -$ConTeam = center_jump();
    -while ($DoPlay)
    -{
    -    print "\n";
    -    if ($ConTeam eq "dart")
    -    {
    -        get_your_shot();
    -        dartmouth_play();
    -    }
    -    else
    -    {
    -        $ShotType = 10.0 / 4 * rand(1) + 1;
    -        opponent_play();
    -    }
    -    if ($Timer >= 100)
    -    {
    -        check_end_game();
    -        last if (!$DoPlay);
    -        $Timer = 93;
    -        $ConTeam = center_jump();
    -    }
    -}
    -exit(0);
    -
    -###############################################################
    -
    -sub dartmouth_play
    -{
    -    $Player = 0;
    -    print "\n";
    -    while (1)
    -    {
    -        $Timer++;
    -        if ($Timer == 50) { end_first_half(); return; }
    -        if ($Timer == 92) { two_min_left(); }
    -
    -        if ($ShotType == 0) 
    -        {
    -            get_defense();
    -            return; # for new ShotType
    -        }
    -        elsif ($ShotType == 1 || $ShotType == 2)
    -        {
    -            print "JUMP SHOT\n";
    -            if (rand(1) <= 0.341 * $Defense / 8)
    -            {
    -                print "SHOT IS GOOD.\n";
    -                dartmouth_score();
    -                last;
    -            }
    -
    -            if (rand(1) <= 0.682*$Defense/8)
    -            {
    -                print "SHOT IS OFF TARGET.\n";
    -                if ($Defense/6*rand(1) > 0.45)
    -                {
    -                    print "REBOUND TO $Opponent\n";
    -                    last;
    -                }
    -
    -                print "DARTMOUTH CONTROLS THE REBOUND.\n";
    -                if (rand(1) <= 0.4)
    -                {
    -                    $ShotType = (rand(1) <= 0.5) ? 3 : 4;
    -                    next;
    -                }
    -                if ($Defense == 6)
    -                {
    -                    if (rand(1) <= 0.6)
    -                    {
    -                        print "PASS STOLEN BY $Opponent, EASY LAYUP.\n";
    -                        opp_score();
    -                        next;
    -                    }
    -                }
    -                print "BALL PASSED BACK TO YOU.\n";
    -                next;
    -            }
    -
    -            if (rand(1) <= 0.782*$Defense/8)
    -            {
    -                print "SHOT IS BLOCKED.  BALL CONTROLLED BY "; # no NL
    -                if (rand(1) > 0.5)
    -                {
    -                    print "$Opponent.\n";
    -                    last;
    -                }
    -                else
    -                {
    -                    print "DARTMOUTH.\n";
    -                    next;
    -                }
    -            }
    -
    -            if (rand(1) > 0.843*$Defense/8)
    -            {
    -                print "CHARGING FOUL.  DARTMOUTH LOSES BALL.\n";
    -                last;
    -            }
    -            else
    -            {
    -                print "SHOOTER IS FOULED.  TWO SHOTS.\n";
    -                foul_shooting();
    -                last;
    -            }
    -        }
    -        else # elsif ($ShotType >= 3)
    -        {
    -            print '', ($ShotType > 3 ? "SET SHOT." : "LAY UP."), "\n";
    -            if (7 / $Defense * rand(1) <= 0.4)
    -            {
    -                print "SHOT IS GOOD.  TWO POINTS.\n";
    -                dartmouth_score();
    -                last;
    -            }
    -
    -            if (7 / $Defense * rand(1) <= 0.7)
    -            {
    -                print "SHOT IS OFF THE RIM.\n";
    -                if (rand(1) <= 0.667)
    -                {
    -                    print "$Opponent CONTROLS THE REBOUND.\n";
    -                    last;
    -                }
    -
    -                print "DARTMOUTH CONTROLS THE REBOUND.\n";
    -                next if (rand(1) <= 0.4);
    -
    -                print "BALL PASSED BACK TO YOU.\n";
    -                next;
    -            }
    -
    -            if (7 / $Defense * rand(1) <= 0.875)
    -            {
    -                print "SHOOTER FOULED.  TWO SHOTS.\n";
    -                foul_shooting();
    -                last;
    -            }
    -
    -            if (7 / $Defense * rand(1) <= 0.925)
    -            {
    -                print "SHOT BLOCKED. $Opponent\'S BALL.\n";
    -                last;
    -            }
    -
    -            print "CHARGING FOUL.  DARTMOUTH LOSES THE BALL.\n";
    -            last;
    -        }
    -    }
    -    $ConTeam = "opp";
    -}
    -
    -sub get_defense
    -{
    -    $Defense = 0;
    -    do {
    -        print "YOUR NEW DEFENSIVE ALLIGNMENT IS (6, 6.5, 7. 7.5): ";
    -        chomp($Defense = <>);
    -        ($Defense) =~ m/(\d(\.\d)?)/;
    -    } while ($Defense < 6.0 || $Defense > 7.5)
    -}
    -
    -sub opponent_play
    -{
    -    $Player = 1;
    -    print "\n";
    -    while (1)
    -    {
    -        $Timer++;
    -        if ($Timer == 50) { end_first_half(); return; }
    -        if ($Timer == 92) { two_min_left(); }
    -
    -        if ($ShotType <= 2.0)
    -        {
    -            print "JUMP SHOT.\n";
    -            if (8.0 / $Defense * rand(1) <= 0.35)
    -            {
    -                print "SHOT IS GOOD.\n";
    -                opp_score();
    -                last;
    -            }
    -
    -            if (8.0 / $Defense * rand(1) <=  0.75)
    -            {
    -                print "SHOT IS OFF RIM.\n";
    -                opp_missed();
    -                return; # for possible new ShotType or team change
    -            }
    -
    -            if (8.0 / $Defense * rand(1) <= 0.9)
    -            {
    -                print "PLAYER FOULED.  TWO SHOTS.\n";
    -                foul_shooting();
    -                last;
    -            }
    -            print "OFFENSIVE FOUL.  DARTMOUTH'S BALL.\n";
    -            last;
    -        }
    -        else # ShotType >= 3
    -        {
    -            print ($ShotType > 3 ? "SET SHOT.\n" : "LAY UP.\n");
    -            if (7.0 / $Defense * rand(1) > 0.413)
    -            {
    -                print "SHOT IS MISSED.\n";
    -                {
    -                    opp_missed();
    -                    return; # for possible new ShotType or team change
    -                }
    -            }
    -            else
    -            {
    -                print "SHOT IS GOOD.\n";
    -                opp_score();
    -                last;
    -            }
    -        }
    -    }
    -    $ConTeam = "dart";
    -}
    -
    -sub opp_missed
    -{
    -    if ($Defense / 6.0 * rand(1) <= 0.5)
    -    {
    -        print "DARTMOUTH CONTROLS THE REBOUND.\n";
    -        $ConTeam = "dart";
    -    }
    -    else
    -    {
    -        print "$Opponent CONTROLS THE REBOUND.\n";
    -        if ($Defense == 6)
    -        {
    -            if (rand(1) <= 0.75)
    -            {
    -                print "BALL STOLEN.  EASY LAY UP FOR DARTMOUTH.\n";
    -                dartmouth_score();
    -                #$ConTeam = "opp";
    -                return; # for possible new ShotType
    -            }
    -        }
    -        if (rand(1) <= 0.5)
    -        {
    -            print "PASS BACK TO $Opponent GUARD.\n";
    -            #$ConTeam = "opp";
    -            return; # for possible new ShotType
    -        }
    -        $ShotType = (rand(1) <= 0.5) ? 3 : 4;
    -    }
    -}
    -
    -sub opp_score
    -{
    -    $Score[0] += 2;
    -    print_score();
    -}
    -
    -sub dartmouth_score
    -{
    -    $Score[1] += 2;
    -    print_score();
    -}
    -
    -sub print_score
    -{
    -    print "SCORE: $Score[1] TO $Score[0]\n";
    -    print "TIME: $Timer\n";
    -}
    -
    -sub end_first_half
    -{
    -    print "\n   ***** END OF FIRST HALF *****\n\n";
    -    print "SCORE: DARTMOUTH: $Score[1]   $Opponent: $Score[0]\n\n\n";
    -    $ConTeam = center_jump();
    -}
    -
    -sub get_your_shot
    -{
    -    $ShotType = -1;
    -    while ($ShotType < 0 || $ShotType > 4)
    -    {
    -        print "YOUR SHOT (0-4): ";
    -        chomp($ShotType = <>);
    -        $ShotType = int($ShotType);
    -        if ($ShotType < 0 || $ShotType > 4)
    -        {
    -            print "INCORRECT ANSWER.  RETYPE IT. ";
    -        }
    -    }
    -}
    -
    -sub center_jump
    -{
    -    print "CENTER JUMP\n";
    -    if (rand(1) <= 0.6)
    -    {
    -        print "$Opponent CONTROLS THE TAP.\n";
    -        return "opp";
    -    }
    -    print "DARTMOUTH CONTROLS THE TAP.\n";
    -    return "dart";
    -}
    -
    -sub check_end_game
    -{
    -    print "\n";
    -    if ($Score[1] != $Score[0])
    -    {
    -        print "   ***** END OF GAME *****\n";
    -        print "FINAL SCORE: DARTMOUTH: $Score[1]    $Opponent: $Score[0]\n\n";
    -        $DoPlay = 0;
    -    }
    -    else
    -    {
    -        print "\n   ***** END OF SECOND HALF *****\n";
    -        print "SCORE AT END OF REGULATION TIME:\n";
    -        print "        DARTMOUTH: $Score[1]    $Opponent: $Score[0]\n\n";
    -        print "BEGIN TWO MINUTE OVERTIME PERIOD\n";
    -    }
    -}
    -
    -sub two_min_left
    -{
    -    print "\n   *** TWO MINUTES LEFT IN THE GAME ***\n\n";
    -}
    -
    -sub foul_shooting
    -{
    -    if (rand(1) > 0.49)
    -    {
    -        if (rand(1) > 0.75)
    -        {
    -            print "BOTH SHOTS MISSED.\n";
    -        }
    -        else
    -        {
    -            print "SHOOTER MAKES ONE SHOT AND MISSES ONE.\n";
    -            $Score[1 - $Player]++;
    -        }
    -    }
    -    else
    -    {
    -        print "SHOOTER MAKES BOTH SHOTS.\n";
    -        $Score[1 - $Player] += 2;
    -    }
    -
    -    print_score();
    -}
    diff --git a/07_Basketball/python/basketball.py b/07_Basketball/python/basketball.py
    index 122185a13..20a6cd94f 100644
    --- a/07_Basketball/python/basketball.py
    +++ b/07_Basketball/python/basketball.py
    @@ -1,79 +1,84 @@
    -"""
    -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
    -"""
    -
     import random
    -from typing import List, Literal, Optional
    -
    -
    -def print_intro() -> None:
    -    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="")
    -
    -
    -class Basketball:
    -    def __init__(self) -> None:
    +
    +# 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_choices: List[float] = [6, 6.5, 7, 7.5]
    -        self.shot: Optional[int] = None
    -        self.shot_choices: List[Literal[0, 1, 2, 3, 4]] = [0, 1, 2, 3, 4]
    -        self.z1: Optional[float] = None
    +        self.defense = None
    +        self.defense_choices = [6, 6.5, 7, 7.5]
    +        self.shot = None
    +        self.shot_choices = [0, 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())
     
    -        print_intro()
    +        except ValueError:
    +            self.defense = None
     
    -        self.defense = get_defense_choice(self.defense_choices)
    +        # 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())
     
    -        self.opponent = get_opponents_name()
    -        self.start_of_period()
    +            except ValueError:
    +                continue
    +
    +        # takes input for opponent's name
    +        print("\nChoose your opponent? ", end='')
     
    -    def add_points(self, team: Literal[0, 1], points: Literal[0, 1, 2]) -> None:
    -        """
    -        Add points to the score.
    +        self.opponent = input()
    +        self.start_of_period()
     
    -        Team can take 0 or 1, for opponent or Dartmouth, respectively
    -        """
    +    # 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) -> None:
    -        print("Ball passed back to you. ", end="")
    +    def ball_passed_back(self):
    +        print("Ball passed back to you. ", end='')
             self.dartmouth_ball()
     
    -    def change_defense(self) -> None:
    -        """change defense, called when the user enters 0 for their shot"""
    -        defense = None
    +    # change defense, called when the user enters 0 for their shot
    +    def change_defense(self):
    +        self.defense = None
     
    -        while defense not in self.defense_choices:
    +        while self.defense not in self.defense_choices:
                 print("Your new defensive allignment is? ")
                 try:
    -                defense = float(input())
    +                self.defense = float(input())
    +
                 except ValueError:
                     continue
    -        assert isinstance(defense, float)
    -        self.defense = defense
             self.dartmouth_ball()
     
    -    def foul_shots(self, team: Literal[0, 1]) -> None:
    -        """Simulate two foul shots for a player and adds the points."""
    +    # simulates two foul shots for a player and adds the points
    +    def foul_shots(self, team):
             print("Shooter fouled.  Two shots.")
    -        if random.random() > 0.49:
    -            if random.random() > 0.75:
    +        if random.random() > .49:
    +            if random.random() > .75:
                     print("Both shots missed.")
                 else:
                     print("Shooter makes one shot and misses one.")
    @@ -84,32 +89,33 @@ def foul_shots(self, team: Literal[0, 1]) -> None:
     
             self.print_score()
     
    -    def halftime(self) -> None:
    -        """called when t = 50, starts a new period"""
    +    # 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()
     
    -    def print_score(self) -> None:
    -        """Print the current score"""
    -        print(f"Score:  {self.score[1]} to {self.score[0]}\n")
    +    # prints the current score
    +    def print_score(self):
    +        print("Score:  " + str(self.score[1])
    +              + " to " + str(self.score[0]) + "\n")
     
    -    def start_of_period(self) -> None:
    -        """Simulate a center jump for posession at the beginning of a period"""
    +    # simulates a center jump for posession at the beginning of a period
    +    def start_of_period(self):
             print("Center jump")
    -        if random.random() > 0.6:
    +        if random.random() > .6:
                 print("Dartmouth controls the tap.\n")
                 self.dartmouth_ball()
             else:
                 print(self.opponent + " controls the tap.\n")
                 self.opponent_ball()
     
    -    def two_minute_warning(self) -> None:
    -        """called when t = 92"""
    +    # called when t = 92
    +    def two_minute_warning(self):
             print("   *** Two minutes left in the game ***")
     
    -    def dartmouth_jump_shot(self) -> None:
    -        """called when the user enters 1 or 2 for their shot"""
    +    # 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()
    @@ -117,54 +123,51 @@ def dartmouth_jump_shot(self) -> None:
                 self.two_minute_warning()
             print("Jump Shot.")
             # simulates chances of different possible outcomes
    -        if random.random() > 0.341 * self.defense / 8:
    -            if random.random() > 0.682 * self.defense / 8:
    -                if random.random() > 0.782 * self.defense / 8:
    -                    if random.random() > 0.843 * self.defense / 8:
    +        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()
    -                elif random.random() > 0.5:
    -                    print(
    -                        "Shot is blocked. Ball controlled by "
    -                        + self.opponent
    -                        + ".\n"
    -                    )
    -                    self.opponent_ball()
    +                        self.opponent_ball()
                     else:
    -                    print("Shot is blocked. Ball controlled by Dartmouth.")
    -                    self.dartmouth_ball()
    +                    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() > 0.45:
    -                    print(f"Rebound to {self.opponent}\n")
    +                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() > 0.4:
    -                        if self.defense == 6 and random.random() > 0.6:
    -                            print(f"Pass stolen by {self.opponent}, easy lay up")
    +                    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()
    +                        print("")
                             self.dartmouth_non_jump_shot()
             else:
                 print("Shot is good.")
                 self.add_points(1, 2)
                 self.opponent_ball()
     
    -    def dartmouth_non_jump_shot(self) -> None:
    -        """
    -        Lay up, set shot, or defense change
    -
    -        called when the user enters 0, 3, or 4
    -        """
    +    # 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()
    @@ -179,21 +182,23 @@ def dartmouth_non_jump_shot(self) -> None:
                 self.change_defense()
     
             # simulates different outcomes after a lay up or set shot
    -        if 7 / self.defense * random.random() > 0.4:
    -            if 7 / self.defense * random.random() > 0.7:
    -                if 7 / self.defense * random.random() > 0.875:
    -                    if 7 / self.defense * random.random() > 0.925:
    +        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(f"Shot blocked. {self.opponent}'s ball.\n")
    +                        print("Shot blocked. " + self.opponent + "'s ball.\n")
    +                        self.opponent_ball()
                     else:
                         self.foul_shots(1)
    -                self.opponent_ball()
    +                    self.opponent_ball()
                 else:
                     print("Shot is off the rim.")
    -                if random.random() > 2 / 3:
    +                if random.random() > 2/3:
                         print("Dartmouth controls the rebound.")
    -                    if random.random() > 0.4:
    +                    if random.random() > .4:
                             print("Ball passed back to you.\n")
                             self.dartmouth_ball()
                         else:
    @@ -206,78 +211,76 @@ def dartmouth_non_jump_shot(self) -> None:
                 self.add_points(1, 2)
                 self.opponent_ball()
     
    -    def dartmouth_ball(self) -> None:
    -        """plays out a Dartmouth posession, starting with your choice of shot"""
    -        shot = get_dartmouth_ball_choice(self.shot_choices)
    -        self.shot = shot
    +    # 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() < 0.5:
    -            if self.shot in [1, 2]:
    +        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()
    -        elif self.score[0] == self.score[1]:
    -            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()
    -
             else:
    -            print("\n   ***** End Of Game *****")
    -            print(
    -                "Final Score: Dartmouth: "
    -                + str(self.score[1])
    -                + "  "
    -                + self.opponent
    -                + ": "
    -                + str(self.score[0])
    -            )
    -
    -    def opponent_jumpshot(self) -> None:
    -        """Simulate the opponents jumpshot"""
    +            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() > 0.35:
    -            if 8 / self.defense * random.random() > 0.75:
    -                if 8 / self.defense * random.random() > 0.9:
    +        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()
    +                    self.dartmouth_ball()
                 else:
                     print("Shot is off the rim.")
    -                if self.defense / 6 * random.random() > 0.5:
    -                    print(f"{self.opponent} controls the rebound.")
    -                    if (
    -                        self.defense == 6
    -                        and random.random() <= 0.75
    -                        and random.random() > 0.5
    -                    ):
    -                        print()
    -                        self.opponent_non_jumpshot()
    -                    elif (
    -                        self.defense == 6
    -                        and random.random() <= 0.75
    -                        and random.random() <= 0.5
    -                        or self.defense != 6
    -                        and random.random() <= 0.5
    -                    ):
    -                        print(f"Pass back to {self.opponent} guard.\n")
    -                        self.opponent_ball()
    -                    elif self.defense == 6 and random.random() > 0.75:
    -                        print("Ball stolen. Easy lay up for Dartmouth.")
    -                        self.add_points(1, 2)
    -                        self.opponent_ball()
    +                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:
    -                        self.opponent_non_jumpshot()
    +                        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()
    @@ -286,39 +289,36 @@ def opponent_jumpshot(self) -> None:
                 self.add_points(0, 2)
                 self.dartmouth_ball()
     
    -    def opponent_non_jumpshot(self) -> None:
    -        """Simulate opponents lay up or set shot."""
    -        if self.z1 > 3:  # type: ignore
    +    # 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() > 0.413:
    +        if 7/self.defense*random.random() > .413:
                 print("Shot is missed.")
    -            if self.defense / 6 * random.random() > 0.5:
    -                print(f"{self.opponent} controls the rebound.")
    -                if (
    -                    self.defense == 6
    -                    and random.random() <= 0.75
    -                    and random.random() > 0.5
    -                    or self.defense != 6
    -                    and random.random() > 0.5
    -                ):
    -                    print()
    -                    self.opponent_non_jumpshot()
    -                elif (
    -                    self.defense == 6
    -                    and random.random() <= 0.75
    -                    and random.random() <= 0.5
    -                ):
    -                    print(f"Pass back to {self.opponent} guard.\n")
    -                    self.opponent_ball()
    -                elif self.defense == 6 and random.random() > 0.75:
    -                    print("Ball stolen. Easy lay up for Dartmouth.")
    -                    self.add_points(1, 2)
    -                    self.opponent_ball()
    +            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:
    -                    print(f"Pass back to {self.opponent} guard\n")
    -                    self.opponent_ball()
    +                    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()
    @@ -327,63 +327,17 @@ def opponent_non_jumpshot(self) -> None:
                 self.add_points(0, 2)
                 self.dartmouth_ball()
     
    -    def opponent_ball(self) -> None:
    -        """
    -        Simulate an opponents possesion
    -
    -        Randomly picks jump shot or lay up / set shot.
    -        """
    +    # 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
    +        self.z1 = 10/4*random.random()+1
             if self.z1 > 2:
                 self.opponent_non_jumpshot()
             else:
                 self.opponent_jumpshot()
     
     
    -def get_defense_choice(defense_choices: List[float]) -> float:
    -    """Takes input for a defense"""
    -    try:
    -        defense = float(input())
    -    except ValueError:
    -        defense = None
    -
    -    # if the input wasn't a valid defense, takes input again
    -    while defense not in defense_choices:
    -        print("Your new defensive allignment is? ", end="")
    -        try:
    -            defense = float(input())
    -        except ValueError:
    -            continue
    -    assert isinstance(defense, float)
    -    return defense
    -
    -
    -def get_dartmouth_ball_choice(shot_choices: List[Literal[0, 1, 2, 3, 4]]) -> int:
    -    print("Your shot? ", end="")
    -    shot = None
    -    try:
    -        shot = int(input())
    -    except ValueError:
    -        shot = None
    -
    -    while shot not in shot_choices:
    -        print("Incorrect answer. Retype it. Your shot? ", end="")
    -        try:
    -            shot = int(input())
    -        except Exception:
    -            continue
    -    assert isinstance(shot, int)
    -    return shot
    -
    -
    -def get_opponents_name() -> str:
    -    """Take input for opponent's name"""
    -    print("\nChoose your opponent? ", end="")
    -    return input()
    -
    -
    -if __name__ == "__main__":
    -    Basketball()
    +new_game = Basketball()
    diff --git a/07_Basketball/ruby/basketball.rb b/07_Basketball/ruby/basketball.rb
    deleted file mode 100644
    index 150c6ae64..000000000
    --- a/07_Basketball/ruby/basketball.rb
    +++ /dev/null
    @@ -1,348 +0,0 @@
    -class Basketball
    -
    -  def initialize
    -    @time = 0
    -    @score = [0, 0]
    -    @defense_choices = [6, 6.5, 7, 7.5]
    -    @shot = nil
    -    @shot_choices = [0, 1, 2, 3, 4]
    -    @z1 = nil
    -
    -    puts "Υou will be Dartmouth captain and playmaker."
    -    puts "Call shots as follows:"
    -    puts "1. Long (30ft.) Jump Shot"
    -    puts "2. Short (15 ft.) Jump Shot"
    -    puts "3. Lay up; 4. Set Shot\n\n"
    -    
    -    puts "Both teams will use the same defense. Call Defense as follows:"
    -    puts "6. Press"
    -    puts "6.5 Man-to-Man"
    -    puts "7. Zone"
    -    puts "7.5 None.\n\n"
    -
    -    puts "To change defense, just type 0 as your next shot."
    -
    -    @defense = get_defense @defense_choices
    -
    -
    -    puts "\nChoose your opponent? "
    -    @opponent = gets.chomp!
    -    start_of_period
    -  end
    -
    -  def dartmouth_ball
    -    while true
    -      puts "Your shot? " 
    -      @shot = gets.chomp!
    -      if @shot_choices.include? @shot.to_i
    -        break
    -      end
    -    end
    -
    -    if @time < 100 or Random.rand < 0.5
    -      if @shot.to_i == 1 or @shot.to_i == 2
    -        dartmouth_jump_shot
    -      else
    -        dartmouth_non_jump_shot
    -      end
    -    else
    -      if @score[0] != @score[1]
    -        puts "\n   ***** End Of Game *****" 
    -        puts "Final Score: Dartmouth: #{@score[1].to_s}  #{@opponent}: #{@score[0].to_s}"
    -      else
    -        puts "\n   ***** End Of Second Half *****"
    -        puts "Score at end of regulation time:"
    -        puts "     Dartmouth: #{@score[1]} #{@opponent}: #{@score[0]}"
    -
    -        puts "Begin two minute overtime period" 
    -        @time = 93
    -        start_of_period
    -      end
    -    end
    -  end
    -
    -  def add_points team, points
    -    @score[team] += points
    -    print_score
    -  end
    -
    -  def ball_passed_back
    -    puts "Ball passed back to you"
    -  end
    -
    -  def change_defense
    -    @defense = get_defense @defense_choices, "new"
    -    dartmouth_ball()
    -  end
    -
    -  def foul_shots team
    -    puts "Shooter fouled.  Two shots."
    -    if Random.rand > 0.49
    -      if Random.rand > 0.75
    -        puts "Both shots missed."
    -      else
    -        puts "Shooter makes one shot and misses one."
    -        @score[team] += 1
    -      end
    -    else
    -      puts "Shooter makes both shots."
    -      @score[team] += 2
    -    end
    -  end
    -
    -  def halftime
    -    puts "\n   ***** End of first half *****\n" 
    -    print_score
    -    start_of_period
    -  end
    -
    -  def print_score
    -    puts "Score:  #{@score[1]} to #{@score[0]}\n" 
    -  end
    -
    -  def start_of_period
    -    puts "Center jump" 
    -    if Random.rand > 0.6
    -      puts "Dartmouth controls the tap.\n" 
    -      dartmouth_ball()
    -    else
    -      puts "#{@opponent} controls the tap.\n" 
    -      opponent_ball
    -    end
    -  end
    -
    -  def two_minute_warning
    -    puts "   *** Two minutes left in the game ***" 
    -  end
    -
    -  def dartmouth_jump_shot
    -    @time += 1
    -    if @time == 50
    -      halftime
    -    elsif @time == 92
    -      two_minute_warning
    -    end
    -    puts "Jumpshot"
    -
    -    if Random.rand > 0.341 * @defense.to_i / 8
    -      if Random.rand > 0.682 * @defense.to_i / 8
    -        if Random.rand > 0.782 * @defense.to_i / 8
    -          if Random.rand > 0.843 * @defense.to_i / 8
    -            puts "Charging foul. Dartmouth loses ball.\n" 
    -            opponent_ball
    -          else
    -            foul_shots 1
    -            opponent_ball
    -          end
    -        else
    -          if Random.rand > 0.5
    -            puts "Shot is blocked. Ball controlled by #{@opponent}\n"
    -            opponent_ball
    -          else
    -            puts "Shot is blocked. Ball controlled by Dartmouth."
    -            dartmouth_ball()
    -          end
    -        end
    -      else
    -        puts "Shot is off target." 
    -        if @defense.to_i / 6 * Random.rand > 0.45
    -          puts "Rebound to " + @opponent + "\n" 
    -          opponent_ball
    -        else
    -          puts "Dartmouth controls the rebound." 
    -          if Random.rand > 0.4
    -            if @defense.to_i == 6 and Random.rand > 0.6
    -              puts "Pass stolen by #{@opponent}, easy lay up" 
    -              add_points(0, 2)
    -              dartmouth_ball()
    -            else
    -              ball_passed_back
    -            end
    -          else
    -            puts "\n" 
    -            dartmouth_non_jump_shot
    -          end
    -        end
    -      end
    -    else
    -      puts "Shot is good." 
    -      add_points(1, 2)
    -      opponent_ball
    -    end
    -  end
    -
    -  def dartmouth_non_jump_shot
    -    @time += 1
    -    if @time == 50
    -      halftime
    -    elsif @time == 92
    -      two_minute_warning
    -    end
    -
    -    if @shot.to_i == 4
    -      puts "Set shot." 
    -    elsif @shot.to_i == 3
    -      puts "Lay up." 
    -    elsif @shot.to_i == 0
    -      change_defense
    -    end
    -
    -    if 7 / @defense.to_i * Random.rand > 0.4
    -      if 7 / @defense.to_i * Random.rand > 0.7
    -        if 7 / @defense.to_i * Random.rand > 0.875
    -          if 7 / @defense.to_i * Random.rand > 0.925
    -            puts "Charging foul. Dartmouth loses the ball.\n"
    -            opponent_ball
    -          else
    -            puts "Shot blocked. #{@opponent}'s ball.\n" 
    -            opponent_ball
    -          end
    -        else
    -          foul_shots(1)
    -          opponent_ball
    -        end
    -      else
    -        puts "Shot is off the rim." 
    -        if Random.rand > 2 / 3
    -          puts "Dartmouth controls the rebound."
    -          if Random.rand > 0.4
    -            puts "Ball passed back to you.\n"
    -            dartmouth_ball()
    -          else
    -            dartmouth_non_jump_shot
    -          end
    -        else
    -          puts "#{@opponent} controls the rebound.\n"
    -          opponent_ball
    -        end
    -      end
    -    else
    -      puts "Shot is good. Two points."
    -      add_points(1, 2)
    -      opponent_ball
    -    end
    -  end
    -
    -  def opponent_jumpshot
    -    puts "Jump Shot." 
    -    if 8 / @defense.to_i * Random.rand > 0.35
    -      if 8 / @defense.to_i * Random.rand > 0.75
    -        if 8 / @defense.to_i * Random.rand > 0.9
    -          puts "Offensive foul. Dartmouth's ball.\n" 
    -          dartmouth_ball()
    -        else
    -          foul_shots(0)
    -          dartmouth_ball()
    -        end
    -      else
    -        puts "Shot is off the rim." 
    -        if @defense.to_i / 6 * Random.rand > 0.5
    -          puts "#{@opponent} controls the rebound." 
    -          if @defense.to_i == 6
    -            if Random.rand > 0.75
    -              puts "Ball stolen. Easy lay up for Dartmouth." 
    -              add_points(1, 2)
    -              opponent_ball
    -            else
    -              if Random.rand > 0.5
    -                puts ""
    -                opponent_non_jumpshot
    -              else
    -                puts "Pass back to #{@opponent} guard.\n" 
    -                opponent_ball
    -              end
    -            end
    -          else
    -            if Random.rand > 0.5
    -              opponent_non_jumpshot
    -            else
    -              puts "Pass back to #{@opponent} guard.\n" 
    -              opponent_ball
    -            end
    -          end
    -        else
    -          puts "Dartmouth controls the rebound.\n" 
    -          dartmouth_ball()
    -        end
    -      end
    -    else
    -      puts "Shot is good." 
    -      add_points(0, 2)
    -      dartmouth_ball()
    -    end
    -  end
    -
    -  def opponent_non_jumpshot
    -    if @z1 > 3
    -        puts "Set shot." 
    -    else
    -      puts "Lay up" 
    -    end
    -
    -    if 7 / @defense.to_i * Random.rand > 0.413
    -      puts "Shot is missed." 
    -      if @defense.to_i / 6 * Random.rand > 0.5
    -        puts "#{@opponent} controls the rebound." 
    -        if @defense.to_i == 6
    -            if Random.rand > 0.75
    -              puts "Ball stolen. Easy lay up for Dartmouth." 
    -              add_points(1, 2)
    -              opponent_ball
    -            else
    -              if Random.rand > 0.5
    -                  puts "" 
    -                  opponent_non_jumpshot
    -              else
    -                puts "Pass back to #{@opponent} guard.\n" 
    -                opponent_ball
    -              end
    -            end
    -        else
    -          if Random.rand > 0.5
    -            puts "" 
    -            opponent_non_jumpshot
    -          else
    -            puts "Pass back to #{@opponent} guard\n" 
    -            opponent_ball
    -          end
    -        end
    -      else
    -        puts "Dartmouth controls the rebound.\n"
    -        dartmouth_ball()
    -      end
    -    else
    -      puts "Shot is good." 
    -      add_points(0, 2)
    -      dartmouth_ball()
    -    end
    -  end
    -
    -  def opponent_ball
    -    @time += 1
    -    if @time == 50
    -      halftime
    -    end
    -
    -    @z1 = 10 / 4 * Random.rand + 1
    -    
    -    if @z1 > 2
    -      opponent_non_jumpshot
    -    else
    -      opponent_jumpshot
    -    end
    -  end
    -
    -  def get_defense defense_choices, type = "starting"
    -    while true
    -      puts "Your #{type} defense will be? [6 - Press] [6.5 - Man-to-Man] [7 - Zone] [7.5 None]"
    -      defense = gets.chomp!
    -      if defense_choices.include? defense.to_i
    -        break
    -      end
    -    end 
    -
    -    return defense.to_i
    -  end
    -end
    -
    -b = Basketball.new
    diff --git a/07_Basketball/rust/Cargo.lock b/07_Basketball/rust/Cargo.lock
    deleted file mode 100644
    index 5d92a1cf5..000000000
    --- a/07_Basketball/rust/Cargo.lock
    +++ /dev/null
    @@ -1,77 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 4
    -
    -[[package]]
    -name = "basketball"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
    -
    -[[package]]
    -name = "chacha20"
    -version = "0.10.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81"
    -dependencies = [
    - "cfg-if",
    - "cpufeatures",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "cpufeatures"
    -version = "0.3.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201"
    -dependencies = [
    - "libc",
    -]
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.4.3"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "r-efi",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.189"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
    -
    -[[package]]
    -name = "r-efi"
    -version = "6.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
    -
    -[[package]]
    -name = "rand"
    -version = "0.10.2"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80"
    -dependencies = [
    - "chacha20",
    - "getrandom",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.10.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69"
    diff --git a/07_Basketball/rust/Cargo.toml b/07_Basketball/rust/Cargo.toml
    deleted file mode 100644
    index 3a4c7c80b..000000000
    --- a/07_Basketball/rust/Cargo.toml
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -[package]
    -name = "basketball"
    -version = "0.1.0"
    -edition = "2024"
    -
    -[dependencies]
    -rand = "0.10.0"
    diff --git a/07_Basketball/rust/src/main.rs b/07_Basketball/rust/src/main.rs
    deleted file mode 100644
    index ca0d6792d..000000000
    --- a/07_Basketball/rust/src/main.rs
    +++ /dev/null
    @@ -1,444 +0,0 @@
    -use rand::{RngExt, rngs::ThreadRng};
    -use std::io::{self, Write};
    -
    -fn main() {
    -    println!("{:>30}BASKETBALL", "");
    -    println!("{:>15}CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY", "");
    -    println!("\n\n");
    -
    -    println!("THIS IS DARTMOUTH COLLEGE BASKETBALL.  YOU WILL BE DARTMOUTH");
    -    println!(" CAPTAIN AND PLAYMAKER.  CALL SHOTS AS FOLLOWS:  1. LONG");
    -    println!(" (30 FT.) JUMP SHOT; 2. SHORT (15 FT.) JUMP SHOT; 3. LAY");
    -    println!(" UP; 4. SET SHOT.");
    -    println!("BOTH TEAMS WILL USE THE SAME DEFENSE.  CALL DEFENSE AS");
    -    println!("FOLLOWS:  6. PRESS; 6.5 MAN-TO MAN; 7. ZONE; 7.5 NONE.");
    -    println!("TO CHANGE DEFENSE, JUST TYPE 0 AS YOUR NEXT SHOT.");
    -
    -    let mut game = BasketballGame::new();
    -    game.play();
    -}
    -
    -struct BasketballGame {
    -    rng: ThreadRng,
    -    // D is the defensive alignment. It is one of 6, 6.5, 7 or 7.5 (but the
    -    // original code only validates that D >= 6).
    -    defense: f64,
    -    // The opponent's name.
    -    opponent: String,
    -    // Game clock. Incremented on most possessions; 50 ends the first half,
    -    // 92 triggers the two-minute warning and 100 forces overtime or the
    -    // final whistle.
    -    time: i32,
    -    // Score: index 0 is the opponent, index 1 is Dartmouth.
    -    score: [i32; 2],
    -}
    -
    -impl BasketballGame {
    -    fn new() -> Self {
    -        let rng = rand::rng();
    -
    -        // Line 76: prompt for the starting defense. The original accepts any
    -        // value >= 6, so we replicate that rather than restricting to the
    -        // documented options.
    -        let defense = loop {
    -            print!("YOUR STARTING DEFENSE WILL BE");
    -            let d: f64 = read_input();
    -            if d >= 6.0 {
    -                break d;
    -            }
    -            // BASIC line 76 falls through to 2010 which re-prompts for the
    -            // defensive alignment; reproducing that behaviour here.
    -        };
    -        println!();
    -
    -        print!("CHOOSE YOUR OPPONENT");
    -        let opponent = read_line().trim().to_string();
    -
    -        Self {
    -            rng,
    -            defense,
    -            opponent,
    -            time: 0,
    -            score: [0, 0],
    -        }
    -    }
    -
    -    fn play(&mut self) {
    -        // Line 370: center jump to open each half/overtime period.
    -        self.center_jump();
    -    }
    -
    -    /// Line 370-420: simulates the center jump that starts each period.
    -    fn center_jump(&mut self) {
    -        println!("CENTER JUMP");
    -        if self.rng.random::() > 3.0 / 5.0 {
    -            println!("DARTMOUTH CONTROLS THE TAP.");
    -            println!();
    -            self.dartmouth_possession();
    -        } else {
    -            println!("{} CONTROLS THE TAP.", self.opponent);
    -            self.opponent_possession();
    -        }
    -    }
    -
    -    /// Lines 425-500: Dartmouth has the ball and asks the player for a shot.
    -    fn dartmouth_possession(&mut self) {
    -        let z = self.read_shot();
    -        // Line 460: half the time, when the clock has run out, we go to the
    -        // end-of-game / overtime logic instead of resolving the shot.
    -        if self.rng.random::() < 0.5 && self.time >= 100 {
    -            self.end_of_game_or_overtime();
    -            return;
    -        }
    -
    -        match z {
    -            1 | 2 => self.dartmouth_jump_shot(),
    -            _ => self.dartmouth_non_jump_shot(z),
    -        }
    -    }
    -
    -    /// Line 430-455: read and validate the player's shot choice.
    -    fn read_shot(&mut self) -> i32 {
    -        loop {
    -            print!("YOUR SHOT");
    -            let line = read_line();
    -            match line.trim().parse::() {
    -                Ok(z) if (0..=4).contains(&z) => return z,
    -                _ => print!("INCORRECT ANSWER.  RETYPE IT. "),
    -            }
    -        }
    -    }
    -
    -    /// Lines 1040-1280: long or short jump shot for Dartmouth.
    -    fn dartmouth_jump_shot(&mut self) {
    -        self.advance_clock_with_two_minute_warning();
    -        println!("JUMP SHOT");
    -
    -        if self.rng.random::() <= 0.341 * self.defense / 8.0 {
    -            println!("SHOT IS GOOD.");
    -            self.add_dartmouth_score();
    -            self.opponent_possession();
    -            return;
    -        }
    -        if self.rng.random::() <= 0.682 * self.defense / 8.0 {
    -            println!("SHOT IS OFF TARGET.");
    -            if self.defense / 6.0 * self.rng.random::() > 0.45 {
    -                println!("REBOUND TO {}", self.opponent);
    -                self.opponent_possession();
    -            } else {
    -                println!("DARTMOUTH CONTROLS THE REBOUND.");
    -                if self.rng.random::() <= 0.4 {
    -                    println!();
    -                    self.dartmouth_non_jump_shot(3);
    -                } else if self.defense == 6.0 && self.rng.random::() > 0.6 {
    -                    // Line 5100-5130: pass stolen, easy lay-up for opponent.
    -                    println!("PASS STOLEN BY {} EASY LAYUP.", self.opponent);
    -                    self.add_opponent_score();
    -                    self.dartmouth_possession();
    -                } else {
    -                    print!("BALL PASSED BACK TO YOU. ");
    -                    self.dartmouth_possession();
    -                }
    -            }
    -            return;
    -        }
    -        if self.rng.random::() <= 0.782 * self.defense / 8.0 {
    -            print!("SHOT IS BLOCKED.  BALL CONTROLLED BY ");
    -            if self.rng.random::() > 0.5 {
    -                println!("DARTMOUTH.");
    -                self.dartmouth_possession();
    -            } else {
    -                println!("{}.", self.opponent);
    -                self.opponent_possession();
    -            }
    -            return;
    -        }
    -        if self.rng.random::() <= 0.843 * self.defense / 8.0 {
    -            println!("SHOOTER IS FOULED.  TWO SHOTS.");
    -            self.foul_shots(1);
    -            self.opponent_possession();
    -            return;
    -        }
    -        println!("CHARGING FOUL.  DARTMOUTH LOSES BALL.");
    -        self.opponent_possession();
    -    }
    -
    -    /// Lines 1300-1700: lay up (3) or set shot (4); also re-entered for a
    -    /// rebound put-back. A shot value of 0 means the player wants to change
    -    /// the defensive alignment (lines 2010-2040).
    -    fn dartmouth_non_jump_shot(&mut self, z: i32) {
    -        self.advance_clock_with_two_minute_warning();
    -
    -        if z == 0 {
    -            self.change_defense();
    -            return;
    -        }
    -
    -        if z == 4 {
    -            println!("SET SHOT.");
    -        } else {
    -            println!("LAY UP.");
    -        }
    -
    -        if 7.0 / self.defense * self.rng.random::() <= 0.4 {
    -            println!("SHOT IS GOOD.  TWO POINTS.");
    -            self.add_dartmouth_score();
    -            self.opponent_possession();
    -            return;
    -        }
    -        if 7.0 / self.defense * self.rng.random::() <= 0.7 {
    -            println!("SHOT IS OFF THE RIM.");
    -            if self.rng.random::() > 2.0 / 3.0 {
    -                println!("DARTMOUTH CONTROLS THE REBOUND.");
    -                if self.rng.random::() > 0.4 {
    -                    println!("BALL PASSED BACK TO YOU.");
    -                    self.dartmouth_possession();
    -                } else {
    -                    self.dartmouth_non_jump_shot(3);
    -                }
    -            } else {
    -                println!("{} CONTROLS THE REBOUND.", self.opponent);
    -                self.opponent_possession();
    -            }
    -            return;
    -        }
    -        if 7.0 / self.defense * self.rng.random::() <= 0.875 {
    -            println!("SHOOTER FOULED.  TWO SHOTS.");
    -            self.foul_shots(1);
    -            self.opponent_possession();
    -            return;
    -        }
    -        if 7.0 / self.defense * self.rng.random::() <= 0.925 {
    -            println!("SHOT BLOCKED.  {}'S BALL.", self.opponent);
    -            self.opponent_possession();
    -            return;
    -        }
    -        println!("CHARGING FOUL.  DARTMOUTH LOSES THE BALL.");
    -        self.opponent_possession();
    -    }
    -
    -    /// Lines 2010-2040: change the defensive alignment. Any value >= 6 is
    -    /// accepted, matching the original (unvalidated) behaviour.
    -    fn change_defense(&mut self) {
    -        loop {
    -            print!("YOUR NEW DEFENSIVE ALLIGNMENT IS");
    -            let d: f64 = read_input();
    -            if d >= 6.0 {
    -                self.defense = d;
    -                break;
    -            }
    -        }
    -        self.dartmouth_possession();
    -    }
    -
    -    /// Lines 3000-3810: opponent has the ball. Picks a shot type at random.
    -    fn opponent_possession(&mut self) {
    -        self.advance_clock();
    -
    -        let z1 = 10.0 / 4.0 * self.rng.random::() + 1.0;
    -        if z1 > 2.0 {
    -            self.opponent_non_jump_shot(z1);
    -        } else {
    -            self.opponent_jump_shot();
    -        }
    -    }
    -
    -    /// Lines 3040-3310: opponent jump shot.
    -    fn opponent_jump_shot(&mut self) {
    -        println!("JUMP SHOT.");
    -        if 8.0 / self.defense * self.rng.random::() <= 0.35 {
    -            println!("SHOT IS GOOD.");
    -            self.add_opponent_score();
    -            self.dartmouth_possession();
    -            return;
    -        }
    -        if 8.0 / self.defense * self.rng.random::() <= 0.75 {
    -            println!("SHOT IS OFF RIM.");
    -            if self.defense / 6.0 * self.rng.random::() > 0.5 {
    -                println!("{} CONTROLS THE REBOUND.", self.opponent);
    -                if self.defense == 6.0 && self.rng.random::() > 0.75 {
    -                    // Line 5000-5030: ball stolen, easy lay-up for Dartmouth.
    -                    println!("BALL STOLEN.  EASY LAY UP FOR DARTMOUTH.");
    -                    self.add_dartmouth_score();
    -                    self.opponent_possession();
    -                } else if self.rng.random::() > 0.5 {
    -                    println!("PASS BACK TO {} GUARD.", self.opponent);
    -                    self.opponent_possession();
    -                } else {
    -                    self.opponent_non_jump_shot(3.0);
    -                }
    -            } else {
    -                println!("DARTMOUTH CONTROLS THE REBOUND.");
    -                self.dartmouth_possession();
    -            }
    -            return;
    -        }
    -        if 8.0 / self.defense * self.rng.random::() <= 0.9 {
    -            println!("PLAYER FOULED.  TWO SHOTS.");
    -            self.foul_shots(0);
    -            self.dartmouth_possession();
    -            return;
    -        }
    -        println!("OFFENSIVE FOUL.  DARTMOUTH'S BALL.");
    -        self.dartmouth_possession();
    -    }
    -
    -    /// Lines 3500-3810: opponent lay up or set shot. `z1` carries the
    -    /// randomly chosen shot type so the put-back message can be re-shown.
    -    fn opponent_non_jump_shot(&mut self, z1: f64) {
    -        if z1 > 3.0 {
    -            println!("SET SHOT.");
    -        } else {
    -            println!("LAY UP");
    -        }
    -        if 7.0 / self.defense * self.rng.random::() <= 0.413 {
    -            println!("SHOT IS GOOD.");
    -            self.add_opponent_score();
    -            self.dartmouth_possession();
    -            return;
    -        }
    -        println!("SHOT IS MISSED.");
    -        if self.defense / 6.0 * self.rng.random::() > 0.5 {
    -            println!("{} CONTROLS THE REBOUND.", self.opponent);
    -            if self.defense == 6.0 && self.rng.random::() > 0.75 {
    -                println!("BALL STOLEN.  EASY LAY UP FOR DARTMOUTH.");
    -                self.add_dartmouth_score();
    -                self.opponent_possession();
    -            } else if self.rng.random::() > 0.5 {
    -                self.opponent_non_jump_shot(z1);
    -            } else {
    -                println!("PASS BACK TO {} GUARD.", self.opponent);
    -                self.opponent_possession();
    -            }
    -        } else {
    -            println!("DARTMOUTH CONTROLS THE REBOUND.");
    -            self.dartmouth_possession();
    -        }
    -    }
    -
    -    /// Lines 4000-4110: two foul shots. `team` is 0 for the opponent (points
    -    /// added to Dartmouth's opponent) or 1 for Dartmouth (points added to
    -    /// Dartmouth).
    -    fn foul_shots(&mut self, team: usize) {
    -        if self.rng.random::() <= 0.49 {
    -            println!("SHOOTER MAKES BOTH SHOTS.");
    -            self.score[1 - team] += 2;
    -            self.print_score();
    -        } else if self.rng.random::() <= 0.75 {
    -            println!("SHOOTER MAKES ONE SHOT AND MISSES ONE.");
    -            self.score[1 - team] += 1;
    -            self.print_score();
    -        } else {
    -            println!("BOTH SHOTS MISSED.");
    -            self.print_score();
    -        }
    -    }
    -
    -    /// Line 6010: prints the running score.
    -    fn print_score(&self) {
    -        println!("SCORE: {} TO {}", self.score[1], self.score[0]);
    -    }
    -
    -    /// Line 7000: Dartmouth scores two points, then prints the score.
    -    fn add_dartmouth_score(&mut self) {
    -        self.score[1] += 2;
    -        self.print_score();
    -    }
    -
    -    /// Line 6000: opponent scores two points, then prints the score.
    -    fn add_opponent_score(&mut self) {
    -        self.score[0] += 2;
    -        self.print_score();
    -    }
    -
    -    /// Lines 1041/1301/3008: advance the clock and handle the end-of-half
    -    /// break at T == 50.
    -    fn advance_clock(&mut self) {
    -        self.time += 1;
    -        if self.time == 50 {
    -            self.end_of_first_half();
    -        }
    -    }
    -
    -    /// Lines 1042-1046 / 1302-1304 / 3012-3015: advance the clock, handle the
    -    /// end-of-half break at T == 50 and the two-minute warning at T == 92.
    -    fn advance_clock_with_two_minute_warning(&mut self) {
    -        self.time += 1;
    -        if self.time == 50 {
    -            self.end_of_first_half();
    -        }
    -        if self.time == 92 {
    -            self.two_minute_warning();
    -        }
    -    }
    -
    -    /// Lines 610-620: two-minute warning message.
    -    fn two_minute_warning(&self) {
    -        println!();
    -        println!("   *** TWO MINUTES LEFT IN THE GAME ***");
    -        println!();
    -    }
    -
    -    /// Lines 8000-8020: end of the first half, then re-jump to start the
    -    /// second half.
    -    fn end_of_first_half(&mut self) {
    -        println!();
    -        println!("   ***** END OF FIRST HALF *****");
    -        println!();
    -        println!(
    -            "SCORE: DARTMOUTH:{}   {}:{}",
    -            self.score[1], self.opponent, self.score[0]
    -        );
    -        println!();
    -        println!();
    -        self.center_jump();
    -    }
    -
    -    /// Lines 490-520: the clock has expired. Either start overtime (if the
    -    /// game is tied) or end the game.
    -    fn end_of_game_or_overtime(&mut self) {
    -        println!();
    -        if self.score[1] != self.score[0] {
    -            println!("   ***** END OF GAME *****");
    -            println!(
    -                "FINAL SCORE: DARTMOUTH:{}   {}:{}",
    -                self.score[1], self.opponent, self.score[0]
    -            );
    -            return;
    -        }
    -
    -        println!();
    -        println!("   ***** END OF SECOND HALF *****");
    -        println!();
    -        println!("SCORE AT END OF REGULATION TIME:");
    -        println!(
    -            "        DARTMOUTH:{}   {}:{}",
    -            self.score[1], self.opponent, self.score[0]
    -        );
    -        println!();
    -        println!("BEGIN TWO MINUTE OVERTIME PERIOD");
    -        self.time = 93;
    -        self.center_jump();
    -    }
    -}
    -
    -/// Reads a line of input, flushing stdout first so the prompt is visible.
    -fn read_line() -> String {
    -    print!("? ");
    -    let _ = io::stdout().flush();
    -
    -    let mut buffer = String::new();
    -    let _ = io::stdin().read_line(&mut buffer);
    -    buffer
    -}
    -
    -/// Reads a line and parses it as the requested numeric type, re-prompting on
    -/// any parse failure.
    -fn read_input() -> T {
    -    loop {
    -        let line = read_line();
    -        if let Ok(value) = line.trim().parse::() {
    -            return value;
    -        }
    -    }
    -}
    diff --git a/07_Basketball/vbnet/Basketball.sln b/07_Basketball/vbnet/Basketball.sln
    deleted file mode 100644
    index b32c954fa..000000000
    --- a/07_Basketball/vbnet/Basketball.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 6d9f101f5..000000000
    --- a/07_Basketball/vbnet/Basketball.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Basketball
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/08_Batnum/README.md b/08_Batnum/README.md
    index bb74a4ec7..e5b4db834 100644
    --- a/08_Batnum/README.md
    +++ b/08_Batnum/README.md
    @@ -18,12 +18,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Known Bugs
    -
    -- Though the instructions say "Enter a negative number for new pile size to stop playing," this does not actually work.
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    -
    diff --git a/08_Batnum/batnum.bas b/08_Batnum/batnum.bas
    index 40ec86161..0f9e80c5f 100644
    --- a/08_Batnum/batnum.bas
    +++ b/08_Batnum/batnum.bas
    @@ -3,7 +3,7 @@
     30 PRINT:PRINT:PRINT
     110 PRINT "THIS PROGRAM IS A 'BATTLE OF NUMBERS' GAME, WHERE THE"
     120 PRINT "COMPUTER IS YOUR OPPONENT."
    -130 PRINT
    +130 PRINT 
     140 PRINT "THE GAME STARTS WITH AN ASSUMED PILE OF OBJECTS. YOU"
     150 PRINT "AND YOUR OPPONENT ALTERNATELY REMOVE OBJECTS FROM THE PILE."
     160 PRINT "WINNING IS DEFINED IN ADVANCE AS TAKING THE LAST OBJECT OR"
    diff --git a/08_Batnum/csharp/BatnumGame.cs b/08_Batnum/csharp/BatnumGame.cs
    index b00eaf99f..1c7028405 100644
    --- a/08_Batnum/csharp/BatnumGame.cs
    +++ b/08_Batnum/csharp/BatnumGame.cs
    @@ -55,7 +55,7 @@ public BatnumGame(int pileSize, WinOptions winCriteria, int minTake, int maxtake
             /// A message to be displayed to the player
             public string TakeTurn()
             {
    -            //Edge condition - can occur when minTake is more > 1
    +            //Edge condition - can occur when minTake is more > 1 
                 if (pileSize < minTake)
                 {
                     pileSize = 0;
    diff --git a/08_Batnum/csharp/ConsoleUtilities.cs b/08_Batnum/csharp/ConsoleUtilities.cs
    index 41097090d..2dd5f09bf 100644
    --- a/08_Batnum/csharp/ConsoleUtilities.cs
    +++ b/08_Batnum/csharp/ConsoleUtilities.cs
    @@ -10,7 +10,7 @@ public static class ConsoleUtilities
         {
             /// 
             /// Ask the user a question and expects a comma separated pair of numbers representing a number range in response
    -        /// the range provided must have a maximum which is greater than the minimum
    +        /// the range provided must have a maximum which is greater than the minimum 
             /// 
             /// The question to ask
             /// The minimum value expected
    diff --git a/08_Batnum/csharp/Program.cs b/08_Batnum/csharp/Program.cs
    index 77a97ec26..08e6b3042 100644
    --- a/08_Batnum/csharp/Program.cs
    +++ b/08_Batnum/csharp/Program.cs
    @@ -27,3 +27,4 @@
         }
     
     }
    +
    diff --git a/08_Batnum/csharp/Properties/Resources.Designer.cs b/08_Batnum/csharp/Properties/Resources.Designer.cs
    index c72b9ed2e..2c2fac7f3 100644
    --- a/08_Batnum/csharp/Properties/Resources.Designer.cs
    +++ b/08_Batnum/csharp/Properties/Resources.Designer.cs
    @@ -10,8 +10,8 @@
     
     namespace Batnum.Properties {
         using System;
    -
    -
    +    
    +    
         /// 
         ///   A strongly-typed resource class, for looking up localized strings, etc.
         /// 
    @@ -23,15 +23,15 @@ namespace Batnum.Properties {
         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
         [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
         internal class Resources {
    -
    +        
             private static global::System.Resources.ResourceManager resourceMan;
    -
    +        
             private static global::System.Globalization.CultureInfo resourceCulture;
    -
    +        
             [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
             internal Resources() {
             }
    -
    +        
             /// 
             ///   Returns the cached ResourceManager instance used by this class.
             /// 
    @@ -45,7 +45,7 @@ internal Resources() {
                     return resourceMan;
                 }
             }
    -
    +        
             /// 
             ///   Overrides the current thread's CurrentUICulture property for all
             ///   resource lookups using this strongly typed resource class.
    @@ -59,7 +59,7 @@ internal Resources() {
                     resourceCulture = value;
                 }
             }
    -
    +        
             /// 
             ///   Looks up a localized string similar to COMPUTER TAKES {0} AND LEAVES {1}.
             /// 
    @@ -68,7 +68,7 @@ internal static string COMPTURN {
                     return ResourceManager.GetString("COMPTURN", resourceCulture);
                 }
             }
    -
    +        
             /// 
             ///   Looks up a localized string similar to COMPUTER TAKES {0} AND LOSES.
             /// 
    @@ -77,7 +77,7 @@ internal static string END_COMPLOSE {
                     return ResourceManager.GetString("END_COMPLOSE", resourceCulture);
                 }
             }
    -
    +        
             /// 
             ///   Looks up a localized string similar to COMPUTER TAKES {0} AND WINS.
             /// 
    @@ -86,7 +86,7 @@ internal static string END_COMPWIN {
                     return ResourceManager.GetString("END_COMPWIN", resourceCulture);
                 }
             }
    -
    +        
             /// 
             ///   Looks up a localized string similar to ITS A DRAW, THERE ARE ONLY {0} PIECES LEFT.
             /// 
    @@ -95,7 +95,7 @@ internal static string END_DRAW {
                     return ResourceManager.GetString("END_DRAW", resourceCulture);
                 }
             }
    -
    +        
             /// 
             ///   Looks up a localized string similar to TOUGH LUCK, YOU LOSE..
             /// 
    @@ -104,7 +104,7 @@ internal static string END_PLAYERLOSE {
                     return ResourceManager.GetString("END_PLAYERLOSE", resourceCulture);
                 }
             }
    -
    +        
             /// 
             ///   Looks up a localized string similar to CONGRATULATIONS, YOU WIN..
             /// 
    @@ -113,7 +113,7 @@ internal static string END_PLAYERWIN {
                     return ResourceManager.GetString("END_PLAYERWIN", resourceCulture);
                 }
             }
    -
    +        
             /// 
             ///   Looks up a localized string similar to BATNUM.
             /// 
    @@ -122,7 +122,7 @@ internal static string GAME_NAME {
                     return ResourceManager.GetString("GAME_NAME", resourceCulture);
                 }
             }
    -
    +        
             /// 
             ///   Looks up a localized string similar to ILLEGAL MOVE, RENETER IT.
             /// 
    @@ -131,7 +131,7 @@ internal static string INPUT_ILLEGAL {
                     return ResourceManager.GetString("INPUT_ILLEGAL", resourceCulture);
                 }
             }
    -
    +        
             /// 
             ///   Looks up a localized string similar to YOUR MOVE ?.
             /// 
    @@ -140,7 +140,7 @@ internal static string INPUT_TURN {
                     return ResourceManager.GetString("INPUT_TURN", resourceCulture);
                 }
             }
    -
    +        
             /// 
             ///   Looks up a localized string similar to I TOLD YOU NOT TO USE ZERO! COMPUTER WINS BY FORFEIT..
             /// 
    @@ -149,7 +149,7 @@ internal static string INPUT_ZERO {
                     return ResourceManager.GetString("INPUT_ZERO", resourceCulture);
                 }
             }
    -
    +        
             /// 
             ///   Looks up a localized string similar to CREATIVE COMPUTING MORRISTOWN, NEW JERSEY.
             /// 
    @@ -158,7 +158,7 @@ internal static string INTRO_HEADER {
                     return ResourceManager.GetString("INTRO_HEADER", resourceCulture);
                 }
             }
    -
    +        
             /// 
             ///   Looks up a localized string similar to THIS PROGRAM IS A 'BATTLE' OF NUMBERS GAME, WHERE THE COMPUTER IS YOUR OPPONENT.
             /// 
    @@ -167,7 +167,7 @@ internal static string INTRO_PART1 {
                     return ResourceManager.GetString("INTRO_PART1", resourceCulture);
                 }
             }
    -
    +        
             /// 
             ///   Looks up a localized string similar to THE GAME STARTS WITH AN ASSUMED PILE OF OBJECTS. YOU AND YOUR OPPONENT ALTERNATELY REMOVE OBJECTS FROM THE PILE. WINNNING IS DEFINED IN ADVANCE AS TAKING THE LAST OBJECT OR NOT. YOU CAN ALSO SPECIFY SOME OTHER BEGINING CONDITIONS. DON'T USER ZERO, HOWWEVER, IN PLAYING THE GAME..
             /// 
    @@ -176,7 +176,7 @@ internal static string INTRO_PART2 {
                     return ResourceManager.GetString("INTRO_PART2", resourceCulture);
                 }
             }
    -
    +        
             /// 
             ///   Looks up a localized string similar to ENTER MIN AND MAX ?.
             /// 
    @@ -185,7 +185,7 @@ internal static string START_QUESTION_DRAWMINMAX {
                     return ResourceManager.GetString("START_QUESTION_DRAWMINMAX", resourceCulture);
                 }
             }
    -
    +        
             /// 
             ///   Looks up a localized string similar to ENTER PILE SIZE ?.
             /// 
    @@ -194,7 +194,7 @@ internal static string START_QUESTION_PILESIZE {
                     return ResourceManager.GetString("START_QUESTION_PILESIZE", resourceCulture);
                 }
             }
    -
    +        
             /// 
             ///   Looks up a localized string similar to ENTER START OPTION - 1 COMPUTER FIRST, 2 YOU FIRST ?.
             /// 
    @@ -203,7 +203,7 @@ internal static string START_QUESTION_WHOSTARTS {
                     return ResourceManager.GetString("START_QUESTION_WHOSTARTS", resourceCulture);
                 }
             }
    -
    +        
             /// 
             ///   Looks up a localized string similar to ENTER WIN OPTION - 1 TO TAKE LAST, 2 TO AVOID LAST: ?.
             /// 
    diff --git a/08_Batnum/csharp/Properties/Resources.en.resx b/08_Batnum/csharp/Properties/Resources.en.resx
    index 1d3be88c1..beed709aa 100644
    --- a/08_Batnum/csharp/Properties/Resources.en.resx
    +++ b/08_Batnum/csharp/Properties/Resources.en.resx
    @@ -1,17 +1,17 @@
     
     
    -  
    @@ -168,4 +168,4 @@
       
         ENTER WIN OPTION - 1 TO TAKE LAST, 2 TO AVOID LAST: ?
       
    -
    +
    \ No newline at end of file
    diff --git a/08_Batnum/csharp/Properties/Resources.fr.resx b/08_Batnum/csharp/Properties/Resources.fr.resx
    index 5033ac929..410562e27 100644
    --- a/08_Batnum/csharp/Properties/Resources.fr.resx
    +++ b/08_Batnum/csharp/Properties/Resources.fr.resx
    @@ -1,17 +1,17 @@
     
     
    -  
    @@ -168,4 +168,4 @@
       
         ENTRE LA CONDITION DE VICTOIRE - 1 PRENDRE LA DERNIERE PIECE, 2 EVITER LA DERNIERE PIECE ?
       
    -
    +
    \ No newline at end of file
    diff --git a/08_Batnum/csharp/Properties/Resources.resx b/08_Batnum/csharp/Properties/Resources.resx
    index 1d3be88c1..beed709aa 100644
    --- a/08_Batnum/csharp/Properties/Resources.resx
    +++ b/08_Batnum/csharp/Properties/Resources.resx
    @@ -1,17 +1,17 @@
     
     
    -  
    @@ -168,4 +168,4 @@
       
         ENTER WIN OPTION - 1 TO TAKE LAST, 2 TO AVOID LAST: ?
       
    -
    +
    \ No newline at end of file
    diff --git a/08_Batnum/csharp/README.md b/08_Batnum/csharp/README.md
    index 9310c3483..cd054abd4 100644
    --- a/08_Batnum/csharp/README.md
    +++ b/08_Batnum/csharp/README.md
    @@ -8,3 +8,4 @@ Functional changes from Original
     - handle edge condition for end game where the minimum draw amount is greater than the number of items remaining in the pile
     - Takes into account the width of the console
     - Mulilingual Support (English/French currently)
    +
    diff --git a/08_Batnum/java/src/BatNum.java b/08_Batnum/java/src/BatNum.java
    index 5a9aa6407..4211d74dd 100644
    --- a/08_Batnum/java/src/BatNum.java
    +++ b/08_Batnum/java/src/BatNum.java
    @@ -289,4 +289,4 @@ private int getDelimitedValue(String text, int pos) {
             String[] tokens = text.split(",");
             return Integer.parseInt(tokens[pos]);
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/08_Batnum/javascript/batnum.html b/08_Batnum/javascript/batnum.html
    index 907ec1ae1..51d8dd113 100644
    --- a/08_Batnum/javascript/batnum.html
    +++ b/08_Batnum/javascript/batnum.html
    @@ -1,10 +1,9 @@
     
     
     BATNUM
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/08_Batnum/javascript/batnum.js b/08_Batnum/javascript/batnum.js
    index caf6056fe..c7d25b78b 100644
    --- a/08_Batnum/javascript/batnum.js
    +++ b/08_Batnum/javascript/batnum.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/08_Batnum/kotlin/README.md b/08_Batnum/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/08_Batnum/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/08_Batnum/lua/README.md b/08_Batnum/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/08_Batnum/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/08_Batnum/perl/README.md b/08_Batnum/perl/README.md
    index 8e05356a7..e69c8b819 100644
    --- a/08_Batnum/perl/README.md
    +++ b/08_Batnum/perl/README.md
    @@ -1,3 +1,3 @@
     Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
     
    -Conversion to [Perl](https://www.perl.org/) by [Austin White](https://github.com/austinwhite)
    +Conversion to [Perl](https://www.perl.org/)
    diff --git a/08_Batnum/perl/batnum.pl b/08_Batnum/perl/batnum.pl
    deleted file mode 100644
    index 27da757b3..000000000
    --- a/08_Batnum/perl/batnum.pl
    +++ /dev/null
    @@ -1,276 +0,0 @@
    -use strict;
    -use warnings;
    -
    -my %WIN_OPTIONS = (
    -    "UNDEFINED" => 0,
    -    "TAKE_LAST" => 1,
    -    "AVOID_LAST" => 2,
    -);
    -
    -my %START_OPTIONS = (
    -    "UNDEFINED" => 0,
    -    "COMPUTER_FIRST" => 1,
    -    "PLAYER_FIRST" => 2,
    -);
    -
    -
    -sub run {
    -    # input:        no input perameters
    -    #
    -    # output:       nothing returned
    -    #
    -    # description:  This is the primary game loop. Once a game is concluded
    -    #               another will begin right away until the exeecution
    -    #               is terminated.
    -
    -    my $pile_size = undef;
    -    my $min_select = undef;
    -    my $max_select = undef;
    -    my $win_option = undef;
    -    my $start_option = undef;
    -
    -    while (1) {
    -        write_intro();
    -
    -        ($pile_size, $min_select, $max_select, $win_option, $start_option)
    -            = &get_user_input();
    -
    -        if ($pile_size < 0) {
    -            last;
    -        }
    -
    -        play($pile_size, $min_select, $max_select, $win_option, $start_option);
    -
    -        printf "\n";
    -    }
    -}
    -
    -
    -sub write_intro {
    -    # input:        no input perameters
    -    #
    -    # output:       nothing returned
    -    #
    -    # description:  This subroutine prints the intro and rules.
    -
    -    printf "%33s", "BATNUM\n";
    -    printf "%15s", "CREATIVE COMPUTING  MORRISSTOWN, NEW JERSEY\n";
    -    printf "%s", "\n";
    -    printf "%s", "\n";
    -    printf "%s", "\n";
    -    printf "%s", "THIS PROGRAM IS A 'BATTLE OF NUMBERS' GAME, WHERE THE\n";
    -    printf "%s", "COMPUTER IS YOUR OPPONENT.\n";
    -    printf "%s", "\n";
    -    printf "%s", "THE GAME STARTS WITH AN ASSUMED PILE OF OBJECTS. YOU\n";
    -    printf "%s", "AND YOUR OPPONENT ALTERNATELY REMOVE OBJECTS FROM THE PILE.\n";
    -    printf "%s", "WINNING IS DEFINED IN ADVANCE AS TAKING THE LAST OBJECT OR\n";
    -    printf "%s", "NOT. YOU CAN ALSO SPECIFY SOME OTHER BEGINNING CONDITIONS.\n";
    -    printf "%s", "DON'T USE ZERO, HOWEVER, IN PLAYING THE GAME.\n";
    -    printf "%s", "ENTER A NEGATIVE NUMBER FOR NEW PILE SIZE TO STOP PLAYING.\n";
    -    printf "%s", "\n";
    -}
    -
    -
    -sub get_user_input {
    -    # input:        no input perameters
    -    #
    -    # output:       (int) pile_size
    -    #               (int) min_select
    -    #               (int) max_select
    -    #               (int) win_option
    -    #               (int) start_option
    -    #
    -    # description:  This subroutine gets the necessary perametes from the player.
    -    #
    -    #               pile_size (int > 0)
    -    #               min_select (int > 0) max_select (int > 0)
    -    #                   -> min/max, space delimated
    -    #               win_option (int 1|2)
    -    #               start_option (int 1|2)
    -
    -    my $pile_size = 0;
    -    my $min_select = 0;
    -    my $max_select = 0;
    -    my $win_option = $WIN_OPTIONS{ "UNDEFINED" };
    -    my $start_option = $START_OPTIONS{ "UNDEFINED" };
    -
    -    while ($pile_size < 1) {
    -        printf "%s", "ENTER PILE SIZE: ";
    -        $pile_size = ;
    -        if ($pile_size < 0) {
    -            return ($pile_size);
    -        }
    -    }
    -
    -    while ($min_select < 1 || $max_select < 1 || $min_select > $max_select) {
    -        printf "%s", "ENTER MIN AND MAX: ";
    -        my $raw_input = ;
    -        ($min_select, $max_select) = split(' ', $raw_input);
    -    }
    -
    -    while ($win_option eq $WIN_OPTIONS{ "UNDEFINED" }) {
    -        printf "%s", "ENTER WIN OPTION - 1 TO TAKE LAST, 2 TO AVOID LAST: ";
    -        $win_option = ;
    -    }
    -
    -    while ($start_option eq $START_OPTIONS{ "UNDEFINED" }) {
    -        printf "%s", "ENTER START OPTION - 1 COMPUTER FIRST, 2 YOU FIRST: ";
    -        $start_option = ;
    -    }
    -
    -    return ($pile_size, $min_select, $max_select, $win_option, $start_option);
    -}
    -
    -
    -sub play {
    -    # input:        (int) pile_size
    -    #               (int) min_select
    -    #               (int) max_select
    -    #               (int) win_option
    -    #               (int) start_option
    -    #
    -    # output:       nothing returned
    -    #
    -    # description:  This is where the game logic lives. The player and computer
    -    #               both take turns until the current game is over.
    -
    -    my $pile_size = shift;
    -    my $min_select = shift;
    -    my $max_select = shift;
    -    my $win_option = shift;
    -    my $start_option = shift;
    -
    -    my $game_over = 0;
    -    my $players_turn = $start_option eq $START_OPTIONS{ "PLAYER_FIRST" } ? 1 : 0;
    -
    -    while (!$game_over) {
    -        if ($players_turn) {
    -            ($game_over, $pile_size) = players_move(
    -                $pile_size, $min_select, $max_select, $win_option);
    -
    -            $players_turn = 0;
    -
    -            if ($game_over) {
    -                return;
    -            }
    -        } else {
    -            ($game_over, $pile_size) = computers_move(
    -                $pile_size, $min_select, $max_select, $win_option);
    -
    -            $players_turn = 1;
    -        }
    -    }
    -
    -    return;
    -}
    -
    -
    -sub players_move {
    -    # input:        (int) pile_size
    -    #               (int) min_select
    -    #               (int) max_select
    -    #               (int) win_option
    -    #
    -    # output:       (boolean) game is over
    -    #               (int) new pile_size
    -    #
    -    # description:  This subroutine handles the players move.
    -
    -    my $pile_size = shift;
    -    my $min_select = shift;
    -    my $max_select = shift;
    -    my $win_option = shift;
    -
    -    my $finished = 0;
    -
    -    while (!$finished) {
    -        my $remove_amount = undef;
    -
    -        printf "%s", "YOUR MOVE: ";
    -        $remove_amount = <>;
    -
    -        if ($remove_amount eq 0) {
    -            printf "%s", "I TOLD YOU NOT TO USE ZERO!  COMPUTER WINS BY FORFEIT.";
    -            return (1, $pile_size);
    -        } elsif ($remove_amount > $max_select || $remove_amount < $min_select) {
    -            printf "%s", "ILLEGAL MOVE, TRY AGAIN.\n";
    -            next;
    -        } else {
    -            $pile_size -= $remove_amount;
    -            $finished = 1;
    -        }
    -
    -        if ($pile_size <= 0) {
    -            if ($win_option eq $WIN_OPTIONS{ "AVOID_LAST" }) {
    -                printf "%s", "TOUGH LUCK, YOU LOSE.\n";
    -            } else {
    -                printf "%s", "CONGRATULATIONS, YOU WIN.\n";
    -            }
    -            return (1, $pile_size);
    -        }
    -    }
    -
    -    return (0, $pile_size);
    -}
    -
    -
    -sub computers_move {
    -    # input:        (int) pile_size
    -    #               (int) min_select
    -    #               (int) max_select
    -    #               (int) win_option
    -    #
    -    # output:       (boolean) game is over
    -    #               (int) new pile_size
    -    #
    -    # description:  This subroutine handles the computers move.
    -
    -    my $pile_size = shift;
    -    my $min_select = shift;
    -    my $max_select = shift;
    -    my $win_option = shift;
    -
    -    if ($win_option eq $WIN_OPTIONS{ "TAKE_LAST" } && $pile_size <= $max_select) {
    -        printf "COMPUTER TAKES %d AND WINS.\n", $pile_size;
    -        return (1, $pile_size);
    -    }
    -
    -    if ($win_option eq $WIN_OPTIONS{ "AVOID_LAST" } && $pile_size <= $min_select) {
    -        printf "COMPUTER TAKES %d AND LOSES.\n", $pile_size;
    -        return (1, $pile_size);
    -    }
    -
    -    my $remove_amount = get_computer_remove_amount($min_select, $max_select);
    -
    -    $pile_size -= $remove_amount;
    -
    -    if ($pile_size <= 0) {
    -        printf "COMPUTER TAKES %d AND WINS.\n", $remove_amount;
    -        return (1, $pile_size);
    -    } else {
    -        printf "COMPUTER TAKES %d AND LEAVES %d.\n", $remove_amount, $pile_size;
    -    }
    -
    -    return (0, $pile_size);
    -}
    -
    -
    -sub get_computer_remove_amount {
    -    # input:        (int) min_select
    -    #               (int) max_select
    -    #
    -    # output:       (int) random number (x) where,
    -    #               min_select <= x <= max_select
    -    #
    -    # description:  This subroutine generates the amount of items the computer
    -    #               will remove.
    -
    -    my $min_select = shift;
    -    my $max_select = shift;
    -
    -    return (int(rand($max_select - $min_select)) + $min_select);
    -}
    -
    -
    -# start the game
    -run();
    diff --git a/08_Batnum/python/batnum.py b/08_Batnum/python/batnum.py
    index bb41d8619..0f3473ed7 100644
    --- a/08_Batnum/python/batnum.py
    +++ b/08_Batnum/python/batnum.py
    @@ -1,49 +1,19 @@
    -from enum import IntEnum
    -from typing import Any, Tuple
    +from enum import Enum
     
    -
    -class WinOptions(IntEnum):
    +class WinOptions(Enum):
         Undefined = 0
         TakeLast = 1
         AvoidLast = 2
     
    -    @classmethod
    -    def _missing_(cls, value: Any) -> "WinOptions":
    -        try:
    -            int_value = int(value)
    -        except Exception:
    -            return WinOptions.Undefined
    -        if int_value == 1:
    -            return WinOptions.TakeLast
    -        elif int_value == 2:
    -            return WinOptions.AvoidLast
    -        else:
    -            return WinOptions.Undefined
    -
    -
    -class StartOptions(IntEnum):
    +class StartOptions(Enum):
         Undefined = 0
         ComputerFirst = 1
         PlayerFirst = 2
     
    -    @classmethod
    -    def _missing_(cls, value: Any) -> "StartOptions":
    -        try:
    -            int_value = int(value)
    -        except Exception:
    -            return StartOptions.Undefined
    -        if int_value == 1:
    -            return StartOptions.ComputerFirst
    -        elif int_value == 2:
    -            return StartOptions.PlayerFirst
    -        else:
    -            return StartOptions.Undefined
    -
    -
    -def print_intro() -> None:
    -    """Print out the introduction and rules for the game."""
    -    print("BATNUM".rjust(33, " "))
    -    print("CREATIVE COMPUTING  MORRISSTOWN, NEW JERSEY".rjust(15, " "))
    +def PrintIntro():
    +    '''Prints out the introduction and rules for the game.'''
    +    print("BATNUM".rjust(33, ' '))
    +    print("CREATIVE COMPUTING  MORRISSTOWN, NEW JERSEY".rjust(15, ' '))
         print()
         print()
         print()
    @@ -51,7 +21,7 @@ def print_intro() -> None:
         print("COMPUTER IS YOUR OPPONENT.")
         print()
         print("THE GAME STARTS WITH AN ASSUMED PILE OF OBJECTS. YOU")
    -    print("AND YOUR OPPONENT ALTERNATELY REMOVE OBJECTS FROM THE PILE.")
    +    print( "AND YOUR OPPONENT ALTERNATELY REMOVE OBJECTS FROM THE PILE.")
         print("WINNING IS DEFINED IN ADVANCE AS TAKING THE LAST OBJECT OR")
         print("NOT. YOU CAN ALSO SPECIFY SOME OTHER BEGINNING CONDITIONS.")
         print("DON'T USE ZERO, HOWEVER, IN PLAYING THE GAME.")
    @@ -59,174 +29,131 @@ def print_intro() -> None:
         print()
         return
     
    -
    -def get_params() -> Tuple[int, int, int, StartOptions, WinOptions]:
    -    """This requests the necessary parameters to play the game.
    +def GetParams():
    +    '''This requests the necessary parameters to play the game.
     
         Returns a set with the five game parameters:
    -        pile_size - the starting size of the object pile
    -        min_select - minimum selection that can be made on each turn
    -        max_select - maximum selection that can be made on each turn
    -        start_option - 1 if the computer is first
    +        pileSize - the starting size of the object pile
    +        minSelect - minimum selection that can be made on each turn
    +        maxSelect - maximum selection that can be made on each turn
    +        startOption - 1 if the computer is first
                           or 2 if the player is first
    -        win_option - 1 if the goal is to take the last object
    +        winOption - 1 if the goal is to take the last object 
                         or 2 if the goal is to not take the last object
    -    """
    -    pile_size = get_pile_size()
    -    if pile_size < 0:
    -        return (-1, 0, 0, StartOptions.Undefined, WinOptions.Undefined)
    -    win_option = get_win_option()
    -    min_select, max_select = get_min_max()
    -    start_option = get_start_option()
    -    return (pile_size, min_select, max_select, start_option, win_option)
    -
    -
    -def get_pile_size() -> int:
    -    # A negative number will stop the game.
    -    pile_size = 0
    -    while pile_size == 0:
    -        try:
    -            pile_size = int(input("ENTER PILE SIZE "))
    -        except ValueError:
    -            pile_size = 0
    -    return pile_size
    -
    -
    -def get_win_option() -> WinOptions:
    -    win_option: WinOptions = WinOptions.Undefined
    -    while win_option == WinOptions.Undefined:
    -        win_option = WinOptions(input("ENTER WIN OPTION - 1 TO TAKE LAST, 2 TO AVOID LAST: "))  # type: ignore
    -    return win_option
    -
    -
    -def get_min_max() -> Tuple[int, int]:
    -    min_select = 0
    -    max_select = 0
    -    while min_select < 1 or max_select < 1 or min_select > max_select:
    -        (min_select, max_select) = (
    -            int(x) for x in input("ENTER MIN AND MAX ").split(" ")
    -        )
    -    return min_select, max_select
    -
    -
    -def get_start_option() -> StartOptions:
    -    start_option: StartOptions = StartOptions.Undefined
    -    while start_option == StartOptions.Undefined:
    -        start_option = StartOptions(input("ENTER START OPTION - 1 COMPUTER FIRST, 2 YOU FIRST "))  # type: ignore
    -    return start_option
    -
    -
    -def player_move(
    -    pile_size: int, min_select: int, max_select: int, win_option: WinOptions
    -) -> Tuple[bool, int]:
    -    """This handles the player's turn - asking the player how many objects
    +    '''
    +    pileSize = 0
    +    winOption = WinOptions.Undefined
    +    minSelect = 0
    +    maxSelect = 0
    +    startOption = StartOptions.Undefined
    +
    +    while pileSize < 1:
    +        pileSize = int(input("ENTER PILE SIZE "))
    +    while winOption == WinOptions.Undefined:
    +        winOption = int(input("ENTER WIN OPTION - 1 TO TAKE LAST, 2 TO AVOID LAST: "))
    +    while minSelect < 1 or maxSelect < 1 or minSelect > maxSelect:
    +        (minSelect, maxSelect) = [int(x) for x in input("ENTER MIN AND MAX ").split(' ')]
    +    while startOption == StartOptions.Undefined:
    +        startOption = int(input("ENTER START OPTION - 1 COMPUTER FIRST, 2 YOU FIRST "))
    +    return (pileSize, minSelect, maxSelect, startOption, winOption)
    +
    +def PlayerMove(pileSize, minSelect, maxSelect, startOption, winOption):
    +    '''This handles the player's turn - asking the player how many objects
         to take and doing some basic validation around that input.  Then it
         checks for any win conditions.
    -
    -    Returns a boolean indicating whether the game is over and the new pile_size."""
    -    player_done = False
    -    while not player_done:
    -        player_move = int(input("YOUR MOVE "))
    -        if player_move == 0:
    -            print("I TOLD YOU NOT TO USE ZERO!  COMPUTER WINS BY FORFEIT.")
    -            return (True, pile_size)
    -        if player_move > max_select or player_move < min_select:
    +    
    +    Returns a boolean indicating whether the game is over and the new pileSize.'''
    +    playerDone = False
    +    while not playerDone:
    +        playerMove = int(input("YOUR MOVE "))
    +        if playerMove == 0:
    +            print ("I TOLD YOU NOT TO USE ZERO!  COMPUTER WINS BY FORFEIT.")
    +            return (True, pileSize)
    +        if playerMove > maxSelect or playerMove < minSelect:
                 print("ILLEGAL MOVE, REENTER IT")
                 continue
    -        pile_size = pile_size - player_move
    -        player_done = True
    -        if pile_size <= 0:
    -            if win_option == WinOptions.AvoidLast:
    +        pileSize = pileSize - playerMove
    +        playerDone = True
    +        if pileSize <= 0:
    +            if winOption == WinOptions.AvoidLast:
                     print("TOUGH LUCK, YOU LOSE.")
                 else:
                     print("CONGRATULATIONS, YOU WIN.")
    -            return (True, pile_size)
    -    return (False, pile_size)
    +            return (True, pileSize)
    +    return (False, pileSize)
     
    -
    -def computer_pick(
    -    pile_size: int, min_select: int, max_select: int, win_option: WinOptions
    -) -> int:
    -    """This handles the logic to determine how many objects the computer
    +def ComputerPick(pileSize, minSelect, maxSelect, startOption, winOption):
    +    '''This handles the logic to determine how many objects the computer
         will select on its turn.
    -    """
    -    q = pile_size - 1 if win_option == WinOptions.AvoidLast else pile_size
    -    c = min_select + max_select
    -    computer_pick = q - (c * int(q / c))
    -    computer_pick = max(computer_pick, min_select)
    -    return min(computer_pick, max_select)
    -
    -
    -def computer_move(
    -    pile_size: int, min_select: int, max_select: int, win_option: WinOptions
    -) -> Tuple[bool, int]:
    -    """This handles the computer's turn - first checking for the various
    +    '''
    +    q = pileSize - 1 if winOption == WinOptions.AvoidLast else pileSize
    +    c = minSelect + maxSelect
    +    computerPick = q - (c * int(q / c))
    +    if computerPick < minSelect:
    +        computerPick = minSelect
    +    if computerPick > maxSelect:
    +        computerPick = maxSelect
    +    return computerPick
    +
    +def ComputerMove(pileSize, minSelect, maxSelect, startOption, winOption):
    +    '''This handles the computer's turn - first checking for the various
         win/lose conditions and then calculating how many objects
         the computer will take.
    -
    -    Returns a boolean indicating whether the game is over and the new pile_size."""
    +    
    +    Returns a boolean indicating whether the game is over and the new pileSize.'''
         # First, check for win conditions on this move
         # In this case, we win by taking the last object and
         # the remaining pile is less than max select
         # so the computer can grab them all and win
    -    if win_option == WinOptions.TakeLast and pile_size <= max_select:
    -        print(f"COMPUTER TAKES {pile_size} AND WINS.")
    -        return (True, pile_size)
    +    if winOption == WinOptions.TakeLast and pileSize <= maxSelect:
    +        print (f"COMPUTER TAKES {pileSize} AND WINS.")
    +        return (True, pileSize)
         # In this case, we lose by taking the last object and
         # the remaining pile is less than minsize and the computer
         # has to take all of them.
    -    if win_option == WinOptions.AvoidLast and pile_size <= min_select:
    -        print(f"COMPUTER TAKES {min_select} AND LOSES.")
    -        return (True, pile_size)
    +    if winOption == WinOptions.AvoidLast and pileSize <= minSelect:
    +        print (f"COMPUTER TAKES {minSelect} AND LOSES.")
    +        return (True, pileSize)
     
         # Otherwise, we determine how many the computer selects
    -    curr_sel = computer_pick(pile_size, min_select, max_select, win_option)
    -    pile_size -= curr_sel
    -    print(f"COMPUTER TAKES {curr_sel} AND LEAVES {pile_size}")
    -    return (False, pile_size)
    -
    +    currSel = ComputerPick(pileSize, minSelect, maxSelect, startOption, winOption)
    +    pileSize = pileSize - currSel
    +    print(f"COMPUTER TAKES {currSel} AND LEAVES {pileSize}")
    +    return (False, pileSize)
     
    -def play_game(
    -    pile_size: int,
    -    min_select: int,
    -    max_select: int,
    -    start_option: StartOptions,
    -    win_option: WinOptions,
    -) -> None:
    -    """This is the main game loop - repeating each turn until one
    +def PlayGame(pileSize, minSelect, maxSelect, startOption, winOption):
    +    '''This is the main game loop - repeating each turn until one
         of the win/lose conditions is met.
    -    """
    -    game_over = False
    -    # players_turn is a boolean keeping track of whether it's the
    +    '''
    +    gameOver = False
    +    # playersTurn is a boolean keeping track of whether it's the
         # player's or computer's turn
    -    players_turn = start_option == StartOptions.PlayerFirst
    +    playersTurn = startOption == StartOptions.PlayerFirst
     
    -    while not game_over:
    -        if players_turn:
    -            (game_over, pile_size) = player_move(
    -                pile_size, min_select, max_select, win_option
    -            )
    -            players_turn = False
    -            if game_over:
    +    while not gameOver:
    +        if playersTurn:
    +            (gameOver, pileSize) = PlayerMove(pileSize, minSelect, maxSelect, startOption, winOption)
    +            playersTurn = False
    +            if gameOver:
                     return
    -        if not players_turn:
    -            (game_over, pile_size) = computer_move(
    -                pile_size, min_select, max_select, win_option
    -            )
    -            players_turn = True
    +        if not playersTurn:
    +            (gameOver, pileSize) = ComputerMove(pileSize, minSelect, maxSelect, startOption, winOption)
    +            playersTurn = True
    +            
    +    return
     
    +if __name__ == "__main__":
    +    
    +    pileSize = 0
    +    minSelect = 0
    +    maxSelect = 0
    +    # 1 = to take last, 2 = to avoid last
    +    winOption = 0
    +    # 1 = computer first, 2 = user first
    +    startOption = 0
     
    -def main() -> None:
         while True:
    -        print_intro()
    -        (pile_size, min_select, max_select, start_option, win_option) = get_params()
    -
    -        if pile_size < 0:
    -            return
    -
    +        PrintIntro()
    +        (pileSize, minSelect, maxSelect, startOption, winOption) = GetParams()
             # Just keep playing the game until the user kills it with ctrl-C
    -        play_game(pile_size, min_select, max_select, start_option, win_option)
    -
    -
    -if __name__ == "__main__":
    -    main()
    +        PlayGame(pileSize, minSelect, maxSelect, startOption, winOption)
    diff --git a/08_Batnum/ruby/batnum.rb b/08_Batnum/ruby/batnum.rb
    deleted file mode 100755
    index a390e339f..000000000
    --- a/08_Batnum/ruby/batnum.rb
    +++ /dev/null
    @@ -1,130 +0,0 @@
    -#!/usr/bin/env ruby
    -
    -def instructions
    -    puts <<~EOF
    -    THIS PROGRAM IS A 'BATTLE OF NUMBERS' GAME, WHERE THE
    -    COMPUTER IS YOUR OPPONENT.
    -
    -    THE GAME STARTS WITH AN ASSUMED PILE OF OBJECTS. YOU
    -    AND YOUR OPPONENT ALTERNATELY REMOVE OBJECTS FROM THE PILE.
    -    WINNING IS DEFINED IN ADVANCE AS TAKING THE LAST OBJECT OR
    -    NOT. YOU CAN ALSO SPECIFY SOME OTHER BEGINNING CONDITIONS.
    -    DON'T USE ZERO, HOWEVER, IN PLAYING THE GAME.
    -    ENTER A NEGATIVE NUMBER FOR NEW PILE SIZE TO STOP PLAYING.
    -    EOF
    -end
    -
    -def ask_for_pile_size
    -    loop do
    -        puts "ENTER PILE SIZE:"
    -        pile_size = gets.to_i
    -        break pile_size if pile_size != 0
    -    end
    -end
    -
    -GOAL_TAKE_LAST = 1
    -GOAL_AVOID_LAST = 2
    -def ask_for_goal
    -    loop do
    -        puts "ENTER WIN OPTION - #{GOAL_TAKE_LAST} TO TAKE LAST, #{GOAL_AVOID_LAST} TO AVOID LAST:"
    -        response = gets.to_i
    -        break response if [GOAL_TAKE_LAST, GOAL_AVOID_LAST].member? response
    -    end
    -end
    -
    -def ask_for_min_max_take
    -    loop do
    -        puts "ENTER MIN AND MAX, SEPARATED BY A COMMA:"
    -        response = gets.split(',').map {|piece| piece.to_i}
    -        next if response.length != 2
    -        min_take, max_take = response
    -        break min_take, max_take if 0 < min_take && min_take <= max_take
    -    end
    -end
    -
    -COMPUTER_MOVE = 1
    -PLAYER_MOVE = 2
    -def ask_who_makes_first_move
    -    loop do
    -        puts "ENTER START OPTION - #{COMPUTER_MOVE} COMPUTER FIRST, #{PLAYER_MOVE} YOU FIRST:"
    -        response = gets.to_i
    -        break response if [COMPUTER_MOVE, PLAYER_MOVE].member? response
    -    end
    -end
    -
    -def ask_for_player_take(min_take:, max_take:)
    -    loop do
    -        puts "YOUR MOVE:"
    -        response = gets.to_i
    -        break response if response == 0 || response == response.clamp(min_take, max_take)
    -        puts "ILLEGAL MOVE, REENTER IT."
    -    end
    -end
    -
    -def battle(pile:, goal:, min_take:, max_take:, first_move:)
    -    next_move = first_move
    -    loop do
    -        if next_move == COMPUTER_MOVE
    -            next_move = PLAYER_MOVE
    -            take = (
    -                if goal == GOAL_TAKE_LAST
    -                    pile % (min_take + max_take)
    -                else
    -                    (pile - 1) % (min_take + max_take)
    -                end
    -            ).clamp(min_take, max_take)
    -            pile = pile - take
    -            if pile > 0
    -                puts "COMPUTER TAKES #{take} AND LEAVES #{pile}"
    -            else
    -                if goal == GOAL_TAKE_LAST
    -                    puts "COMPUTER TAKES #{take} AND WINS."
    -                    break
    -                else
    -                    puts "COMPUTER TAKES #{take} AND LOSES."
    -                    break
    -                end
    -            end
    -        else
    -            next_move = COMPUTER_MOVE
    -            take = ask_for_player_take(min_take: min_take, max_take: max_take)
    -            if take == 0
    -                puts "I TOLD YOU NOT TO USE ZERO! COMPUTER WINS BY FORFEIT."
    -                break
    -            end
    -            pile = pile - take
    -            if pile > 0
    -                puts "PLAYER TAKES #{take} AND LEAVES #{pile}"
    -            else
    -                if goal == GOAL_TAKE_LAST
    -                    puts "CONGRATULATIONS, YOU WIN."
    -                    break
    -                else
    -                    puts "TOUGH LUCK, YOU LOSE."
    -                    break
    -                end
    -            end
    -        end
    -    end
    -end
    -
    -
    -def main
    -    instructions
    -    loop do
    -        pile = ask_for_pile_size
    -        break if pile < 0
    -        goal = ask_for_goal
    -        min_take, max_take = ask_for_min_max_take
    -        first_move = ask_who_makes_first_move
    -        battle(
    -            pile: pile,
    -            goal: goal,
    -            min_take: min_take,
    -            max_take: max_take,
    -            first_move: first_move,
    -        )
    -    end
    -end
    -
    -main
    diff --git a/08_Batnum/rust/Cargo.lock b/08_Batnum/rust/Cargo.lock
    deleted file mode 100644
    index b21cc6a2d..000000000
    --- a/08_Batnum/rust/Cargo.lock
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    diff --git a/08_Batnum/rust/Cargo.toml b/08_Batnum/rust/Cargo.toml
    deleted file mode 100644
    index 1ec696335..000000000
    --- a/08_Batnum/rust/Cargo.toml
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -[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]
    diff --git a/08_Batnum/rust/src/main.rs b/08_Batnum/rust/src/main.rs
    deleted file mode 100644
    index 761e1939b..000000000
    --- a/08_Batnum/rust/src/main.rs
    +++ /dev/null
    @@ -1,239 +0,0 @@
    -use std::io::{self, Write};
    -
    -/// Print out the introduction and rules for the game.
    -fn print_intro() {
    -    println!();
    -    println!();
    -    println!("{:>33}", "BATNUM");
    -    println!("{:>15}", "CREATIVE COMPUTING  MORRISSTOWN, NEW JERSEY");
    -    println!();
    -    println!();
    -    println!();
    -    println!("THIS PROGRAM IS A 'BATTLE OF NUMBERS' GAME, WHERE THE");
    -    println!("COMPUTER IS YOUR OPPONENT.");
    -    println!();
    -    println!("THE GAME STARTS WITH AN ASSUMED PILE OF OBJECTS. YOU");
    -    println!("AND YOUR OPPONENT ALTERNATELY REMOVE OBJECTS FROM THE PILE.");
    -    println!("WINNING IS DEFINED IN ADVANCE AS TAKING THE LAST OBJECT OR");
    -    println!("NOT. YOU CAN ALSO SPECIFY SOME OTHER BEGINNING CONDITIONS.");
    -    println!("DON'T USE ZERO, HOWEVER, IN PLAYING THE GAME.");
    -    println!("ENTER A NEGATIVE NUMBER FOR NEW PILE SIZE TO STOP PLAYING.");
    -    println!();
    -}
    -
    -/// This requests the necessary parameters to play the game.
    -/// five game parameters:
    -/// * pile_size - the starting size of the object pile
    -/// * min_select - minimum selection that can be made on each turn
    -/// * max_select - maximum selection that can be made on each turn
    -/// * start_option - computer first or player first
    -/// * win_option - goal is to take the last object
    -///                or the goal is to not take the last object
    -struct Params {
    -    pub pile_size: usize,
    -    pub min_select: usize,
    -    pub max_select: usize,
    -    pub start_option: StartOption,
    -    pub win_option: WinOption,
    -}
    -
    -#[derive(PartialEq, Eq)]
    -enum StartOption {
    -    ComputerFirst,
    -    PlayerFirst,
    -}
    -
    -#[derive(PartialEq, Eq)]
    -enum WinOption {
    -    TakeLast,
    -    AvoidLast,
    -}
    -
    -impl Params {
    -    pub fn get_params() -> Self {
    -        let pile_size = Self::get_pile_size();
    -        let (min_select, max_select) = Self::get_min_max();
    -        let start_option = Self::get_start_option();
    -        let win_option = Self::get_win_option();
    -
    -        Self {
    -            pile_size,
    -            min_select,
    -            max_select,
    -            start_option,
    -            win_option,
    -        }
    -    }
    -
    -    fn get_pile_size() -> usize {
    -        print!("ENTER PILE SIZE ");
    -        let _ = io::stdout().flush();
    -        read_input_integer()
    -    }
    -
    -    fn get_win_option() -> WinOption {
    -        print!("ENTER WIN OPTION: 1 TO TAKE LAST, 2 TO AVOID LAST: ");
    -        let _ = io::stdout().flush();
    -
    -        loop {
    -            match read_input_integer() {
    -                1 => {
    -                    return WinOption::TakeLast;
    -                }
    -                2 => {
    -                    return WinOption::AvoidLast;
    -                }
    -                _ => {
    -                    print!("Please enter 1 or 2 ");
    -                    let _ = io::stdout().flush();
    -                    continue;
    -                }
    -            }
    -        }
    -    }
    -
    -    fn get_start_option() -> StartOption {
    -        print!("ENTER START OPTION: 1 COMPUTER FIRST, 2 YOU FIRST ");
    -        let _ = io::stdout().flush();
    -
    -        loop {
    -            match read_input_integer() {
    -                1 => {
    -                    return StartOption::ComputerFirst;
    -                }
    -                2 => {
    -                    return StartOption::PlayerFirst;
    -                }
    -                _ => {
    -                    print!("Please enter 1 or 2 ");
    -                    let _ = io::stdout().flush();
    -                    continue;
    -                }
    -            }
    -        }
    -    }
    -
    -    fn get_min_max() -> (usize, usize) {
    -        print!("ENTER MIN ");
    -        let _ = io::stdout().flush();
    -        let min = read_input_integer();
    -
    -        print!("ENTER MAX ");
    -        let _ = io::stdout().flush();
    -        let max = read_input_integer();
    -
    -        (min, max)
    -    }
    -}
    -
    -fn read_input_integer() -> usize {
    -    loop {
    -        let mut input = String::new();
    -        io::stdin()
    -            .read_line(&mut input)
    -            .expect("Failed to read line");
    -        match input.trim().parse::() {
    -            Ok(num) => {
    -                if num == 0 {
    -                    print!("Must be greater than zero ");
    -                    let _ = io::stdout().flush();
    -                    continue;
    -                }
    -                return num;
    -            }
    -            Err(_err) => {
    -                print!("Please enter a number greater than zero ");
    -                let _ = io::stdout().flush();
    -                continue;
    -            }
    -        }
    -    }
    -}
    -
    -fn player_move(pile_size: &mut usize, params: &Params) -> bool {
    -    loop {
    -        print!("YOUR MOVE ");
    -        let _ = io::stdout().flush();
    -
    -        let player_move = read_input_integer();
    -        if player_move == 0 {
    -            println!("I TOLD YOU NOT TO USE ZERO!  COMPUTER WINS BY FORFEIT.");
    -            return true;
    -        }
    -        if player_move > params.max_select || player_move < params.min_select {
    -            println!("ILLEGAL MOVE, REENTER IT");
    -            continue;
    -        }
    -        *pile_size -= player_move;
    -        if *pile_size == 0 {
    -            if params.win_option == WinOption::AvoidLast {
    -                println!("TOUGH LUCK, YOU LOSE.");
    -            } else {
    -                println!("CONGRATULATIONS, YOU WIN.")
    -            }
    -            return true;
    -        }
    -        return false;
    -    }
    -}
    -
    -fn computer_pick(pile_size: usize, params: &Params) -> usize {
    -    let q = if params.win_option == WinOption::AvoidLast {
    -        pile_size - 1
    -    } else {
    -        pile_size
    -    };
    -    let c = params.min_select + params.max_select;
    -    let computer_pick = q - (c * (q / c));
    -    let computer_pick = if computer_pick < params.min_select {
    -        params.min_select
    -    } else {
    -        computer_pick
    -    };
    -    if computer_pick > params.max_select {
    -        params.max_select
    -    } else {
    -        computer_pick
    -    }
    -}
    -
    -fn computer_move(pile_size: &mut usize, params: &Params) -> bool {
    -    if params.win_option == WinOption::TakeLast && *pile_size <= params.max_select {
    -        println!("COMPUTER TAKES {pile_size} AND WINS.");
    -        return true;
    -    }
    -    if params.win_option == WinOption::AvoidLast && *pile_size >= params.min_select {
    -        println!("COMPUTER TAKES {} AND LOSES.", params.min_select);
    -        return true;
    -    }
    -
    -    let curr_sel = computer_pick(*pile_size, params);
    -    *pile_size -= curr_sel;
    -    println!("COMPUTER TAKES {curr_sel} AND LEAVES {pile_size}");
    -    false
    -}
    -
    -fn play_game(params: &Params) {
    -    let mut pile_size = params.pile_size;
    -
    -    if params.start_option == StartOption::ComputerFirst && computer_move(&mut pile_size, params) {
    -        return;
    -    }
    -
    -    loop {
    -        if player_move(&mut pile_size, params) {
    -            return;
    -        }
    -        if computer_move(&mut pile_size, params) {
    -            return;
    -        }
    -    }
    -}
    -
    -fn main() -> ! {
    -    loop {
    -        print_intro();
    -        let params = Params::get_params();
    -        play_game(¶ms);
    -    }
    -}
    diff --git a/08_Batnum/vbnet/batnum.sln b/08_Batnum/vbnet/batnum.sln
    index ca05e41b2..b3f63f596 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 17
    -VisualStudioVersion = 17.0.32014.148
    +# Visual Studio Version 16
    +VisualStudioVersion = 16.0.31321.278
     MinimumVisualStudioVersion = 10.0.40219.1
    -Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "Batnum", "Batnum.vbproj", "{D577E429-F84D-4E84-86E7-E6526CFD5FD9}"
    +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "batnum", "batnum.vbproj", "{D577E429-F84D-4E84-86E7-E6526CFD5FD9}"
     EndProject
     Global
     	GlobalSection(SolutionConfigurationPlatforms) = preSolution
    diff --git a/08_Batnum/vbnet/batnum.vbproj b/08_Batnum/vbnet/batnum.vbproj
    index aad6e2181..3c21499cf 100644
    --- a/08_Batnum/vbnet/batnum.vbproj
    +++ b/08_Batnum/vbnet/batnum.vbproj
    @@ -2,9 +2,8 @@
     
       
         Exe
    -    Batnum
    +    batnum
         netcoreapp3.1
    -    16.9
       
     
     
    diff --git a/09_Battle/README.md b/09_Battle/README.md
    index 29d2622e7..815cacd23 100644
    --- a/09_Battle/README.md
    +++ b/09_Battle/README.md
    @@ -13,7 +13,7 @@ The first thing you should learn is how to locate and designate positions on the
     
     The second thing you should learn about is the splash/hit ratio. “What is a ratio?” A good reply is “It’s a fraction or quotient.” Specifically, the spash/hit ratio is the number of splashes divided by the number of hits. If you had 9 splashes and 15 hits, the ratio would be 9/15 or 3/5, both of which are correct. The computer would give this splash/hit ratio as .6.
     
    -The main objective and primary education benefit of BATTLE comes from attempting to decode the bad guys’ fleet disposition code. To do this, you must make a comparison between the coded matrix and the actual matrix which you construct as you play the game.
    +The main objective and primary education benefit of BATTLE comes from attempting to decode the bas guys’ fleet disposition code. To do this, you must make a comparison between the coded matrix and the actual matrix which you construct as you play the game.
     
     The original author of both the program and these descriptive notes is Ray Westergard of Lawrence Hall of Science, Berkeley, California.
     
    @@ -25,7 +25,3 @@ As published in Basic Computer Games (1978)
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -- The original game has no way to re-view the fleet disposition code once it scrolls out of view.  Ports should consider allowing the user to enter "?" at the "??" prompt, to reprint the disposition code.  (This is added by the MiniScript port under Alternate Languages, for example.)
    \ No newline at end of file
    diff --git a/09_Battle/csharp/Game.cs b/09_Battle/csharp/Game.cs
    index 1ee9ceb5d..c74a48cac 100644
    --- a/09_Battle/csharp/Game.cs
    +++ b/09_Battle/csharp/Game.cs
    @@ -305,7 +305,7 @@ public void UserInteraction()
     
                     var shipType = (shipNum - 1) / 2 + 1;
                     lost[shipType] = lost[shipType] + 1;
    -
    +    
                     Print("AND YOU SUNK IT.  HURRAH FOR THE GOOD GUYS.");
                     Print("SO FAR, THE BAD GUYS HAVE LOST");
                     Write($"{lost[1]} DESTROYER(S), {lost[2]} CRUISER(S), AND ");
    diff --git a/09_Battle/java/Battle.java b/09_Battle/java/Battle.java
    index 3b58ada62..c0b279064 100644
    --- a/09_Battle/java/Battle.java
    +++ b/09_Battle/java/Battle.java
    @@ -155,7 +155,7 @@ public void play() {
     
                                     System.out.println("\n****************************\n");
                                 }
    -                        }
    +                        }       
                         }
                     }
                 }
    diff --git a/09_Battle/java/Input.java b/09_Battle/java/Input.java
    index 2b905601d..ee87465f9 100644
    --- a/09_Battle/java/Input.java
    +++ b/09_Battle/java/Input.java
    @@ -38,10 +38,10 @@ public boolean readCoordinates() throws IOException {
                     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
    +            // 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());
    diff --git a/09_Battle/java/Sea.java b/09_Battle/java/Sea.java
    index fd6820aba..f0c31facd 100644
    --- a/09_Battle/java/Sea.java
    +++ b/09_Battle/java/Sea.java
    @@ -1,4 +1,4 @@
    -// Track the content of the sea
    +// 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
    @@ -20,11 +20,11 @@ public Sea(int make_size) {
         public String encodedDump() {
             StringBuilder out = new StringBuilder();
             for (int x = 0; x < size; ++x) {
    -            for (int y = 0; y < size; ++y)
    +            for (int y = 0; y < size; ++y) 
                     out.append(Integer.toString(get(x, y)));
                 out.append('\n');
             }
    -        return out.toString();
    +        return out.toString();   
         }
     
         /* return true if x,y is in the sea and empty
    diff --git a/09_Battle/java/Ship.java b/09_Battle/java/Ship.java
    index 86712db8d..23605e5c5 100644
    --- a/09_Battle/java/Ship.java
    +++ b/09_Battle/java/Ship.java
    @@ -17,7 +17,7 @@ class Ship {
         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;               // starting position coordinates
         private int startY;
         private int orientX;              // x and y deltas from each tile occupied to the next
    diff --git a/09_Battle/javascript/battle.html b/09_Battle/javascript/battle.html
    index 19ba74032..83cccf103 100644
    --- a/09_Battle/javascript/battle.html
    +++ b/09_Battle/javascript/battle.html
    @@ -1,10 +1,9 @@
     
     
     BATTLE
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/09_Battle/javascript/battle.js b/09_Battle/javascript/battle.js
    index d3f307f65..3adcfaba4 100644
    --- a/09_Battle/javascript/battle.js
    +++ b/09_Battle/javascript/battle.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    @@ -258,11 +258,6 @@ async function main()
             print("START GAME\n");
             while (1) {
                 str = await input();
    -            // Check if user types anything other than a number
    -            if (isNaN(str)) {
    -                print("INVALID INPUT. TRY ENTERING A NUMBER INSTEAD.\n");
    -                continue;
    -            }
                 x = parseInt(str);
                 y = parseInt(str.substr(str.indexOf(",") + 1));
                 if (x < 1 || x > 6 || y < 1 || y > 6) {
    diff --git a/09_Battle/kotlin/README.md b/09_Battle/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/09_Battle/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/09_Battle/lua/README.md b/09_Battle/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/09_Battle/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/09_Battle/python/battle.py b/09_Battle/python/battle.py
    deleted file mode 100755
    index 2418b35d5..000000000
    --- a/09_Battle/python/battle.py
    +++ /dev/null
    @@ -1,180 +0,0 @@
    -#!/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) or any(
    -            value_at(point, sea) 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: 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_str_list = guess.split(",")
    -
    -            if len(point_str_list) != 2:
    -                raise ValueError()
    -
    -            point = (int(point_str_list[0]), int(point_str_list[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) -> None:
    -    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:
    -    sea = tuple([0 for _ in range(SEA_WIDTH)] for _ in range(SEA_WIDTH))
    -    setup_ships(sea)
    -    print(
    -        """
    -                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(
    -        """
    -
    -DE-CODE IT AND USE IT IF YOU CAN
    -BUT KEEP THE DE-CODING METHOD A SECRET.
    -
    -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, 7)):
    -            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("\n****************************")
    -        break
    -
    -
    -if __name__ == "__main__":
    -    main()
    diff --git a/09_Battle/rust/Cargo.lock b/09_Battle/rust/Cargo.lock
    deleted file mode 100644
    index 10a595996..000000000
    --- a/09_Battle/rust/Cargo.lock
    +++ /dev/null
    @@ -1,75 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.11"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.151"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/09_Battle/rust/Cargo.toml b/09_Battle/rust/Cargo.toml
    deleted file mode 100644
    index 3b1d02f52..000000000
    --- a/09_Battle/rust/Cargo.toml
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -[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/09_Battle/rust/src/main.rs b/09_Battle/rust/src/main.rs
    deleted file mode 100644
    index f9e8d36ec..000000000
    --- a/09_Battle/rust/src/main.rs
    +++ /dev/null
    @@ -1,273 +0,0 @@
    -use rand::Rng;
    -use std::{
    -    cmp::Ordering,
    -    fmt,
    -    io::{self, Write},
    -};
    -
    -#[derive(Clone, Copy)]
    -#[repr(C)]
    -enum ShipLength {
    -    Destroyer = 2,
    -    Cruiser = 3,
    -    AircraftCarrier = 4,
    -}
    -
    -#[derive(Clone, Copy, PartialEq)]
    -struct Point(i8, i8);
    -
    -impl core::ops::Add for Point {
    -    type Output = Self;
    -
    -    fn add(self, rhs: Self) -> Self::Output {
    -        Self(self.0 + rhs.0, self.1 + rhs.1)
    -    }
    -}
    -
    -impl Point {
    -    pub fn is_outside(&self, width: usize) -> bool {
    -        let w = width as i8;
    -        (!(0..w).contains(&self.0)) || (!(0..w).contains(&self.1))
    -    }
    -
    -    pub fn userinput2coordinate(self) -> Self {
    -        Self(self.0 - 1, See::WIDTH as i8 - self.1)
    -    }
    -}
    -
    -struct Ship(Vec);
    -
    -impl Ship {
    -    pub fn new(length: ShipLength) -> Self {
    -        'try_again: loop {
    -            let start = Point(
    -                rand::thread_rng().gen_range(0..See::WIDTH) as i8,
    -                rand::thread_rng().gen_range(0..See::WIDTH) as i8,
    -            );
    -            let vector = Self::random_vector();
    -
    -            let mut ship = vec![start];
    -            for _ in 1..length as usize {
    -                let last = ship.last().unwrap();
    -                let new_part = *last + vector;
    -                if new_part.is_outside(See::WIDTH) {
    -                    continue 'try_again;
    -                }
    -                ship.push(new_part);
    -            }
    -
    -            return Self(ship);
    -        }
    -    }
    -
    -    fn random_vector() -> Point {
    -        loop {
    -            let vector = Point(
    -                rand::thread_rng().gen_range(-1..2),
    -                rand::thread_rng().gen_range(-1..2),
    -            );
    -            if vector != Point(0, 0) {
    -                return vector;
    -            }
    -        }
    -    }
    -
    -    pub fn collide(&self, see: &[Vec]) -> bool {
    -        self.0.iter().any(|p| see[p.0 as usize][p.1 as usize] != 0)
    -    }
    -
    -    pub fn place(self, see: &mut [Vec], code: i8) {
    -        for p in self.0.iter() {
    -            see[p.0 as usize][p.1 as usize] = code;
    -        }
    -    }
    -}
    -
    -enum Report {
    -    Already(i8),
    -    Splash,
    -    Hit(i8),
    -}
    -
    -struct See {
    -    data: Vec>,
    -}
    -
    -impl See {
    -    pub const WIDTH: usize = 6;
    -
    -    fn place_ship(data: &mut [Vec], length: ShipLength, code: i8) {
    -        let ship = loop {
    -            let ship = Ship::new(length);
    -            if ship.collide(data) {
    -                continue;
    -            }
    -            break ship;
    -        };
    -        ship.place(data, code);
    -    }
    -
    -    pub fn new() -> Self {
    -        let mut data = vec![vec![0; Self::WIDTH]; Self::WIDTH];
    -
    -        Self::place_ship(&mut data, ShipLength::Destroyer, 1);
    -        Self::place_ship(&mut data, ShipLength::Destroyer, 2);
    -        Self::place_ship(&mut data, ShipLength::Cruiser, 3);
    -        Self::place_ship(&mut data, ShipLength::Cruiser, 4);
    -        Self::place_ship(&mut data, ShipLength::AircraftCarrier, 5);
    -        Self::place_ship(&mut data, ShipLength::AircraftCarrier, 6);
    -
    -        Self { data }
    -    }
    -
    -    pub fn report(&mut self, point: Point) -> Report {
    -        let (x, y) = (point.0 as usize, point.1 as usize);
    -        let value = self.data[x][y];
    -        match value.cmp(&0) {
    -            Ordering::Less => Report::Already(-value),
    -            Ordering::Equal => Report::Splash,
    -            Ordering::Greater => {
    -                self.data[x][y] = -value;
    -                Report::Hit(value)
    -            }
    -        }
    -    }
    -
    -    pub fn has_ship(&self, code: i8) -> bool {
    -        self.data.iter().any(|v| v.contains(&code))
    -    }
    -
    -    pub fn has_any_ship(&self) -> bool {
    -        (1..=6).any(|c| self.has_ship(c))
    -    }
    -
    -    pub fn count_sunk(&self, ship: ShipLength) -> i32 {
    -        let codes = match ship {
    -            ShipLength::Destroyer => (1, 2),
    -            ShipLength::Cruiser => (3, 4),
    -            ShipLength::AircraftCarrier => (5, 6),
    -        };
    -
    -        let ret = if self.has_ship(codes.0) { 0 } else { 1 };
    -        ret + if self.has_ship(codes.1) { 0 } else { 1 }
    -    }
    -}
    -
    -impl fmt::Display for See {
    -    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    -        for row in &self.data {
    -            write!(f, "\r\n")?;
    -            for cell in row {
    -                write!(f, "{:2} ", cell)?;
    -            }
    -        }
    -        write!(f, "\r\n")
    -    }
    -}
    -
    -fn input_point() -> Result {
    -    let mut input = String::new();
    -    io::stdin()
    -        .read_line(&mut input)
    -        .expect("Failed to read line");
    -    let point_str: Vec<&str> = input.trim().split(',').collect();
    -
    -    if point_str.len() != 2 {
    -        return Err(());
    -    }
    -
    -    let x = point_str[0].parse::().map_err(|_| ())?;
    -    let y = point_str[1].parse::().map_err(|_| ())?;
    -
    -    Ok(Point(x, y))
    -}
    -
    -fn get_next_target() -> Point {
    -    loop {
    -        print!("? ");
    -        let _ = io::stdout().flush();
    -
    -        if let Ok(p) = input_point() {
    -            let p = p.userinput2coordinate();
    -            if !p.is_outside(See::WIDTH) {
    -                return p;
    -            }
    -        }
    -
    -        println!(
    -            "INVALID. SPECIFY TWO NUMBERS FROM 1 TO {}, SEPARATED BY A COMMA.",
    -            See::WIDTH
    -        );
    -    }
    -}
    -
    -fn main() {
    -    let mut see = See::new();
    -    println!(
    -        "
    -                BATTLE
    -CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY
    -
    -THE FOLLOWING CODE OF THE BAD GUYS' FLEET DISPOSITION
    -HAS BEEN CAPTURED BUT NOT DECODED:
    -        "
    -    );
    -
    -    println!("{see}");
    -
    -    println!(
    -        "
    -
    -DE-CODE IT AND USE IT IF YOU CAN
    -BUT KEEP THE DE-CODING METHOD A SECRET.
    -
    -START GAME
    -        "
    -    );
    -
    -    let mut splashes = 0;
    -    let mut hits = 0;
    -
    -    loop {
    -        let target = get_next_target();
    -
    -        let r = see.report(target);
    -        if let Report::Hit(c) = r {
    -            println!("A DIRECT HIT ON SHIP NUMBER {c}");
    -            hits += 1;
    -
    -            if !see.has_ship(c) {
    -                println!("AND YOU SUNK IT. HURRAH FOR THE GOOD GUYS.");
    -                println!("SO FAR, THE BAD GUYS HAVE LOST");
    -                println!("{} DESTROYER(S),", see.count_sunk(ShipLength::Destroyer));
    -                println!("{} CRUISER(S),", see.count_sunk(ShipLength::Cruiser));
    -                println!(
    -                    "AND {} AIRCRAFT CARRIER(S),",
    -                    see.count_sunk(ShipLength::AircraftCarrier)
    -                );
    -            }
    -        } else {
    -            if let Report::Already(c) = r {
    -                println!("YOU ALREADY PUT A HOLE IN SHIP NUMBER {c} AT THAT POINT.");
    -            }
    -            println!("SPLASH! TRY AGAIN.");
    -            splashes += 1;
    -            continue;
    -        }
    -
    -        if see.has_any_ship() {
    -            println!("YOUR CURRENT SPLASH/HIT RATIO IS {splashes}/{hits}");
    -            continue;
    -        }
    -
    -        println!("YOU HAVE TOTALLY WIPED OUT THE BAD GUYS' FLEET ");
    -        println!("WITH A FINAL SPLASH/HIT RATIO OF {splashes}/{hits}");
    -
    -        if splashes == 0 {
    -            println!("CONGRATULATIONS -- A DIRECT HIT EVERY TIME.");
    -        }
    -
    -        println!("\n****************************");
    -        break;
    -    }
    -}
    diff --git a/09_Battle/vbnet/Battle.sln b/09_Battle/vbnet/Battle.sln
    deleted file mode 100644
    index bf92bf39a..000000000
    --- a/09_Battle/vbnet/Battle.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index dc5c59083..000000000
    --- a/09_Battle/vbnet/Battle.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Battle
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/10_Blackjack/README.md b/10_Blackjack/README.md
    index 66cfee65c..43cf263ce 100644
    --- a/10_Blackjack/README.md
    +++ b/10_Blackjack/README.md
    @@ -14,17 +14,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -
    -#### Porting Notes
    -
    -The program makes extensive use of the assumption that a boolean expression evaluates to **-1** for true.  This was the case in some classic BASIC environments but not others; and it is not the case in [JS Basic](https://troypress.com/wp-content/uploads/user/js-basic/index.html), leading to nonsensical results.  In an environment that uses **1** instead of **-1** for truth, you would need to negate the boolean expression in the following lines:
    -	- 10
    -	- 570
    -	- 590
    -	- 2220
    -	- 2850
    -	- 3100
    -	- 3400
    -	- 3410
    -	- 3420
    diff --git a/10_Blackjack/blackjack.bas b/10_Blackjack/blackjack.bas
    index 121c6502c..5274d31fa 100644
    --- a/10_Blackjack/blackjack.bas
    +++ b/10_Blackjack/blackjack.bas
    @@ -289,7 +289,7 @@
     3125 PRINT "---TOTAL IS";AA
     3130 PRINT
     3140 REM--TALLY THE RESULT
    -3150 REM
    +3150 REM 
     3160 Z$="LOSES PUSHES WINS "
     3165 PRINT
     3170 FOR I=1 TO N
    diff --git a/10_Blackjack/csharp/Blackjack.sln b/10_Blackjack/csharp/Blackjack.sln
    deleted file mode 100644
    index 1a01fb8b3..000000000
    --- a/10_Blackjack/csharp/Blackjack.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/java/src/Blackjack.java b/10_Blackjack/java/src/Blackjack.java
    deleted file mode 100644
    index 2809431e9..000000000
    --- a/10_Blackjack/java/src/Blackjack.java
    +++ /dev/null
    @@ -1,57 +0,0 @@
    -import java.io.InputStreamReader;
    -import java.io.OutputStreamWriter;
    -import java.io.Reader;
    -import java.io.Writer;
    -import java.util.Collections;
    -
    -/**
    - * Plays a game of blackjack on the terminal. Looking at the code, the reader
    - * might conclude that this implementation is "over engineered." We use many
    - * techniques and patterns developed for much larger code bases to create more
    - * maintainable code, which may not be as relevant for a simple game of
    - * Blackjack. To wit, the rules and requirements are not likely to ever change
    - * so there is not so much value making the code flexible.
    - * 
    - * Nevertheless, this is meant to be an example that the reader can learn good
    - * Java coding techniques from. Furthermore, many of the "over-engineering"
    - * tactics are as much about testability as they are about maintainability.
    - * Imagine trying to manually test infrequent scenarios like Blackjack,
    - * insurance, or splitting without any ability to automate a specific scenario
    - * and the value of unit testing becomes immediately apparent.
    - * 
    - * Another "unnecessary" aspect of this codebase is good Javadoc. Again, this is
    - * meant to be educational, but another often overlooked benefit is that most
    - * IDEs will display Javadoc in "autocomplete" suggestions. This is remarkably
    - * helpful when using a class as a quick reminder of what you coded earlier.
    - * This is true even if no one ever publishes or reads the HTML output of the
    - * javadoc.
    - * 
    - */
    -public class Blackjack {
    -	public static void main(String[] args) {
    -		// Intuitively it might seem like the main program logic should be right
    -		// here in 'main' and that we should just use System.in and System.out
    -		// directly whenever we need them.  However, notice that System.out and
    -		// System.in are just an OutputStream and InputStream respectively. By
    -		// allowing alternate streams to be specified to Game at runtime, we can
    -		// write non-interactive tests of the code. See UserIoTest as an
    -		// example.
    -		// Likewise, by allowing an alternative "shuffle" algorithm, test code
    -		// can provide a deterministic card ordering.
    -		try (Reader in = new InputStreamReader(System.in)) {
    -			Writer out = new OutputStreamWriter(System.out);
    -			UserIo userIo = new UserIo(in, out);
    -			Deck deck = new Deck(cards -> {
    -				userIo.println("RESHUFFLING");
    -			    Collections.shuffle(cards);
    -			    return cards;
    -			});
    -			Game game = new Game(deck, userIo);
    -			game.run();
    -		} catch (Exception e) {
    -			// This allows us to elegantly handle CTRL+D / CTRL+Z by throwing an exception.
    -			System.out.println(e.getMessage());
    -			System.exit(1);
    -		}
    -	}
    -}
    diff --git a/10_Blackjack/java/src/Card.java b/10_Blackjack/java/src/Card.java
    deleted file mode 100644
    index 90daafaf3..000000000
    --- a/10_Blackjack/java/src/Card.java
    +++ /dev/null
    @@ -1,59 +0,0 @@
    -/**
    - * This is an example of an "record" class in Java. That's just a fancy way
    - * of saying the properties (value and suit) can't change after the object has
    - * been created (it has no 'setter' methods and the properties are implicitly 'final'). 
    - *
    - * Immutability often makes it easier to reason about code logic and avoid
    - * certain classes of bugs.
    - *
    - * Since it would never make sense for a card to change in the middle of a game,
    - * this is a good candidate for immutability.
    - */
    -record Card(int value, Suit suit) {
    -
    -	public enum Suit {
    -		HEARTS, DIAMONDS, SPADES, CLUBS;
    -	}
    -
    -	public Card {
    -        if(value < 1 || value > 13) {
    -            throw new IllegalArgumentException("Invalid card value " + value);
    -        }
    -        if(suit == null) {
    -            throw new IllegalArgumentException("Card suit must be non-null");
    -        }
    -	}
    -
    -    public String toString() {
    -        StringBuilder result = new StringBuilder(2); 
    -        if(value == 1) {
    -            result.append("A");
    -        } else if(value < 11) {
    -            result.append(value);
    -        } else if(value == 11) {
    -            result.append('J');
    -        } else if(value == 12) {
    -            result.append('Q');
    -        } else if(value == 13) {
    -            result.append('K');
    -        }
    -        // Uncomment to include the suit in output. Useful for debugging, but
    -        // doesn't match the original BASIC behavior.
    -        // result.append(suit.name().charAt(0));
    -        return result.toString();
    -    }
    -
    -    /**
    -     * Returns the value of {@link #toString()} preceded by either "AN " or "A " depending on which is gramatically correct.
    -     * 
    -     * @return "AN [x]" when [x] is "an" ace or "an" 8, and "A [X]" otherwise.
    -     */
    -    public String toProseString() {
    -		if(value == 1 || value == 8) {
    -            return "AN " + toString();
    -        } else {
    -            return "A " + toString();
    -        }
    -    }
    -
    -}
    \ No newline at end of file
    diff --git a/10_Blackjack/java/src/Deck.java b/10_Blackjack/java/src/Deck.java
    deleted file mode 100644
    index 791490150..000000000
    --- a/10_Blackjack/java/src/Deck.java
    +++ /dev/null
    @@ -1,66 +0,0 @@
    -import java.util.Collections;
    -import java.util.LinkedList;
    -import java.util.List;
    -import java.util.function.Function;
    -
    -public class Deck {
    -
    -    private LinkedList cards;
    -    private Function, LinkedList> shuffleAlgorithm;
    -    
    -    /**
    -     * Initialize the game deck with the given number of standard decks.
    -     * e.g. if you want to play with 2 decks, then {@code new Decks(2)} will
    -     * initialize 'cards' with 2 copies of a standard 52 card deck.
    -     * 
    -     * @param shuffleAlgorithm A function that takes the initial sorted card
    -     * list and returns a shuffled list ready to deal.
    -     * 
    -     */
    -    public Deck(Function, LinkedList> shuffleAlgorithm) {
    -        this.shuffleAlgorithm = shuffleAlgorithm;
    -    }
    -
    -    /**
    -     * Deals one card from the deck, removing it from this object's state. If
    -     * the deck is empty, it will be reshuffled before dealing a new card.
    -     * 
    -     * @return The card that was dealt.
    -     */
    -    public Card deal() {
    -        if(cards == null || cards.isEmpty()) {
    -            reshuffle();
    -        }
    -        return cards.pollFirst();
    -    }
    -
    -    /**
    -     * Shuffle the cards in this deck using the shuffleAlgorithm.
    -     */
    -    public void reshuffle() {
    -        LinkedList newCards = new LinkedList<>();
    -        for(Card.Suit suit : Card.Suit.values()) {
    -            for(int value = 1; value < 14; value++) {
    -                newCards.add(new Card(value, suit));
    -            }
    -        }
    -        this.cards = this.shuffleAlgorithm.apply(newCards);
    -    }
    -
    -    /**
    -     * Get the number of cards in this deck.
    -     * @return The number of cards in this deck. For example, 52 for a single deck.
    -     */
    -    public int size() {
    -        return cards.size();
    -    }
    -
    -    /**
    -     * Returns the cards in this deck.
    -     * @return An immutable view of the cards in this deck.
    -     */
    -    public List getCards() {
    -        // The returned list is immutable because we don't want other code messing with the deck.
    -        return Collections.unmodifiableList(cards);
    -    }
    -}
    diff --git a/10_Blackjack/java/src/Game.java b/10_Blackjack/java/src/Game.java
    deleted file mode 100644
    index 09afd5f8c..000000000
    --- a/10_Blackjack/java/src/Game.java
    +++ /dev/null
    @@ -1,344 +0,0 @@
    -import java.util.ArrayList;
    -import java.util.Collection;
    -import java.util.List;
    -import java.text.DecimalFormat;
    -
    -/**
    - * This is the primary class that runs the game itself.
    - */
    -public class Game {
    -    
    -    private Deck deck;
    -    private UserIo userIo;
    -
    -    public Game(Deck deck, UserIo userIo) {
    -        this.deck = deck;
    -        this.userIo = userIo;
    -    }
    -
    -	/**
    -	 * Run the game, running rounds until ended with CTRL+D/CTRL+Z or CTRL+C
    -	 */
    -    public void run() {
    -		userIo.println("BLACK JACK", 31);
    -		userIo.println("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n", 15);
    -		if(userIo.promptBoolean("DO YOU WANT INSTRUCTIONS")){
    -			userIo.println("THIS IS THE GAME OF 21. AS MANY AS 7 PLAYERS MAY PLAY THE");
    -			userIo.println("GAME. ON EACH DEAL, BETS WILL BE ASKED FOR, AND THE");
    -			userIo.println("PLAYERS' BETS SHOULD BE TYPED IN. THE CARDS WILL THEN BE");
    -			userIo.println("DEALT, AND EACH PLAYER IN TURN PLAYS HIS HAND. THE");
    -			userIo.println("FIRST RESPONSE SHOULD BE EITHER 'D', INDICATING THAT THE");
    -			userIo.println("PLAYER IS DOUBLING DOWN, 'S', INDICATING THAT HE IS");
    -			userIo.println("STANDING, 'H', INDICATING HE WANTS ANOTHER CARD, OR '/',");
    -			userIo.println("INDICATING THAT HE WANTS TO SPLIT HIS CARDS. AFTER THE");
    -			userIo.println("INITIAL RESPONSE, ALL FURTHER RESPONSES SHOULD BE 'S' OR");
    -			userIo.println("'H', UNLESS THE CARDS WERE SPLIT, IN WHICH CASE DOUBLING");
    -			userIo.println("DOWN IS AGAIN PERMITTED. IN ORDER TO COLLECT FOR");
    -			userIo.println("BLACKJACK, THE INITIAL RESPONSE SHOULD BE 'S'.");
    -		}
    -
    -		int nPlayers = 0;
    -		while(nPlayers < 1 || nPlayers > 7) {
    -			nPlayers = userIo.promptInt("NUMBER OF PLAYERS");
    -		}
    -
    -		deck.reshuffle();
    -
    -		Player dealer = new Player(0); //Dealer is Player 0
    -		
    -		List players = new ArrayList<>();
    -		for(int i = 0; i < nPlayers; i++) {
    -			players.add(new Player(i + 1));
    -		}
    -
    -		while(true) {
    -			while(!betsAreValid(players)){
    -				userIo.println("BETS:");
    -				for(int i = 0; i < nPlayers; i++) {
    -					double bet = userIo.promptDouble("#" + (i + 1)); // 1st player is "Player 1" not "Player 0"
    -					players.get(i).setCurrentBet(bet);
    -				}
    -			}
    -
    -			// It doesn't *really* matter whether we deal two cards at once to each player
    -			// or one card to each and then a second card to each, but this technically
    -			// mimics the way a deal works in real life.
    -			for(int i = 0; i < 2; i++){
    -				for(Player player : players){
    -					player.dealCard(deck.deal());
    -				}
    -				dealer.dealCard(deck.deal());
    -			}
    -
    -			printInitialDeal(players, dealer);
    -
    -			if(dealer.getHand().get(0).value() == 1) {
    -				collectInsurance(players);
    -			}
    -
    -			if(ScoringUtils.scoreHand(dealer.getHand()) == 21) {
    -				userIo.println("DEALER HAS " + dealer.getHand().get(1).toProseString() + " IN THE HOLE");
    -				userIo.println("FOR BLACKJACK");
    -			} else {
    -				Card dealerFirstCard = dealer.getHand().get(0);
    -				if(dealerFirstCard.value() == 1 || dealerFirstCard.value() > 9) {
    -					userIo.println("");
    -					userIo.println("NO DEALER BLACKJACK.");
    -				} // else dealer blackjack is imposible
    -				for(Player player : players){
    -					play(player);
    -				}
    -
    -				if(shouldPlayDealer(players)){
    -					playDealer(dealer);
    -				} else {
    -					userIo.println("DEALER HAD " + dealer.getHand().get(1).toProseString() + " CONCEALED.");
    -				}
    -			}
    -
    -			evaluateRound(players, dealer);
    -		} 
    -    }
    -
    -	protected void collectInsurance(Iterable players) {
    -		boolean isInsurance = userIo.promptBoolean("ANY INSURANCE");
    -		if(isInsurance) {
    -			userIo.println("INSURANCE BETS");
    -			for(Player player : players) {
    -				while(true) {
    -					double insuranceBet = userIo.promptDouble("# " + player.getPlayerNumber() + " ");
    -					// 0 indicates no insurance for that player.
    -					if(insuranceBet >= 0 && insuranceBet <= (player.getCurrentBet() / 2)) {
    -						player.setInsuranceBet(insuranceBet);
    -						break;
    -					}
    -				}
    -			}
    -		}
    -	}
    -
    -	/**
    -	 * Print the cards for each player and the up card for the dealer.
    -	 * Prints the initial deal in the following format:
    -	 *		
    -	 *	PLAYER 1     2    DEALER
    -     *         7    10     4   
    -     *         2     A   
    -	 */
    -	private void printInitialDeal(List players, Player dealer) {
    -	
    -        StringBuilder output = new StringBuilder(); 
    -		output.append("PLAYERS ");
    -		for (Player player : players) {
    -			output.append(player.getPlayerNumber() + "\t");
    -		}
    -		output.append("DEALER\n");
    -		//Loop through two rows of cards		
    -        for (int j = 0; j < 2; j++) {
    -			output.append("\t");
    -			for (Player player : players) {
    -				output.append(player.getHand().get(j).toString()).append("\t");
    -			}
    -			if(j == 0 ){
    -				output.append(dealer.getHand().get(j).toString());
    -			}
    -			output.append("\n");
    -		}
    -		userIo.print(output.toString());
    -	}
    -
    -	/**
    -	 * Plays the players turn. Prompts the user to hit (H), stay (S), or if
    -	 * appropriate, split (/) or double down (D), and then performs those
    -	 * actions. On a hit, prints "RECEIVED A  [x]  HIT? "
    -	 * 
    -	 * @param player
    -	 */
    -	protected void play(Player player) {
    -		play(player, 1);
    -	}
    -
    -	private void play(Player player, int handNumber) {
    -		String action;
    -		if(player.isSplit()){
    -			action = userIo.prompt("HAND " + handNumber);
    -		} else {
    -			action = userIo.prompt("PLAYER " + player.getPlayerNumber() + " ");
    -		}
    -		while(true){
    -			if(action.equalsIgnoreCase("H")){ // HIT
    -				Card c = deck.deal();
    -				player.dealCard(c, handNumber);
    -				if(ScoringUtils.scoreHand(player.getHand(handNumber)) > 21){
    -					userIo.println("RECEIVED " + c.toProseString() + "  ...BUSTED");
    -					break;
    -				}
    -				action = userIo.prompt("RECEIVED " + c.toProseString() + " HIT");
    -			} else if(action.equalsIgnoreCase("S")){ // STAY
    -				break;
    -			} else if(action.equalsIgnoreCase("D") && player.canDoubleDown(handNumber)) { // DOUBLE DOWN
    -				Card c = deck.deal();
    -				player.doubleDown(c, handNumber);
    -				if(ScoringUtils.scoreHand(player.getHand(handNumber)) > 21){
    -					userIo.println("RECEIVED " + c.toProseString() + "  ...BUSTED");
    -					break;
    -				}
    -				userIo.println("RECEIVED " + c.toProseString());
    -				break;
    -			} else if(action.equalsIgnoreCase("/")) { // SPLIT
    -				if(player.isSplit()) {
    -					// The original basic code printed different output
    -					// if a player tries to split twice vs if they try to split
    -					// a non-pair hand.
    -					action = userIo.prompt("TYPE H, S OR D, PLEASE");
    -				} else if(player.canSplit()) {
    -					player.split();
    -					Card card = deck.deal();
    -					player.dealCard(card, 1);
    -					userIo.println("FIRST HAND RECEIVES " + card.toProseString());
    -					card = deck.deal();
    -					player.dealCard(card, 2);
    -					userIo.println("SECOND HAND RECEIVES " + card.toProseString());					
    -					if(player.getHand().get(0).value() > 1){ //Can't play after splitting aces
    -						play(player, 1);
    -						play(player, 2);
    -					}
    -					return; // Don't fall out of the while loop and print another total
    -				} else {
    -					userIo.println("SPLITTING NOT ALLOWED");
    -					action = userIo.prompt("PLAYER " + player.getPlayerNumber() + " ");
    -				}
    -			} else {
    -				if(player.getHand(handNumber).size() == 2) {
    -					action = userIo.prompt("TYPE H,S,D, OR /, PLEASE");
    -				} else {
    -					action = userIo.prompt("TYPE H, OR S, PLEASE");
    -				}
    -			}
    -		}
    -		int total = ScoringUtils.scoreHand(player.getHand(handNumber));
    -		if(total == 21) {
    -			userIo.println("BLACKJACK");
    -		} else {
    -			userIo.println("TOTAL IS " + total);
    -		}
    -	}
    -
    -	/**
    -	 * Check the Dealer's hand should be played out. If every player has either busted or won with natural Blackjack,
    -	 * the Dealer doesn't need to play.
    -	 * 
    -	 * @param players
    -	 * @return boolean whether the dealer should play
    -	 */
    -	protected boolean shouldPlayDealer(List players){
    -		for(Player player : players){
    -			int score = ScoringUtils.scoreHand(player.getHand());
    -			if(score < 21 || (score == 21 && player.getHand().size() > 2)){
    -				return true;
    -			}
    -			if(player.isSplit()){				
    -				int splitScore = ScoringUtils.scoreHand(player.getHand(2));
    -				if(splitScore < 21 || (splitScore == 21 && player.getHand(2).size() > 2)){
    -					return true;
    -				}
    -			}
    -		}
    -		return false;
    -	}	
    -
    -	/**
    -	 * Play the dealer's hand. The dealer draws until they have >=17 or busts. Prints each draw as in the following example:
    -	 * 
    -	 * DEALER HAS A  5 CONCEALED FOR A TOTAL OF 11 
    -	 * DRAWS 10   ---TOTAL IS 21
    -	 *  
    -	 * @param dealerHand
    -	 */
    -	protected void playDealer(Player dealer) {
    -		int score = ScoringUtils.scoreHand(dealer.getHand());
    -		userIo.println("DEALER HAS " + dealer.getHand().get(1).toProseString() + " CONCEALED FOR A TOTAL OF " + score);
    -
    -		if(score < 17){
    -			userIo.print("DRAWS");
    -		}
    -		while(score < 17) {
    -			Card dealtCard = deck.deal();
    -			dealer.dealCard(dealtCard);
    -			score = ScoringUtils.scoreHand(dealer.getHand());
    -			userIo.print("  " + String.format("%-4s", dealtCard.toString()));
    -		}
    -		
    -		if(score > 21) {
    -			userIo.println("...BUSTED\n");
    -		} else {
    -			userIo.println("---TOTAL IS " + score + "\n");
    -		}
    -	}
    -
    -	/**
    -	 * Evaluates the result of the round, prints the results, and updates player/dealer totals.
    -	 * 
    -	 *	PLAYER 1 LOSES   100 TOTAL=-100 
    -	 *	PLAYER 2  WINS   150 TOTAL= 150
    -	 *	DEALER'S TOTAL= 200
    -	  *
    -	 * @param players
    -	 * @param dealerHand
    -	 */
    -	protected void evaluateRound(List players, Player dealer) {
    -		DecimalFormat formatter = new DecimalFormat("0.#"); //Removes trailing zeros
    -		for(Player player : players){
    -			int result = ScoringUtils.compareHands(player.getHand(), dealer.getHand());
    -			double totalBet = 0;
    -			if(result > 0) {
    -				totalBet += player.getCurrentBet();
    -			} else if(result < 0){
    -				totalBet -= player.getCurrentBet();
    -			}
    -			if(player.isSplit()) {
    -				int splitResult = ScoringUtils.compareHands(player.getHand(2), dealer.getHand());
    -				if(splitResult > 0){
    -					totalBet += player.getSplitBet();
    -				} else if(splitResult < 0){
    -					totalBet -= player.getSplitBet();
    -				} 
    -			}
    -			if(player.getInsuranceBet() != 0){
    -				int dealerResult = ScoringUtils.scoreHand(dealer.getHand());
    -				if(dealerResult == 21 && dealer.getHand().size() == 2){
    -					totalBet += (player.getInsuranceBet() * 2);
    -				} else {
    -					totalBet -= player.getInsuranceBet();
    -				}
    -			}
    -			
    -			userIo.print("PLAYER " + player.getPlayerNumber());
    -			if(totalBet < 0) {
    -				userIo.print(" LOSES " + String.format("%6s", formatter.format(Math.abs(totalBet)))); 
    -			} else if(totalBet > 0) {
    -				userIo.print("  WINS " + String.format("%6s", formatter.format(totalBet))); 
    -			} else {
    -				userIo.print(" PUSHES      ");
    -			}
    -			player.recordRound(totalBet);
    -			dealer.recordRound(totalBet * (-1));
    -			userIo.println(" TOTAL= " + formatter.format(player.getTotal()));
    -			player.resetHand();
    -		}
    -		userIo.println("DEALER'S TOTAL= " + formatter.format(dealer.getTotal()) + "\n");
    -		dealer.resetHand();
    -	}
    -
    -	/**
    -	 * Validates that all bets are between 0 (exclusive) and 500 (inclusive). Fractional bets are valid.
    -	 * 
    -	 * @param players The players with their current bet set.
    -	 * @return true if all bets are valid, false otherwise.
    -	 */
    -	public boolean betsAreValid(Collection players) {
    -		return players.stream()
    -			.map(Player::getCurrentBet)
    -			.allMatch(bet -> bet > 0 && bet <= 500);
    -	}
    -}
    diff --git a/10_Blackjack/java/src/Player.java b/10_Blackjack/java/src/Player.java
    deleted file mode 100644
    index 85b8b1ddd..000000000
    --- a/10_Blackjack/java/src/Player.java
    +++ /dev/null
    @@ -1,190 +0,0 @@
    -import java.util.Collections;
    -import java.util.LinkedList;
    -import java.util.List;
    -
    -/**
    - * Represents a player and data related to them (number, bets, cards).
    - */
    -public class Player {
    -
    -    private int playerNumber;     // e.g. playerNumber = 1 means "this is Player 1"
    -    private double currentBet;
    -    private double insuranceBet; // 0 when the player has not made an insurance bet (either it does not apply or they chose not to)
    -    private double splitBet; // 0 whenever the hand is not split
    -    private double total;
    -    private LinkedList hand;
    -    private LinkedList splitHand; // null whenever the hand is not split
    -
    -    /**
    -    * Represents a player in the game with cards, bets, total and a playerNumber. 
    -    */
    -    public Player(int playerNumber) {
    -        this.playerNumber = playerNumber;
    -        currentBet = 0;
    -        insuranceBet = 0;
    -        splitBet = 0;
    -        total = 0;
    -        hand = new LinkedList<>();
    -        splitHand = null;
    -    }
    -
    -    public int getPlayerNumber() {
    -        return this.playerNumber;
    -    }
    -    
    -    public double getCurrentBet() {
    -        return this.currentBet;
    -    }
    -
    -    public void setCurrentBet(double currentBet) {
    -        this.currentBet = currentBet;
    -    }
    -
    -    public double getSplitBet() {
    -        return splitBet;
    -    }
    -
    -    public double getInsuranceBet() {
    -        return insuranceBet;
    -    }
    -
    -    public void setInsuranceBet(double insuranceBet) {
    -        this.insuranceBet = insuranceBet;
    -    }
    -
    -    /**
    -    * RecordRound adds input paramater 'totalBet' to 'total' and then 
    -    * sets 'currentBet', 'splitBet', and 'insuranceBet' to zero
    -    */
    -    public void recordRound(double totalBet) {
    -        this.total = this.total + totalBet;
    -        this.currentBet = 0;
    -        this.splitBet = 0;
    -        this.insuranceBet = 0;
    -    }
    -
    -    /**
    -     * Returns the total of all bets won/lost.
    -     * @return Total value
    -     */
    -    public double getTotal() {
    -        return this.total;
    -    }
    -
    -    /**
    -     * Add the given card to the players main hand.
    -     * 
    -     * @param card The card to add.
    -     */
    -    public void dealCard(Card card) {
    -        dealCard(card, 1);
    -    }
    -    
    -    /**
    -     * Adds the given card to the players hand or split hand depending on the handNumber.
    -     * 
    -     * @param card The card to add
    -     * @param handNumber 1 for the "first" hand and 2 for the "second" hand in a split hand scenario.
    -     */
    -    public void dealCard(Card card, int handNumber) {
    -        if(handNumber == 1) {
    -            hand.add(card);
    -        } else if (handNumber == 2) {
    -            splitHand.add(card);
    -        } else {
    -            throw new IllegalArgumentException("Invalid hand number " + handNumber);
    -        }
    -    }
    -
    -    /**
    -     * Determines whether the player is eligible to split.
    -     * @return True if the player has not already split, and their hand is a pair. False otherwise.
    -     */
    -    public boolean canSplit() {
    -        if(isSplit()) {
    -            // Can't split twice
    -            return false;
    -        } else {
    -            boolean isPair = this.hand.get(0).value() == this.hand.get(1).value();
    -            return isPair;
    -        }
    -    }
    -
    -    /**
    -     * Determines whether the player has already split their hand.
    -     * @return false if splitHand is null, true otherwise.
    -     */
    -    public boolean isSplit() {
    -        return this.splitHand != null;
    -    }
    -
    -    /**
    -     * Removes first card from hand to add it to new split hand
    -     */
    -    public void split() {
    -        this.splitBet = this.currentBet;
    -        this.splitHand = new LinkedList<>();
    -        splitHand.add(hand.pop());
    -    }
    -
    -    /**
    -     * Determines whether the player can double down.
    -     * 
    -     * @param handNumber
    -     * @return
    -     */
    -    public boolean canDoubleDown(int handNumber) {
    -        if(handNumber == 1){
    -            return this.hand.size() == 2;
    -        } else if(handNumber == 2){
    -            return this.splitHand.size() == 2;
    -        } else {
    -            throw new IllegalArgumentException("Invalid hand number " + handNumber);
    -        }
    -    }
    -
    -    /**
    -     * Doubles down on the given hand. Specifically, this method doubles the bet for the given hand and deals the given card.
    -     * 
    -     * @param card The card to deal
    -     * @param handNumber The hand to deal to and double the bet for
    -     */
    -    public void doubleDown(Card card, int handNumber) {
    -        if(handNumber == 1){
    -            this.currentBet = this.currentBet * 2;
    -        } else if(handNumber == 2){
    -            this.splitBet = this.splitBet * 2;
    -        } else {
    -            throw new IllegalArgumentException("Invalid hand number " + handNumber);
    -        }
    -        this.dealCard(card, handNumber);
    -    }
    -
    -    /**
    -     * Resets the hand to an empty list and the splitHand to null.
    -     */
    -    public void resetHand() {
    -        this.hand = new LinkedList<>();
    -        this.splitHand = null;
    -    }
    -
    -    public List getHand() {
    -        return getHand(1);
    -    }
    -
    -    /**
    -     * Returns the given hand
    -     * @param handNumber 1 for the "first" of a split hand (or the main hand when there is no split) or 2 for the "second" hand of a split hand.
    -     * @return The hand specified by handNumber
    -     */
    -    public List getHand(int handNumber) {
    -        if(handNumber == 1){
    -            return Collections.unmodifiableList(this.hand);
    -        } else if(handNumber == 2){
    -            return Collections.unmodifiableList(this.splitHand);
    -        } else {
    -            throw new IllegalArgumentException("Invalid hand number " + handNumber);
    -        }
    -    }
    -
    -}
    \ No newline at end of file
    diff --git a/10_Blackjack/java/src/ScoringUtils.java b/10_Blackjack/java/src/ScoringUtils.java
    deleted file mode 100644
    index 573abb624..000000000
    --- a/10_Blackjack/java/src/ScoringUtils.java
    +++ /dev/null
    @@ -1,61 +0,0 @@
    -import java.util.List;
    -
    -public final class ScoringUtils {
    -
    -	/**
    -	 * Calculates the value of a hand. When the hand contains aces, it will
    -	 * count one of them as 11 if that does not result in a bust.
    -	 * 
    -	 * @param hand the hand to evaluate
    -	 * @return The numeric value of a hand. A value over 21 indicates a bust.
    -	 */
    -	public static final int scoreHand(List hand) {
    -		int nAces = (int) hand.stream().filter(c -> c.value() == 1).count();
    -		int value = hand.stream()
    -				.mapToInt(Card::value)
    -				.filter(v -> v != 1) // start without aces
    -				.map(v -> v > 10 ? 10 : v) // all face cards are worth 10. The 'expr ? a : b' syntax is called the
    -											// 'ternary operator'
    -				.sum();
    -		value += nAces; // start by treating all aces as 1
    -		if (nAces > 0 && value <= 11) {
    -			value += 10; // We can use one of the aces to an 11
    -			// You can never use more than one ace as 11, since that would be 22 and a bust.
    -		}
    -		return value;
    -	}
    -
    -	/**
    -	 * Compares two hands accounting for natural blackjacks and busting using the
    -	 * java.lang.Comparable convention of returning positive or negative integers
    -	 * 
    -	 * @param handA hand to compare
    -	 * @param handB other hand to compare
    -	 * @return a negative integer, zero, or a positive integer as handA is less
    -	 *         than, equal to, or greater than handB.
    -	 */
    -	public static final int compareHands(List handA, List handB) {
    -		int scoreA = scoreHand(handA);
    -		int scoreB = scoreHand(handB);
    -		if (scoreA == 21 && scoreB == 21) {
    -			if (handA.size() == 2 && handB.size() != 2) {
    -				return 1; // Hand A wins with a natural blackjack
    -			} else if (handA.size() != 2 && handB.size() == 2) {
    -				return -1; // Hand B wins with a natural blackjack
    -			} else {
    -				return 0; // Tie
    -			}
    -		} else if (scoreA > 21 || scoreB > 21) {
    -			if (scoreA > 21 && scoreB > 21) {
    -				return 0; // Tie, both bust
    -			} else if (scoreB > 21) {
    -				return 1; // A wins, B busted
    -			} else {
    -				return -1; // B wins, A busted
    -			}
    -		} else {
    -			return Integer.compare(scoreA, scoreB);
    -		}
    -	}
    -
    -}
    diff --git a/10_Blackjack/java/src/UserIo.java b/10_Blackjack/java/src/UserIo.java
    deleted file mode 100644
    index fcaf826f7..000000000
    --- a/10_Blackjack/java/src/UserIo.java
    +++ /dev/null
    @@ -1,160 +0,0 @@
    -import java.io.BufferedReader;
    -import java.io.EOFException;
    -import java.io.IOException;
    -import java.io.PrintWriter;
    -import java.io.Reader;
    -import java.io.UncheckedIOException;
    -import java.io.Writer;
    -import java.util.stream.IntStream;
    -
    -/**
    - * This class is responsible for printing output to the screen and reading input
    - * from the user. It must be initialized with a reader to get input data from
    - * and a writer to send output to. Typically these will wrap System.in and
    - * System.out respectively, but can be a StringReader and StringWriter when
    - * running in test code.
    - */
    -public class UserIo {
    -
    -    private BufferedReader in;
    -    private PrintWriter out;
    -
    -	/**
    -	 * Initializes the UserIo with the given reader/writer. The reader will be
    -	 * wrapped in a BufferedReader and so should not be a BufferedReader
    -	 * already (to avoid double buffering).
    -	 * 
    -	 * @param in Typically an InputStreamReader wrapping System.in or a StringReader
    -	 * @param out Typically an OuputStreamWriter wrapping System.out or a StringWriter
    -	 */
    -    public UserIo(Reader in, Writer out) {
    -        this.in = new BufferedReader(in);
    -        this.out = new PrintWriter(out, true);
    -    }
    -
    -	/**
    -	 * Print the line of text to output including a trailing linebreak.
    -	 * 
    -	 * @param text the text to print
    -	 */
    -	public void println(String text) {
    -		out.println(text);
    -	}
    -
    -	/**
    -	 * Print the given text left padded with spaces.
    -	 * 
    -	 * @param text The text to print
    -	 * @param leftPad The number of spaces to pad with.
    -	 */
    -	public void println(String text, int leftPad) {
    -		IntStream.range(0, leftPad).forEach((i) -> out.print(' '));
    -		out.println(text);
    -	}
    -
    -	/**
    -	 * Print the given text without a trailing linebreak.
    -	 * 
    -	 * @param text The text to print.
    -	 */
    -	public void print(String text) {
    -		out.print(text);
    -		out.flush();
    -	}
    -
    -	/**
    -	 * Reads a line of text from input.
    -	 * 
    -	 * @return The line entered into input.
    -	 * @throws UncheckedIOException if the line is null (CTRL+D or CTRL+Z was pressed)
    -	 */
    -	private String readLine() {
    -		try {
    -			String line = in.readLine();
    -			if(line == null) {
    -				throw new UncheckedIOException("!END OF INPUT", new EOFException());
    -			}
    -			return line;
    -		} catch (IOException e) {
    -			throw new UncheckedIOException(e);
    -		}
    -	}
    -
    -	/**
    -	 * Prompt the user via input.
    -	 * 
    -	 * @param prompt The text to display as a prompt. A question mark and space will be added to the end, so if prompt = "EXAMPLE" then the user will see "EXAMPLE? ".
    -	 * @return The line read from input.
    -	 */
    -	public String prompt(String prompt) {
    -		print(prompt + "? ");
    -		return readLine();
    -	}
    -
    -	/**
    -	 * Prompts the user for a "Yes" or "No" answer.
    -	 * @param prompt The prompt to display to the user on STDOUT.
    -	 * @return false if the user enters a value beginning with "N" or "n"; true otherwise.
    -	 */
    -	public boolean promptBoolean(String prompt) {
    -		print(prompt + "? ");
    -
    -		String input = readLine();
    -
    -		if(input.toLowerCase().startsWith("n")) {
    -			return false;
    -		} else {
    -			return true;
    -		}
    -	}
    -
    -	/**
    -	 * Prompts the user for an integer.  As in Vintage Basic, "the optional
    -	 * prompt string is followed by a question mark and a space." and if the
    -	 * input is non-numeric, "an error will be generated and the user will be
    -	 * re-prompted.""
    -	 *
    -	 * @param prompt The prompt to display to the user.
    -	 * @return the number given by the user.
    -	 */
    -	public int promptInt(String prompt) {
    -		print(prompt + "? ");
    -
    -		while(true) {
    -			String input = readLine();
    -			try {
    -				return Integer.parseInt(input);
    -			} catch(NumberFormatException e) {
    -				// Input was not numeric.
    -				println("!NUMBER EXPECTED - RETRY INPUT LINE");
    -				print("? ");
    -				continue;
    -			}
    -		}
    -	}
    -
    -	/**
    -	 * Prompts the user for a double.  As in Vintage Basic, "the optional
    -	 * prompt string is followed by a question mark and a space." and if the
    -	 * input is non-numeric, "an error will be generated and the user will be
    -	 * re-prompted.""
    -	 *
    -	 * @param prompt The prompt to display to the user.
    -	 * @return the number given by the user.
    -	 */
    -	public double promptDouble(String prompt) {
    -		print(prompt + "? ");
    -
    -		while(true) {
    -			String input = readLine();
    -			try {
    -				return Double.parseDouble(input);
    -			} catch(NumberFormatException e) {
    -				// Input was not numeric.
    -				println("!NUMBER EXPECTED - RETRY INPUT LINE");
    -				print("? ");
    -				continue;
    -			}
    -		}
    -	}
    -}
    diff --git a/10_Blackjack/java/test/DeckTest.java b/10_Blackjack/java/test/DeckTest.java
    deleted file mode 100644
    index 2da7cdc65..000000000
    --- a/10_Blackjack/java/test/DeckTest.java
    +++ /dev/null
    @@ -1,32 +0,0 @@
    -import static org.junit.jupiter.api.Assertions.assertEquals;
    -import static org.junit.jupiter.api.Assertions.assertAll;
    -import org.junit.jupiter.api.Test;
    -
    -public class DeckTest {
    -
    -    @Test
    -    void testInit() {
    -        // When
    -        Deck deck = new Deck((cards) -> cards);
    -        deck.reshuffle();
    -
    -        // Then
    -        long nCards = deck.size();
    -        long nSuits = deck.getCards().stream()
    -                .map(card -> card.suit())
    -                .distinct()
    -                .count();
    -        long nValues = deck.getCards().stream()
    -                .map(card -> card.value())
    -                .distinct()
    -                .count();
    -
    -        assertAll("deck",
    -            () -> assertEquals(52, nCards, "Expected 52 cards in a deck, but got " + nCards),
    -            () -> assertEquals(4, nSuits, "Expected 4 suits, but got " + nSuits),
    -            () -> assertEquals(13, nValues, "Expected 13 values, but got " + nValues)
    -        );
    -        
    -    }
    -
    -}
    diff --git a/10_Blackjack/java/test/GameTest.java b/10_Blackjack/java/test/GameTest.java
    deleted file mode 100644
    index e79ad6359..000000000
    --- a/10_Blackjack/java/test/GameTest.java
    +++ /dev/null
    @@ -1,622 +0,0 @@
    -import org.junit.jupiter.api.Test;
    -
    -import org.junit.jupiter.api.AfterEach;
    -import org.junit.jupiter.api.BeforeEach;
    -import org.junit.jupiter.api.DisplayName;
    -
    -import static org.junit.jupiter.api.Assertions.assertAll;
    -import static org.junit.jupiter.api.Assertions.assertEquals;
    -import static org.junit.jupiter.api.Assertions.assertFalse;
    -import static org.junit.jupiter.api.Assertions.assertThrows;
    -import static org.junit.jupiter.api.Assertions.assertTrue;
    -
    -import java.io.EOFException;
    -import java.io.StringReader;
    -import java.io.StringWriter;
    -import java.io.UncheckedIOException;
    -import java.util.Arrays;
    -import java.util.Collections;
    -import java.util.LinkedList;
    -import java.util.List;
    -
    -public class GameTest {
    -
    -    private StringReader in;
    -    private StringWriter out;
    -    private Game game;
    -
    -    private StringBuilder playerActions;
    -    private LinkedList cards;
    -
    -    @BeforeEach
    -    public void resetIo() {
    -        in = null;
    -        out = null;
    -        game = null;
    -        playerActions = new StringBuilder();
    -        cards = new LinkedList<>();
    -    }
    -
    -    private void playerGets(int value, Card.Suit suit) {
    -        cards.add(new Card(value, suit));
    -    }
    -
    -    private void playerSays(String action) {
    -        playerActions.append(action).append(System.lineSeparator());
    -    }
    -
    -    private void initGame() {
    -        System.out.printf("Running game with input: %s\tand cards: %s\n",playerActions.toString(), cards);
    -        in = new StringReader(playerActions.toString());
    -        out = new StringWriter();
    -        UserIo userIo = new UserIo(in, out);
    -        Deck deck = new Deck((c) -> cards);
    -        game = new Game(deck, userIo);
    -    }
    -
    -    @AfterEach
    -    private void printOutput() {
    -        System.out.println(out.toString());
    -    }
    -
    -    @Test
    -    public void shouldQuitOnCtrlD() {
    -        // Given
    -        playerSays("\u2404"); // U+2404 is "End of Transmission" sent by CTRL+D (or CTRL+Z on Windows)
    -        initGame();
    -
    -        // When
    -        Exception e = assertThrows(UncheckedIOException.class, game::run);
    -
    -        // Then
    -        assertTrue(e.getCause() instanceof EOFException);
    -        assertEquals("!END OF INPUT", e.getMessage());
    -    }
    -
    -    @Test
    -    @DisplayName("collectInsurance() should not prompt on N")
    -    public void collectInsuranceNo(){
    -        // Given
    -        List players = Collections.singletonList(new Player(1));
    -        playerSays("N");
    -        initGame();
    -
    -        // When
    -        game.collectInsurance(players);
    -
    -        // Then
    -        assertAll(
    -            () -> assertTrue(out.toString().contains("ANY INSURANCE")),
    -            () -> assertFalse(out.toString().contains("INSURANCE BETS"))
    -        );
    -    }
    -
    -    @Test
    -    @DisplayName("collectInsurance() should collect on Y")
    -    public void collectInsuranceYes(){
    -        // Given
    -        List players = Collections.singletonList(new Player(1));
    -        players.get(0).setCurrentBet(100);
    -        playerSays("Y");
    -        playerSays("50");
    -        initGame();
    -
    -        // When
    -        game.collectInsurance(players);
    -
    -        // Then
    -        assertAll(
    -            () -> assertTrue(out.toString().contains("ANY INSURANCE")),
    -            () -> assertTrue(out.toString().contains("INSURANCE BETS")),
    -            () -> assertEquals(50, players.get(0).getInsuranceBet())
    -        );
    -    }
    -
    -    @Test
    -    @DisplayName("collectInsurance() should not allow more than 50% of current bet")
    -    public void collectInsuranceYesTooMuch(){
    -        // Given
    -        List players = Collections.singletonList(new Player(1));
    -        players.get(0).setCurrentBet(100);
    -        playerSays("Y");
    -        playerSays("51");
    -        playerSays("50");
    -        initGame();
    -
    -        // When
    -        game.collectInsurance(players);
    -
    -        // Then
    -        assertAll(
    -            () -> assertEquals(50, players.get(0).getInsuranceBet()),
    -            () -> assertTrue(out.toString().contains("# 1 ? # 1 ?"))
    -        );
    -    }
    -
    -    @Test
    -    @DisplayName("collectInsurance() should not allow negative bets")
    -    public void collectInsuranceYesNegative(){
    -        // Given
    -        List players = Collections.singletonList(new Player(1));
    -        players.get(0).setCurrentBet(100);
    -        playerSays("Y");
    -        playerSays("-1");
    -        playerSays("1");
    -        initGame();
    -
    -        // When
    -        game.collectInsurance(players);
    -
    -        // Then
    -        assertAll(
    -            () -> assertEquals(1, players.get(0).getInsuranceBet()),
    -            () -> assertTrue(out.toString().contains("# 1 ? # 1 ?"))
    -        );
    -    }
    -
    -    @Test
    -    @DisplayName("collectInsurance() should prompt all players")
    -    public void collectInsuranceYesTwoPlayers(){
    -        // Given
    -        List players = Arrays.asList(
    -            new Player(1),
    -            new Player(2)
    -        );
    -        players.get(0).setCurrentBet(100);
    -        players.get(1).setCurrentBet(100);
    -
    -        playerSays("Y");
    -        playerSays("50");
    -        playerSays("25");
    -        initGame();
    -
    -        // When
    -        game.collectInsurance(players);
    -
    -        // Then
    -        assertAll(
    -            () -> assertEquals(50, players.get(0).getInsuranceBet()),
    -            () -> assertEquals(25, players.get(1).getInsuranceBet()),
    -            () -> assertTrue(out.toString().contains("# 1 ? # 2 ?"))
    -        );
    -    }
    -
    -    @Test
    -    @DisplayName("play() should end on STAY")
    -    public void playEndOnStay(){
    -        // Given
    -        Player player = new Player(1);
    -        player.dealCard(new Card(3, Card.Suit.CLUBS));
    -        player.dealCard(new Card(2, Card.Suit.SPADES));
    -        playerSays("S"); // "I also like to live dangerously."
    -        initGame();
    -
    -        // When
    -        game.play(player);
    -
    -        // Then
    -        assertTrue(out.toString().startsWith("PLAYER 1 ? TOTAL IS 5"));
    -    }
    -
    -    @Test
    -    @DisplayName("play() should allow HIT until BUST")
    -    public void playHitUntilBust() {
    -        // Given
    -        Player player = new Player(1);
    -        player.dealCard(new Card(10, Card.Suit.HEARTS));
    -        player.dealCard(new Card(10, Card.Suit.SPADES));
    -
    -        playerSays("H");
    -        playerGets(1, Card.Suit.SPADES); // 20
    -        playerSays("H");
    -        playerGets(1, Card.Suit.HEARTS); // 21
    -        playerSays("H");
    -        playerGets(1, Card.Suit.CLUBS); // 22 - D'oh!
    -        initGame();
    -
    -        // When
    -        game.play(player);
    -
    -        // Then
    -        assertTrue(out.toString().contains("BUSTED"));
    -    }
    -
    -    @Test
    -    @DisplayName("Should allow double down on initial turn")
    -    public void playDoubleDown(){
    -        // Given
    -        Player player = new Player(1);
    -        player.setCurrentBet(100);
    -        player.dealCard(new Card(10, Card.Suit.HEARTS));
    -        player.dealCard(new Card(4, Card.Suit.SPADES));
    -
    -        playerSays("D");
    -        playerGets(7, Card.Suit.SPADES);
    -        initGame();
    -
    -        // When
    -        game.play(player);
    -
    -        // Then
    -        assertTrue(player.getCurrentBet() == 200);
    -        assertTrue(player.getHand().size() == 3);
    -    }
    -
    -    @Test
    -    @DisplayName("Should NOT allow double down after initial deal")
    -    public void playDoubleDownLate(){
    -        // Given
    -        Player player = new Player(1);
    -        player.setCurrentBet(100);
    -        player.dealCard(new Card(10, Card.Suit.HEARTS));
    -        player.dealCard(new Card(2, Card.Suit.SPADES));
    -
    -        playerSays("H");
    -        playerGets(7, Card.Suit.SPADES);
    -        playerSays("D");
    -        playerSays("S");
    -        initGame();
    -
    -        // When
    -        game.play(player);
    -
    -        // Then
    -        assertTrue(out.toString().contains("TYPE H, OR S, PLEASE"));
    -    }
    -
    -    @Test
    -    @DisplayName("play() should end on STAY after split")
    -    public void playSplitEndOnStay(){
    -        // Given
    -        Player player = new Player(1);
    -        player.dealCard(new Card(1, Card.Suit.CLUBS));
    -        player.dealCard(new Card(1, Card.Suit.SPADES));
    -
    -        playerSays("/");
    -        playerGets(2, Card.Suit.SPADES); // First hand
    -        playerSays("S");
    -        playerGets(2, Card.Suit.SPADES); // Second hand
    -        playerSays("S");
    -        initGame();
    -
    -        // When
    -        game.play(player);
    -
    -        // Then
    -        assertTrue(out.toString().contains("FIRST HAND RECEIVES"));
    -        assertTrue(out.toString().contains("SECOND HAND RECEIVES"));
    -    }
    -
    -    @Test
    -    @DisplayName("play() should allow HIT until BUST after split")
    -    public void playSplitHitUntilBust() {
    -        // Given
    -        Player player = new Player(1);
    -        player.dealCard(new Card(10, Card.Suit.HEARTS));
    -        player.dealCard(new Card(10, Card.Suit.SPADES));
    -
    -        playerSays("/");
    -        playerGets(12, Card.Suit.SPADES); // First hand has 20
    -        playerSays("H");
    -        playerGets(12, Card.Suit.HEARTS); // First hand busted
    -        playerGets(10, Card.Suit.HEARTS); // Second hand gets a 10
    -        playerSays("S");
    -        initGame();
    -
    -        // When
    -        game.play(player);
    -
    -        // Then
    -        assertTrue(out.toString().contains("BUSTED"));
    -    }
    -
    -    @Test
    -    @DisplayName("play() should allow HIT on split hand until BUST")
    -    public void playSplitHitUntilBustHand2() {
    -        // Given
    -        Player player = new Player(1);
    -        player.dealCard(new Card(10, Card.Suit.HEARTS));
    -        player.dealCard(new Card(10, Card.Suit.SPADES));
    -
    -        playerSays("/");
    -        playerGets(1, Card.Suit.CLUBS); // First hand is 21
    -        playerSays("S");
    -        playerGets(12, Card.Suit.SPADES); // Second hand is 20
    -        playerSays("H");
    -        playerGets(12, Card.Suit.HEARTS); // Busted
    -        playerSays("H");
    -        initGame();
    -
    -        // When
    -        game.play(player);
    -
    -        // Then
    -        assertTrue(out.toString().contains("BUSTED"));
    -    }
    -
    -    @Test
    -    @DisplayName("play() should allow double down on split hands")
    -    public void playSplitDoubleDown(){
    -        // Given
    -        Player player = new Player(1);
    -        player.setCurrentBet(100);
    -        player.dealCard(new Card(9, Card.Suit.HEARTS));
    -        player.dealCard(new Card(9, Card.Suit.SPADES));
    -
    -        playerSays("/");
    -        playerGets(5, Card.Suit.DIAMONDS); // First hand is 14
    -        playerSays("D");
    -        playerGets(6, Card.Suit.HEARTS); // First hand is 20
    -        playerGets(7, Card.Suit.CLUBS); // Second hand is 16
    -        playerSays("D");
    -        playerGets(4, Card.Suit.CLUBS); // Second hand is 20
    -        initGame();
    -
    -        // When
    -        game.play(player);
    -
    -        // Then
    -        assertAll(
    -            () -> assertEquals(200, player.getCurrentBet(), "Current bet should be doubled"),
    -            () -> assertEquals(200, player.getSplitBet(), "Split bet should be doubled"),
    -            () -> assertEquals(3, player.getHand(1).size(), "First hand should have exactly three cards"),
    -            () -> assertEquals(3, player.getHand(2).size(), "Second hand should have exactly three cards")
    -        );
    -    }
    -
    -    @Test
    -    @DisplayName("play() should NOT allow re-splitting first split hand")
    -    public void playSplitTwice(){
    -        // Given
    -        Player player = new Player(1);
    -        player.setCurrentBet(100);
    -        player.dealCard(new Card(2, Card.Suit.HEARTS));
    -        player.dealCard(new Card(2, Card.Suit.SPADES));
    -
    -        playerSays("/");
    -        playerGets(13, Card.Suit.CLUBS); // First hand
    -        playerSays("/"); // Not allowed
    -        playerSays("S");
    -        playerGets(13, Card.Suit.SPADES); // Second hand
    -        playerSays("S");
    -        initGame();
    -
    -        // When
    -        game.play(player);
    -
    -        // Then
    -        assertTrue(out.toString().contains("TYPE H, S OR D, PLEASE"));
    -    }
    -
    -    @Test
    -    @DisplayName("play() should NOT allow re-splitting second split hand")
    -    public void playSplitTwiceHand2(){
    -        // Given
    -        Player player = new Player(1);
    -        player.setCurrentBet(100);
    -        player.dealCard(new Card(10, Card.Suit.HEARTS));
    -        player.dealCard(new Card(10, Card.Suit.SPADES));
    -
    -        playerSays("/");
    -        playerGets(13, Card.Suit.CLUBS); // First hand
    -        playerSays("S");
    -        playerGets(13, Card.Suit.SPADES); // Second hand
    -        playerSays("/"); // Not allowed
    -        playerSays("S");
    -        initGame();
    -
    -        // When
    -        game.play(player);
    -
    -        // Then
    -        assertTrue(out.toString().contains("TYPE H, S OR D, PLEASE"));
    -    }
    -
    -    @Test
    -    @DisplayName("evaluateRound() should total both hands when split")
    -    public void evaluateRoundWithSplitHands(){
    -        // Given
    -        Player dealer = new Player(0); //Dealer
    -        dealer.dealCard(new Card(1, Card.Suit.HEARTS));
    -        dealer.dealCard(new Card(1, Card.Suit.SPADES));
    -
    -        Player player = new Player(1);
    -        player.recordRound(200);//Set starting total
    -        player.setCurrentBet(50);
    -        player.dealCard(new Card(1, Card.Suit.HEARTS));
    -        player.dealCard(new Card(1, Card.Suit.SPADES));
    -        
    -        playerSays("/");
    -        playerGets(13, Card.Suit.CLUBS); // First hand
    -        playerSays("S");
    -        playerGets(13, Card.Suit.SPADES); // Second hand
    -        playerSays("S");
    -        initGame();
    -
    -        // When
    -        game.play(player);
    -        game.evaluateRound(Arrays.asList(player), dealer);
    -
    -        // Then
    -        assertAll(
    -            () -> assertTrue(out.toString().contains("PLAYER 1  WINS    100 TOTAL= 300")),
    -            () -> assertTrue(out.toString().contains("DEALER'S TOTAL= -100"))
    -        );
    -    }
    -
    -    @Test
    -    @DisplayName("evaluateRound() should total add twice insurance bet")
    -    public void evaluateRoundWithInsurance(){
    -        // Given
    -        Player dealer = new Player(0); //Dealer
    -        dealer.dealCard(new Card(10, Card.Suit.HEARTS));
    -        dealer.dealCard(new Card(1, Card.Suit.SPADES));
    -
    -        Player player = new Player(1);
    -        player.setCurrentBet(50);
    -        player.setInsuranceBet(10);
    -        player.dealCard(new Card(2, Card.Suit.HEARTS));
    -        player.dealCard(new Card(1, Card.Suit.SPADES));
    -        initGame();
    -
    -        // When
    -        game.evaluateRound(Arrays.asList(player), dealer);
    -
    -        // Then
    -        // Loses current bet (50) and wins 2*10 for total -30
    -        assertAll(
    -            () -> assertTrue(out.toString().contains("PLAYER 1 LOSES     30 TOTAL= -30")),
    -            () -> assertTrue(out.toString().contains("DEALER'S TOTAL= 30"))
    -        );
    -    }
    -
    -    @Test
    -    @DisplayName("evaluateRound() should push with no total change")
    -    public void evaluateRoundWithPush(){
    -        // Given
    -        Player dealer = new Player(0);
    -        dealer.dealCard(new Card(10, Card.Suit.HEARTS));
    -        dealer.dealCard(new Card(8, Card.Suit.SPADES)); 
    -
    -        Player player = new Player(1);
    -        player.setCurrentBet(10);
    -        player.dealCard(new Card(9, Card.Suit.HEARTS));
    -        player.dealCard(new Card(9, Card.Suit.SPADES));
    -        initGame();
    -
    -        // When (Dealer and Player both have 19)
    -        game.evaluateRound(Arrays.asList(player), dealer);
    -
    -        // Then        
    -        assertAll(
    -            () -> assertTrue(out.toString().contains("PLAYER 1 PUSHES       TOTAL= 0")),
    -            () -> assertTrue(out.toString().contains("DEALER'S TOTAL= 0"))
    -        );
    -    }
    -
    -    @Test
    -    @DisplayName("shouldPlayDealer() return false when players bust")
    -    public void shouldPlayDealerBust(){
    -        // Given
    -        Player player = new Player(1);
    -        player.dealCard(new Card(10, Card.Suit.SPADES));
    -        player.dealCard(new Card(10, Card.Suit.SPADES));
    -        player.split();
    -        player.dealCard(new Card(5, Card.Suit.SPADES));
    -        player.dealCard(new Card(8, Card.Suit.SPADES));//First hand Busted
    -
    -        player.dealCard(new Card(5, Card.Suit.SPADES),2);
    -        player.dealCard(new Card(8, Card.Suit.SPADES),2);//Second hand Busted
    -
    -        Player playerTwo = new Player(2);
    -        playerTwo.dealCard(new Card(7, Card.Suit.HEARTS));
    -        playerTwo.dealCard(new Card(8, Card.Suit.HEARTS));
    -        playerTwo.dealCard(new Card(9, Card.Suit.HEARTS));
    -        initGame();
    -
    -        // When 
    -        boolean result = game.shouldPlayDealer(Arrays.asList(player,playerTwo));
    -
    -        // Then        
    -        assertFalse(result);
    -    }
    -
    -    @Test
    -    @DisplayName("shouldPlayDealer() return false when players bust")
    -    public void ShouldPlayer(){
    -        // Given
    -        Player player = new Player(1);
    -        player.dealCard(new Card(10, Card.Suit.SPADES));
    -        player.dealCard(new Card(10, Card.Suit.SPADES));
    -        player.split();
    -        player.dealCard(new Card(5, Card.Suit.SPADES));
    -        player.dealCard(new Card(8, Card.Suit.SPADES));//First hand Busted
    -
    -        player.dealCard(new Card(5, Card.Suit.SPADES),2);
    -        player.dealCard(new Card(8, Card.Suit.SPADES),2);//Second hand Busted
    -
    -        Player playerTwo = new Player(2);
    -        playerTwo.dealCard(new Card(7, Card.Suit.HEARTS));
    -        playerTwo.dealCard(new Card(8, Card.Suit.HEARTS));
    -        playerTwo.dealCard(new Card(9, Card.Suit.HEARTS));
    -        initGame();
    -
    -        // When 
    -        boolean result = game.shouldPlayDealer(Arrays.asList(player,playerTwo));
    -
    -        // Then        
    -        assertFalse(result);
    -    }
    -
    -    @Test
    -    @DisplayName("shouldPlayDealer() return true when player has non-natural blackjack")
    -    public void shouldPlayDealerNonNaturalBlackjack(){
    -        // Given
    -        Player player = new Player(1);
    -        player.dealCard(new Card(5, Card.Suit.SPADES));
    -        player.dealCard(new Card(6, Card.Suit.DIAMONDS));
    -        player.dealCard(new Card(10, Card.Suit.SPADES));
    -
    -        initGame();
    -
    -        // When 
    -        boolean result = game.shouldPlayDealer(Arrays.asList(player));
    -
    -        // Then        
    -        assertTrue(result);
    -    }
    -
    -    @Test
    -    @DisplayName("shouldPlayDealer() return true when player doesn't have blackjack")
    -    public void shouldPlayDealerNonBlackjack(){
    -        // Given
    -        Player player = new Player(1);
    -        player.dealCard(new Card(10, Card.Suit.SPADES));
    -        player.dealCard(new Card(6, Card.Suit.DIAMONDS));
    -        initGame();
    -
    -        // When 
    -        boolean result = game.shouldPlayDealer(Arrays.asList(player));
    -
    -        // Then        
    -        assertTrue(result);
    -    }
    -
    -
    -    @Test
    -    @DisplayName("playDealer() should DRAW on less than 17 intial deal")
    -    public void playDealerLessThanSeventeen(){
    -        // Given
    -        Player dealer = new Player(0);
    -        dealer.dealCard(new Card(10, Card.Suit.SPADES));
    -        dealer.dealCard(new Card(6, Card.Suit.DIAMONDS));
    -        playerGets(11, Card.Suit.DIAMONDS);
    -        initGame();
    -
    -        // When 
    -       game.playDealer(dealer);
    -
    -        // Then        
    -        assertTrue(out.toString().contains("DRAWS"));
    -        assertTrue(out.toString().contains("BUSTED"));
    -    }
    -
    -    @Test
    -    @DisplayName("playDealer() should stay on more than 17 intial deal")
    -    public void playDealerMoreThanSeventeen(){
    -        // Given
    -        Player dealer = new Player(0);
    -        dealer.dealCard(new Card(10, Card.Suit.SPADES));
    -        dealer.dealCard(new Card(8, Card.Suit.DIAMONDS));
    -        initGame();
    -
    -        // When 
    -       game.playDealer(dealer);
    -
    -        // Then        
    -        assertFalse(out.toString().contains("DRAWS"));
    -        assertFalse(out.toString().contains("BUSTED"));
    -        assertTrue(out.toString().contains("---TOTAL IS"));
    -    }
    -
    -}
    diff --git a/10_Blackjack/java/test/ScoringUtilsTest.java b/10_Blackjack/java/test/ScoringUtilsTest.java
    deleted file mode 100644
    index 01a1738c2..000000000
    --- a/10_Blackjack/java/test/ScoringUtilsTest.java
    +++ /dev/null
    @@ -1,193 +0,0 @@
    -import org.junit.jupiter.api.Test;
    -
    -import org.junit.jupiter.api.DisplayName;
    -
    -import static org.junit.jupiter.api.Assertions.assertEquals;
    -
    -import java.util.LinkedList;
    -
    -public class ScoringUtilsTest {
    -
    -    @Test
    -    @DisplayName("scoreHand should score aces as 1 when using 11 would bust")
    -    public void scoreHandHardAce() {
    -        // Given
    -        LinkedList hand = new LinkedList<>();
    -        hand.add(new Card(10, Card.Suit.SPADES));
    -        hand.add(new Card(9, Card.Suit.SPADES));
    -        hand.add(new Card(1, Card.Suit.SPADES));
    -
    -        // When
    -        int result = ScoringUtils.scoreHand(hand);
    -
    -        // Then
    -        assertEquals(20, result);
    -    }
    -
    -    @Test
    -    @DisplayName("scoreHand should score 3 aces as 13")
    -    public void scoreHandMultipleAces() {
    -        // Given
    -        LinkedList hand = new LinkedList<>();
    -        hand.add(new Card(1, Card.Suit.SPADES));
    -        hand.add(new Card(1, Card.Suit.CLUBS));
    -        hand.add(new Card(1, Card.Suit.HEARTS));
    -
    -        // When
    -        int result = ScoringUtils.scoreHand(hand);
    -
    -        // Then
    -        assertEquals(13, result);
    -    }
    -
    -    @Test
    -    @DisplayName("compareHands should return 1 meaning A beat B, 20 to 12")
    -    public void compareHandsAWins() {
    -        LinkedList handA = new LinkedList<>();
    -        handA.add(new Card(10, Card.Suit.SPADES));
    -        handA.add(new Card(10, Card.Suit.CLUBS));
    -
    -        LinkedList handB = new LinkedList<>();
    -        handB.add(new Card(1, Card.Suit.SPADES));
    -        handB.add(new Card(1, Card.Suit.CLUBS));
    -
    -        int result = ScoringUtils.compareHands(handA,handB);
    -
    -        assertEquals(1, result);
    -    }
    -
    -    @Test
    -    @DisplayName("compareHands should return -1 meaning B beat A, 18 to 4")
    -    public void compareHandsBwins() {
    -        LinkedList handA = new LinkedList<>();
    -        handA.add(new Card(2, Card.Suit.SPADES));
    -        handA.add(new Card(2, Card.Suit.CLUBS));
    -
    -        LinkedList handB = new LinkedList<>();
    -        handB.add(new Card(5, Card.Suit.SPADES));
    -        handB.add(new Card(6, Card.Suit.HEARTS));
    -        handB.add(new Card(7, Card.Suit.CLUBS));
    -
    -        int result = ScoringUtils.compareHands(handA,handB);
    -
    -        assertEquals(-1, result);
    -    }
    -
    -    @Test
    -    @DisplayName("compareHands should return 1 meaning A beat B, natural Blackjack to Blackjack")
    -    public void compareHandsAWinsWithNaturalBlackJack() {
    -        //Hand A wins with natural BlackJack, B with Blackjack
    -        LinkedList handA = new LinkedList<>();
    -        handA.add(new Card(10, Card.Suit.SPADES));
    -        handA.add(new Card(1, Card.Suit.CLUBS));
    -
    -        LinkedList handB = new LinkedList<>();
    -        handB.add(new Card(6, Card.Suit.SPADES));
    -        handB.add(new Card(7, Card.Suit.HEARTS));
    -        handB.add(new Card(8, Card.Suit.CLUBS));
    -
    -        int result = ScoringUtils.compareHands(handA,handB);
    -
    -        assertEquals(1, result);
    -    }
    -
    -    @Test
    -    @DisplayName("compareHands should return -1 meaning B beat A, natural Blackjack to Blackjack")
    -    public void compareHandsBWinsWithNaturalBlackJack() {
    -        LinkedList handA = new LinkedList<>();
    -        handA.add(new Card(6, Card.Suit.SPADES));
    -        handA.add(new Card(7, Card.Suit.HEARTS));
    -        handA.add(new Card(8, Card.Suit.CLUBS));
    -        
    -        LinkedList handB = new LinkedList<>();
    -        handB.add(new Card(10, Card.Suit.SPADES));
    -        handB.add(new Card(1, Card.Suit.CLUBS));
    -
    -        int result = ScoringUtils.compareHands(handA,handB);
    -
    -        assertEquals(-1, result);
    -    }
    -
    -    @Test
    -    @DisplayName("compareHands should return 0, hand A and B tied with a Blackjack")
    -    public void compareHandsTieBothBlackJack() {
    -        LinkedList handA = new LinkedList<>();
    -        handA.add(new Card(11, Card.Suit.SPADES));
    -        handA.add(new Card(10, Card.Suit.CLUBS));
    -        
    -        LinkedList handB = new LinkedList<>();
    -        handB.add(new Card(10, Card.Suit.SPADES));
    -        handB.add(new Card(11, Card.Suit.CLUBS));
    -
    -        int result = ScoringUtils.compareHands(handA,handB);
    -
    -        assertEquals(0, result);
    -    }
    -
    -    @Test
    -    @DisplayName("compareHands should return 0, hand A and B tie without a Blackjack")
    -    public void compareHandsTieNoBlackJack() {
    -        LinkedList handA = new LinkedList<>();
    -        handA.add(new Card(10, Card.Suit.DIAMONDS));
    -        handA.add(new Card(10, Card.Suit.HEARTS));
    -        
    -        LinkedList handB = new LinkedList<>();
    -        handB.add(new Card(10, Card.Suit.SPADES));
    -        handB.add(new Card(10, Card.Suit.CLUBS));
    -
    -        int result = ScoringUtils.compareHands(handA,handB);
    -
    -        assertEquals(0, result);
    -    }
    -
    -    @Test
    -    @DisplayName("compareHands should return 0, hand A and B tie when both bust")
    -    public void compareHandsTieBust() {
    -        LinkedList handA = new LinkedList<>();
    -        handA.add(new Card(10, Card.Suit.DIAMONDS));
    -        handA.add(new Card(10, Card.Suit.HEARTS));
    -        handA.add(new Card(3, Card.Suit.HEARTS));
    -        
    -        LinkedList handB = new LinkedList<>();
    -        handB.add(new Card(10, Card.Suit.SPADES));
    -        handB.add(new Card(11, Card.Suit.SPADES));
    -        handB.add(new Card(4, Card.Suit.SPADES));
    -
    -        int result = ScoringUtils.compareHands(handA,handB);
    -
    -        assertEquals(0, result);
    -    }
    -    @Test
    -    @DisplayName("compareHands should return -1, meaning B beat A, A busted")
    -    public void compareHandsABusted() {
    -        LinkedList handA = new LinkedList<>();
    -        handA.add(new Card(10, Card.Suit.DIAMONDS));
    -        handA.add(new Card(10, Card.Suit.HEARTS));
    -        handA.add(new Card(3, Card.Suit.HEARTS));
    -        
    -        LinkedList handB = new LinkedList<>();
    -        handB.add(new Card(10, Card.Suit.SPADES));
    -        handB.add(new Card(10, Card.Suit.SPADES));
    -
    -        int result = ScoringUtils.compareHands(handA,handB);
    -
    -        assertEquals(-1, result);
    -    }
    -
    -    @Test
    -    @DisplayName("compareHands should return 1, meaning A beat B, B busted")
    -    public void compareHandsBBusted() {
    -        LinkedList handA = new LinkedList<>();
    -        handA.add(new Card(10, Card.Suit.DIAMONDS));
    -        handA.add(new Card(3, Card.Suit.HEARTS));
    -        
    -        LinkedList handB = new LinkedList<>();
    -        handB.add(new Card(10, Card.Suit.SPADES));
    -        handB.add(new Card(10, Card.Suit.SPADES));
    -        handB.add(new Card(5, Card.Suit.SPADES));
    -
    -        int result = ScoringUtils.compareHands(handA,handB);
    -
    -        assertEquals(1, result);
    -    }
    -}
    diff --git a/10_Blackjack/java/test/UserIoTest.java b/10_Blackjack/java/test/UserIoTest.java
    deleted file mode 100644
    index a2fccc26b..000000000
    --- a/10_Blackjack/java/test/UserIoTest.java
    +++ /dev/null
    @@ -1,84 +0,0 @@
    -import static org.junit.jupiter.api.Assertions.assertEquals;
    -import static org.junit.jupiter.api.Assertions.assertFalse;
    -import static org.junit.jupiter.api.Assertions.assertTrue;
    -
    -import java.io.Reader;
    -import java.io.StringReader;
    -import java.io.StringWriter;
    -
    -import org.junit.jupiter.api.DisplayName;
    -import org.junit.jupiter.api.Test;
    -import org.junit.jupiter.params.ParameterizedTest;
    -import org.junit.jupiter.params.provider.CsvSource;
    -import org.junit.jupiter.params.provider.ValueSource;
    -
    -public class UserIoTest {
    -
    -    @ParameterizedTest(name = "''{0}'' is accepted as ''no''")
    -    @ValueSource(strings = {"N", "n", "No", "NO", "no"})
    -    public void testPromptBooleanAcceptsNo(String response) {
    -        // Given
    -        Reader in = new StringReader(response + "\n");
    -        StringWriter out = new StringWriter();
    -        UserIo userIo = new UserIo(in, out);
    -
    -        // When
    -        boolean result = userIo.promptBoolean("TEST");
    -
    -        // Then
    -        assertEquals("TEST? ", out.toString());
    -        assertFalse(result);
    -    }
    -
    -    @ParameterizedTest(name = "''{0}'' is accepted as ''yes''")
    -    @ValueSource(strings = {"Y", "y", "Yes", "YES", "yes", "", "foobar"})
    -    public void testPromptBooleanAcceptsYes(String response) {
    -        // Given
    -        Reader in = new StringReader(response + "\n");
    -        StringWriter out = new StringWriter();
    -        UserIo userIo = new UserIo(in, out);
    -
    -        // When
    -        boolean result = userIo.promptBoolean("TEST");
    -
    -        // Then
    -        assertEquals("TEST? ", out.toString());
    -        assertTrue(result);
    -    }
    -
    -    @ParameterizedTest(name = "''{0}'' is accepted as number")
    -    @CsvSource({
    -        "1,1",
    -        "0,0",
    -        "-1,-1",
    -    })
    -    public void testPromptIntAcceptsNumbers(String response, int expected) {
    -        // Given
    -        Reader in = new StringReader(response + "\n");
    -        StringWriter out = new StringWriter();
    -        UserIo userIo = new UserIo(in, out);
    -
    -        // When
    -        int result = userIo.promptInt("TEST");
    -
    -        // Then
    -        assertEquals("TEST? ", out.toString());
    -        assertEquals(expected, result);
    -    }
    -
    -    @Test
    -    @DisplayName("promptInt should print an error and reprompt if given a non-numeric response")
    -    public void testPromptIntRepromptsOnNonNumeric() {
    -        // Given
    -        Reader in = new StringReader("foo" + System.lineSeparator() +"1"); // word, then number
    -        StringWriter out = new StringWriter();
    -        UserIo userIo = new UserIo(in, out);
    -
    -        // When
    -        int result = userIo.promptInt("TEST");
    -
    -        // Then
    -        assertEquals("TEST? !NUMBER EXPECTED - RETRY INPUT LINE" + System.lineSeparator() +"? ", out.toString());
    -        assertEquals(1, result);
    -    }
    -}
    diff --git a/10_Blackjack/javascript/blackjack.html b/10_Blackjack/javascript/blackjack.html
    index 3582a8e3e..eb18ca9e5 100644
    --- a/10_Blackjack/javascript/blackjack.html
    +++ b/10_Blackjack/javascript/blackjack.html
    @@ -1,10 +1,9 @@
     
     
     BLACKJACK
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/10_Blackjack/javascript/blackjack.js b/10_Blackjack/javascript/blackjack.js
    index 21e11b9ef..16f5a3434 100644
    --- a/10_Blackjack/javascript/blackjack.js
    +++ b/10_Blackjack/javascript/blackjack.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    @@ -217,7 +217,7 @@ async function main()
         // --ta[i] IS THE TOTAL FOR PLAYER I, sa[i] IS THE TOTAL THIS HAND FOR
         // --PLAYER I, ba[i] IS TH BET FOR HAND I
         // --ra[i] IS THE LENGTH OF pa[I,*]
    -
    +    
         // --Program starts here
         // --Initialize
         for (i = 1; i <= 15; i++)
    @@ -416,7 +416,7 @@ async function main()
                         if (pa[i][1] != 1) {
                             // --Now play the two hands
                             do {
    -
    +                            
                                 print("HAND " + (i > d1 ? 2 : 1) + " ");
                                 h1 = 5;
                                 while (1) {
    @@ -472,7 +472,7 @@ async function main()
                     if (aa <= 16) {
                         print("DRAWS");
                         do {
    -
    +                        
                             x = get_card();
                             alt_card_print(x);
                             add_card_to_row(i, x);
    diff --git a/10_Blackjack/kotlin/README.md b/10_Blackjack/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/10_Blackjack/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/10_Blackjack/lua/README.md b/10_Blackjack/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/10_Blackjack/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/10_Blackjack/pascal/README.md b/10_Blackjack/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/10_Blackjack/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/10_Blackjack/python/blackjack.py b/10_Blackjack/python/blackjack.py
    deleted file mode 100644
    index 615aec79b..000000000
    --- a/10_Blackjack/python/blackjack.py
    +++ /dev/null
    @@ -1,470 +0,0 @@
    -"""
    -Blackjack
    -
    -Ported by Martin Thoma in 2022,
    -using the rust implementation of AnthonyMichaelTDM
    -"""
    -
    -import enum
    -import random
    -from dataclasses import dataclass
    -from typing import List, NamedTuple
    -
    -
    -class PlayerType(enum.Enum):
    -    Player = "Player"
    -    Dealer = "Dealer"
    -
    -
    -class Play(enum.Enum):
    -    Stand = enum.auto()
    -    Hit = enum.auto()
    -    DoubleDown = enum.auto()
    -    Split = enum.auto()
    -
    -
    -class Card(NamedTuple):
    -    name: str
    -
    -    @property
    -    def value(self) -> int:
    -        """
    -        returns the value associated with a card with the passed name
    -        return 0 if the passed card name doesn't exist
    -        """
    -        return {
    -            "ACE": 11,
    -            "2": 2,
    -            "3": 3,
    -            "4": 4,
    -            "5": 5,
    -            "6": 6,
    -            "7": 7,
    -            "8": 8,
    -            "9": 9,
    -            "10": 10,
    -            "JACK": 10,
    -            "QUEEN": 10,
    -            "KING": 10,
    -        }.get(self.name, 0)
    -
    -
    -class Hand(NamedTuple):
    -    cards: List[Card]
    -
    -    def add_card(self, card: Card) -> None:
    -        """add a passed card to this hand"""
    -        self.cards.append(card)
    -
    -    def get_total(self) -> int:
    -        """returns the total points of the cards in this hand"""
    -        total: int = sum(int(card.value) for card in self.cards)
    -        # if there is an ACE, and the hand would otherwise bust,
    -        # treat the ace like it's worth 1
    -        if total > 21 and any(card.name == "ACE" for card in self.cards):
    -            total -= 10
    -
    -        return total
    -
    -    def discard_hand(self, deck: "Decks") -> None:
    -        """adds the cards in hand into the discard pile"""
    -        _len = len(self.cards)
    -        for _i in range(_len):
    -            if len(self.cards) == 0:
    -                raise ValueError("hand empty")
    -            deck.discard_pile.append(self.cards.pop())
    -
    -
    -class Decks(NamedTuple):
    -    deck: List[Card]
    -    discard_pile: List[Card]
    -
    -    @classmethod
    -    def new(cls) -> "Decks":
    -        """creates a new full and shuffled deck, and an empty discard pile"""
    -        # returns a number of full decks of 52 cards, shuffles them
    -        deck = Decks(deck=[], discard_pile=[])
    -        number_of_decks = 3
    -
    -        # fill deck
    -        for _n in range(number_of_decks):
    -            # fill deck with number_of_decks decks worth of cards
    -            for card_name in CARD_NAMES:
    -                # add 4 of each card, totaling one deck with 4 of each card
    -                for _ in range(4):
    -                    deck.deck.append(Card(name=card_name))
    -
    -        deck.shuffle()
    -        return deck
    -
    -    def shuffle(self) -> None:
    -        """shuffles the deck"""
    -        random.shuffle(self.deck)
    -
    -    def draw_card(self) -> Card:
    -        """
    -        draw card from deck, and return it
    -        if deck is empty, shuffles discard pile into it and tries again
    -        """
    -        if len(self.deck) != 0:
    -            return self.deck.pop()
    -        _len = len(self.discard_pile)
    -
    -        if _len <= 0:
    -            # discard pile and deck are empty, should never happen
    -            raise Exception("discard pile empty")
    -        # deck is empty, shuffle discard pile into deck and try again
    -        print("deck is empty, shuffling")
    -        for _i in range(_len):
    -            if len(self.discard_pile) == 0:
    -                raise ValueError("discard pile is empty")
    -            self.deck.append(self.discard_pile.pop())
    -        self.shuffle()
    -        return self.draw_card()
    -
    -
    -@dataclass
    -class Player:
    -    hand: Hand
    -    balance: int
    -    bet: int
    -    wins: int
    -    player_type: PlayerType
    -    index: int
    -
    -    @classmethod
    -    def new(cls, player_type: PlayerType, index: int) -> "Player":
    -        """creates a new player of the given type"""
    -        return Player(
    -            hand=Hand(cards=[]),
    -            balance=STARTING_BALANCE,
    -            bet=0,
    -            wins=0,
    -            player_type=player_type,
    -            index=index,
    -        )
    -
    -    def get_name(self) -> str:
    -        return f"{self.player_type}{self.index}"
    -
    -    def get_bet(self) -> None:
    -        """gets a bet from the player"""
    -        if PlayerType.Player == self.player_type:
    -            if self.balance < 1:
    -                print(f"{self.get_name()} is out of money :(")
    -                self.bet = 0
    -            self.bet = get_number_from_user_input(
    -                f"{self.get_name()}\tWhat is your bet", 1, self.balance
    -            )
    -
    -    def hand_as_string(self, hide_dealer: bool) -> str:
    -        """
    -        returns a string of the players hand
    -
    -        if player is a dealer, returns the first card in the hand followed
    -        by *'s for every other card
    -        if player is a player, returns every card and the total
    -        """
    -        if hide_dealer and self.player_type == PlayerType.Dealer:
    -            return "".join(f"{c.name}\t" for c in self.hand.cards[1::-1])
    -        elif (
    -            hide_dealer
    -            and self.player_type == PlayerType.Player
    -            or not hide_dealer
    -        ):
    -            s = "".join(
    -                f"{cards_in_hand.name}\t"
    -                for cards_in_hand in self.hand.cards[::-1]
    -            )
    -            s += f"total points = {self.hand.get_total()}"
    -            return s
    -        raise Exception("This is unreachable")
    -
    -    def get_play(self) -> Play:
    -        """get the players 'play'"""
    -        # do different things depending on what type of player this is:
    -        # if it's a dealer, use an algorithm to determine the play
    -        # if it's a player, ask user for input
    -        if self.player_type == PlayerType.Dealer:
    -            return Play.Stand if self.hand.get_total() > 16 else Play.Hit
    -        elif self.player_type == PlayerType.Player:
    -            valid_results: List[str]
    -            if len(self.hand.cards) > 2:
    -                # if there are more than 2 cards in the hand,
    -                # at least one turn has happened, so splitting and
    -                # doubling down are not allowed
    -                valid_results = ["s", "h"]
    -            else:
    -                valid_results = ["s", "h", "d", "/"]
    -            play = get_char_from_user_input("\tWhat is your play?", valid_results)
    -            if play == "s":
    -                return Play.Stand
    -            elif play == "h":
    -                return Play.Hit
    -            elif play == "d":
    -                return Play.DoubleDown
    -            elif play == "/":
    -                return Play.Split
    -            else:
    -                raise ValueError(f"got invalid character {play}")
    -        raise Exception("This is unreachable")
    -
    -
    -@dataclass
    -class Game:
    -    players: List[Player]  # last item in this is the dealer
    -    decks: Decks
    -    games_played: int
    -
    -    @classmethod
    -    def new(cls, num_players: int) -> "Game":
    -        players: List[Player] = [Player.new(PlayerType.Dealer, 0)]
    -
    -        # create human player(s) (at least one)
    -        players.append(Player.new(PlayerType.Player, 1))
    -        players.extend(Player.new(PlayerType.Player, i) for i in range(2, num_players))
    -        if get_char_from_user_input("Do you want instructions", ["y", "n"]) == "y":
    -            print_instructions()
    -        print()
    -
    -        return Game(players=players, decks=Decks.new(), games_played=0)
    -
    -    def _print_stats(self) -> None:
    -        """prints the score of every player"""
    -        print(f"{self.stats_as_string()}")
    -
    -    def stats_as_string(self) -> str:
    -        """returns a string of the wins, balance, and bets of every player"""
    -        s = ""
    -        for p in self.players:
    -            # format the presentation of player stats
    -            if p.player_type == PlayerType.Dealer:
    -                s += f"{p.get_name()} Wins:\t{p.wins}\n"
    -            elif p.player_type == PlayerType.Player:
    -                s += f"{p.get_name()} "
    -                s += f"Wins:\t{p.wins}\t\t"
    -                s += f"Balance:\t{p.balance}\t\tBet\t{p.bet}\n"
    -        return f"Scores:\n{s}"
    -
    -    def play_game(self) -> None:
    -        """plays a round of blackjack"""
    -        game = self.games_played
    -        player_hands_message: str = ""
    -
    -        # deal two cards to each player
    -        for _i in range(2):
    -            for player in self.players:
    -                player.hand.add_card(self.decks.draw_card())
    -
    -        # get everyones bets
    -        for player in self.players:
    -            player.get_bet()
    -        scores = self.stats_as_string()
    -
    -        # play game for each player
    -        for player in self.players:
    -            # turn loop, ends when player finishes their turn
    -            while True:
    -                clear()
    -                print_welcome_screen()
    -                print(f"\n\t\t\tGame {game}")
    -                print(scores)
    -                print(player_hands_message)
    -                print(f"{player.get_name()} Hand:\t{player.hand_as_string(True)}")
    -
    -                if PlayerType.Player == player.player_type and player.bet == 0:
    -                    break
    -
    -                # play through turn
    -                # check their hand value for a blackjack(21) or bust
    -                score = player.hand.get_total()
    -                if score >= 21:
    -                    if score == 21:
    -                        print("\tBlackjack! (21 points)")
    -                    else:
    -                        print(f"\tBust      ({score} points)")
    -                    break
    -
    -                # get player move
    -                play = player.get_play()
    -                # process play
    -                if play == Play.Stand:
    -                    print(f"\t{play}")
    -                    break
    -                elif play == Play.Hit:
    -                    print(f"\t{play}")
    -                    player.hand.add_card(self.decks.draw_card())
    -                elif play == Play.DoubleDown:
    -                    print(f"\t{play}")
    -
    -                    # double their balance if there's enough money,
    -                    # othewise go all-in
    -                    if player.bet * 2 < player.balance:
    -                        player.bet *= 2
    -                    else:
    -                        player.bet = player.balance
    -                    player.hand.add_card(self.decks.draw_card())
    -            # add player to score cache thing
    -            player_hands_message += (
    -                f"{player.get_name()} Hand:\t{player.hand_as_string(True)}\n"
    -            )
    -
    -        # determine winner
    -        top_score = 0
    -
    -        # player with the highest points
    -        num_winners = 1
    -
    -        non_burst_players = [
    -            player for player in self.players if player.hand.get_total() <= 21
    -        ]
    -        for player in non_burst_players:
    -            score = player.hand.get_total()
    -            if score > top_score:
    -                top_score = score
    -                num_winners = 1
    -            elif score == top_score:
    -                num_winners += 1
    -
    -        # show winner(s)
    -        top_score_players = [
    -            player
    -            for player in non_burst_players
    -            if player.hand.get_total() == top_score
    -        ]
    -        for x in top_score_players:
    -            print(f"{x.get_name()} ")
    -            x.wins += 1
    -            # increment their wins
    -        if num_winners > 1:
    -            print(f"all tie with {top_score}\n\n\n")
    -        else:
    -            print(
    -                f"wins with {top_score}!\n\n\n",
    -            )
    -
    -        # handle bets
    -        # remove money from losers
    -        losers = [
    -            player for player in self.players if player.hand.get_total() != top_score
    -        ]
    -        for loser in losers:
    -            loser.balance -= loser.bet
    -        # add money to winner
    -        winners = [
    -            player for player in self.players if player.hand.get_total() == top_score
    -        ]
    -        for winner in winners:
    -            winner.balance += winner.bet
    -
    -        # discard hands
    -        for player in self.players:
    -            player.hand.discard_hand(self.decks)
    -
    -        # increment games_played
    -        self.games_played += 1
    -
    -
    -CARD_NAMES: List[str] = [
    -    "ACE",
    -    "2",
    -    "3",
    -    "4",
    -    "5",
    -    "6",
    -    "7",
    -    "8",
    -    "9",
    -    "10",
    -    "JACK",
    -    "QUEEN",
    -    "KING",
    -]
    -STARTING_BALANCE: int = 100
    -
    -
    -def main() -> None:
    -    game: Game
    -
    -    print_welcome_screen()
    -
    -    # create game
    -    game = Game.new(
    -        get_number_from_user_input("How many players should there be", 1, 7)
    -    )
    -
    -    # game loop, play game until user wants to stop
    -    char = "y"
    -    while char == "y":
    -        game.play_game()
    -        char = get_char_from_user_input("Play Again?", ["y", "n"])
    -
    -
    -def print_welcome_screen() -> None:
    -    print(
    -        """
    -                            BLACK JACK
    -              CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY
    -    \n\n"""
    -    )
    -
    -
    -def print_instructions() -> None:
    -    print(
    -        """
    -    THIS IS THE GAME OF 21. AS MANY AS 7 PLAYERS MAY PLAY THE
    -    GAME. ON EACH DEAL, BETS WILL BE ASKED FOR, AND THE
    -    PLAYERS' BETS SHOULD BE TYPED IN. THE CARDS WILL THEN BE
    -    DEALT, AND EACH PLAYER IN TURN PLAYS HIS HAND. THE
    -    FIRST RESPONSE SHOULD BE EITHER 'D', INDICATING THAT THE
    -    PLAYER IS DOUBLING DOWN, 'S', INDICATING THAT HE IS
    -    STANDING, 'H', INDICATING HE WANTS ANOTHER CARD, OR '/',
    -    INDICATING THAT HE WANTS TO SPLIT HIS CARDS. AFTER THE
    -    INITIAL RESPONSE, ALL FURTHER RESPONSES SHOULD BE 'S' OR
    -    'H', UNLESS THE CARDS WERE SPLIT, IN WHICH CASE DOUBLING
    -    DOWN IS AGAIN PERMITTED. IN ORDER TO COLLECT FOR
    -    BLACKJACK, THE INITIAL RESPONSE SHOULD BE 'S'.
    -    NUMBER OF PLAYERS
    -
    -    NOTE:'/' (splitting) is not currently implemented, and does nothing
    -
    -    PRESS ENTER TO CONTINUE
    -    """
    -    )
    -    input()
    -
    -
    -def get_number_from_user_input(prompt: str, min_value: int, max_value: int) -> int:
    -    """gets a int integer from user input"""
    -    # input loop
    -    user_input = None
    -    while user_input is None or user_input < min_value or user_input > max_value:
    -        raw_input = input(f"{prompt} ({min_value}-{max_value})? ")
    -
    -        try:
    -            user_input = int(raw_input)
    -            if user_input < min_value or user_input > max_value:
    -                print("Invalid input, please try again")
    -        except ValueError:
    -            print("Invalid input, please try again")
    -    return user_input
    -
    -
    -def get_char_from_user_input(prompt: str, valid_results: List[str]) -> str:
    -    """returns the first character they type"""
    -    user_input = None
    -    while user_input not in valid_results:
    -        user_input = input(f"{prompt} {valid_results}? ").lower()
    -        if user_input not in valid_results:
    -            print("Invalid input, please try again")
    -    assert user_input is not None
    -    return user_input
    -
    -
    -def clear() -> None:
    -    """clear std out"""
    -    print("\x1b[2J\x1b[0;0H")
    -
    -
    -if __name__ == "__main__":
    -    main()
    diff --git a/10_Blackjack/ruby/blackjack.rb b/10_Blackjack/ruby/blackjack.rb
    deleted file mode 100644
    index f2346f447..000000000
    --- a/10_Blackjack/ruby/blackjack.rb
    +++ /dev/null
    @@ -1,20 +0,0 @@
    -require_relative "./game.rb"
    -
    -def intro
    -    puts "Welcome to Blackjack"
    -end
    -
    -def ask_for_players_count
    -    puts "How many of you want to join the table?"
    -    return gets.to_i
    -end
    -
    -begin
    -    intro
    -    players_count = ask_for_players_count
    -    Game.new(players_count).start
    -rescue SystemExit, Interrupt
    -    exit
    -rescue => exception
    -   p exception
    -end
    diff --git a/10_Blackjack/ruby/game.rb b/10_Blackjack/ruby/game.rb
    deleted file mode 100644
    index b73fb9f08..000000000
    --- a/10_Blackjack/ruby/game.rb
    +++ /dev/null
    @@ -1,152 +0,0 @@
    -require_relative "./model/hand.rb"
    -require_relative "./model/player.rb"
    -require_relative "./model/card_kind.rb"
    -require_relative "./model/pack.rb"
    -
    -class Game
    -
    -  ALLOWED_HAND_ACTIONS = {
    -    "hit" => ["H", "S"],
    -    "split" => ["H", "S", "D"],
    -    "normal" => ["H", "S", "/", "D"]
    -  }
    -
    -  def initialize(players_count)
    -    @pack = Model::Pack.new
    -    @dealer_balance = 0
    -    @dealer_hand = nil
    -    @players = 1.upto(players_count).map { |id| Model::Player.new(id) }
    -  end
    -
    -  def start
    -    loop do
    -      collect_bets_and_deal
    -      play_players
    -      check_for_insurance_bets
    -      play_dealer
    -      settle
    -    end
    -  end
    -
    -  private
    -
    -  def collect_bets_and_deal
    -    puts "BETS"
    -
    -    @players.each_entry do |player|
    -      print "# #{player.id} ? "
    -      bet = gets.to_i
    -      player.deal_initial_hand Model::Hand.new(bet, [@pack.draw, @pack.draw])
    -    end
    -
    -    @dealer_hand = Model::Hand.new(0, [@pack.draw, @pack.draw])
    -    print_players_and_dealer_hands
    -  end
    -
    -  def play_players
    -    @players.each_entry do |player|
    -      play_hand player, player.hand
    -    end
    -  end
    -
    -  def check_for_insurance_bets
    -    return if @dealer_hand.cards[0].label != "A"
    -
    -    print "ANY INSURANCE? "
    -    return if gets.strip != "Y"
    -
    -    @players.each_entry do |player|
    -      print "PLAYER #{player.id} INSURANCE BET? "
    -      player.bet_insurance(gets.to_i)
    -    end
    -  end
    -
    -  def play_dealer
    -    puts "DEALER HAS A \t#{@dealer_hand.cards[1].label} CONCEALED FOR A TOTAL OF #{@dealer_hand.total}"
    -
    -    while @dealer_hand.total(is_dealer: true) < 17
    -      card = @pack.draw
    -      @dealer_hand.hit card
    -
    -      puts "DRAWS #{card.label} \t---TOTAL = #{@dealer_hand.total}"
    -    end
    -
    -    if !@dealer_hand.is_busted?
    -      @dealer_hand.stand
    -    end
    -  end
    -
    -  def settle
    -    @players.each_entry do |player|
    -      player_balance_update = player.update_balance @dealer_hand
    -      @dealer_balance -= player_balance_update
    -
    -      puts "PLAYER #{player.id} #{player_balance_update < 0 ? "LOSES" : "WINS"} \t#{player_balance_update} \tTOTAL=#{player.balance}"
    -    end
    -
    -    puts "DEALER'S TOTAL = #{@dealer_balance}"
    -  end
    -
    -
    -  def print_players_and_dealer_hands
    -    puts "PLAYER\t#{@players.map(&:id).join("\t")}\tDEALER"
    -    puts "      \t#{@players.map {|p| p.hand.cards[0].label}.join("\t")}\t#{@dealer_hand.cards[0].label}"
    -    puts "      \t#{@players.map {|p| p.hand.cards[1].label}.join("\t")}"
    -  end
    -
    -  def play_hand player, hand
    -    allowed_actions = ALLOWED_HAND_ACTIONS[(hand.is_split_hand || !hand.can_split?) ? "split" : "normal"]
    -    name = "PLAYER #{player.id}"
    -    if hand.is_split_hand
    -      name += " - HAND #{hand === player.hand ? 1 : 2}"
    -    end
    -
    -    did_hit = false
    -
    -    while hand.is_playing?
    -      print "#{name}? "
    -
    -      action = gets.strip
    -
    -      if !allowed_actions.include?(action)
    -        puts "Possible actions: #{allowed_actions.join(", ")}"
    -        next
    -      end
    -
    -      if action === "/"
    -        player.split
    -
    -        play_hand player, player.hand
    -        play_hand player, player.split_hand
    -
    -        return
    -      end
    -
    -      if action === "S"
    -        hand.stand
    -      end
    -
    -      if action === "D"
    -        card = @pack.draw
    -        hand.double_down card
    -
    -        puts "RECEIVED #{card.label}"
    -      end
    -
    -      if action === "H"
    -        did_hit = true
    -        allowed_actions = ALLOWED_HAND_ACTIONS["hit"]
    -        card = @pack.draw
    -        hand.hit card
    -
    -        puts "RECEIVED #{card.label}"
    -      end
    -    end
    -
    -    puts "TOTAL IS #{hand.total}"
    -
    -    if hand.is_busted?
    -      puts "... BUSTED"
    -    end
    -  end
    -end
    diff --git a/10_Blackjack/ruby/model/card_kind.rb b/10_Blackjack/ruby/model/card_kind.rb
    deleted file mode 100644
    index 0be340ce0..000000000
    --- a/10_Blackjack/ruby/model/card_kind.rb
    +++ /dev/null
    @@ -1,41 +0,0 @@
    -module Model
    -class CardKind
    -  def initialize(label, value)
    -    @label = label
    -    @value = value
    -  end
    -  
    -  private_class_method :new
    -
    -  TWO = self.new("2", 2)
    -  THREE = self.new("3", 3)
    -  FOUR = self.new("4", 4)
    -  FIVE = self.new("5", 5)
    -  SIX = self.new("6", 6)
    -  SEVEN = self.new("7", 7)
    -  EIGHT = self.new("8", 8)
    -  NINE = self.new("9", 9)
    -  TEN = self.new("10", 10)
    -  JACK = self.new("J", 10)
    -  QUEEN = self.new("Q", 10)
    -  KING = self.new("K", 10)
    -  ACE = self.new("A", 11)
    -
    -  KINDS_SET = [
    -    TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN,
    -    JACK, QUEEN, KING, ACE
    -  ]
    -
    -  def same_value?(other_card)
    -    value == other_card.value
    -  end
    -
    -  def +(other)
    -    throw "other doesn't respond to +" unless other.responds_to? :+
    -
    -    other.+(@value)
    -  end 
    -
    -  attr_reader :label, :value
    -end
    -end
    diff --git a/10_Blackjack/ruby/model/hand.rb b/10_Blackjack/ruby/model/hand.rb
    deleted file mode 100644
    index e52052cf6..000000000
    --- a/10_Blackjack/ruby/model/hand.rb
    +++ /dev/null
    @@ -1,97 +0,0 @@
    -require_relative "./card_kind.rb"
    -
    -module Model
    -class Hand
    -  HAND_STATE_PLAYING = :hand_playing
    -  HAND_STATE_BUSTED = :hand_busted
    -  HAND_STATE_STAND = :hand_stand
    -  HAND_STATE_DOUBLED_DOWN = :hand_doubled_down
    -
    -  def initialize(bet, cards, is_split_hand: false)
    -    @state = HAND_STATE_PLAYING
    -    @bet = bet
    -    @cards = cards
    -    @total = nil
    -    @is_split_hand = is_split_hand
    -  end
    -
    -  attr_reader :bet, :cards, :is_split_hand
    -
    -  def is_playing?
    -    @state == HAND_STATE_PLAYING
    -  end
    -
    -  def is_busted?
    -    @state == HAND_STATE_BUSTED
    -  end
    -
    -  def is_standing?
    -    @state == HAND_STATE_STAND
    -  end
    -
    -  def is_blackjack?
    -    total == 21 && @cards.length == 2
    -  end
    -
    -  def total(is_dealer: false)
    -    return @total unless @total.nil?
    -    
    -    @total = @cards.reduce(0) {|sum, card| sum + card.value}
    -
    -    if @total > 21
    -      aces_count = @cards.count {|c| c == CardKind::ACE}
    -      while ((!is_dealer && @total > 21) || (is_dealer && @total < 16)) && aces_count > 0 do
    -        @total -= 10
    -        aces_count -= 1
    -      end
    -    end
    -
    -    @total
    -  end
    -
    -  ## Hand actions
    -
    -  def can_split?
    -    not @is_split_hand and @cards.length == 2 && @cards[0].same_value?(cards[1])
    -  end
    -
    -  def split
    -    throw "can't split" unless can_split?
    -    [
    -      Hand.new(@bet, @cards[0...1], is_split_hand: true),
    -      Hand.new(@bet, @cards[1..1], is_split_hand: true)
    -    ]
    -  end
    -
    -  def hit(card)
    -    throw "can't hit" unless is_playing?
    -
    -    @cards.push(card)
    -    @total = nil
    -
    -    check_busted
    -  end
    -
    -  def double_down(card)
    -    throw "can't double down" unless is_playing?
    -
    -    @bet *= 2
    -    hit card
    -
    -    @state = HAND_STATE_DOUBLED_DOWN
    -  end
    -
    -  def stand
    -    throw "can't stand" unless is_playing?
    -
    -    @state = HAND_STATE_STAND
    -  end
    -
    -
    -  private
    -
    -  def check_busted
    -    @state = HAND_STATE_BUSTED if total > 21
    -  end
    -end
    -end
    diff --git a/10_Blackjack/ruby/model/pack.rb b/10_Blackjack/ruby/model/pack.rb
    deleted file mode 100644
    index 20c0f227f..000000000
    --- a/10_Blackjack/ruby/model/pack.rb
    +++ /dev/null
    @@ -1,28 +0,0 @@
    -require_relative "./card_kind.rb"
    -
    -module Model
    -class Pack
    -  def initialize
    -    @cards = []
    -    reshuffle
    -  end
    -
    -  def reshuffle_if_necessary
    -    return if @cards.count > 2
    -    reshuffle
    -  end
    -
    -  def draw
    -    reshuffle_if_necessary
    -    @cards.pop
    -  end
    -
    -  private
    -
    -  def reshuffle
    -    puts "RESHUFFLING"
    -    @cards = 4.times.map {|_| CardKind::KINDS_SET}.flatten
    -    @cards.shuffle!
    -  end
    -end
    -end
    diff --git a/10_Blackjack/ruby/model/player.rb b/10_Blackjack/ruby/model/player.rb
    deleted file mode 100644
    index 134cf2dc4..000000000
    --- a/10_Blackjack/ruby/model/player.rb
    +++ /dev/null
    @@ -1,89 +0,0 @@
    -require_relative "./hand.rb"
    -
    -module Model
    -class Player
    -  def initialize(id)
    -    @id = id
    -    @balance = 0
    -    @original_bet = 0
    -    @insurance = 0
    -
    -    @hand = nil
    -    @split_hand = nil
    -  end
    -
    -  attr_reader :id, :balance, :hand, :split_hand, :insurance
    -
    -  ## Begining of hand dealing actions
    -  def deal_initial_hand(hand)
    -    @hand = hand
    -    @split_hand = nil
    -    @max_insurance = @hand.bet / 2
    -    @insurance = 0
    -  end
    -
    -  def has_split_hand?
    -    !@split_hand.nil?
    -  end
    -
    -  def can_split?
    -    not has_split_hand? and @hand.can_split?
    -  end
    -
    -  def split
    -    throw "can't split" unless can_split?
    -
    -    @hand, @split_hand = @hand.split
    -  end
    -
    -  def bet_insurance(bet)
    -    if bet < 0
    -      bet = 0
    -      puts "NEGATIVE BET -- using 0 insurance bet"
    -    end
    -
    -    if bet > @max_insurance
    -      bet = @max_insurance
    -      puts "TOO HIGH -- using max insurance bet of #{bet}"
    -    end
    -
    -    @insurance = bet
    -  end
    -
    -  ## End of hand dealing actions
    -
    -  def update_balance(dealer_hand)
    -    balance_update = 0
    -
    -    balance_update += get_balance_update(@hand, dealer_hand)
    -    if has_split_hand? then
    -      balance_update += get_balance_update(@split_hand, dealer_hand)
    -    end
    -
    -    if dealer_hand.is_blackjack?
    -      balance_update += 2 * @insurance
    -    else
    -      balance_update -= @insurance
    -    end
    -
    -    @balance += balance_update
    -
    -    balance_update
    -  end
    -
    -
    -  private
    -
    -  def get_balance_update(hand, dealer_hand)
    -    if hand.is_busted?
    -      return -hand.bet
    -    elsif dealer_hand.is_busted?
    -      return hand.bet
    -    elsif dealer_hand.total == hand.total
    -      return 0
    -    else
    -      return (dealer_hand.total < hand.total ? 1 : -1) * hand.bet
    -    end
    -  end
    -end
    -end
    diff --git a/10_Blackjack/rust/Cargo.lock b/10_Blackjack/rust/Cargo.lock
    deleted file mode 100644
    index 4fe2abbea..000000000
    --- a/10_Blackjack/rust/Cargo.lock
    +++ /dev/null
    @@ -1,75 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.10"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.147"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/10_Blackjack/rust/Cargo.toml b/10_Blackjack/rust/Cargo.toml
    deleted file mode 100644
    index 3b1d02f52..000000000
    --- a/10_Blackjack/rust/Cargo.toml
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -[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/10_Blackjack/rust/README.md b/10_Blackjack/rust/README.md
    deleted file mode 100644
    index 7e85f9a15..000000000
    --- a/10_Blackjack/rust/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Rust](https://www.rust-lang.org/) by Anthony Rubick [AnthonyMichaelTDM](https://github.com/AnthonyMichaelTDM)
    diff --git a/10_Blackjack/rust/src/main.rs b/10_Blackjack/rust/src/main.rs
    deleted file mode 100644
    index e649f3562..000000000
    --- a/10_Blackjack/rust/src/main.rs
    +++ /dev/null
    @@ -1,634 +0,0 @@
    -use rand::{prelude::{thread_rng, SliceRandom}};
    -use std::{io, io::{stdout, Write}};
    -
    -/**
    - * todo list:
    - *
    - * allow splitting
    - */
    -
    -
    -//DATA
    -//enums
    -enum PlayerType {
    -    Player,
    -    Dealer,
    -}
    -impl ToString for PlayerType {
    -    fn to_string(&self) -> String {
    -        match self {
    -            &PlayerType::Dealer => return String::from("Dealer"),
    -            &PlayerType::Player => return String::from("Player"),
    -        }
    -    }
    -}
    -enum Play {
    -    Stand,
    -    Hit,
    -    DoubleDown,
    -    Split,
    -}
    -impl ToString for Play {
    -    fn to_string(&self) -> String {
    -        match self {
    -            &Play::Hit => return String::from("Hit"),
    -            &Play::Stand => return String::from("Stand"),
    -            &Play::DoubleDown => return String::from("Double Down"),
    -            &Play::Split => return String::from("Split")
    -        }
    -    }
    -}
    -//structs
    -struct CARD<'a> {
    -    name: &'a str,
    -    value: u8,
    -}
    -impl<'a> CARD<'a> {
    -    /**
    -     * creates a new card from the passed card name
    -     */
    -    fn new(card_name: &str) -> CARD {
    -        return CARD { name: card_name, value: CARD::determine_value_from_name(card_name) };
    -    }
    -
    -    /**
    -     * returns the value associated with a card with the passed name
    -     * return 0 if the passed card name doesn't exist
    -     */
    -    fn determine_value_from_name(card_name: &str) -> u8 {
    -        //DATA
    -        let value:u8;
    -
    -        match card_name.to_ascii_uppercase().as_str() {
    -            "ACE" => value = 11,
    -            "2" => value = 2,
    -            "3" => value = 3,
    -            "4" => value = 4,
    -            "5" => value = 5,
    -            "6" => value = 6,
    -            "7" => value = 7,
    -            "8" => value = 8,
    -            "9" => value = 9,
    -            "10" => value = 10,
    -            "JACK" => value = 10,
    -            "QUEEN" => value = 10,
    -            "KING" => value = 10,
    -            _ => value = 0,
    -        }
    -
    -        return value;
    -    }
    -}
    -struct HAND<'a> {
    -    cards: Vec>,
    -}
    -impl<'a> HAND<'a> {
    -    /**
    -     * returns a new empty hand
    -     */
    -    fn new() -> HAND<'a> {
    -        return HAND { cards: Vec::new()};
    -    }
    -
    -    /**
    -     * add a passed card to this hand
    -     */
    -    fn add_card(&mut self, card: CARD<'a>) {
    -        self.cards.push(card);
    -    }
    -
    -    /**
    -     * returns the total points of the cards in this hand
    -     */
    -    fn get_total(&self) -> usize {
    -        let mut total:usize = 0;
    -        for card in &self.cards {
    -            total += card.value as usize;
    -        }
    -
    -        //if there is an ACE, and the hand would otherwise bust, treat the ace like it's worth 1
    -        if total > 21 && self.cards.iter().any(|c| -> bool {*c.name == *"ACE"}) {
    -            total -= 10;
    -        }
    -
    -        return total;
    -    }
    -
    -    /**
    -     * adds the cards in hand into the discard pile
    -     */
    -    fn discard_hand(&mut self, deck: &mut DECKS<'a>) {
    -        let len = self.cards.len();
    -        for _i in 0..len {
    -            deck.discard_pile.push(self.cards.pop().expect("hand empty"));
    -        }
    -    }
    -}
    -struct DECKS<'a> {
    -    deck: Vec>, //cards in the deck
    -    discard_pile: Vec> //decks discard pile
    -}
    -impl<'a> DECKS<'a> {
    -    /**
    -     * creates a new full and shuffled deck, and an empty discard pile
    -     */
    -    fn new() -> DECKS<'a> {
    -        //returns a number of full decks of 52 cards, shuffles them
    -        //DATA
    -        let mut deck = DECKS{deck: Vec::new(), discard_pile: Vec::new()};
    -        let number_of_decks = 3;
    -
    -        //fill deck
    -        for _n in 0..number_of_decks { //fill deck with number_of_decks decks worth of cards
    -            for card_name in CARD_NAMES { //add 4 of each card, totaling one deck with 4 of each card
    -                deck.deck.push( CARD::new(card_name) );
    -                deck.deck.push( CARD::new(card_name) );
    -                deck.deck.push( CARD::new(card_name) );
    -                deck.deck.push( CARD::new(card_name) );
    -            }
    -        }
    -
    -        //shuffle deck
    -        deck.shuffle();
    -
    -        //return deck
    -        return deck;
    -    }
    -
    -    /**
    -     * shuffles the deck
    -     */
    -    fn shuffle(&mut self) {
    -        self.deck.shuffle(&mut thread_rng());
    -    }
    -
    -    /**
    -     * draw card from deck, and return it
    -     * if deck is empty, shuffles discard pile into it and tries again
    -     */
    -    fn draw_card(&mut self) -> CARD<'a> {
    -        match self.deck.pop() {
    -            Some(card) => return card,
    -            None => {
    -                let len = self.discard_pile.len();
    -
    -                if len > 0 {//deck is empty, shuffle discard pile into deck and try again
    -                    println!("deck is empty, shuffling");
    -                    for _i in 0..len {
    -                        self.deck.push( self.discard_pile.pop().expect("discard pile empty") )
    -                    }
    -                    self.shuffle();
    -                    return self.draw_card();
    -                } else { //discard pile and deck are empty, should never happen
    -                    panic!("discard pile empty");
    -                }
    -            }
    -        }
    -    }
    -}
    -
    -struct PLAYER<'a> {
    -    hand: HAND<'a>,
    -    balance: usize,
    -    bet: usize,
    -    wins: usize,
    -    player_type: PlayerType,
    -    index: usize,
    -
    -}
    -impl<'a> PLAYER<'a> {
    -    /**
    -     * creates a new player of the given type
    -     */
    -    fn new(player_type: PlayerType, index: usize) -> PLAYER<'a> {
    -        return PLAYER { hand: HAND::new(), balance: STARTING_BALANCE, bet: 0, wins: 0, player_type: player_type, index: index};
    -    }
    -
    -    fn get_name(&self) -> String {
    -        format!("{}{}", self.player_type.to_string(),self.index)
    -    }
    -
    -    /**
    -     * gets a bet from the player
    -     */
    -    fn get_bet(&mut self) {
    -        if let PlayerType::Player = self.player_type {
    -            if self.balance < 1 {
    -                println!("{} is out of money :(", self.get_name());
    -                self.bet = 0;
    -            }
    -            self.bet = get_number_from_user_input(format!("{}\tBet?",self.get_name()).as_str(), 1, self.balance);
    -        }
    -    }
    -
    -    /**
    -     * returns a string of the players hand
    -     *
    -     * if player is a dealer, returns the first card in the hand followed by *'s for every other card
    -     * if player is a player, returns every card and the total
    -     */
    -    fn hand_as_string(&self, hide_dealer:bool) -> String {
    -        if !hide_dealer {
    -            return format!(
    -                "{}\n\ttotal points = {}", //message
    -                { //cards in hand
    -                    let mut s:String = String::new();
    -                    for cards_in_hand in self.hand.cards.iter().rev() {
    -                        s += format!("{}\t", cards_in_hand.name).as_str();
    -                    }
    -                    s
    -                },
    -                self.hand.get_total() //total points in hand
    -            );
    -        }
    -        else {
    -            match &self.player_type {
    -                &PlayerType::Dealer =>  { //if this is a dealer
    -                    return format!(
    -                        "{}*",//message
    -                        { //*'s for other cards
    -                            let mut s:String = String::new();
    -                            let mut cards_in_hand = self.hand.cards.iter();
    -                            cards_in_hand.next();//consume first card drawn
    -                            for c in cards_in_hand.rev() {
    -                                s += format!("{}\t", c.name).as_str();
    -                            }
    -                            s
    -                        }
    -                    );
    -                },
    -                &PlayerType::Player => { //if this is a player
    -                    return format!(
    -                        "{}\n\ttotal points = {}", //message
    -                        { //cards in hand
    -                            let mut s:String = String::new();
    -                            for cards_in_hand in self.hand.cards.iter().rev() {
    -                                s += format!("{}\t", cards_in_hand.name).as_str();
    -                            }
    -                            s
    -                        },
    -                        self.hand.get_total() //total points in hand
    -                    );
    -                }
    -            }
    -        }
    -    }
    -
    -    /**
    -     * get the players 'play'
    -     */
    -    fn get_play(&self) -> Play {
    -        /*
    -         do different things depending on what type of player this is:
    -         if it's a dealer, use an algorithm to determine the play
    -         if it's a player, ask user for input
    -         */
    -        match &self.player_type {
    -            &PlayerType::Dealer => {
    -                if self.hand.get_total() > 16 { // if total value of hand is greater than 16, stand
    -                    return Play::Stand;
    -                } else { //otherwise hit
    -                    return Play::Hit;
    -                }
    -            },
    -            &PlayerType::Player => {
    -                let valid_results:Vec;
    -                if self.hand.cards.len() > 2 {//if there are more than 2 cards in the hand, at least one turn has happened, so splitting and doubling down are not allowed
    -                    valid_results = vec!['s','S','h','H'];
    -                } else {
    -                    valid_results = vec!['s','S','h','H','d','D','/'];
    -                }
    -                let play = get_char_from_user_input("\tWhat is your play?", &valid_results);
    -                match play {
    -                    's' | 'S' => return Play::Stand,
    -                    'h' | 'H' => return Play::Hit,
    -                    'd' | 'D' => return Play::DoubleDown,
    -                    '/'       => return Play::Split,
    -                    _ => panic!("get_char_from_user_input() returned invalid character"),
    -                }
    -            },
    -        }
    -    }
    -}
    -
    -struct GAME<'a> {
    -    players: Vec>, //last item in this is the dealer
    -    decks: DECKS<'a>,
    -    games_played:usize,
    -}
    -impl<'a> GAME<'a> {
    -    /**
    -     * creates a new game
    -     */
    -    fn new(num_players:usize) -> GAME<'a> {
    -        //DATA
    -        let mut players: Vec = Vec::new();
    -
    -        //add dealer
    -        players.push(PLAYER::new(PlayerType::Dealer,0));
    -        //create human player(s) (at least one)
    -        players.push(PLAYER::new(PlayerType::Player,1));
    -        for i in 2..=num_players { //one less than num_players players
    -            players.push(PLAYER::new(PlayerType::Player,i));
    -        }
    -
    -        //ask if they want instructions
    -        if let 'y'|'Y' = get_char_from_user_input("Do you want instructions? (y/n)", &vec!['y','Y','n','N']) {
    -            instructions();
    -        }
    -        println!();
    -
    -        //return a game
    -        return GAME { players: players, decks: DECKS::new(), games_played: 0}
    -    }
    -
    -    /**
    -     * prints the score of every player
    -     */
    -    fn _print_stats(&self) {
    -        println!("{}", self.stats_as_string());
    -    }
    -
    -    /**
    -     * returns a string of the wins, balance, and bets of every player
    -     */
    -    fn stats_as_string(&self) -> String {
    -        format!("Scores:\n{}",{
    -            let mut s = String::new();
    -            self.players.iter().for_each(|p| {
    -                //format the presentation of player stats
    -                match p.player_type {
    -                    PlayerType::Player => s+= format!("{} Wins:\t{}\t\tBalance:\t{}\t\tBet\t{}\n",p.get_name(),p.wins,p.balance,p.bet).as_str(),
    -                    PlayerType::Dealer => s+= format!("{} Wins:\t{}\n",p.get_name(),p.wins).as_str()
    -                }
    -            });
    -            s
    -        })
    -    }
    -
    -    /**
    -     * plays a round of blackjack
    -     */
    -    fn play_game(&mut self) {
    -        //DATA
    -        let scores;
    -        let game = self.games_played; //save it here so we don't have borrowing issues
    -        let mut player_hands_message: String = String::new();//cache it here so we don't have borrowing issues
    -
    -        //deal cards to each player
    -        for _i in 0..2 { // do this twice
    -            //draw card for each player
    -            self.players.iter_mut().for_each(|player| {player.hand.add_card( self.decks.draw_card() );});
    -        }
    -
    -        //get everyones bets
    -        self.players.iter_mut().for_each(|player| player.get_bet());
    -        scores = self.stats_as_string(); //save it here so we don't have borrowing issues later
    -
    -        //play game for each player
    -        for player in self.players.iter_mut() {
    -            //turn loop, ends when player finishes their turn
    -            loop{
    -                //clear screen
    -                clear();
    -                //print welcome
    -                welcome();
    -                //print game state
    -                println!("\n\t\t\tGame {}", game);
    -                //print scores
    -                println!("{}",scores);
    -                //print hands of all players
    -                print!("{}", player_hands_message);
    -                println!("{} Hand:\t{}", player.get_name(), player.hand_as_string(true));
    -
    -                if let PlayerType::Player = player.player_type { //player isn't the dealer
    -                    if player.bet == 0 {//player is out of money
    -                        break;//exit turn loop
    -                    }
    -                }
    -
    -                //play through turn
    -                //check their hand value for a blackjack(21) or bust
    -                let score = player.hand.get_total();
    -                if score >= 21 {
    -                    if score == 21 { // == 21
    -                        println!("\tBlackjack! (21 points)");
    -                    } else { // > 21
    -                        println!("\tBust      ({} points)", score);
    -                    }
    -                    break; //end turn
    -                }
    -
    -                //get player move
    -                let play = player.get_play();
    -                //process play
    -                match play {
    -                    Play::Stand => {
    -                        println!("\t{}", play.to_string());
    -                        break; //end turn
    -                    },
    -                    Play::Hit => {
    -                        println!("\t{}", play.to_string());
    -                        //give them a card
    -                        player.hand.add_card( self.decks.draw_card() );
    -                    },
    -                    Play::DoubleDown => {
    -                        println!("\t{}", play.to_string());
    -
    -                        //double their balance if there's enough money, othewise go all-in
    -                        if player.bet * 2 < player.balance {
    -                            player.bet *= 2;
    -                        }
    -                        else {
    -                            player.bet = player.balance;
    -                        }
    -                        //give them a card
    -                        player.hand.add_card( self.decks.draw_card() );
    -                    },
    -                    Play::Split => {
    -
    -                    },
    -                }
    -            }
    -
    -            //add player to score cache thing
    -            player_hands_message += format!("{} Hand:\t{}\n", player.get_name(), player.hand_as_string(true)).as_str();
    -        }
    -
    -        //determine winner
    -        let mut top_score = 0; //player with the highest points
    -        let mut num_winners = 1;
    -        for player in self.players.iter_mut().enumerate().filter( |x| -> bool {x.1.hand.get_total()<=21}) { //players_who_didnt_bust
    -            let score = player.1.hand.get_total();
    -            if score > top_score {
    -                top_score = score;
    -                num_winners = 1;
    -            } else if score == top_score {
    -                num_winners += 1;
    -            }
    -        }
    -
    -        //print winner(s)
    -        self.players.iter_mut().filter(|x|->bool{x.hand.get_total()==top_score}).for_each(|x| {//for each player with the top score
    -            print!("{} ", x.get_name());//print name
    -            x.wins += 1;//increment their wins
    -        });
    -        if num_winners > 1 {println!("all tie with {}\n\n\n", top_score);}
    -        else {println!("wins with {}!\n\n\n",top_score);}
    -
    -        //handle bets
    -        //remove money from losers
    -        self.players.iter_mut().filter(|p| p.hand.get_total()!=top_score).for_each( |p| p.balance -= p.bet); //for every player who didn't get the winning score, remove their bet from their balance
    -        //add money to winner
    -        self.players.iter_mut().filter(|p| p.hand.get_total()==top_score).for_each(|p| p.balance += p.bet); //for each player who got the winning score, add their bet to their balance
    -
    -        //discard hands
    -        self.players.iter_mut().for_each(|player| {player.hand.discard_hand(&mut self.decks);});
    -
    -        //increment games_played
    -        self.games_played += 1;
    -    }
    -
    -
    -
    -}
    -
    -const CARD_NAMES: [&str;13] = ["ACE","2","3","4","5","6","7","8","9","10","JACK","QUEEN","KING"];
    -const STARTING_BALANCE: usize = 100;
    -
    -fn main() {
    -    //DATA
    -    let mut game: GAME;
    -
    -    //print welcome message
    -    welcome();
    -
    -    //create game
    -    game = GAME::new( get_number_from_user_input("How many players should there be (at least 1)?", 1, 7) );
    -
    -    //game loop, play game until user wants to stop
    -    loop {
    -        //play round
    -        game.play_game();
    -
    -        //ask if they want to play again
    -        match get_char_from_user_input("Play Again? (y/n)", &vec!['y','Y','n','N']) {
    -            'y' | 'Y' => continue,
    -            'n' | 'N' => break,
    -            _ => break,
    -        }
    -    }
    -}
    -
    -/**
    - * prints the welcome screen
    - */
    -fn welcome() {
    -    //welcome message
    -    print!("
    -                            BLACK JACK
    -              CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY
    -    \n\n");
    -}
    -
    -/**
    - * prints the instructions
    - */
    -fn instructions() {
    -    println!("
    -    THIS IS THE GAME OF 21. AS MANY AS 7 PLAYERS MAY PLAY THE
    -    GAME. ON EACH DEAL, BETS WILL BE ASKED FOR, AND THE
    -    PLAYERS' BETS SHOULD BE TYPED IN. THE CARDS WILL THEN BE
    -    DEALT, AND EACH PLAYER IN TURN PLAYS HIS HAND. THE
    -    FIRST RESPONSE SHOULD BE EITHER 'D', INDICATING THAT THE
    -    PLAYER IS DOUBLING DOWN, 'S', INDICATING THAT HE IS
    -    STANDING, 'H', INDICATING HE WANTS ANOTHER CARD, OR '/',
    -    INDICATING THAT HE WANTS TO SPLIT HIS CARDS. AFTER THE
    -    INITIAL RESPONSE, ALL FURTHER RESPONSES SHOULD BE 'S' OR
    -    'H', UNLESS THE CARDS WERE SPLIT, IN WHICH CASE DOUBLING
    -    DOWN IS AGAIN PERMITTED. IN ORDER TO COLLECT FOR
    -    BLACKJACK, THE INITIAL RESPONSE SHOULD BE 'S'.
    -    NUMBER OF PLAYERS
    -
    -    NOTE:'/' (splitting) is not currently implemented, and does nothing
    -
    -    PRESS ENTER TO CONTINUE
    -    ");
    -    io::stdin().read_line(&mut String::new()).expect("Failed to read line");
    -}
    -
    -/**
    - * gets a usize integer from user input
    - */
    -fn get_number_from_user_input(prompt: &str, min:usize, max:usize) -> usize {
    -    //input loop
    -    return loop {
    -        let mut raw_input = String::new(); // temporary variable for user input that can be parsed later
    -
    -        //print prompt
    -        println!("{}", prompt);
    -        stdout().flush().expect("Failed to flush to stdout.");
    -        //read user input from standard input, and store it to raw_input
    -        //raw_input.clear(); //clear input
    -        io::stdin().read_line(&mut raw_input).expect( "CANNOT READ INPUT!");
    -
    -        //from input, try to read a number
    -        match raw_input.trim().parse::() {
    -            Ok(i) => {
    -                if i < min || i > max { //input out of desired range
    -                    println!("INPUT OUT OF VALID RANGE.  TRY AGAIN.  {}-{}",min,max);
    -                    continue; // run the loop again
    -                }
    -                else {
    -                    break i;// this escapes the loop, returning i
    -                }
    -            },
    -            Err(e) => {
    -                println!("INVALID INPUT.  TRY AGAIN.  {}", e.to_string().to_uppercase());
    -                continue; // run the loop again
    -            }
    -        };
    -    };
    -}
    -
    -/**
    - * gets a character from user input
    - * returns the first character they type
    - */
    -fn get_char_from_user_input(prompt: &str, valid_results: &Vec) -> char {
    -    //input loop
    -    return loop {
    -        let mut raw_input = String::new(); // temporary variable for user input that can be parsed later
    -
    -        //print prompt
    -        println!("{}", prompt);
    -        stdout().flush().expect("Failed to flush to stdout.");
    -        //read user input from standard input, and store it to raw_input
    -        //raw_input.clear(); //clear input
    -        io::stdin().read_line(&mut raw_input).expect( "CANNOT READ INPUT!");
    -
    -        //from input, try to read a valid character
    -        match raw_input.trim().chars().nth(0) {
    -            Some(i) => {
    -                if !valid_results.contains(&i) { //input out of desired range
    -                    println!("INPUT IS NOT VALID CHARACTER.  TRY AGAIN.");
    -                    continue; // run the loop again
    -                }
    -                else {
    -                    break i;// this escapes the loop, returning i
    -                }
    -            },
    -            None => {
    -                println!("INVALID INPUT.  TRY AGAIN.");
    -                continue; // run the loop again
    -            }
    -        };
    -    };
    -}
    -
    -/**
    - * clear std out
    - */
    -fn clear() {
    -    println!("\x1b[2J\x1b[0;0H");
    -}
    diff --git a/10_Blackjack/vbnet/Blackjack.sln b/10_Blackjack/vbnet/Blackjack.sln
    deleted file mode 100644
    index 2610b4a73..000000000
    --- a/10_Blackjack/vbnet/Blackjack.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index bc1d8eed3..000000000
    --- a/10_Blackjack/vbnet/Blackjack.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Blackjack
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/11_Bombardment/README.md b/11_Bombardment/README.md
    index d4bd08d74..4ab31b054 100644
    --- a/11_Bombardment/README.md
    +++ b/11_Bombardment/README.md
    @@ -2,7 +2,7 @@
     
     BOMBARDMENT is played on two, 5x5 grids or boards with 25 outpost locations numbered 1 to 25. Both you and the computer have four platoons of troops that can be located at any four outposts on your respective grids.
     
    -At the start of the game, you locate (or hide) your four platoons on your grid. The computer does the same on its grid. You then take turns firing missiles or bombs at each other’s outposts trying to destroy all four platoons. The one who finds all four opponents’ platoons first, wins.
    +At the start of the game, you locate (or hide) your four platoons on your grid. The computer does the same on it’s grid. You then take turns firing missiles or bombs at each other’s outposts trying to destroy all four platoons. The one who finds all four opponents’ platoons first, wins.
     
     This program was slightly modified from the original written by Martin Burdash of Parlin, New Jersey.
     
    @@ -14,13 +14,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Known Bugs
    -
    -- Though the instructions say you can't place two platoons on the same outpost, the code does not enforce this.  So the player can "cheat" and guarantee a win by entering the same outpost number two or more times.
    -
    -#### Porting Notes
    -
    -- To ensure the instructions don't scroll off the top of the screen, we may want to insert a "(Press Return)" or similar prompt before printing the tear-off matrix.
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/11_Bombardment/csharp/Bombardment.cs b/11_Bombardment/csharp/Bombardment.cs
    index dcaeb86e7..bcbdcc261 100644
    --- a/11_Bombardment/csharp/Bombardment.cs
    +++ b/11_Bombardment/csharp/Bombardment.cs
    @@ -18,7 +18,7 @@ internal class Bombardment
             private List computerPositions = new List();
             private List playerPositions = new List();
             private List computerGuesses = new List();
    -
    +        
             private void PrintStartingMessage()
             {
                 Console.WriteLine("{0}BOMBARDMENT", new string(' ', 33));
    @@ -26,7 +26,7 @@ private void PrintStartingMessage()
                 Console.WriteLine();
                 Console.WriteLine();
                 Console.WriteLine();
    -
    +        
                 Console.WriteLine("YOU ARE ON A BATTLEFIELD WITH 4 PLATOONS AND YOU");
                 Console.WriteLine("HAVE 25 OUTPOSTS AVAILABLE WHERE THEY MAY BE PLACED.");
                 Console.WriteLine("YOU CAN ONLY PLACE ONE PLATOON AT ANY ONE OUTPOST.");
    @@ -51,9 +51,9 @@ private void PrintStartingMessage()
                 {
                     // The token replacement can be padded by using the format {tokenPosition, padding}
                     // Negative values for the padding cause the output to be left-aligned.
    -                Console.WriteLine("{0,-3}{1,-3}{2,-3}{3,-3}{4,-3}", i, i + 1, i + 2, i + 3, i + 4);
    +                Console.WriteLine("{0,-3}{1,-3}{2,-3}{3,-3}{4,-3}", i, i + 1, i + 2, i + 3, i + 4);                
                 }
    -
    +            
                 Console.WriteLine("\n");
             }
     
    diff --git a/11_Bombardment/csharp/Bombardment.sln b/11_Bombardment/csharp/Bombardment.sln
    deleted file mode 100644
    index a401c67e1..000000000
    --- a/11_Bombardment/csharp/Bombardment.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/java/src/Bombardment.java b/11_Bombardment/java/src/Bombardment.java
    index 1657913c2..1dede841c 100644
    --- a/11_Bombardment/java/src/Bombardment.java
    +++ b/11_Bombardment/java/src/Bombardment.java
    @@ -366,4 +366,4 @@ private int randomNumber() {
             return (int) (Math.random()
                     * (MAX_GRID_SIZE) + 1);
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/11_Bombardment/javascript/bombardment.html b/11_Bombardment/javascript/bombardment.html
    index 455cbb514..5255cdd9f 100644
    --- a/11_Bombardment/javascript/bombardment.html
    +++ b/11_Bombardment/javascript/bombardment.html
    @@ -1,10 +1,9 @@
     
     
     BOMBARDMENT
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/11_Bombardment/javascript/bombardment.js b/11_Bombardment/javascript/bombardment.js
    index 6db01df20..3cd0a5d7d 100644
    --- a/11_Bombardment/javascript/bombardment.js
    +++ b/11_Bombardment/javascript/bombardment.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    @@ -103,7 +103,7 @@ async function main()
                 y = parseInt(await input());
             } while (y < 0 || y > 25) ;
             if (y == c || y == d || y == e || y == f) {
    -
    +            
                 // The original game has a bug. You can shoot the same outpost
                 // several times. This solves it.
                 if (y == c)
    diff --git a/11_Bombardment/kotlin/README.md b/11_Bombardment/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/11_Bombardment/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/11_Bombardment/lua/README.md b/11_Bombardment/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/11_Bombardment/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/11_Bombardment/pascal/README.md b/11_Bombardment/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/11_Bombardment/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/11_Bombardment/perl/bombardment.pl b/11_Bombardment/perl/bombardment.pl
    index 158c34938..0641102e2 100644
    --- a/11_Bombardment/perl/bombardment.pl
    +++ b/11_Bombardment/perl/bombardment.pl
    @@ -54,7 +54,7 @@ sub computer_turn {
     				else {
     					print "YOU'RE DEAD. YOUR LAST OUTPOST WAS AT $target. HA, HA, HA.\nBETTER LUCK NEXT TIME\n";
     				}
    -
    +				
     			}
     			else {
     				print "I MISSED YOU, YOU DIRTY RAT. I PICKED $target. YOUR TURN:\n";
    diff --git a/11_Bombardment/python/bombardment.py b/11_Bombardment/python/bombardment.py
    index b125987aa..a16113e79 100755
    --- a/11_Bombardment/python/bombardment.py
    +++ b/11_Bombardment/python/bombardment.py
    @@ -1,12 +1,10 @@
     #!/usr/bin/env python3
     import random
     from functools import partial
    -from typing import Callable, List, Set
     
    -
    -def print_intro() -> None:
    -    print(" " * 33 + "BOMBARDMENT")
    -    print(" " * 15 + " CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
    +def display_intro():
    +    print("" * 33 + "BOMBARDMENT")
    +    print("" * 15 + " CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
         print("\n\n")
         print("YOU ARE ON A BATTLEFIELD WITH 4 PLATOONS AND YOU")
         print("HAVE 25 OUTPOSTS AVAILABLE WHERE THEY MAY BE PLACED.")
    @@ -24,45 +22,47 @@ def print_intro() -> None:
         print("\n" * 4)
     
     
    -def display_field() -> None:
    +def display_field():
         for row in range(5):
             initial = row * 5 + 1
    -        print("\t".join([str(initial + column) for column in range(5)]))
    +        print('\t'.join([str(initial + column) for column in range(5)]))
    +
         print("\n" * 9)
     
     
    -def positions_list() -> List[int]:
    +def positions_list():
         return list(range(1, 26, 1))
     
     
    -def generate_enemy_positions() -> Set[int]:
    -    """Randomly choose 4 'positions' out of a range of 1 to 25"""
    +def generate_enemy_positions():
    +    """ Randomly choose 4 'positions' out of a range of 1 to 25 """
         positions = positions_list()
         random.shuffle(positions)
         return set(positions[:4])
     
     
    -def is_valid_position(pos: int) -> bool:
    +def is_valid_position(pos):
         return pos in positions_list()
     
     
    -def prompt_for_player_positions() -> Set[int]:
    +def prompt_for_player_positions():
    +
         while True:
             raw_positions = input("WHAT ARE YOUR FOUR POSITIONS? ")
    -        positions = {int(pos) for pos in raw_positions.split()}
    +        positions = set(int(pos) for pos in raw_positions.split())
             # Verify user inputs (for example, if the player gives a
             # a position for 26, the enemy can never hit it)
    -        if len(positions) != 4:
    +        if (len(positions) != 4):
                 print("PLEASE ENTER 4 UNIQUE POSITIONS\n")
                 continue
    -        elif any(not is_valid_position(pos) for pos in positions):
    +        elif (any(not is_valid_position(pos) for pos in positions)):
                 print("ALL POSITIONS MUST RANGE (1-25)\n")
                 continue
             else:
                 return positions
     
     
    -def prompt_player_for_target() -> int:
    +def prompt_player_for_target():
     
         while True:
             target = int(input("WHERE DO YOU WISH TO FIRE YOUR MISSLE? "))
    @@ -73,14 +73,8 @@ def prompt_player_for_target() -> int:
             return target
     
     
    -def attack(
    -    target: int,
    -    positions: Set[int],
    -    hit_message: str,
    -    miss_message: str,
    -    progress_messages: str,
    -) -> bool:
    -    """Performs attack procedure returning True if we are to continue."""
    +def attack(target, positions, hit_message, miss_message, progress_messages):
    +    """ Performs attack procedure returning True if we are to continue. """
     
         if target in positions:
             print(hit_message.format(target))
    @@ -92,19 +86,16 @@ def attack(
         return len(positions) > 0
     
     
    -def init_enemy() -> Callable[[], int]:
    -    """
    -    Return a closure analogous to prompt_player_for_target.
    -
    -    Will choose from a unique sequence of positions to avoid picking the
    -    same position twice.
    -    """
    +def init_enemy():
    +    """ Returns a closure analogous to prompt_player_for_target. Will
    +        choose from a unique sequence of positions to avoid picking the
    +        same position twice. """
     
         position_sequence = positions_list()
         random.shuffle(position_sequence)
         position = iter(position_sequence)
     
    -    def choose() -> int:
    +    def choose():
             return next(position)
     
         return choose
    @@ -112,53 +103,49 @@ def choose() -> int:
     
     # Messages correspond to outposts remaining (3, 2, 1, 0)
     PLAYER_PROGRESS_MESSAGES = (
    -    "YOU GOT ME, I'M GOING FAST. BUT I'LL GET YOU WHEN\nMY TRANSISTO&S RECUP%RA*E!",
    +    "YOU GOT ME, I'M GOING FAST. BUT I'LL GET YOU WHEN\n"
    +    "MY TRANSISTO&S RECUP%RA*E!",
         "THREE DOWN, ONE TO GO.\n\n",
         "TWO DOWN, TWO TO GO.\n\n",
    -    "ONE DOWN, THREE TO GO.\n\n",
    -)
    +    "ONE DOWN, THREE TO GO.\n\n"
    +    )
     
     
     ENEMY_PROGRESS_MESSAGES = (
    -    "YOU'RE DEAD. YOUR LAST OUTPOST WAS AT {}. HA, HA, HA.\nBETTER LUCK NEXT TIME.",
    +    "YOU'RE DEAD. YOUR LAST OUTPOST WAS AT {}. HA, HA, HA.\n"
    +    "BETTER LUCK NEXT TIME.",
         "YOU HAVE ONLY ONE OUTPOST LEFT.\n\n",
         "YOU HAVE ONLY TWO OUTPOSTS LEFT.\n\n",
         "YOU HAVE ONLY THREE OUTPOSTS LEFT.\n\n",
    -)
    +    )
     
     
    -def main() -> None:
    -    print_intro()
    +def play():
    +    display_intro()
         display_field()
     
         enemy_positions = generate_enemy_positions()
         player_positions = prompt_for_player_positions()
     
         # Build partial functions only requiring the target as input
    -    player_attacks = partial(
    -        attack,
    -        positions=enemy_positions,
    -        hit_message="YOU GOT ONE OF MY OUTPOSTS!",
    -        miss_message="HA, HA YOU MISSED. MY TURN NOW:\n\n",
    -        progress_messages=PLAYER_PROGRESS_MESSAGES,
    -    )
    -
    -    enemy_attacks = partial(
    -        attack,
    -        positions=player_positions,
    -        hit_message="I GOT YOU. IT WON'T BE LONG NOW. POST {} WAS HIT.",
    -        miss_message="I MISSED YOU, YOU DIRTY RAT. I PICKED {}. YOUR TURN:\n\n",
    -        progress_messages=ENEMY_PROGRESS_MESSAGES,
    -    )
    +    player_attacks = partial(attack,
    +                             positions=enemy_positions,
    +                             hit_message="YOU GOT ONE OF MY OUTPOSTS!",
    +                             miss_message="HA, HA YOU MISSED. MY TURN NOW:\n\n",
    +                             progress_messages=PLAYER_PROGRESS_MESSAGES)
    +
    +    enemy_attacks = partial(attack,
    +                            positions=player_positions,
    +                            hit_message="I GOT YOU. IT WON'T BE LONG NOW. POST {} WAS HIT.",
    +                            miss_message="I MISSED YOU, YOU DIRTY RAT. I PICKED {}. YOUR TURN:\n\n",
    +                            progress_messages=ENEMY_PROGRESS_MESSAGES)
     
         enemy_position_choice = init_enemy()
     
         # Play as long as both player_attacks and enemy_attacks allow to continue
    -    while player_attacks(prompt_player_for_target()) and enemy_attacks(
    -        enemy_position_choice()
    -    ):
    +    while player_attacks(prompt_player_for_target()) and enemy_attacks(enemy_position_choice()):
             pass
     
     
     if __name__ == "__main__":
    -    main()
    +    play()
    diff --git a/11_Bombardment/rust/Cargo.lock b/11_Bombardment/rust/Cargo.lock
    deleted file mode 100644
    index 81365033b..000000000
    --- a/11_Bombardment/rust/Cargo.lock
    +++ /dev/null
    @@ -1,82 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.10"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.147"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
    -
    -[[package]]
    -name = "morristown"
    -version = "0.1.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "f83b191fd96370b91c2925125774011a7a0f69b4db9e2045815e4fd20af725f6"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    -dependencies = [
    - "morristown",
    - "rand",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/11_Bombardment/rust/Cargo.toml b/11_Bombardment/rust/Cargo.toml
    deleted file mode 100644
    index a3c90d23c..000000000
    --- a/11_Bombardment/rust/Cargo.toml
    +++ /dev/null
    @@ -1,10 +0,0 @@
    -[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"
    -morristown = "0.1.4"
    \ No newline at end of file
    diff --git a/11_Bombardment/rust/README.md b/11_Bombardment/rust/README.md
    deleted file mode 100644
    index f1c9749e7..000000000
    --- a/11_Bombardment/rust/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Rust](https://www.rust-lang.org/) by [ugurkupeli](https://github.com/ugurkupeli)
    diff --git a/11_Bombardment/rust/src/main.rs b/11_Bombardment/rust/src/main.rs
    deleted file mode 100644
    index a90c17b35..000000000
    --- a/11_Bombardment/rust/src/main.rs
    +++ /dev/null
    @@ -1,134 +0,0 @@
    -use morristown::PromptMultiOption;
    -use rand::{prelude::SliceRandom, thread_rng};
    -use std::time::Duration;
    -
    -fn main() {
    -    morristown::print_intro("BOMBARDMENT");
    -
    -    println!(
    -        r#"
    -
    -YOU ARE ON A BATTLEFIELD WITH 4 PLATOONS AND YOU
    -HAVE 25 OUTPOSTS AVAILABLE WHERE THEY MAY BE PLACED.
    -YOU CAN ONLY PLACE ONE PLATOON AT ANY ONE OUTPOST.
    -THE COMPUTER DOES THE SAME WITH ITS FOUR PLATOONS.
    -
    -THE OBJECT OF THE GAME IS TO FIRE MISSLES AT THE
    -OUTPOSTS OF THE COMPUTER.  IT WILL DO THE SAME TO YOU.
    -THE ONE WHO DESTROYS ALL FOUR OF THE ENEMY'S PLATOONS
    -FIRST IS THE WINNER.
    -
    -GOOD LUCK... AND TELL US WHERE YOU WANT THE BODIES SENT!
    -
    -TEAR OFF MATRIX AND USE IT TO CHECK OFF THE NUMBERS.
    -
    -
    -"#
    -    );
    -
    -    let mut all_positions = Vec::with_capacity(25);
    -
    -    for i in 1u8..=25 {
    -        all_positions.push(i);
    -
    -        print!("{i}\t");
    -        if (i % 5) == 0 {
    -            println!();
    -        }
    -    }
    -
    -    let mut player_positions = morristown::prompt_multi_number::(
    -        "WHAT ARE YOUR FOUR POSITIONS?\n",
    -        ",",
    -        Some(PromptMultiOption::UnitAmount(4)),
    -        Some(1..=25),
    -    );
    -
    -    let mut rng = thread_rng();
    -
    -    let ai_positions = rand::seq::index::sample(&mut rng, 24, 4).into_vec();
    -    let mut ai_positions: Vec = ai_positions.iter().map(|i| (i + 1) as u8).collect();
    -
    -    loop {
    -        if !player_turn(&mut ai_positions) {
    -            break;
    -        } else if !ai_turn(&mut all_positions, &mut player_positions) {
    -            break;
    -        }
    -    }
    -}
    -
    -fn player_turn(ai_positions: &mut Vec) -> bool {
    -    let player_missile =
    -        morristown::prompt_number_range::("WHERE DO YOU WISH TO FIRE YOUR MISSILE?", 1..=25);
    -
    -    if let Some(index) = ai_positions.iter().position(|p| *p == player_missile) {
    -        ai_positions.remove(index);
    -
    -        let remaining = ai_positions.len();
    -
    -        if remaining > 0 {
    -            let down = 4 - remaining;
    -
    -            println!(
    -                "YOU GOT ONE OF MY OUTPOSTS.\n{} DOWN, {} TO GO\n",
    -                get_text_from_number(down),
    -                get_text_from_number(remaining)
    -            );
    -        } else {
    -            println!(
    -                "YOU GOT ME, I'M GOING FAST. BUT I'LL GET YOU WHEN MY TRANSISTO&S RECUP%RA*E!\n\n"
    -            );
    -            return false;
    -        }
    -    } else {
    -        println!("HA, HA YOU MISSED. MY TURN NOW\n");
    -    }
    -    true
    -}
    -
    -fn ai_turn(all_positions: &mut Vec, player_positions: &mut Vec) -> bool {
    -    std::thread::sleep(Duration::from_secs(1));
    -
    -    let ai_missile = *all_positions
    -        .choose(&mut rand::thread_rng())
    -        .expect("AI RAN OUT OF OPTIONS!");
    -
    -    let index = all_positions
    -        .iter()
    -        .position(|p| p == &ai_missile)
    -        .expect("AI CHOOSE AN INVALID POSITION!");
    -
    -    all_positions.remove(index);
    -
    -    if let Some(index) = player_positions.iter().position(|p| p == &ai_missile) {
    -        player_positions.remove(index);
    -
    -        let remaining = player_positions.len();
    -
    -        if remaining > 0 {
    -            println!("I GOT YOU. IT WON'T BE LONG NOW. POST {ai_missile} WAS HIT.");
    -            println!(
    -                "YOU HAVE ONLY {} OUTPOST LEFT.\n",
    -                get_text_from_number(remaining)
    -            );
    -        } else {
    -            println!("YOU'RE DEAD. YOUR LAST OUTPOST WAS AT {ai_missile} . HA, HA, HA.");
    -            println!("BETTER LUCK NEXT TIME.");
    -            return false;
    -        }
    -    } else {
    -        println!("I MISSED YOU, YOU DIRTY RAT. I PICKED {ai_missile} . YOUR TURN.\n")
    -    }
    -
    -    true
    -}
    -
    -fn get_text_from_number(n: usize) -> &'static str {
    -    match n {
    -        1 => "ONE",
    -        2 => "TWO",
    -        3 => "THREE",
    -        _ => panic!("INVALID INDEX!"),
    -    }
    -}
    diff --git a/11_Bombardment/vbnet/Bombardment.sln b/11_Bombardment/vbnet/Bombardment.sln
    deleted file mode 100644
    index 326fb0001..000000000
    --- a/11_Bombardment/vbnet/Bombardment.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 746887ce2..000000000
    --- a/11_Bombardment/vbnet/Bombardment.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Bombardment
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/12_Bombs_Away/README.md b/12_Bombs_Away/README.md
    index 603516fb1..b1b60277b 100644
    --- a/12_Bombs_Away/README.md
    +++ b/12_Bombs_Away/README.md
    @@ -12,11 +12,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Known Bugs
    -
    -- If you play as Japan and say it is not your first mission, it is impossible to complete your mission; the only possible outcomes are "you made it through" or "boom".  Moreover, the odds of each outcome depend on a variable (R) that is only set if you played a previous mission as a different side.  It's possible this is an intentional layer of complexity meant to encourage repeat play, but it's more likely just a logical error.
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/12_Bombs_Away/bombsaway.bas b/12_Bombs_Away/bombsaway.bas
    index bbf61c8a3..38af3edfc 100644
    --- a/12_Bombs_Away/bombsaway.bas
    +++ b/12_Bombs_Away/bombsaway.bas
    @@ -35,7 +35,7 @@
     280 PRINT
     285 INPUT "HOW MANY MISSIONS HAVE YOU FLOWN";D
     290 IF D<160 THEN 300
    -292 PRINT "MISSIONS, NOT MILES..."
    +292 PRINT "MISSIONS, NOT MILES..." 
     295 PRINT "150 MISSIONS IS HIGH EVEN FOR OLD-TIMERS."
     297 PRINT "NOW THEN, "; : GOTO 285
     300 PRINT:IF D<100 THEN 310
    diff --git a/12_Bombs_Away/csharp/BombsAwayConsole/Program.cs b/12_Bombs_Away/csharp/BombsAwayConsole/Program.cs
    index 04d9fed1a..35728cfcc 100644
    --- a/12_Bombs_Away/csharp/BombsAwayConsole/Program.cs
    +++ b/12_Bombs_Away/csharp/BombsAwayConsole/Program.cs
    @@ -23,3 +23,4 @@ bool UserWantsToPlayAgain(IUserInterface ui)
     
         return result;
     }
    +
    diff --git a/12_Bombs_Away/java/src/BombsAway.java b/12_Bombs_Away/java/src/BombsAway.java
    index 4f43d99bd..290b2c6d2 100644
    --- a/12_Bombs_Away/java/src/BombsAway.java
    +++ b/12_Bombs_Away/java/src/BombsAway.java
    @@ -519,4 +519,4 @@ private double randomNumber(int range) {
             return (Math.random()
                     * (range));
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/12_Bombs_Away/javascript/bombsaway.html b/12_Bombs_Away/javascript/bombsaway.html
    index 1f96c1dce..c58c753f5 100644
    --- a/12_Bombs_Away/javascript/bombsaway.html
    +++ b/12_Bombs_Away/javascript/bombsaway.html
    @@ -1,10 +1,9 @@
     
     
     BOMBARDMENT
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/12_Bombs_Away/javascript/bombsaway.js b/12_Bombs_Away/javascript/bombsaway.js
    index 7fccf55b7..848318566 100644
    --- a/12_Bombs_Away/javascript/bombsaway.js
    +++ b/12_Bombs_Away/javascript/bombsaway.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/12_Bombs_Away/kotlin/README.md b/12_Bombs_Away/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/12_Bombs_Away/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/12_Bombs_Away/lua/README.md b/12_Bombs_Away/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/12_Bombs_Away/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/12_Bombs_Away/lua/bombs_away.lua b/12_Bombs_Away/lua/bombs_away.lua
    deleted file mode 100644
    index 27c857448..000000000
    --- a/12_Bombs_Away/lua/bombs_away.lua
    +++ /dev/null
    @@ -1,211 +0,0 @@
    --- Ported by Brian Wilkins (BrianWilkinsFL)
    --- Influenced by bombsaway.py
    --- Requires: Lua 5.4.x
    -
    -missileHitRate = 0
    -gunsHitRate = 0
    -
    -nanMessage = "Invalid user entry! Please use a number and try again."
    -function has_key(table, key)
    -   return table[key]~=nil
    -end
    -
    -function choice(prompt, table)
    -    resp = getInput(prompt)
    -    while not has_key(table, resp) do
    -       print("TRY AGAIN...")
    -       resp = getInput(prompt)
    -    end
    -    return resp
    -end
    -
    --- reused from Bagels.lua
    -function getInput(prompt)
    -    io.write(prompt)
    -    io.flush()
    -    local input = io.read("l") 
    -    if not input then  --- test for EOF
    -        print("GOODBYE")
    -        os.exit(0)
    -    end
    -    return input
    -end
    -
    -function playerSurvived()
    -    print("YOU MADE IT THROUGH TREMENDOUS FLAK!!")
    -end
    -
    -function playerDeath()
    -    print("* * * * BOOM * * * *")
    -    print("YOU HAVE BEEN SHOT DOWN.....")
    -    print("DEARLY BELOVED, WE ARE GATHERED HERE TODAY TO PAY OUR")
    -    print("LAST TRIBUTE...")
    -end
    -
    --- Enhancement: Partially killed don't count so floor the float
    -function missionSuccess()
    -   print("DIRECT HIT!!!! " .. math.floor(100*math.random()) .. " KILLED.")
    -   print("MISSION SUCCESSFUL.")
    -end
    -
    -function missionFailure()
    -    weapons_choices = {
    -        ["1"] = "GUNS",
    -        ["2"] = "MISSILES",
    -        ["3"] = "BOTH",
    -    }
    -    print("MISSED TARGET BY " .. math.floor(2 + 30 * math.random()) .. " MILES!")
    -    print("NOW YOU'RE REALLY IN FOR IT !!")
    -    print()
    -    enemy_weapons = choice("DOES THE ENEMY HAVE GUNS(1), MISSILES(2), OR BOTH(3)? ", weapons_choices)
    -
    -    if enemy_weapons == "2" or enemy_weapons == "3" then
    -        missileHitRate = 35
    -    end
    -
    -    if enemy_weapons == "2" then
    -       -- gunsHitRate is a reused global variable so
    -       -- its possible that previously selected gunsHitRate
    -       -- will be used here leading to interesting
    -       -- randomness
    -       if missileHitRate+gunsHitRate > 100*math.random() then
    -          playerDeath()
    -       else
    -          playerSurvived()
    -       end
    -    end
    -
    -    if enemy_weapons == "1" or enemy_weapons == "3" then
    -        while true do
    -           resp = getInput("WHAT'S THE PERCENT HIT RATE OF ENEMY GUNNERS (10 TO 50)? ")
    -           if assert(tonumber(resp)) then
    -              gunsHitRate = tonumber(resp)
    -              break
    -           end
    -        end
    -        if gunsHitRate < 10 then
    -           print("YOU LIE, BUT YOU'LL PAY...")
    -           playerDeath()
    -           return
    -        end
    -        if missileHitRate+gunsHitRate > 100*math.random() then
    -           playerDeath()
    -        else
    -           playerSurvived()
    -        end
    -    end
    -end
    -
    --- override assert so Lua doesn't throw an error
    --- and stack trace
    --- We just want the user to enter in a correct value
    -assert = function(truth, message)
    -   if not truth then
    -      print(message)
    -   end
    -   return truth
    -end
    -
    --- Added logic to verify user is actually entering in a number
    -function commence_non_kamikaze_attack()
    -    local numMissions = 0
    -    while numMissions < 160 do
    -       while numMissions == 0 do
    -          resp = getInput("HOW MANY MISSIONS HAVE YOU FLOWN? ")
    -          if assert(tonumber(resp), nanMessage) then
    -             numMissions = tonumber(resp)
    -             break
    -          end
    -       end
    -       if numMissions < 160 then break end
    -
    -       print("MISSIONS, NOT MILES...")
    -       print("150 MISSIONS IS HIGH EVEN FOR OLD-TIMERS.")
    -       print("NOW THEN, ")
    -       numMissions = 0
    -    end
    -
    -    if numMissions >= 100 then
    -       print("THAT'S PUSHING THE ODDS!")
    -    end
    -
    -    if numMissions < 25 then
    -       print("FRESH OUT OF TRAINING, EH?")
    -    end
    -
    -    if numMissions >= 160*math.random() then 
    -        missionSuccess()
    -    else 
    -        missionFailure() 
    -    end
    -end
    -
    -function playItaly()
    -    targets_to_messages = {
    -       ["1"] = "SHOULD BE EASY -- YOU'RE FLYING A NAZI-MADE PLANE.",
    -       ["2"] = "BE CAREFUL!!!",
    -       ["3"] = "YOU'RE GOING FOR THE OIL, EH?",
    -    }
    -
    -    target = choice("YOUR TARGET -- ALBANIA(1), GREECE(2), NORTH AFRICA(3)? ", targets_to_messages)
    -    print(targets_to_messages[target])
    -    commence_non_kamikaze_attack()
    -end
    -
    -function playAllies()
    -    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 = choice("AIRCRAFT -- LIBERATOR(1), B-29(2), B-17(3), LANCASTER(4)? ", aircraft_to_message)
    -    print(aircraft_to_message[aircraft])
    -    commence_non_kamikaze_attack()
    -end
    -
    -function playJapan()
    -    print("YOU'RE FLYING A KAMIKAZE MISSION OVER THE USS LEXINGTON.")
    -    first_mission = getInput("YOUR FIRST KAMIKAZE MISSION? (Y OR N)? "):match("[yYnN].*")
    -    if first_mission:lower() == "n" then
    -        return playerDeath()
    -    end
    -    if math.random() > 0.65 then
    -       return missionSuccess()
    -    else
    -       playerDeath()
    -    end
    -end
    -
    -function playGermany()
    -    targets_to_messages = {
    -        ["1"] = "YOU'RE NEARING STALINGRAD.",
    -        ["2"] = "NEARING LONDON.  BE CAREFUL, THEY'VE GOT RADAR.",
    -        ["3"] = "NEARING VERSAILLES.  DUCK SOUP.  THEY'RE NEARLY DEFENSELESS.",
    -    }
    -    target = choice("A NAZI, EH?  OH WELL.  ARE YOU GOING FOR RUSSIA(1),\nENGLAND(2), OR FRANCE(3)? ", targets_to_messages)
    -
    -    print(targets_to_messages[target])
    -    return commence_non_kamikaze_attack()
    -end
    -
    -function playGame()
    -   sides = {
    -        ["1"] = playItaly,
    -        ["2"] = playAllies,
    -        ["3"] = playJapan,
    -        ["4"] = playGermany
    -   }
    -   print("YOU ARE A PILOT IN A WORLD WAR II BOMBER.")
    -
    -   target = choice("WHAT SIDE -- ITALY(1), ALLIES(2), JAPAN(3), GERMANY(4)? ", sides)
    -   sides[target]()
    -end
    -
    -local again = true
    -while again do
    -   playGame()
    -   again = getInput("ANOTHER MISSION (Y OR N)? "):match("[yY].*")
    -end
    -
    -print("CHICKEN !!!")
    \ No newline at end of file
    diff --git a/12_Bombs_Away/pascal/README.md b/12_Bombs_Away/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/12_Bombs_Away/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/12_Bombs_Away/perl/bombsaway.pl b/12_Bombs_Away/perl/bombsaway.pl
    index 9cd4b1bd2..1b4989f66 100644
    --- a/12_Bombs_Away/perl/bombsaway.pl
    +++ b/12_Bombs_Away/perl/bombsaway.pl
    @@ -155,7 +155,7 @@ ($question, @comments)
        # and $guns_hit_rate here because the original BASIC code did not reset
        # the associated variables (respectively T and S) at every mission, thus
        # leaking state from one mission to the following ones.
    -   #
    +   # 
        # In particular, both are leaked to the Japan mission(s), and
        # $guns_hit_rate is leaked to future "multiple()" missions that have
        # missiles only.
    diff --git a/12_Bombs_Away/python/bombs_away.py b/12_Bombs_Away/python/bombs_away.py
    index 819315e0e..5c591f44f 100644
    --- a/12_Bombs_Away/python/bombs_away.py
    +++ b/12_Bombs_Away/python/bombs_away.py
    @@ -186,4 +186,4 @@ def play_game() -> None:
         again = True
         while again:
             play_game()
    -        again = input("ANOTHER MISSION? (Y OR N): ").upper() == "Y"
    +        again = True if input("ANOTHER MISSION? (Y OR N): ").upper() == "Y" else False
    diff --git a/12_Bombs_Away/rust/Cargo.lock b/12_Bombs_Away/rust/Cargo.lock
    deleted file mode 100644
    index 59dc11cca..000000000
    --- a/12_Bombs_Away/rust/Cargo.lock
    +++ /dev/null
    @@ -1,75 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.14"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.153"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/12_Bombs_Away/rust/Cargo.toml b/12_Bombs_Away/rust/Cargo.toml
    deleted file mode 100644
    index 3b1d02f52..000000000
    --- a/12_Bombs_Away/rust/Cargo.toml
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -[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/12_Bombs_Away/rust/src/main.rs b/12_Bombs_Away/rust/src/main.rs
    deleted file mode 100644
    index d049fd849..000000000
    --- a/12_Bombs_Away/rust/src/main.rs
    +++ /dev/null
    @@ -1,309 +0,0 @@
    -use std::{
    -    io::{self, Write},
    -    str::FromStr,
    -};
    -
    -use rand::Rng;
    -
    -struct Italy;
    -struct Allies;
    -struct Japan;
    -struct Germany;
    -
    -#[derive(Debug, PartialEq, Eq)]
    -struct ParseChoiceTargetError;
    -
    -#[derive(PartialEq)]
    -enum ThreeTarget {
    -    One,
    -    Two,
    -    Three,
    -}
    -
    -impl FromStr for ThreeTarget {
    -    type Err = ParseChoiceTargetError;
    -
    -    fn from_str(s: &str) -> Result {
    -        let n = s.parse::().map_err(|_| ParseChoiceTargetError)?;
    -        match n {
    -            1 => Ok(Self::One),
    -            2 => Ok(Self::Two),
    -            3 => Ok(Self::Three),
    -            _ => Err(ParseChoiceTargetError),
    -        }
    -    }
    -}
    -
    -enum FourTarget {
    -    One,
    -    Two,
    -    Three,
    -    Four,
    -}
    -
    -impl FromStr for FourTarget {
    -    type Err = ParseChoiceTargetError;
    -
    -    fn from_str(s: &str) -> Result {
    -        let n = s.parse::().map_err(|_| ParseChoiceTargetError)?;
    -        match n {
    -            1 => Ok(Self::One),
    -            2 => Ok(Self::Two),
    -            3 => Ok(Self::Three),
    -            4 => Ok(Self::Four),
    -            _ => Err(ParseChoiceTargetError),
    -        }
    -    }
    -}
    -
    -pub trait Brefing {
    -    type TargetOption;
    -    fn prompt<'a>(&self) -> &'a str;
    -    fn targets_to_messages<'a>(&self, target: Self::TargetOption) -> &'a str;
    -}
    -
    -impl Brefing for Italy {
    -    type TargetOption = ThreeTarget;
    -
    -    fn prompt<'a>(&self) -> &'a str {
    -        "YOUR TARGET -- ALBANIA(1), GREECE(2), NORTH AFRICA(3)"
    -    }
    -
    -    fn targets_to_messages<'a>(&self, target: Self::TargetOption) -> &'a str {
    -        match target {
    -            ThreeTarget::One => "SHOULD BE EASY -- YOU'RE FLYING A NAZI-MADE PLANE.",
    -            ThreeTarget::Two => "BE CAREFUL!!!",
    -            ThreeTarget::Three => "YOU'RE GOING FOR THE OIL, EH?",
    -        }
    -    }
    -}
    -
    -impl Brefing for Allies {
    -    type TargetOption = FourTarget;
    -
    -    fn prompt<'a>(&self) -> &'a str {
    -        "AIRCRAFT -- LIBERATOR(1), B-29(2), B-17(3), LANCASTER(4): "
    -    }
    -
    -    fn targets_to_messages<'a>(&self, target: Self::TargetOption) -> &'a str {
    -        match target {
    -            FourTarget::One => "YOU'VE GOT 2 TONS OF BOMBS FLYING FOR PLOESTI.",
    -            FourTarget::Two => "YOU'RE DUMPING THE A-BOMB ON HIROSHIMA.",
    -            FourTarget::Three => "YOU'RE CHASING THE BISMARK IN THE NORTH SEA.",
    -            FourTarget::Four => "YOU'RE BUSTING A GERMAN HEAVY WATER PLANT IN THE RUHR.",
    -        }
    -    }
    -}
    -
    -impl Brefing for Germany {
    -    type TargetOption = ThreeTarget;
    -
    -    fn prompt<'a>(&self) -> &'a str {
    -        "A NAZI, EH?  OH WELL.  ARE YOU GOING FOR RUSSIA(1),\nENGLAND(2), OR FRANCE(3)? "
    -    }
    -
    -    fn targets_to_messages<'a>(&self, target: Self::TargetOption) -> &'a str {
    -        match target {
    -            ThreeTarget::One => "YOU'RE NEARING STALINGRAD.",
    -            ThreeTarget::Two => "NEARING LONDON.  BE CAREFUL, THEY'VE GOT RADAR.",
    -            ThreeTarget::Three => "NEARING VERSAILLES.  DUCK SOUP.  THEY'RE NEARLY DEFENSELESS.",
    -        }
    -    }
    -}
    -
    -enum Side {
    -    Italy(Italy),
    -    Allies(Allies),
    -    Japan(Japan),
    -    Germany(Germany),
    -}
    -
    -impl From for Side {
    -    fn from(value: FourTarget) -> Self {
    -        match value {
    -            FourTarget::One => Self::Italy(Italy),
    -            FourTarget::Two => Self::Allies(Allies),
    -            FourTarget::Three => Self::Japan(Japan),
    -            FourTarget::Four => Self::Germany(Germany),
    -        }
    -    }
    -}
    -
    -fn stdin_choice(prompt: &str) -> C {
    -    let mut buffer = String::new();
    -
    -    print!("{prompt}");
    -    io::stdout().flush().unwrap();
    -    io::stdin().read_line(&mut buffer).unwrap();
    -    loop {
    -        if let Ok(choice) = buffer.trim().parse::() {
    -            return choice;
    -        }
    -        print!("TRY AGAIN...");
    -        io::stdout().flush().unwrap();
    -        io::stdin().read_line(&mut buffer).unwrap();
    -    }
    -}
    -
    -fn stdin_y_or_n(prompt: &str) -> bool {
    -    let mut buffer = String::new();
    -
    -    print!("{prompt}");
    -    io::stdout().flush().unwrap();
    -    io::stdin().read_line(&mut buffer).unwrap();
    -    buffer.trim().to_uppercase() == "Y"
    -}
    -
    -fn commence_non_kamikazi_attack() {
    -    let nmissions = loop {
    -        let nmissions = stdin_choice::("HOW MANY MISSIONS HAVE YOU FLOWN? ");
    -        if nmissions < 160 {
    -            break nmissions;
    -        }
    -        println!("MISSIONS, NOT MILES...");
    -        println!("150 MISSIONS IS HIGH EVEN FOR OLD-TIMERS");
    -        print!("NOW THEN, ");
    -    };
    -
    -    if nmissions >= 100 {
    -        println!("THAT'S PUSHING THE ODDS!");
    -    }
    -
    -    if nmissions < 25 {
    -        println!("FRESH OUT OF TRAINING, EH?");
    -    }
    -
    -    println!();
    -
    -    let mut rng = rand::thread_rng();
    -    let y: f32 = rng.gen();
    -
    -    if nmissions as f32 >= 160_f32 * y {
    -        mission_success();
    -    } else {
    -        mission_failure();
    -    }
    -}
    -
    -fn play_japan() {
    -    if !stdin_y_or_n("YOUR FIRST KAMIKAZE MISSION? (Y OR N): ") {
    -        player_death();
    -        return;
    -    }
    -
    -    let mut rng = rand::thread_rng();
    -    let y: f32 = rng.gen();
    -    if y > 0.65 {
    -        mission_success();
    -    } else {
    -        player_death();
    -    }
    -}
    -
    -fn player_death() {
    -    println!("* * * * BOOM * * * *");
    -    println!("YOU HAVE BEEN SHOT DOWN.....");
    -    println!("DEARLY BELOVED, WE ARE GATHERED HERE TODAY TO PAY OUR");
    -    println!("LAST TRIBUTE...");
    -}
    -
    -fn mission_success() {
    -    let mut rng = rand::thread_rng();
    -    let y: f32 = rng.gen();
    -
    -    let killed = (100f32 * y) as i32;
    -    println!("DIRECT HIT!!!! {killed} KILLED.");
    -    println!("MISSION SUCCESSFUL.");
    -}
    -
    -fn mission_failure() {
    -    let mut rng = rand::thread_rng();
    -    let y: f32 = rng.gen();
    -    let miles = 2 + (30f32 * y) as i32;
    -    println!("MISSED TARGET BY {miles} MILES!");
    -    println!("NOW YOU'RE REALLY IN FOR IT !!");
    -    println!();
    -    let enemy_weapons =
    -        stdin_choice::("DOES THE ENEMY HAVE GUNS(1), MISSILES(2), OR BOTH(3)? ");
    -
    -    let enemy_gunner_accuracy = if enemy_weapons != ThreeTarget::Two {
    -        let m = loop {
    -            let m =
    -                stdin_choice::("WHAT'S THE PERCENT HIT RATE OF ENEMY GUNNERS (10 TO 50)? ");
    -            if m <= 50 {
    -                break m;
    -            }
    -            println!("TRY AGAIN...");
    -        };
    -        if m < 10 {
    -            println!("YOU LIE, BUT YOU'LL PAY...");
    -            player_death();
    -            return;
    -        }
    -        m
    -    } else {
    -        0
    -    };
    -
    -    let missile_threat_weighting = if enemy_weapons == ThreeTarget::One {
    -        0
    -    } else {
    -        35
    -    };
    -
    -    let death =
    -        death_with_chance((enemy_gunner_accuracy + missile_threat_weighting) as f32 / 100f32);
    -
    -    if death {
    -        player_death();
    -    } else {
    -        player_survived();
    -    }
    -}
    -
    -fn player_survived() {
    -    println!("YOU MADE IT THROUGH TREMENDOUS FLAK!!");
    -}
    -
    -fn death_with_chance(p_death: f32) -> bool {
    -    let mut rng = rand::thread_rng();
    -    let y: f32 = rng.gen();
    -    p_death > y
    -}
    -
    -fn main() {
    -    loop {
    -        println!("YOU ARE A PILOT IN A WORLD WAR II BOMBER.");
    -        let side: Side =
    -            stdin_choice::("WHAT SIDE -- ITALY(1), ALLIES(2), JAPAN(3), GERMANY(4): ")
    -                .into();
    -
    -        match side {
    -            Side::Japan(_) => {
    -                println!("YOU'RE FLYING A KAMIKAZE MISSION OVER THE USS LEXINGTON.");
    -            }
    -            Side::Italy(ref s) => {
    -                let target = stdin_choice(s.prompt());
    -                println!("{}", s.targets_to_messages(target));
    -            }
    -            Side::Allies(ref s) => {
    -                let target = stdin_choice(s.prompt());
    -                println!("{}", s.targets_to_messages(target));
    -            }
    -            Side::Germany(ref s) => {
    -                let target = stdin_choice(s.prompt());
    -                println!("{}", s.targets_to_messages(target));
    -            }
    -        }
    -
    -        match side {
    -            Side::Japan(_) => play_japan(),
    -            _ => commence_non_kamikazi_attack(),
    -        }
    -
    -        println!();
    -        if !stdin_y_or_n("ANOTHER MISSION? (Y OR N): ") {
    -            break;
    -        }
    -    }
    -}
    diff --git a/12_Bombs_Away/vbnet/BombsAway.sln b/12_Bombs_Away/vbnet/BombsAway.sln
    deleted file mode 100644
    index 124d3943b..000000000
    --- a/12_Bombs_Away/vbnet/BombsAway.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index da557be99..000000000
    --- a/12_Bombs_Away/vbnet/BombsAway.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    BombsAway
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/13_Bounce/README.md b/13_Bounce/README.md
    index 770bc1222..396b534dd 100644
    --- a/13_Bounce/README.md
    +++ b/13_Bounce/README.md
    @@ -14,7 +14,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/13_Bounce/csharp/Bounce.cs b/13_Bounce/csharp/Bounce.cs
    deleted file mode 100644
    index c250e7df3..000000000
    --- a/13_Bounce/csharp/Bounce.cs
    +++ /dev/null
    @@ -1,38 +0,0 @@
    -namespace Bounce;
    -
    -/// 
    -/// Represents the bounce of the ball, calculating duration, height and position in time.
    -/// 
    -/// 
    -/// All calculations are derived from the equation for projectile motion: s = vt + 0.5at^2
    -/// 
    -internal class Bounce
    -{
    -    private const float _acceleration = -32; // feet/s^2
    -
    -    private readonly float _velocity;
    -
    -    internal Bounce(float velocity)
    -    {
    -        _velocity = velocity;
    -    }
    -
    -    public float Duration => -2 * _velocity / _acceleration;
    -
    -    public float MaxHeight =>
    -        (float)Math.Round(-_velocity * _velocity / 2 / _acceleration, MidpointRounding.AwayFromZero);
    -
    -    public float Plot(Graph graph, float startTime)
    -    {
    -        var time = 0f;
    -        for (; time <= Duration; time += graph.TimeIncrement)
    -        {
    -            var height = _velocity * time + _acceleration * time * time / 2;
    -            graph.Plot(startTime + time, height);
    -        }
    -
    -        return startTime + time;
    -    }
    -
    -    public Bounce Next(float elasticity) => new Bounce(_velocity * elasticity);
    -}
    diff --git a/13_Bounce/csharp/Bounce.csproj b/13_Bounce/csharp/Bounce.csproj
    deleted file mode 100644
    index e377b9049..000000000
    --- a/13_Bounce/csharp/Bounce.csproj
    +++ /dev/null
    @@ -1,17 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    -  
    -    
    -  
    -
    -  
    -    
    -  
    -
    diff --git a/13_Bounce/csharp/Bounce.sln b/13_Bounce/csharp/Bounce.sln
    deleted file mode 100644
    index f844a126f..000000000
    --- a/13_Bounce/csharp/Bounce.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/csharp/Game.cs b/13_Bounce/csharp/Game.cs
    deleted file mode 100644
    index 155bdf481..000000000
    --- a/13_Bounce/csharp/Game.cs
    +++ /dev/null
    @@ -1,38 +0,0 @@
    -using static Bounce.Resources.Resource;
    -
    -namespace Bounce;
    -
    -internal class Game
    -{
    -    private readonly IReadWrite _io;
    -
    -    public Game(IReadWrite io)
    -    {
    -        _io = io;
    -    }
    -
    -    public void Play(Func playAgain)
    -    {
    -        _io.Write(Streams.Title);
    -        _io.Write(Streams.Instructions);
    -
    -        while (playAgain.Invoke())
    -        {
    -            var timeIncrement = _io.ReadParameter("Time increment (sec)");
    -            var velocity = _io.ReadParameter("Velocity (fps)");
    -            var elasticity = _io.ReadParameter("Coefficient");
    -
    -            var bounce = new Bounce(velocity);
    -            var bounceCount = (int)(Graph.Row.Width * timeIncrement / bounce.Duration);
    -            var graph = new Graph(bounce.MaxHeight, timeIncrement);
    -
    -            var time = 0f;
    -            for (var i = 0; i < bounceCount; i++, bounce = bounce.Next(elasticity))
    -            {
    -                time = bounce.Plot(graph, time);
    -            }
    -
    -            _io.WriteLine(graph);
    -        }
    -    }
    -}
    diff --git a/13_Bounce/csharp/Graph.cs b/13_Bounce/csharp/Graph.cs
    deleted file mode 100644
    index 608b5bda4..000000000
    --- a/13_Bounce/csharp/Graph.cs
    +++ /dev/null
    @@ -1,116 +0,0 @@
    -using System.Text;
    -
    -namespace Bounce;
    -
    -/// 
    -/// Provides support for plotting a graph of height vs time, and rendering it to a string.
    -/// 
    -internal class Graph
    -{
    -    private readonly Dictionary _rows;
    -
    -    public Graph(float maxHeight, float timeIncrement)
    -    {
    -        // 1 row == 1/2 foot + 1 row for zero
    -        var rowCount = 2 * (int)Math.Round(maxHeight, MidpointRounding.AwayFromZero) + 1;
    -        _rows = Enumerable.Range(0, rowCount)
    -            .ToDictionary(x => x, x => new Row(x % 2 == 0 ? $" {x / 2} " : ""));
    -        TimeIncrement = timeIncrement;
    -    }
    -
    -    public float TimeIncrement { get; }
    -    public float MaxTimePlotted { get; private set; }
    -
    -    public void Plot(float time, float height)
    -    {
    -        var rowIndex = (int)Math.Round(height * 2, MidpointRounding.AwayFromZero);
    -        var colIndex = (int)(time / TimeIncrement) + 1;
    -        if (_rows.TryGetValue(rowIndex, out var row))
    -        {
    -            row[colIndex] = '0';
    -        }
    -        MaxTimePlotted = Math.Max(time, MaxTimePlotted);
    -    }
    -
    -    public override string ToString()
    -    {
    -        var sb = new StringBuilder().AppendLine("Feet").AppendLine();
    -        foreach (var (_, row) in _rows.OrderByDescending(x => x.Key))
    -        {
    -            sb.Append(row).AppendLine();
    -        }
    -        sb.Append(new Axis(MaxTimePlotted, TimeIncrement));
    -
    -        return sb.ToString();
    -    }
    -
    -    internal class Row
    -    {
    -        public const int Width = 70;
    -
    -        private readonly char[] _chars = new char[Width + 2];
    -        private int nextColumn = 0;
    -
    -        public Row(string label)
    -        {
    -            Array.Fill(_chars, ' ');
    -            Array.Copy(label.ToCharArray(), _chars, label.Length);
    -            nextColumn = label.Length;
    -        }
    -
    -        public char this[int column]
    -        {
    -            set
    -            {
    -                if (column >= _chars.Length) { return; }
    -                if (column < nextColumn) { column = nextColumn; }
    -                _chars[column] = value;
    -                nextColumn = column + 1;
    -            }
    -        }
    -
    -        public override string ToString() => new string(_chars);
    -    }
    -
    -    internal class Axis
    -    {
    -        private readonly int _maxTimeMark;
    -        private readonly float _timeIncrement;
    -        private readonly Labels _labels;
    -
    -        internal Axis(float maxTimePlotted, float timeIncrement)
    -        {
    -            _maxTimeMark = (int)Math.Ceiling(maxTimePlotted);
    -            _timeIncrement = timeIncrement;
    -
    -            _labels = new Labels();
    -            for (var i = 1; i <= _maxTimeMark; i++)
    -            {
    -                _labels.Add((int)(i / _timeIncrement), $" {i} ");
    -            }
    -        }
    -
    -        public override string ToString()
    -            => new StringBuilder()
    -                .Append(' ').Append('.', (int)(_maxTimeMark / _timeIncrement) + 1).AppendLine()
    -                .Append(_labels).AppendLine()
    -                .Append(' ', (int)(_maxTimeMark / _timeIncrement / 2 - 2)).AppendLine("Seconds")
    -                .ToString();
    -    }
    -
    -    internal class Labels : Row
    -    {
    -        public Labels()
    -            : base(" 0")
    -        {
    -        }
    -
    -        public void Add(int column, string label)
    -        {
    -            for (var i = 0; i < label.Length; i++)
    -            {
    -                this[column + i] = label[i];
    -            }
    -        }
    -    }
    -}
    diff --git a/13_Bounce/csharp/IReadWriteExtensions.cs b/13_Bounce/csharp/IReadWriteExtensions.cs
    deleted file mode 100644
    index bafeee42f..000000000
    --- a/13_Bounce/csharp/IReadWriteExtensions.cs
    +++ /dev/null
    @@ -1,11 +0,0 @@
    -namespace Bounce;
    -
    -internal static class IReadWriteExtensions
    -{
    -    internal static float ReadParameter(this IReadWrite io, string parameter)
    -    {
    -        var value = io.ReadNumber(parameter);
    -        io.WriteLine();
    -        return value;
    -    }
    -}
    \ No newline at end of file
    diff --git a/13_Bounce/csharp/Program.cs b/13_Bounce/csharp/Program.cs
    deleted file mode 100644
    index 86af3365e..000000000
    --- a/13_Bounce/csharp/Program.cs
    +++ /dev/null
    @@ -1,6 +0,0 @@
    -global using Games.Common.IO;
    -global using Games.Common.Numbers;
    -
    -using Bounce;
    -
    -new Game(new ConsoleIO()).Play(() => true);
    \ No newline at end of file
    diff --git a/13_Bounce/csharp/README.md b/13_Bounce/csharp/README.md
    index 6323d9d1e..4daabb5c1 100644
    --- a/13_Bounce/csharp/README.md
    +++ b/13_Bounce/csharp/README.md
    @@ -1,26 +1,3 @@
    -# Bounce
    -
     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/)
    -
    -## Conversion notes
    -
    -### Mode of Operation
    -
    -This conversion performs the same function as the original, and provides the same experience, but does it in a different
    -way.
    -
    -The original BASIC code builds the graph as it writes to the screen, scanning each line for points that need to be
    -plotted.
    -
    -This conversion steps through time, calculating the position of the ball at each instant, building the graph in memory.
    -It then writes the graph to the output in one go.
    -
    -### Failure Modes
    -
    -The original BASIC code performs no validation of the input parameters. Some combinations of parameters produce no
    -output, others crash the program.
    -
    -In the spirit of the original this conversion also performs no validation of the parameters, but it does not attempt to
    -replicate the original's failure modes. It fails quite happily in its own way.
    diff --git a/13_Bounce/csharp/Resources/Instructions.txt b/13_Bounce/csharp/Resources/Instructions.txt
    deleted file mode 100644
    index d2901d6e6..000000000
    --- a/13_Bounce/csharp/Resources/Instructions.txt
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -This simulation lets you specify the initial velocity
    -of a ball thrown straight up, and the coefficient of
    -elasticity of the ball.  Please use a decimal fraction
    -coefficiency (less than 1).
    -
    -You also specify the time increment to be used in
    -'strobing' the ball's flight (try .1 initially).
    -
    diff --git a/13_Bounce/csharp/Resources/Resource.cs b/13_Bounce/csharp/Resources/Resource.cs
    deleted file mode 100644
    index 68bebee01..000000000
    --- a/13_Bounce/csharp/Resources/Resource.cs
    +++ /dev/null
    @@ -1,17 +0,0 @@
    -using System.Reflection;
    -using System.Runtime.CompilerServices;
    -
    -namespace Bounce.Resources;
    -
    -internal static class Resource
    -{
    -    internal static class Streams
    -    {
    -        public static Stream Instructions => GetStream();
    -        public static Stream Title => GetStream();
    -    }
    -
    -    private static Stream GetStream([CallerMemberName] string? name = null)
    -        => Assembly.GetExecutingAssembly().GetManifestResourceStream($"Bounce.Resources.{name}.txt")
    -            ?? throw new ArgumentException($"Resource stream {name} does not exist", nameof(name));
    -}
    \ No newline at end of file
    diff --git a/13_Bounce/csharp/Resources/Title.txt b/13_Bounce/csharp/Resources/Title.txt
    deleted file mode 100644
    index 5bcd04962..000000000
    --- a/13_Bounce/csharp/Resources/Title.txt
    +++ /dev/null
    @@ -1,5 +0,0 @@
    -                                 Bounce
    -               Creative Computing  Morristown, New Jersey
    -
    -
    -
    diff --git a/13_Bounce/java/Bounce.java b/13_Bounce/java/Bounce.java
    index ca7275a19..6d39daa27 100644
    --- a/13_Bounce/java/Bounce.java
    +++ b/13_Bounce/java/Bounce.java
    @@ -9,52 +9,52 @@
      * 

    * Note: The idea was to create a version of the 1970's BASIC game in Java, without introducing * new features - no additional text, error checking, etc has been added. - * + * * Converted from BASIC to Java by Darren Cardenas. */ - -public class Bounce { + +public class Bounce { private final Scanner scan; // For user input - + public Bounce() { - + scan = new Scanner(System.in); + + } // End of constructor Bounce - } // End of constructor Bounce - - public void play() { + public void play() { showIntro(); startGame(); + + } // End of method play - } // End of method play - - private void showIntro() { - + private void showIntro() { + System.out.println(" ".repeat(32) + "BOUNCE"); System.out.println(" ".repeat(14) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); System.out.println("\n\n"); - + } // End of method showIntro - private void startGame() { + private void startGame() { double coefficient = 0; - double height = 0; + double height = 0; double timeIncrement = 0; double timeIndex = 0; double timeTotal = 0; - double velocity = 0; - + double velocity = 0; + double[] timeData = new double[21]; - + int heightInt = 0; int index = 0; int maxData = 0; - + String lineContent = ""; - + System.out.println("THIS SIMULATION LETS YOU SPECIFY THE INITIAL VELOCITY"); System.out.println("OF A BALL THROWN STRAIGHT UP, AND THE COEFFICIENT OF"); System.out.println("ELASTICITY OF THE BALL. PLEASE USE A DECIMAL FRACTION"); @@ -63,107 +63,107 @@ private void startGame() { System.out.println("YOU ALSO SPECIFY THE TIME INCREMENT TO BE USED IN"); System.out.println("'STROBING' THE BALL'S FLIGHT (TRY .1 INITIALLY)."); System.out.println(""); - + // Begin outer while loop while (true) { - + System.out.print("TIME INCREMENT (SEC)? "); timeIncrement = Double.parseDouble(scan.nextLine()); System.out.println(""); - + System.out.print("VELOCITY (FPS)? "); - velocity = Double.parseDouble(scan.nextLine()); + velocity = Double.parseDouble(scan.nextLine()); System.out.println(""); - + System.out.print("COEFFICIENT? "); - coefficient = Double.parseDouble(scan.nextLine()); + coefficient = Double.parseDouble(scan.nextLine()); System.out.println(""); System.out.println("FEET"); System.out.println(""); - + maxData = (int)(70 / (velocity / (16 * timeIncrement))); - - for (index = 1; index <= maxData; index++) { + + for (index = 1; index <= maxData; index++) { timeData[index] = velocity * Math.pow(coefficient, index - 1) / 16; } - + // Begin loop through all rows of y-axis data - for (heightInt = (int)(-16 * Math.pow(velocity / 32, 2) + Math.pow(velocity, 2) / 32 + 0.5) * 10; + for (heightInt = (int)(-16 * Math.pow(velocity / 32, 2) + Math.pow(velocity, 2) / 32 + 0.5) * 10; heightInt >= 0; heightInt -= 5) { height = heightInt / 10.0; lineContent = ""; - + if ((int)(Math.floor(height)) == height) { lineContent += " " + (int)(height) + " "; - } - - timeTotal = 0; - - for (index = 1; index <= maxData; index++) { - + } + + timeTotal = 0; + + for (index = 1; index <= maxData; index++) { + for (timeIndex = 0; timeIndex <= timeData[index]; timeIndex += timeIncrement) { - + timeTotal += timeIncrement; - if (Math.abs(height - (0.5 * (-32) * Math.pow(timeIndex, 2) + velocity + if (Math.abs(height - (0.5 * (-32) * Math.pow(timeIndex, 2) + velocity * Math.pow(coefficient, index - 1) * timeIndex)) <= 0.25) { - - while (lineContent.length() < (timeTotal / timeIncrement) - 1) { - lineContent += " "; - } - lineContent += "0"; - } + + while (lineContent.length() < (timeTotal / timeIncrement) - 1) { + lineContent += " "; + } + lineContent += "0"; + } } - + timeIndex = timeData[index + 1] / 2; - + if (-16 * Math.pow(timeIndex, 2) + velocity * Math.pow(coefficient, index - 1) * timeIndex < height) { - - break; - } - } - + + break; + } + } + System.out.println(lineContent); - + } // End loop through all rows of y-axis data lineContent = ""; - + // Show the x-axis for (index = 1; index <= (int)(timeTotal + 1) / timeIncrement + 1; index++) { - - lineContent += "."; + + lineContent += "."; } - + System.out.println(lineContent); - + lineContent = " 0"; - + for (index = 1; index <= (int)(timeTotal + 0.9995); index++) { - - while (lineContent.length() < (int)(index / timeIncrement)) { - lineContent += " "; - } - lineContent += index; + + while (lineContent.length() < (int)(index / timeIncrement)) { + lineContent += " "; + } + lineContent += index; } - + System.out.println(lineContent); - System.out.println(" ".repeat((int)((timeTotal + 1) / (2 * timeIncrement) - 3)) + "SECONDS"); - - } // End outer while loop - - } // End of method startGame + System.out.println(" ".repeat((int)((timeTotal + 1) / (2 * timeIncrement) - 3)) + "SECONDS"); + + } // End outer while loop + } // End of method startGame + public static void main(String[] args) { - + Bounce game = new Bounce(); game.play(); - + } // End of method main - + } // End of class Bounce diff --git a/13_Bounce/javascript/bounce.html b/13_Bounce/javascript/bounce.html index ccf6f4c47..b1e8c5297 100644 --- a/13_Bounce/javascript/bounce.html +++ b/13_Bounce/javascript/bounce.html @@ -1,10 +1,9 @@ BOUNCE - -

    
    +
    
     
     
     
    diff --git a/13_Bounce/javascript/bounce.js b/13_Bounce/javascript/bounce.js
    index 177ff4ffa..d9cac590f 100644
    --- a/13_Bounce/javascript/bounce.js
    +++ b/13_Bounce/javascript/bounce.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/13_Bounce/kotlin/README.md b/13_Bounce/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/13_Bounce/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/13_Bounce/lua/README.md b/13_Bounce/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/13_Bounce/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/13_Bounce/pascal/README.md b/13_Bounce/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/13_Bounce/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/13_Bounce/perl/README.md b/13_Bounce/perl/README.md
    index 6d213dba3..e69c8b819 100644
    --- a/13_Bounce/perl/README.md
    +++ b/13_Bounce/perl/README.md
    @@ -1,6 +1,3 @@
     Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
     
     Conversion to [Perl](https://www.perl.org/)
    -
    -Added feature so that if "TIME" value is "0" then it will quit,
    -so you don't have to hit Control-C. Also added a little error checking of the input.
    diff --git a/13_Bounce/perl/bounce.pl b/13_Bounce/perl/bounce.pl
    deleted file mode 100755
    index 4aeacf1f7..000000000
    --- a/13_Bounce/perl/bounce.pl
    +++ /dev/null
    @@ -1,97 +0,0 @@
    -#!/usr/bin/perl
    -
    -# Bounce program in Perl
    -# Translated by Kevin Brannen (kbrannen)
    -
    -use strict;
    -use warnings;
    -
    -print "\n";
    -print " " x 31,"BOUNCE\n";
    -print " " x 15, "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n";
    -print "\n\n\n";
    -
    -print "THIS SIMULATION LETS YOU SPECIFY THE INITIAL VELOCITY\n";
    -print "OF A BALL THROWN STRAIGHT UP, AND THE COEFFICIENT OF\n";
    -print "ELASTICITY OF THE BALL.  PLEASE USE A DECIMAL FRACTION\n";
    -print "COEFFICIENCY (LESS THAN 1).\n\n";
    -print "YOU ALSO SPECIFY THE TIME INCREMENT TO BE USED IN\n";
    -print "'STROBING' THE BALL'S FLIGHT (TRY .1 INITIALLY).\n\n";
    -
    -# deal with basic's tab() for line positioning
    -#   line = line string we're starting with
    -#   pos = position to start writing
    -#   s = string to write
    -# returns the resultant string, which might not have been changed
    -sub line_tab
    -{
    -    my ($line, $pos, $s) = @_;
    -    my $len = length($line);
    -    # if curser is past position, do nothing
    -    if ($len <= $pos) { $line .= " " x ($pos - $len) . $s; }
    -    return $line;
    -}
    -
    -while (1)
    -{
    -    my @T;          # time slice?
    -    my $time_inc;   # time increment, probably in fractions of seconds
    -    my $velocity;   # velocity in feet/sec
    -    my $coeff_elas; # coeeficent of elasticity
    -    my $line_pos;   # position on line
    -    my $S1          # duration in full seconds?
    -
    -    # get input
    -    print "TIME INCREMENT (SEC, 0=QUIT): "; chomp($time_inc = <>);
    -    last if ($time_inc == 0);
    -    print "VELOCITY (FPS): "; chomp($velocity = <>);
    -    print "COEFFICIENT: "; chomp($coeff_elas = <>);
    -    if ($coeff_elas >= 1.0 || $coeff_elas <= 0)
    -    {
    -        print "COEFFICIENT MUST BE > 0 AND < 1.0\n\n\n";
    -        next;
    -    }
    -
    -    print "\nFEET\n";
    -    $S1 = int(70.0 / ($velocity / (16.0 * $time_inc)));
    -    for my $i (1 .. $S1)
    -    {
    -        $T[$i] = $velocity * $coeff_elas ** ($i - 1) / 16.0;
    -    }
    -
    -    # draw graph
    -    for (my $height=int(-16.0 * ($velocity / 32.0) ** 2.0 + $velocity ** 2.0 / 32.0 + .5) ; $height >= 0 ; $height -= .5)
    -    {
    -        if (int($height) == $height) { print sprintf("%2d", $height); }
    -        else                         { print "  "; }
    -        $line_pos = 0;
    -        my $curr_line = "";
    -        for my $i (1 .. $S1)
    -        {
    -            my $time;
    -            for ($time=0 ; $time <= $T[$i] ; $time += $time_inc)
    -            {
    -                $line_pos += $time_inc;
    -                if (abs($height - (.5 * (-32) * $time ** 2.0 + $velocity * $coeff_elas ** ($i - 1) * $time)) <= .25)
    -                {
    -                    $curr_line = line_tab($curr_line, ($line_pos / $time_inc), "0");
    -                }
    -            }
    -            $time = ($T[$i + 1] // 0) / 2; # we can reach 1 past the end, use 0 if that happens
    -            last if (-16.0 * $time ** 2.0 + $velocity * $coeff_elas ** ($i - 1) * $time < $height);
    -        }
    -        print "$curr_line\n";
    -    }
    -
    -    # draw scale
    -    print "  .";
    -    print "." x (int($line_pos + 1) / $time_inc + 1), "\n";
    -    print "  0";
    -    my $curr_line = "";
    -    for my $i (1 .. int($line_pos + .9995))
    -    {
    -        $curr_line = line_tab($curr_line, int($i / $time_inc), $i);
    -    }
    -    print "$curr_line\n";
    -    print " " x (int($line_pos + 1) / (2 * $time_inc) - 2), "SECONDS\n\n";
    -}
    diff --git a/13_Bounce/python/bounce.py b/13_Bounce/python/bounce.py
    index e454183b0..3ab7411c5 100644
    --- a/13_Bounce/python/bounce.py
    +++ b/13_Bounce/python/bounce.py
    @@ -6,17 +6,16 @@
     Ported by Dave LeCompte
     """
     
    -from typing import Tuple, List
     
     PAGE_WIDTH = 64
     
     
    -def print_centered(msg: str) -> None:
    +def print_centered(msg):
         spaces = " " * ((PAGE_WIDTH - len(msg)) // 2)
         print(spaces + msg)
     
     
    -def print_header(title: str) -> None:
    +def print_header(title):
         print_centered(title)
         print_centered("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
         print()
    @@ -24,7 +23,7 @@ def print_header(title: str) -> None:
         print()
     
     
    -def print_instructions() -> None:
    +def print_instructions():
         print("THIS SIMULATION LETS YOU SPECIFY THE INITIAL VELOCITY")
         print("OF A BALL THROWN STRAIGHT UP, AND THE COEFFICIENT OF")
         print("ELASTICITY OF THE BALL.  PLEASE USE A DECIMAL FRACTION")
    @@ -35,7 +34,7 @@ def print_instructions() -> None:
         print()
     
     
    -def get_initial_conditions() -> Tuple[float, float, float]:
    +def get_initial_conditions():
         delta_t = float(input("TIME INCREMENT (SEC)? "))
         print()
         v0 = float(input("VELOCITY (FPS)? "))
    @@ -46,57 +45,57 @@ def get_initial_conditions() -> Tuple[float, float, float]:
         return delta_t, v0, coeff_rest
     
     
    -def print_at_tab(line: str, tab: int, s: str) -> str:
    +def print_at_tab(line, tab, s):
         line += (" " * (tab - len(line))) + s
         return line
     
     
    -def run_simulation(delta_t: float, v0: float, coeff_rest: float) -> None:
    -    bounce_time: List[float] = [0] * 20  # time of each bounce
    +def run_simulation(delta_t, v0, coeff_rest):
    +    t = [0] * 20  # time of each bounce
     
         print("FEET")
         print()
     
         sim_dur = int(70 / (v0 / (16 * delta_t)))
         for i in range(1, sim_dur + 1):
    -        bounce_time[i] = v0 * coeff_rest ** (i - 1) / 16
    +        t[i] = v0 * coeff_rest ** (i - 1) / 16
     
         # Draw the trajectory of the bouncing ball, one slice of height at a time
    -    h: float = int(-16 * (v0 / 32) ** 2 + v0**2 / 32 + 0.5)
    +    h = int(-16 * (v0 / 32) ** 2 + v0 ** 2 / 32 + 0.5)
         while h >= 0:
             line = ""
             if int(h) == h:
                 line += str(int(h))
    -        total_time: float = 0
    +        l = 0
             for i in range(1, sim_dur + 1):
    -            tm: float = 0
    -            while tm <= bounce_time[i]:
    -                total_time += delta_t
    +            tm = 0
    +            while tm <= t[i]:
    +                l += delta_t
                     if (
    -                    abs(h - (0.5 * (-32) * tm**2 + v0 * coeff_rest ** (i - 1) * tm))
    +                    abs(h - (0.5 * (-32) * tm ** 2 + v0 * coeff_rest ** (i - 1) * tm))
                         <= 0.25
                     ):
    -                    line = print_at_tab(line, int(total_time / delta_t), "0")
    +                    line = print_at_tab(line, int(l / delta_t), "0")
                     tm += delta_t
    -            tm = bounce_time[i + 1] / 2
    +            tm = t[i + 1] / 2
     
    -            if -16 * tm**2 + v0 * coeff_rest ** (i - 1) * tm < h:
    +            if -16 * tm ** 2 + v0 * coeff_rest ** (i - 1) * tm < h:
                     break
             print(line)
    -        h -= 0.5
    +        h = h - 0.5
     
    -    print("." * (int((total_time + 1) / delta_t) + 1))
    +    print("." * (int((l + 1) / delta_t) + 1))
         print
         line = " 0"
    -    for i in range(1, int(total_time + 0.9995) + 1):
    +    for i in range(1, int(l + 0.9995) + 1):
             line = print_at_tab(line, int(i / delta_t), str(i))
         print(line)
         print()
    -    print(print_at_tab("", int((total_time + 1) / (2 * delta_t) - 2), "SECONDS"))
    +    print(print_at_tab("", int((l + 1) / (2 * delta_t) - 2), "SECONDS"))
         print()
     
     
    -def main() -> None:
    +def main():
         print_header("BOUNCE")
         print_instructions()
     
    diff --git a/13_Bounce/ruby/bounce.rb b/13_Bounce/ruby/bounce.rb
    index 6af0d4755..e215a8971 100644
    --- a/13_Bounce/ruby/bounce.rb
    +++ b/13_Bounce/ruby/bounce.rb
    @@ -108,7 +108,7 @@ def plot_bouncing_ball(strobbing_time, v0, c)
                     # skipped by line 98
                     plot_width += 1 if plotted_height == 0
                 }
    -
    +            
                 if heighest_position_in_next_bounce(time_in_bounce, v0, i, c) < plotted_height then
                     # If we got no more ball positions at or above current height in the next bounce,
                     # we can skip the rest of the bounces and move down to the next height to plot
    diff --git a/13_Bounce/rust/Cargo.lock b/13_Bounce/rust/Cargo.lock
    deleted file mode 100644
    index b21cc6a2d..000000000
    --- a/13_Bounce/rust/Cargo.lock
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    diff --git a/13_Bounce/rust/Cargo.toml b/13_Bounce/rust/Cargo.toml
    deleted file mode 100644
    index 7d75412a6..000000000
    --- a/13_Bounce/rust/Cargo.toml
    +++ /dev/null
    @@ -1,6 +0,0 @@
    -[package]
    -name = "rust"
    -version = "0.1.0"
    -edition = "2021"
    -
    -[dependencies]
    diff --git a/13_Bounce/rust/src/main.rs b/13_Bounce/rust/src/main.rs
    deleted file mode 100644
    index 99050227d..000000000
    --- a/13_Bounce/rust/src/main.rs
    +++ /dev/null
    @@ -1,183 +0,0 @@
    -/** BOUNCE GAME 
    - * https://github.com/coding-horror/basic-computer-games/blob/main/13_Bounce/bounce.bas
    - * Direct conversion from BASIC to Rust by Pablo Marques (marquesrs).
    - * No additional features or improvements were added. As a faithful translation, 
    - * many of the code here are done in an unrecommended way by today's standards.
    - * 03/03/25
    -*/
    -
    -use std::io::Write;
    -
    -fn input(msg: &str) -> String {
    -    print!("{}", msg);
    -    let _ =std::io::stdout().flush().unwrap();
    -    let mut input = String::new();
    -    std::io::stdin().read_line(&mut input).unwrap();
    -    return input.trim().to_uppercase();
    -}
    -
    -fn main() {
    -    //10 PRINT TAB(33);"BOUNCE"
    -    //20 PRINT TAB(15);"CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY"
    -    //30 PRINT:PRINT:PRINT
    -    print!("{}{}\n{}{}\n\n\n",
    -        " ".repeat(33),
    -        "BOUNCE",
    -        " ".repeat(15),
    -        "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY"
    -    );
    -
    -    //90 DIM T(20)
    -    let mut t: Vec = Vec::with_capacity(20);
    -    
    -    //100 PRINT "THIS SIMULATION LETS YOU SPECIFY THE INITIAL VELOCITY"
    -    //110 PRINT "OF A BALL THROWN STRAIGHT UP, AND THE COEFFICIENT OF"
    -    //120 PRINT "ELASTICITY OF THE BALL.  PLEASE USE A DECIMAL FRACTION"
    -    //130 PRINT "COEFFICIENCY (LESS THAN 1)."
    -    //131 PRINT
    -    //132 PRINT "YOU ALSO SPECIFY THE TIME INCREMENT TO BE USED IN"
    -    //133 PRINT "'STROBING' THE BALL'S FLIGHT (TRY .1 INITIALLY)."
    -    //134 PRINT
    -    print!("{}\n{}\n{}\n{}\n\n{}\n{}\n\n",
    -        "THIS SIMULATION LETS YOU SPECIFY THE INITIAL VELOCITY",
    -        "OF A BALL THROWN STRAIGHT UP, AND THE COEFFICIENT OF",
    -        "ELASTICITY OF THE BALL.  PLEASE USE A DECIMAL FRACTION",
    -        "COEFFICIENCY (LESS THAN 1).",
    -        "YOU ALSO SPECIFY THE TIME INCREMENT TO BE USED IN",
    -        "'STROBING' THE BALL'S FLIGHT (TRY .1 INITIALLY).",
    -    );
    -
    -    loop {
    -       //135 INPUT "TIME INCREMENT (SEC)";S2
    -        let s2 = input("TIME INCREMENT (SEC): ").parse::().unwrap();
    -        //let s2 = 0.2f32;
    -
    -        //140 PRINT
    -        println!();
    -        
    -        //150 INPUT "VELOCITY (FPS)";V
    -        let v = input("VELOCITY (FPS): ").parse::().unwrap();
    -        //let v = 20.0f32;
    -
    -        //160 PRINT
    -        println!();
    -
    -        //170 INPUT "COEFFICIENT";C
    -        let c = input("COEFFICIENT: ").parse::().unwrap();
    -        //let c = 0.6f32;
    -
    -        //180 PRINT
    -        //182 PRINT "FEET"
    -        //184 PRINT
    -        print!("\nFEET\n\n");
    -
    -        //186 S1=INT(70/(V/(16*S2))) // verified
    -        let s1 = (70.0 / (v/(16.0*s2))) as i32;
    -
    -        //190 FOR I=1 TO S1
    -        for i in 1..=s1 {
    -            //200 T(I)=V*C^(I-1)/16
    -            t.push(v * c.powf(i as f32 - 1.0) / 16.0); // verified
    -            //210 NEXT I
    -        }
    -
    -        let mut l = 0.0;
    -
    -        //220 FOR H=INT(-16*(V/32)^2+V^2/32+.5) TO 0 STEP -.5
    -        let mut h = (-16.0 * (v / 32.0).powi(2) + (v.powi(2)) / 32.0 + 0.5).floor();
    -        while h >= 0.0 {
    -            let mut line_content = String::new();
    -            //221 IF INT(H)<>H THEN 225
    -            if h.floor() == h {
    -                //222 PRINT H;
    -                line_content.push_str(h.to_string().as_str());
    -                line_content.push(' ');
    -            }
    -            //225 L=0
    -            l = 0.0;
    -            //230 FOR I=1 TO S1
    -            for i in 1..=s1 {
    -                let mut t_val = 0.0;
    -                //240 FOR T=0 TO T(I) STEP S2
    -                while t_val <= t[(i - 1) as usize] {
    -                    //245 L=L+S2
    -                    l = l + s2;
    -                    
    -                    //250 IF ABS(H-(.5*(-32)*T^2+V*C^(I-1)*T))>.25 THEN 270
    -                    let condition = h - (0.5 * (-32.0) * t_val.powf(2.0) + v * c.powf((i-1) as f32) * t_val);
    -                    if condition.abs() >= 0.25{
    -                        t_val = t_val + s2;
    -                        continue;
    -                    }
    -                    // TABS ARE NOT SPACES, BUT A TERMINAL POSITION
    -                    //260 PRINT TAB(L/S2);"0";
    -                    let spaces = ((l / s2) - 1.0) as usize;
    -                    while line_content.len() < spaces  {
    -                        line_content.push(' ');
    -                    }
    -                    line_content.push('0');
    -                   
    -                    //270 NEXT T
    -                    t_val = t_val + s2;
    -                }
    -                
    -                //275 T=T(I+1)/2
    -                if i as usize == t.len() { break; }
    -                t_val = t[i as usize] / 2.0;
    -
    -                //276 IF -16*T^2+V*C^(I-1)*T
    -  
    -    Exe
    -    Bounce
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/14_Bowling/README.md b/14_Bowling/README.md
    index 52a0ab448..99a7fade5 100644
    --- a/14_Bowling/README.md
    +++ b/14_Bowling/README.md
    @@ -16,15 +16,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Known Bugs
    -
    -- In the original code, scores is not kept accurately in multiplayer games.  It stores scores in F*P, where F is the frame and P is the player.  So, for example, frame 8 player 1 (index 16) clobbers the score from frame 4 player 2 (also index 16).
    -
    -- Even when scores are kept accurately, they don't match normal bowling rules.  In this game, the score for each ball is just the total number of pins down after that ball, and the third row of scores is a status indicator (3 for strike, 2 for spare, 1 for anything else).
    -
    -- The program crashes with a "NEXT without FOR" error if you elect to play again after the first game.
    -
    -#### Porting Notes
    -
    -- The funny control characters in the "STRIKE!" string literal are there to make the terminal beep.
    diff --git a/14_Bowling/bowling.bas b/14_Bowling/bowling.bas
    index a6732580e..916c19389 100644
    --- a/14_Bowling/bowling.bas
    +++ b/14_Bowling/bowling.bas
    @@ -18,7 +18,7 @@
     1440 PRINT "SCORES ."
     1530 PRINT "FIRST OF ALL...HOW MANY ARE PLAYING";
     1620 INPUT R
    -1710 PRINT
    +1710 PRINT 
     1800 PRINT "VERY GOOD..."
     1890 FOR I=1 TO 100: FOR J=1 TO 6: A(I,J)=0: NEXT J: NEXT I
     1980 F=1
    @@ -69,7 +69,7 @@
     6030 IF B<>1 OR D>=10 THEN 6210
     6120 PRINT "ROLL YOUR 2ND BALL"
     6210 REM ARK STORAGE OF THE SCORES
    -6300 PRINT
    +6300 PRINT 
     6390 A(F*P,B)=D
     6480 IF B=2 THEN 7020
     6570 B=2
    @@ -85,15 +85,15 @@
     7380 FOR I=1 TO 10
     7470 PRINT I;
     7560 NEXT I
    -7650 PRINT
    +7650 PRINT 
     7740 FOR P=1 TO R
     7830 FOR I=1 TO 3
     7920 FOR J=1 TO 10
     8010 PRINT A(J*P,I);
     8100 NEXT J
    -8105 PRINT
    +8105 PRINT 
     8190 NEXT I
    -8280 PRINT
    +8280 PRINT 
     8370 NEXT P
     8460 PRINT "DO YOU WANT ANOTHER GAME"
     8550 INPUT A$
    diff --git a/14_Bowling/csharp/Bowling.cs b/14_Bowling/csharp/Bowling.cs
    deleted file mode 100644
    index 98a8eb32d..000000000
    --- a/14_Bowling/csharp/Bowling.cs
    +++ /dev/null
    @@ -1,198 +0,0 @@
    -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/Bowling.csproj b/14_Bowling/csharp/Bowling.csproj
    deleted file mode 100644
    index d3fe4757c..000000000
    --- a/14_Bowling/csharp/Bowling.csproj
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    diff --git a/14_Bowling/csharp/Bowling.sln b/14_Bowling/csharp/Bowling.sln
    deleted file mode 100644
    index aa48103b6..000000000
    --- a/14_Bowling/csharp/Bowling.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/csharp/FrameResult.cs b/14_Bowling/csharp/FrameResult.cs
    deleted file mode 100644
    index c28b5c0f7..000000000
    --- a/14_Bowling/csharp/FrameResult.cs
    +++ /dev/null
    @@ -1,23 +0,0 @@
    -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
    deleted file mode 100644
    index 10f1e7353..000000000
    --- a/14_Bowling/csharp/GameResults.cs
    +++ /dev/null
    @@ -1,23 +0,0 @@
    -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
    deleted file mode 100644
    index 5321b5300..000000000
    --- a/14_Bowling/csharp/Pins.cs
    +++ /dev/null
    @@ -1,56 +0,0 @@
    -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
    deleted file mode 100644
    index 85e058b7a..000000000
    --- a/14_Bowling/csharp/Program.cs
    +++ /dev/null
    @@ -1,16 +0,0 @@
    -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
    deleted file mode 100644
    index 09687232d..000000000
    --- a/14_Bowling/csharp/Utility.cs
    +++ /dev/null
    @@ -1,54 +0,0 @@
    -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();
    -        }
    -    }
    -}
    diff --git a/14_Bowling/java/Bowling.java b/14_Bowling/java/Bowling.java
    index ced25e863..998f4fb3c 100644
    --- a/14_Bowling/java/Bowling.java
    +++ b/14_Bowling/java/Bowling.java
    @@ -9,35 +9,35 @@
      * 

    * Note: The idea was to create a version of the 1970's BASIC game in Java, without introducing * new features - no additional text, error checking, etc has been added. - * + * * Converted from BASIC to Java by Darren Cardenas. */ - -public class Bowling { - - private final Scanner scan; // For user input - + +public class Bowling { + + private final Scanner scan; // For user input + public Bowling() { - + scan = new Scanner(System.in); - - } // End of constructor Bowling + + } // End of constructor Bowling public void play() { - + showIntro(); startGame(); - - } // End of method play - + + } // End of method play + private static void showIntro() { - + System.out.println(" ".repeat(33) + "BOWL"); System.out.println(" ".repeat(14) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); System.out.println("\n\n"); - } // End of method showIntro - + } // End of method showIntro + private void startGame() { int ball = 0; @@ -45,234 +45,234 @@ private void startGame() { int frame = 0; int ii = 0; // Loop iterator int jj = 0; // Loop iterator - int kk = 0; // Loop iterator + int kk = 0; // Loop iterator int numPlayers = 0; int pinsDownBefore = 0; int pinsDownNow = 0; int player = 0; int randVal = 0; int result = 0; - + int[] pins = new int[16]; - + int[][] scores = new int[101][7]; - + String userResponse = ""; System.out.println("WELCOME TO THE ALLEY"); - System.out.println("BRING YOUR FRIENDS"); + System.out.println("BRING YOUR FRIENDS"); System.out.println("OKAY LET'S FIRST GET ACQUAINTED"); System.out.println(""); System.out.println("THE INSTRUCTIONS (Y/N)"); System.out.print("? "); - + userResponse = scan.nextLine(); - - if (userResponse.toUpperCase().equals("Y")) { + + if (userResponse.toUpperCase().equals("Y")) { printRules(); } - + System.out.print("FIRST OF ALL...HOW MANY ARE PLAYING? "); numPlayers = Integer.parseInt(scan.nextLine()); - - System.out.println(""); - System.out.println("VERY GOOD..."); + + System.out.println(""); + System.out.println("VERY GOOD..."); // Begin outer while loop while (true) { - - for (ii = 1; ii <= 100; ii++) { - for (jj = 1; jj <= 6; jj++) { - scores[ii][jj] = 0; - } + + for (ii = 1; ii <= 100; ii++) { + for (jj = 1; jj <= 6; jj++) { + scores[ii][jj] = 0; + } } - - frame = 1; + + frame = 1; // Begin frame while loop while (frame < 11) { // Begin loop through all players for (player = 1; player <= numPlayers; player++) { - + pinsDownBefore = 0; ball = 1; result = 0; - - for (ii = 1; ii <= 15; ii++) { - pins[ii] = 0; + + for (ii = 1; ii <= 15; ii++) { + pins[ii] = 0; } - + while (true) { - + // Ball generator using mod '15' system - + System.out.println("TYPE ROLL TO GET THE BALL GOING."); System.out.print("? "); scan.nextLine(); - + kk = 0; pinsDownNow = 0; - + for (ii = 1; ii <= 20; ii++) { - - randVal = (int)(Math.random() * 100) + 1; - + + randVal = (int)(Math.random() * 100) + 1; + for (jj = 1; jj <= 10; jj++) { - - if (randVal < 15 * jj) { + + if (randVal < 15 * jj) { break; - } - } - pins[15 * jj - randVal] = 1; + } + } + pins[15 * jj - randVal] = 1; } - + // Pin diagram - + System.out.println("PLAYER: " + player + " FRAME: " + frame + " BALL: " + ball); - + for (ii = 0; ii <= 3; ii++) { - + System.out.println(""); - + System.out.print(" ".repeat(ii)); for (jj = 1; jj <= 4 - ii; jj++) { kk++; - - if (pins[kk] == 1) { - + + if (pins[kk] == 1) { + System.out.print("O "); - + } else { - - System.out.print("+ "); + + System.out.print("+ "); } - } + } } - + System.out.println(""); - + // Roll analysis - - for (ii = 1; ii <= 10; ii++) { - pinsDownNow += pins[ii]; + + for (ii = 1; ii <= 10; ii++) { + pinsDownNow += pins[ii]; + } + + if (pinsDownNow - pinsDownBefore == 0) { + System.out.println("GUTTER!!"); } - - if (pinsDownNow - pinsDownBefore == 0) { - System.out.println("GUTTER!!"); - } - - if (ball == 1 && pinsDownNow == 10) { - System.out.println("STRIKE!!!!!"); - - // Ring bell - for (bell = 1; bell <= 4; bell++) { - System.out.print("\007"); + + if (ball == 1 && pinsDownNow == 10) { + System.out.println("STRIKE!!!!!"); + + // Ring bell + for (bell = 1; bell <= 4; bell++) { + System.out.print("\007"); try { Thread.sleep(500); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } - } + } result = 3; } - + if (ball == 2 && pinsDownNow == 10) { System.out.println("SPARE!!!!"); - result = 2; + result = 2; } - + if (ball == 2 && pinsDownNow < 10) { System.out.println("ERROR!!!"); - result = 1; + result = 1; } - + if (ball == 1 && pinsDownNow < 10) { - System.out.println("ROLL YOUR 2ND BALL"); + System.out.println("ROLL YOUR 2ND BALL"); } - + // Storage of the scores - + System.out.println(""); - + scores[frame * player][ball] = pinsDownNow; - - if (ball != 2) { + + if (ball != 2) { ball = 2; - pinsDownBefore = pinsDownNow; + pinsDownBefore = pinsDownNow; - if (result != 3) { - scores[frame * player][ball] = pinsDownNow - pinsDownBefore; + if (result != 3) { + scores[frame * player][ball] = pinsDownNow - pinsDownBefore; if (result == 0) { continue; } } else { scores[frame * player][ball] = pinsDownNow; } - + } break; } - - scores[frame * player][3] = result; - + + scores[frame * player][3] = result; + } // End loop through all players - + frame++; - - } // End frame while loop + + } // End frame while loop System.out.println("FRAMES"); - + System.out.print(" "); - for (ii = 1; ii <= 10; ii++) { - System.out.print(ii + " "); + for (ii = 1; ii <= 10; ii++) { + System.out.print(ii + " "); } - + System.out.println(""); - - for (player = 1; player <= numPlayers; player++) { - for (ii = 1; ii <= 3; ii++) { - System.out.print(" "); - for (jj = 1; jj <= 10; jj++) { - System.out.print (scores[jj * player][ii] + " "); + + for (player = 1; player <= numPlayers; player++) { + for (ii = 1; ii <= 3; ii++) { + System.out.print(" "); + for (jj = 1; jj <= 10; jj++) { + System.out.print (scores[jj * player][ii] + " "); } - System.out.println(""); + System.out.println(""); } System.out.println(""); } - + System.out.println("DO YOU WANT ANOTHER GAME"); System.out.print("? "); - + userResponse = scan.nextLine(); - + if (!String.valueOf(userResponse.toUpperCase().charAt(0)).equals("Y")) { - break; + break; } - - } // End outer while loop - - } // End of method startGame - + + } // End outer while loop + + } // End of method startGame + public static void printRules() { - + System.out.println("THE GAME OF BOWLING TAKES MIND AND SKILL.DURING THE GAME"); System.out.println("THE COMPUTER WILL KEEP SCORE.YOU MAY COMPETE WITH"); System.out.println("OTHER PLAYERS[UP TO FOUR].YOU WILL BE PLAYING TEN FRAMES"); System.out.println("ON THE PIN DIAGRAM 'O' MEANS THE PIN IS DOWN...'+' MEANS THE"); System.out.println("PIN IS STANDING.AFTER THE GAME THE COMPUTER WILL SHOW YOUR"); System.out.println("SCORES ."); - + } // End of method printRules - + public static void main(String[] args) { - + Bowling game = new Bowling(); game.play(); - + } // End of method main - + } // End of class Bowling diff --git a/14_Bowling/javascript/bowling.html b/14_Bowling/javascript/bowling.html index 02030a1c8..bb5d32258 100644 --- a/14_Bowling/javascript/bowling.html +++ b/14_Bowling/javascript/bowling.html @@ -1,10 +1,9 @@ BOWLING - -

    
    +
    
     
     
     
    diff --git a/14_Bowling/javascript/bowling.js b/14_Bowling/javascript/bowling.js
    index 70c33ac73..056397cbb 100644
    --- a/14_Bowling/javascript/bowling.js
    +++ b/14_Bowling/javascript/bowling.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/14_Bowling/kotlin/README.md b/14_Bowling/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/14_Bowling/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/14_Bowling/lua/README.md b/14_Bowling/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/14_Bowling/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/14_Bowling/pascal/README.md b/14_Bowling/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/14_Bowling/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/14_Bowling/perl/README.md b/14_Bowling/perl/README.md
    index 9e030cb05..e69c8b819 100644
    --- a/14_Bowling/perl/README.md
    +++ b/14_Bowling/perl/README.md
    @@ -1,22 +1,3 @@
     Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
     
     Conversion to [Perl](https://www.perl.org/)
    -
    -###Bowling program in Perl
    -
    -Run normally, this is a fairly faithful translation of the Basic game.
    -The only real differences are a few trivial fix-ups on the prints to make it
    -look better, and the player/frame/ball line was put before the "get the ball
    -going" line to make it more obvious who's turn it is.
    -
    -However, if you run it with "-a" on the command line, it will go into
    -"advanced" mode, which means that "." is used to show pin down and "!" for
    -pin up, current running scores are shown at the end of each frame, and the
    -scoring also looks more normal at the end. This is all done because I think it
    -looks better and I wanted to see a score. Having a flag says you can play
    -whichever version of the game you like.
    -
    -Note, the original code doesn't do the 10th frame correctly, in that it will
    -never do more than 2 balls, so the best score you can get is a 290.
    -This is true in both modes. That being said, it will always give you a mediocre
    -game; I don't think I've ever seen a score over 140.
    diff --git a/14_Bowling/perl/bowling.pl b/14_Bowling/perl/bowling.pl
    deleted file mode 100755
    index 1a00cd6ba..000000000
    --- a/14_Bowling/perl/bowling.pl
    +++ /dev/null
    @@ -1,254 +0,0 @@
    -#!/usr/bin/perl
    -
    -# Bowling program in Perl
    -#   Run normally, this is a fairly faithful translation of the Basic game.
    -#   The only real differences are a few trivial fix-ups on the prints to make it
    -#   look better, and the player/frame/ball line was put before the "get the ball
    -#   going" line to make it more obvious who's turn it is.
    -#
    -#   However, if you run it with "-a" on the command line, it will go into
    -#   'advanced' mode, which means that "." is used to show pin down and "!" for
    -#   pin up, current running scores are shown at the end of each frame, and the
    -#   scoring also looks more normal at the end. This is all done because I think it
    -#   looks better and I wanted to see a score. Having a flag says you can play
    -#   whichever version of the game you like.
    -#
    -#   Note, the original code doesn't do the 10th frame correctly, in that it will
    -#   never do more than 2 balls, so the best score you can get is a 290.
    -#   This is true in both modes. That being said, it will always give you a mediocre game.
    -# Translated by Kevin Brannen (kbrannen)
    -
    -use strict;
    -use warnings;
    -
    -print "\n";
    -print " " x 34, "BASKETBALL\n";
    -print " " x 15, "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n";
    -
    -# globals
    -my @C;              # pin position matraix?
    -my @Scores;         # scores: [player num][frame][ball] # ball3 is end-result, ball4 is frame score (advanced mode)
    -my $Answer;         # get answers
    -my $Num_players;    # number of players
    -my $Advanced = 0;   # flag, 1 to use advanced code, 0 for original code
    -my $char_down = '0'; # char to show pin is down
    -my $char_up = '+';   # char to show pin is standing
    -
    -if ($ARGV[0] && $ARGV[0] eq "-a")
    -{
    -    shift;
    -    $Advanced = 1;
    -    $char_down = '.';
    -    $char_up = '!';
    -}
    -
    -print "WELCOME TO THE ALLEY\n";
    -print "BRING YOUR FRIENDS\n";
    -print "OKAY LET'S FIRST GET ACQUAINTED\n\n";
    -print "SEE THE INSTRUCTIONS (Y/N): ";
    -chomp($Answer = uc(<>));
    -if ($Answer eq "Y")
    -{
    -    print "THE GAME OF BOWLING TAKES MIND AND SKILL. DURING THE GAME\n";
    -    print "THE COMPUTER WILL KEEP SCORE.YOU MAY COMPETE WITH\n";
    -    print "OTHER PLAYERS[UP TO FOUR]. YOU WILL BE PLAYING TEN FRAMES\n";
    -    print "ON THE PIN DIAGRAM 'O' MEANS THE PIN IS DOWN...'+' MEANS THE\n";
    -    print "PIN IS STANDING. AFTER THE GAME THE COMPUTER WILL SHOW YOUR SCORES.\n";
    -}
    -
    -do {
    -    print "FIRST OF ALL...HOW MANY ARE PLAYING (1-4): ";
    -    $Num_players = int(<>);
    -} while ($Num_players < 1 || $Num_players > 4);
    -
    -print "\nVERY GOOD...\n";
    -
    -while (1)
    -{
    -    # reset all scores
    -    for my $p (1 .. $Num_players) # players
    -    {
    -        for my $f (1 .. 10) # frames
    -        {
    -            for my $b (1 .. 3) # balls
    -            {
    -                $Scores[$p][$f][$b] = 0;
    -            }
    -        }
    -    }
    -
    -    # play the game
    -    for my $frame (1 .. 10) # frame
    -    {
    -        for my $curr_player (1 .. $Num_players) # player
    -        {
    -            my $last_pins=0;    # pins down for last ball
    -            my $ball=1;         # ball number, 1 or 2
    -            my $end_result=0;   # result at end of turn: 3=strike, 2=spare, 1=pins-left
    -            for my $i (1 .. 15) { $C[$i] = 0 }
    -
    -            while (1) # another ball
    -            {
    -                # ARK BALL GENERATOR USING MOD '15' SYSTEM
    -                my $K=0;
    -                my $curr_pins=0; # pins down for this ball
    -                for my $i (1 .. 20)
    -                {
    -                    my $x = int(rand(1) * 100);
    -                    my $j;
    -                    for ($j=1 ; $j <= 10 ; $j++)
    -                    {
    -                        last if ($x < 15 * $j);
    -                    }
    -                    $C[15 * $j - $x] = 1;
    -                }
    -
    -                # ARK PIN DIAGRAM
    -                print "PLAYER: $curr_player  FRAME: $frame  BALL: $ball\n";
    -                print "PRESS ENTER TO GET THE BALL GOING.";
    -                $Answer = <>; # not used, just need an enter
    -                for my $i (0 .. 3)
    -                {
    -                    print "\n";
    -                    print " " x $i; # avoid the TAB(), just shift each row over for the triangle
    -                    for my $j (1 .. 4 - $i)
    -                    {
    -                        $K++;
    -                        print ($C[$K] == 1 ? " $char_down" : " $char_up");
    -                    }
    -                }
    -                print "\n";
    -
    -                # ARK ROLL ANALYSIS
    -                for my $i (1 .. 10)
    -                {
    -                    $curr_pins += $C[$i];
    -                }
    -                if ($curr_pins - $last_pins == 0)
    -                {
    -                    print "GUTTER!!\n";
    -                }
    -                if ($ball == 1 && $curr_pins == 10)
    -                {
    -                    print "STRIKE!!!!!\a\a\a\a\n"; # \a is for bell
    -                    $end_result = 3;
    -                }
    -                elsif ($ball == 2 && $curr_pins == 10)
    -                {
    -                    print "SPARE!!!!\n";
    -                    $end_result = 2;
    -                }
    -                elsif ($ball == 2 && $curr_pins < 10)
    -                {
    -                    if ($Advanced) { print 10 - $curr_pins, " PENS LEFT!!!\n"; }
    -                    else           { print "ERROR!!!\n"; }
    -                    $end_result = 1;
    -                }
    -                if ($ball == 1 && $curr_pins < 10)
    -                {
    -                    print "ROLL YOUR 2ND BALL\n";
    -                }
    -                print "\n";
    -
    -                # ARK STORAGE OF THE SCORES
    -                if ($Advanced) { $Scores[$curr_player][$frame][$ball] = $curr_pins - $last_pins; }
    -                else           { $Scores[$curr_player][$frame][$ball] = $curr_pins; }
    -                if ($ball == 1)
    -                {
    -                    $ball = 2;
    -                    $last_pins = $curr_pins;
    -
    -                    if ($end_result == 3) # strike, no more rolls, goto last
    -                    {
    -                        $Scores[$curr_player][$frame][$ball] = $curr_pins;
    -                    }
    -                    else
    -                    {
    -                        $Scores[$curr_player][$frame][$ball] = $curr_pins - $last_pins;
    -                        next if ($end_result == 0); # next roll
    -                    }
    -                }
    -                last;
    -            }
    -            $Scores[$curr_player][$frame][3] = $end_result;
    -        } # next player
    -        if ($Advanced)
    -        {
    -            print "Scores:\n";
    -            for my $p (1 .. $Num_players)
    -            {
    -                my $total = calc_score($p);
    -                print "\tPlayer $p: $total\n";
    -            }
    -            print "\n";
    -        }
    -    } # next frame
    -
    -    # end of game, show full scoreboard
    -    show_scoreboard();
    -
    -    print "DO YOU WANT ANOTHER GAME (Y/N): ";
    -    chomp($Answer = uc(<>));
    -    print "\n";
    -    last if ($Answer ne "Y");
    -}
    -exit(0);
    -
    -sub show_scoreboard
    -{
    -    print "FRAMES\n";
    -    for my $i (1 .. 10)
    -    {
    -        print " $i ";
    -    }
    -    print "\n";
    -    my @results = ( "-", ".", "/", "X" );
    -    for my $p (1 .. $Num_players)
    -    {
    -        print "Player $p\n" if ($Advanced);
    -        my $ball_max = ($Advanced ? 4 : 3);
    -        for my $b (1 .. $ball_max)
    -        {
    -            for my $f (1 .. 10)
    -            {
    -                if ($b != 3) { print sprintf("%2d ", $Scores[$p][$f][$b]); }
    -                else         { print sprintf("%2s ", $results[$Scores[$p][$f][$b]]); }
    -            }
    -            print "\n";
    -        }
    -        print "\n";
    -    }
    -}
    -
    -sub calc_score
    -{
    -    my $player = shift;
    -    my $total = 0;
    -    for my $frame (1 .. 10)
    -    {
    -        my $score = 0;
    -        if ($frame == 10 || $Scores[$player][$frame][3] == 1) # pins
    -        {
    -            $score = $Scores[$player][$frame][1] + $Scores[$player][$frame][2];
    -        }
    -        elsif ($Scores[$player][$frame][3] == 2) # spare
    -        {
    -            $score = 10 + $Scores[$player][$frame+1][1];
    -        }
    -        elsif ($Scores[$player][$frame][3] == 3) # strike
    -        {
    -            $score = 10 + $Scores[$player][$frame+1][1];
    -            if ($Scores[$player][$frame+1][1] == 10)
    -            {
    -                $score += ($frame < 9 ? $Scores[$player][$frame+2][1] : $Scores[$player][$frame+1][2]);
    -            }
    -            else
    -            {
    -                $score += $Scores[$player][$frame+1][2];
    -            }
    -        }
    -        $Scores[$player][$frame][4] = $score;
    -        $total += $score;
    -    }
    -    return $total;
    -}
    diff --git a/14_Bowling/python/bowling.py b/14_Bowling/python/bowling.py
    index fc923ddbc..42eaeddbe 100644
    --- a/14_Bowling/python/bowling.py
    +++ b/14_Bowling/python/bowling.py
    @@ -1,15 +1,14 @@
     import random
    -from typing import List
     
     
    -def simulate_roll(pins: List[int]) -> None:
    +def simulateRoll(pins):
         for _ in range(20):
             x = random.randint(0, 14)
             if x < len(pins):
                 pins[x] = 1
     
     
    -def calculate_score(rolls: List[int]) -> int:
    +def calculate_score(rolls):
         score = 0
         frame = 1
         b = 1
    @@ -17,12 +16,12 @@ def calculate_score(rolls: List[int]) -> int:
             score += pins
             if b == 1:
                 if pins == 10:  # strike
    -                score += sum(rolls[index + 1 : index + 3])
    +                score += sum(rolls[index + 1:index + 3])
                     frame += 1
                 else:
                     b = 2
             else:
    -            if sum(rolls[index - 1 : index + 1]) == 10:  # spare
    +            if sum(rolls[index - 1:index + 1]) == 10:  # spare
                     score += rolls[index + 1]
                 b = 1
                 frame += 1
    @@ -33,21 +32,21 @@ def calculate_score(rolls: List[int]) -> int:
     
     
     class Player:
    -    def __init__(self, name: str) -> None:
    +    def __init__(self, name):
             self.name = name
    -        self.rolls: List[int] = []
    +        self.rolls = []
     
    -    def play_frame(self, frame: int) -> None:
    +    def play_frame(self, frame):
             extra = 0
             prev_score = 0
             pins = [0] * 10  # reset the pins
             for ball in range(2):
    -            simulate_roll(pins)
    +            simulateRoll(pins)
                 score = sum(pins)
                 self.show(pins)
                 pin_count = score - prev_score
                 self.rolls.append(pin_count)  # log the number of pins toppled this roll
    -            print(f"{pin_count} for {self.name}")
    +            print(f'{pin_count} for {self.name}')
                 if score - prev_score == 0:
                     print("GUTTER!!!")
                 if ball == 0:
    @@ -57,66 +56,67 @@ def play_frame(self, frame: int) -> None:
                         break  # cannot roll more than once in a frame
                     else:
                         print(f"next roll {self.name}")
    -            elif score == 10:
    -                print("SPARE!")
    -                extra = 1
    +            else:
    +                if score == 10:
    +                    print("SPARE!")
    +                    extra = 1
     
                 prev_score = score  # remember previous pins to distinguish ...
             if frame == 9 and extra > 0:
    -            print(f"Extra rolls for {self.name}")
    +            print(f'Extra rolls for {self.name}')
                 pins = [0] * 10  # reset the pins
                 score = 0
    -            for _ball in range(extra):
    +            for ball in range(extra):
                     if score == 10:
                         pins = [0] * 10
    -                simulate_roll(pins)
    +                simulateRoll(pins)
                     score = sum(pins)
                     self.rolls.append(score)
     
    -    def __str__(self) -> str:
    -        return f"{self.name}: {self.rolls}, total:{calculate_score(self.rolls)}"
    +    def __str__(self):
    +        return f'{self.name}: {self.rolls}, total:{calculate_score(self.rolls)}'
     
    -    def show(self, pins: List[int]) -> None:
    +    def show(self, pins):
             pins_iter = iter(pins)
             print()
             for row in range(4):
    -            print(" " * row, end="")
    +            print(' ' * row, end='')
                 for _ in range(4 - row):
                     p = next(pins_iter)
    -                print("O " if p else "+ ", end="")
    +                print('O ' if p else '+ ', end='')
                 print()
     
     
    -def centre_text(text: str, width: int) -> str:
    +def centreText(text, width):
         t = len(text)
    -    return (" " * ((width - t) // 2)) + text
    +    return (' ' * ((width - t) // 2)) + text
     
     
    -def main() -> None:
    -    print(centre_text("Bowl", 80))
    -    print(centre_text("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY", 80))
    +def main():
    +    print(centreText('Bowl', 80))
    +    print(centreText('CREATIVE COMPUTING MORRISTOWN, NEW JERSEY', 80))
         print()
    -    print("WELCOME TO THE ALLEY.")
    -    print("BRING YOUR FRIENDS.")
    +    print('WELCOME TO THE ALLEY.')
    +    print('BRING YOUR FRIENDS.')
         print("OKAY LET'S FIRST GET ACQUAINTED.")
     
         while True:
             print()
    -        if input("THE INSTRUCTIONS (Y/N)? ") in "yY":
    -            print("THE GAME OF BOWLING TAKES MIND AND SKILL. DURING THE GAME")
    -            print("THE COMPUTER WILL KEEP SCORE. YOU MAY COMPETE WITH")
    -            print("OTHER PLAYERS[UP TO FOUR]. YOU WILL BE PLAYING TEN FRAMES.")
    +        if input('THE INSTRUCTIONS (Y/N)? ') in 'yY':
    +            print('THE GAME OF BOWLING TAKES MIND AND SKILL. DURING THE GAME')
    +            print('THE COMPUTER WILL KEEP SCORE. YOU MAY COMPETE WITH')
    +            print('OTHER PLAYERS[UP TO FOUR]. YOU WILL BE PLAYING TEN FRAMES.')
                 print("ON THE PIN DIAGRAM 'O' MEANS THE PIN IS DOWN...'+' MEANS THE")
    -            print("PIN IS STANDING. AFTER THE GAME THE COMPUTER WILL SHOW YOUR")
    -            print("SCORES.")
    +            print('PIN IS STANDING. AFTER THE GAME THE COMPUTER WILL SHOW YOUR')
    +            print('SCORES.')
     
    -        total_players = int(input("FIRST OF ALL...HOW MANY ARE PLAYING? "))
    +        total_players = int(input('FIRST OF ALL...HOW MANY ARE PLAYING? '))
    +        player_names = []
             print()
    -        print("VERY GOOD...")
    -        player_names = [
    -            Player(input(f"Enter name for player {index + 1}: "))
    -            for index in range(total_players)
    -        ]
    +        print('VERY GOOD...')
    +        for index in range(total_players):
    +            player_names.append(Player(input(f'Enter name for player {index + 1}: ')))
    +
             for frame in range(10):
                 for player in player_names:
                     player.play_frame(frame)
    @@ -124,11 +124,11 @@ def main() -> None:
             for player in player_names:
                 print(player)
     
    -        if input("DO YOU WANT ANOTHER GAME? ") not in "yY":
    +        if input('DO YOU WANT ANOTHER GAME? ') not in 'yY':
                 break
     
     
    -if __name__ == "__main__":
    +if __name__ == '__main__':
         main()
     
     
    diff --git a/14_Bowling/rust/Cargo.lock b/14_Bowling/rust/Cargo.lock
    deleted file mode 100644
    index 54f98ac40..000000000
    --- a/14_Bowling/rust/Cargo.lock
    +++ /dev/null
    @@ -1,77 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 4
    -
    -[[package]]
    -name = "bowling"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
    -
    -[[package]]
    -name = "chacha20"
    -version = "0.10.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81"
    -dependencies = [
    - "cfg-if",
    - "cpufeatures",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "cpufeatures"
    -version = "0.3.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201"
    -dependencies = [
    - "libc",
    -]
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.4.3"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "r-efi",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.189"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
    -
    -[[package]]
    -name = "r-efi"
    -version = "6.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
    -
    -[[package]]
    -name = "rand"
    -version = "0.10.2"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80"
    -dependencies = [
    - "chacha20",
    - "getrandom",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.10.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69"
    diff --git a/14_Bowling/rust/Cargo.toml b/14_Bowling/rust/Cargo.toml
    deleted file mode 100644
    index 159e7f1f9..000000000
    --- a/14_Bowling/rust/Cargo.toml
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -[package]
    -name = "bowling"
    -version = "0.1.0"
    -edition = "2024"
    -
    -[dependencies]
    -rand = "0.10.0"
    diff --git a/14_Bowling/rust/src/main.rs b/14_Bowling/rust/src/main.rs
    deleted file mode 100644
    index 0520cfca1..000000000
    --- a/14_Bowling/rust/src/main.rs
    +++ /dev/null
    @@ -1,213 +0,0 @@
    -//! Rust port of "Bowl" (14_Bowling) from _Basic Computer Games_ (1978).
    -use rand::{rngs::ThreadRng, RngExt};
    -use std::io::{self, BufRead, Write};
    -
    -/// Number of cells in the pin-accumulator array (`DIM C(15)` in BASIC).
    -const CELLS: usize = 15;
    -/// The first ten cells correspond to the ten real pins drawn on the diagram.
    -const PINS: usize = 10;
    -
    -fn main() {
    -    println!("{:>34}BOWL", "");
    -    println!("{:>15}CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY", "");
    -    println!("\n\n");
    -
    -    println!("WELCOME TO THE ALLEY");
    -    println!("BRING YOUR FRIENDS");
    -    println!("OKAY LET'S FIRST GET ACUUAINTED");
    -    println!();
    -
    -    let mut game = BowlingGame::new();
    -    loop {
    -        let answer = prompt_line("THE INSTRUCTIONS (Y/N)");
    -        if answer.starts_with('Y') {
    -            print_instructions();
    -        } else if answer.starts_with('N') {
    -            // fall through to the game
    -        } else {
    -            continue;
    -        }
    -
    -        game.play();
    -
    -        let again = prompt_line("DO YOU WANT ANOTHER GAME");
    -        if !again.starts_with('Y') {
    -            break;
    -        }
    -    }
    -}
    -
    -fn print_instructions() {
    -    println!("THE GAME OF BOWLING TAKES MIND AND SKILL.DURING THE GAME");
    -    println!("THE COMPUTER WILL KEEP SCORE.YOU MAY COMPETE WITH");
    -    println!("OTHER PLAYERS[UP TO FOUR].YOU WILL BE PLAYING TEN FRAMES");
    -    println!("ON THE PIN DIAGRAM 'O' MEANS THE PIN IS DOWN...'+' MEANS THE");
    -    println!("PIN IS STANDING.AFTER THE GAME THE COMPUTER WILL SHOW YOUR");
    -    println!("SCORES .");
    -}
    -
    -struct BowlingGame {
    -    rng: ThreadRng,
    -}
    -
    -impl BowlingGame {
    -    fn new() -> Self {
    -        Self { rng: rand::rng() }
    -    }
    -
    -    /// Play one complete game (10 frames, all players), then print the scorecard.
    -    fn play(&mut self) {
    -        let players = loop {
    -            // "FIRST OF ALL...HOW MANY ARE PLAYING"
    -            let line = prompt_line("FIRST OF ALL...HOW MANY ARE PLAYING");
    -            if line.is_empty() {
    -                // EOF on input — bail out of this game.
    -                return;
    -            }
    -            if let Ok(n) = line.trim().parse::() {
    -                if (1..=4).contains(&n) {
    -                    break n;
    -                }
    -            }
    -            println!("?RE-ENTER");
    -        };
    -
    -        println!();
    -        println!("VERY GOOD...");
    -
    -        // One row per player: [ball1, ball2, status] for each of 10 frames.
    -        let mut scores: Vec<[[u32; 3]; 10]> = (0..players).map(|_| [[0; 3]; 10]).collect();
    -
    -        for frame in 1..=10 {
    -            for (player_idx, player_scores) in scores.iter_mut().enumerate() {
    -                self.play_ball(frame, player_idx + 1, player_scores);
    -            }
    -        }
    -
    -        print_scorecard(&scores);
    -    }
    -
    -    /// Roll the balls for one player in one frame, recording the result.
    -    fn play_ball(&mut self, frame: usize, player: usize, scores: &mut [[u32; 3]; 10]) {
    -        let mut prev_down = 0; // M: pins down after the previous ball this frame
    -        let mut status = 0; // Q: 3 strike, 2 spare, 1 error, 0 otherwise
    -
    -        let mut cells = [0u32; CELLS + 1];
    -
    -        for ball in 1..=2 {
    -            // "TYPE ROLL TO GET THE BALL GOING."
    -            let _ = prompt_line("TYPE ROLL TO GET THE BALL GOING");
    -
    -            // Knock down more pins: 20 random hits, each landing in cell
    -            // (15*J - X) where J is the smallest bucket with X < 15*J.
    -            self.roll_pins(&mut cells);
    -
    -            // Draw the triangle diagram (only the first 10 cells are real pins).
    -            print!("PLAYER:{} FRAME:{} BALL:{}\n", player, frame, ball);
    -            print_pin_diagram(&cells);
    -
    -            // Count pins down among the real pins (cells 1..=10).
    -            let down = cells[1..=PINS].iter().filter(|&&c| c == 1).count() as u32;
    -
    -            // Roll analysis. Order mirrors the original IF chain.
    -            if down == prev_down {
    -                println!("GUTTER!!");
    -            }
    -            if ball == 1 && down == 10 {
    -                println!("STRIKE!!!!!\x07\x07\x07\x07");
    -                status = 3;
    -            }
    -            if ball == 2 && down == 10 {
    -                println!("SPARE!!!!");
    -                status = 2;
    -            }
    -            if ball == 2 && down < 10 {
    -                println!("ERROR!!!");
    -                status = 1;
    -            }
    -            if ball == 1 && down < 10 {
    -                println!("ROLL YOUR 2ND BALL");
    -            }
    -            println!();
    -
    -            // Record the score for this ball: total pins down so far this frame.
    -            scores[frame - 1][ball - 1] = down;
    -
    -            if ball == 1 {
    -                prev_down = down;
    -                // On a strike, the frame ends; otherwise prompt the second ball.
    -                if status == 3 {
    -                    scores[frame - 1][1] = 0;
    -                    break;
    -                }
    -            }
    -        }
    -
    -        scores[frame - 1][2] = status;
    -    }
    -
    -    fn roll_pins(&mut self, cells: &mut [u32]) {
    -        for _ in 0..20 {
    -            let x = (self.rng.random::() * 100.0) as usize; // INT(RND(1)*100)
    -            // Find the smallest J in 1..=10 with x < 15*J.
    -            let mut j = 1;
    -            while j <= 10 && x >= 15 * j {
    -                j += 1;
    -            }
    -            // j may exceed 10 if x >= 150 (impossible here since x < 100) — guard anyway.
    -            if j <= 10 {
    -                let idx = 15 * j - x; // 1..=15
    -                if idx >= 1 && idx <= CELLS {
    -                    cells[idx] = 1;
    -                }
    -            }
    -        }
    -    }
    -}
    -
    -/// Draw the standing/down pins as a triangle: '+' standing, 'O' down.
    -fn print_pin_diagram(cells: &[u32]) {
    -    let mut k = 1; // pin index, 1-based (K in BASIC)
    -    for i in 0..4 {
    -        print!("{}", " ".repeat(i));
    -        for _ in 0..(4 - i) {
    -            if cells[k] == 1 {
    -                print!("O ");
    -            } else {
    -                print!("+ ");
    -            }
    -            k += 1;
    -        }
    -        println!();
    -    }
    -    println!();
    -}
    -
    -fn print_scorecard(scores: &[[[u32; 3]; 10]]) {
    -    println!("FRAMES");
    -    for frame in 1..=10 {
    -        print!("{} ", frame);
    -    }
    -    println!();
    -    for player_scores in scores {
    -        for row in 0..3 {
    -            for frame in 0..10 {
    -                print!("{} ", player_scores[frame][row]);
    -            }
    -            println!();
    -        }
    -        println!();
    -    }
    -}
    -
    -fn prompt_line(prompt: &str) -> String {
    -    print!("{}? ", prompt);
    -    let _ = io::stdout().lock().flush();
    -
    -    let mut buffer = String::new();
    -    // Treat EOF (or a read error) as an empty line so callers can decide what
    -    // to do — for this game, an empty answer never matches Y/N, so the program
    -    // simply exits its current loop instead of spinning forever on EOF.
    -    let _ = io::stdin().lock().read_line(&mut buffer);
    -    buffer.trim().to_uppercase()
    -}
    diff --git a/14_Bowling/vbnet/Bowling.sln b/14_Bowling/vbnet/Bowling.sln
    deleted file mode 100644
    index 98b8a996f..000000000
    --- a/14_Bowling/vbnet/Bowling.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 36ec929fa..000000000
    --- a/14_Bowling/vbnet/Bowling.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Bowling
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/15_Boxing/README.md b/15_Boxing/README.md
    index f0e6692dd..e34406766 100644
    --- a/15_Boxing/README.md
    +++ b/15_Boxing/README.md
    @@ -2,7 +2,7 @@
     
     This program simulates a three-round Olympic boxing match. The computer coaches one of the boxers and determines his punches and defences, while you do the same for your boxer. At the start of the match, you may specify your man’s best punch and his vulnerability.
     
    -There are approximately seven major punches per round, although this may be varied. The best out of three rounds wins.
    +There are approximately seven major punches per round, although this may be varied. The best out if three rounds wins.
     
     Jesse Lynch of St. Paul, Minnesota created this program.
     
    @@ -14,15 +14,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Known Bugs
    -
    -- The code that handles player punch type 1 checks for opponent weakness type 4; this is almost certainly a mistake.
    -
    -- Line breaks or finishing messages are omitted in various cases.  For example, if the player does a hook, and that's the opponent's weakness, then 7 points are silently awarded without outputting any description or line break, and the next sub-round will begin on the same line.
    -
    -- When the opponent selects a hook, control flow falls through to the uppercut case.  Perhaps related, a player weakness of type 2 (hook) never has any effect on the game.
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/15_Boxing/csharp/AttackStrategy.cs b/15_Boxing/csharp/AttackStrategy.cs
    index dbc4617d8..5ffdb2cce 100644
    --- a/15_Boxing/csharp/AttackStrategy.cs
    +++ b/15_Boxing/csharp/AttackStrategy.cs
    @@ -21,7 +21,7 @@ public void Attack()
             {
                 Other.DamageTaken += 2;
             }
    -
    +        
             Work.Push(punch.Punch switch
             {
                 Punch.FullSwing => FullSwing,
    @@ -36,7 +36,7 @@ public void Attack()
         protected abstract void Hook();
         protected abstract void Uppercut();
         protected abstract void Jab();
    -
    +    
         protected void RegisterKnockout(string knockoutMessage)
         {
             Work.Clear();
    @@ -45,4 +45,4 @@ protected void RegisterKnockout(string 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
    index 1162826b3..3f5fdd265 100644
    --- a/15_Boxing/csharp/Boxer.cs
    +++ b/15_Boxing/csharp/Boxer.cs
    @@ -42,4 +42,4 @@ public void SetRandomPunches()
                 Vulnerability = (Punch) GameUtils.Roll(4); // D1
             } while (BestPunch == Vulnerability);
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/15_Boxing/csharp/OpponentAttackStrategy.cs b/15_Boxing/csharp/OpponentAttackStrategy.cs
    index b2617685d..c5bf3e388 100644
    --- a/15_Boxing/csharp/OpponentAttackStrategy.cs
    +++ b/15_Boxing/csharp/OpponentAttackStrategy.cs
    @@ -112,4 +112,4 @@ protected override void Jab() // 640
     
         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
    index b523ed748..fd43c0ed1 100644
    --- a/15_Boxing/csharp/PlayerAttackStrategy.cs
    +++ b/15_Boxing/csharp/PlayerAttackStrategy.cs
    @@ -6,7 +6,7 @@ public class PlayerAttackStrategy : AttackStrategy
     {
         private readonly Boxer _player;
     
    -    public PlayerAttackStrategy(Boxer player, Opponent opponent, Action notifyGameEnded, Stack work)
    +    public PlayerAttackStrategy(Boxer player, Opponent opponent, Action notifyGameEnded, Stack work) 
             : base(opponent, work, notifyGameEnded) => _player = player;
     
         protected override AttackPunch GetPunch()
    @@ -118,4 +118,4 @@ protected override void Jab()
     
             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
    index 6f7404981..57923de00 100644
    --- a/15_Boxing/csharp/Program.cs
    +++ b/15_Boxing/csharp/Program.cs
    @@ -6,9 +6,9 @@
     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();
    +var opponent = new Opponent(); 
     opponent.SetName("WHAT IS YOUR OPPONENT'S NAME"); // J$
    -var player = new Boxer();
    +var player = new Boxer(); 
     player.SetName("INPUT YOUR MAN'S NAME"); // L$
     
     PrintPunchDescription();
    @@ -26,4 +26,4 @@
         round.CheckPlayerWin();
         if (round.GameEnded) break;
     }
    -WriteLine("{0}{0}AND NOW GOODBYE FROM THE OLYMPIC ARENA.{0}", Environment.NewLine);
    +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
    index dc2db88e5..add2003a5 100644
    --- a/15_Boxing/csharp/Punch.cs
    +++ b/15_Boxing/csharp/Punch.cs
    @@ -6,4 +6,4 @@ public enum Punch
         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
    index 20220d20b..dfa1e26ba 100644
    --- a/15_Boxing/csharp/Round.cs
    +++ b/15_Boxing/csharp/Round.cs
    @@ -2,14 +2,14 @@
     
     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)
    @@ -34,7 +34,7 @@ public void Start()
                 // 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);
    +            Thread.Sleep(300); 
                 action();
             }
         }
    @@ -47,7 +47,7 @@ public void CheckOpponentWin()
                 GameEnded = true;
             }
         }
    -
    +    
         public void CheckPlayerWin()
         {
             if (_player.IsWinner)
    @@ -63,7 +63,7 @@ private void ResetPlayers()
             _opponent.ResetForNewRound();
             _work.Push(RoundBegins);
         }
    -
    +    
         private void RoundBegins()
         {
             Console.WriteLine();
    @@ -93,4 +93,4 @@ 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
    index 55dc7a4a5..1ada516ca 100644
    --- a/15_Boxing/csharp/Utils.cs
    +++ b/15_Boxing/csharp/Utils.cs
    @@ -17,7 +17,7 @@ public static Punch GetPunch(string prompt)
             }
             return result;
         }
    -
    +    
         public static Func Roll { get;  } =  upperLimit => (int) (upperLimit * Rnd.NextSingle()) + 1;
     
         public static bool RollSatisfies(int upperLimit, Predicate predicate) => predicate(Roll(upperLimit));
    @@ -32,4 +32,4 @@ public static string ToFriendlyString(this Punch punch)
                 _ => throw new ArgumentOutOfRangeException(nameof(punch), punch, null)
             };
     
    -}
    +}
    \ No newline at end of file
    diff --git a/15_Boxing/java/Basic.java b/15_Boxing/java/Basic.java
    index 5fcd5baf9..3822e3f3e 100644
    --- a/15_Boxing/java/Basic.java
    +++ b/15_Boxing/java/Basic.java
    @@ -42,4 +42,4 @@ public void print(String message, Object... args) {
                 System.out.printf(message, args);
             }
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/15_Boxing/java/Boxing.java b/15_Boxing/java/Boxing.java
    index 0eb694597..64b20155e 100644
    --- a/15_Boxing/java/Boxing.java
    +++ b/15_Boxing/java/Boxing.java
    @@ -7,9 +7,9 @@
      * 

    */ public class Boxing { - + private static final Basic.Console console = new Basic.Console(); - + private GameSession session; public void play() { @@ -224,4 +224,4 @@ private void showIntro () { console.print(" CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n\n\n"); console.print("BOXING OLYMPIC STYLE (3 ROUNDS -- 2 OUT OF 3 WINS)\n\n"); } -} +} \ No newline at end of file diff --git a/15_Boxing/java/GameSession.java b/15_Boxing/java/GameSession.java index 70292a121..3a2c77a5e 100644 --- a/15_Boxing/java/GameSession.java +++ b/15_Boxing/java/GameSession.java @@ -64,4 +64,4 @@ public boolean isGameWinner(Player player) { public boolean isPlayerKnocked() { return knocked; } -} +} \ No newline at end of file diff --git a/15_Boxing/java/Player.java b/15_Boxing/java/Player.java index e2cc152fc..2462b9d0a 100644 --- a/15_Boxing/java/Player.java +++ b/15_Boxing/java/Player.java @@ -39,4 +39,4 @@ public Player(String name) { public boolean hitVulnerability(Punch punch) { return vulnerability == punch; } -} +} \ No newline at end of file diff --git a/15_Boxing/javascript/boxing.html b/15_Boxing/javascript/boxing.html index 48881b395..f72e1eb49 100644 --- a/15_Boxing/javascript/boxing.html +++ b/15_Boxing/javascript/boxing.html @@ -1,10 +1,9 @@ BOXING - -

    
    +
    
     
     
     
    diff --git a/15_Boxing/javascript/boxing.js b/15_Boxing/javascript/boxing.js
    index 197c2f533..12620f77d 100644
    --- a/15_Boxing/javascript/boxing.js
    +++ b/15_Boxing/javascript/boxing.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/15_Boxing/kotlin/README.md b/15_Boxing/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/15_Boxing/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/15_Boxing/lua/README.md b/15_Boxing/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/15_Boxing/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/15_Boxing/pascal/README.md b/15_Boxing/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/15_Boxing/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/15_Boxing/perl/boxing.pl b/15_Boxing/perl/boxing.pl
    deleted file mode 100644
    index 5068e58a4..000000000
    --- a/15_Boxing/perl/boxing.pl
    +++ /dev/null
    @@ -1,252 +0,0 @@
    -#!/usr/bin/perl
    -
    -# Boxing program in Perl
    -#   Required extensive restructuring to remove all of the GOTO's.
    -# Translated by Kevin Brannen (kbrannen)
    -
    -use strict;
    -use warnings;
    -
    -# globals
    -my $Opp_won = 0;    # num rounds opponent has won
    -my $You_won = 0;    # num rounds you have won
    -my $Opp_name = "";  # opponent name
    -my $Your_name = ""; # your name
    -my $Your_best = 0;  # your best punch
    -my $Your_worst = 0; # your worst punch
    -my $Opp_best;       # opponent best punch
    -my $Opp_worst;      # opponent worst punch
    -my $Opp_damage;     # opponent damage ?
    -my $Your_damage;    # your damage ?
    -
    -sub get_punch
    -{
    -    my $prompt = shift;
    -    my $p;
    -    while (1)
    -    {
    -        print "$prompt: ";
    -        chomp($p = int(<>));
    -        last if ($p >= 1 && $p <= 4);
    -        print "DIFFERENT PUNCHES ARE: (1) FULL SWING; (2) HOOK; (3) UPPERCUT; (4) JAB.\n";
    -    }
    -    return $p;
    -}
    -
    -print "\n";
    -print " " x 33, "BOXING\n";
    -print " " x 15, "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n";
    -
    -print "BOXING OLYMPIC STYLE (3 ROUNDS -- 2 OUT OF 3 WINS)\n\n";
    -print "WHAT IS YOUR OPPONENT'S NAME: ";
    -chomp($Opp_name = <>);
    -print "INPUT YOUR MAN'S NAME: ";
    -chomp($Your_name = <>);
    -print "DIFFERENT PUNCHES ARE: (1) FULL SWING; (2) HOOK; (3) UPPERCUT; (4) JAB.\n";
    -$Your_best = get_punch("WHAT IS YOUR MANS BEST");
    -$Your_worst = get_punch("WHAT IS HIS VULNERABILITY");
    -
    -do {
    -    $Opp_best = int(4*rand(1)+1);
    -    $Opp_worst = int(4*rand(1)+1);
    -} while ($Opp_best == $Opp_worst);
    -print "$Opp_name\'S ADVANTAGE IS $Opp_best AND VULNERABILITY IS SECRET.\n\n";
    -
    -for my $R (1 .. 3) # rounds
    -{
    -    last if ($Opp_won >= 2 || $You_won >= 2);
    -    $Opp_damage = 0;
    -    $Your_damage = 0;
    -    print "ROUND $R BEGINS...\n";
    -    for my $R1 (1 .. 7) # 7 events per round?
    -    {
    -        if (int(10*rand(1)+1) <= 5)
    -        {
    -            my $your_punch = get_punch("$Your_name\'S PUNCH");
    -            $Opp_damage += 2 if ($your_punch == $Your_best);
    -
    -            if    ($your_punch == 1) { punch1(); }
    -            elsif ($your_punch == 2) { punch2(); }
    -            elsif ($your_punch == 3) { punch3(); }
    -            else                     { punch4(); }
    -            next;
    -        }
    -
    -        my $Opp_punch = int(4*rand(1)+1);
    -        $Your_damage += 2 if ($Opp_punch  == $Opp_best);
    -            
    -        if    ($Opp_punch == 1) { opp1(); }
    -        elsif ($Opp_punch == 2) { opp2(); }
    -        elsif ($Opp_punch == 3) { opp3(); }
    -        else                    { opp4(); }
    -    }
    -
    -    if ($Opp_damage > $Your_damage)
    -    {
    -        print "\n$Your_name WINS ROUND $R\n\n";
    -        $You_won++;
    -    }
    -    else
    -    {
    -        print "\n$Opp_name WINS ROUND $R\n\n";
    -        $Opp_won++;
    -    }
    -}
    -
    -if ($Opp_won >= 2)
    -{
    -    done("$Opp_name WINS (NICE GOING, $Opp_name).");
    -}
    -
    -#else # if ($You_won >= 2)
    -done("$Your_name AMAZINGLY WINS!!");
    -
    -###################################################
    -
    -sub done
    -{
    -    my $msg = shift;
    -    print $msg;
    -    print "\n\nAND NOW GOODBYE FROM THE OLYMPIC ARENA.\n\n";
    -    exit(0);
    -}
    -
    -sub punch1
    -{
    -    # $your_punch == 1, full swing
    -    print "$Your_name SWINGS AND ";
    -    if ($Opp_worst == 4 || int(30*rand(1)+1) < 10)
    -    {
    -        print "HE CONNECTS!\n";
    -        if ($Opp_damage > 35)
    -        {
    -            done("$Opp_name IS KNOCKED COLD AND $Your_name IS THE WINNER AND CHAMP! ");
    -        }
    -        $Opp_damage += 15;
    -    }
    -    else
    -    {
    -        print "HE MISSES\n";
    -        print "\n\n" if ($Opp_damage != 1);
    -    }
    -}
    -
    -sub punch2
    -{
    -    # $your_punch == 2, hook
    -    print "$Your_name GIVES THE HOOK... ";
    -    if ($Opp_worst == 2)
    -    {
    -        $Opp_damage += 7;
    -        return;
    -    }
    -    if (int(2*rand(1)+1) == 1)
    -    {
    -        print "BUT IT'S BLOCKED!!!!!!!!!!!!!\n";
    -    }
    -    else
    -    {
    -        print "CONNECTS...\n";
    -        $Opp_damage += 7;
    -    }
    -}
    -
    -sub punch3
    -{
    -    # $your_punch == 3, uppercut
    -    print "$Your_name TRIES AN UPPERCUT ";
    -    if ($Opp_worst == 3 || int(100*rand(1)+1) < 51)
    -    {
    -        print "AND HE CONNECTS!\n";
    -        $Opp_damage += 4;
    -    }
    -    else
    -    {
    -        print "AND IT'S BLOCKED (LUCKY BLOCK!)\n";
    -    }
    -}
    -
    -sub punch4
    -{
    -    # $your_punch == 4, jab
    -    print "$Your_name JABS AT $Opp_name\'S HEAD ";
    -    if ($Opp_worst == 4 || (int(8*rand(1)+1)) >= 4)
    -    {
    -        $Opp_damage += 3;
    -        print "\n";
    -    }
    -    else
    -    {
    -        print "IT'S BLOCKED.\n";
    -    }
    -}
    -
    -sub opp1
    -{
    -    # opp_punch == 1
    -    print "$Opp_name TAKES A FULL SWING AND ";
    -    if ($Your_worst == 1 || int(60*rand(1)+1) < 30)
    -    {
    -        print " POW!!!!! HE HITS HIM RIGHT IN THE FACE!\n";
    -        if ($Your_damage > 35)
    -        {
    -            done("$Your_name IS KNOCKED COLD AND $Opp_name IS THE WINNER AND CHAMP!");
    -        }
    -        $Your_damage += 15;
    -    }
    -    else
    -    {
    -        print " IT'S BLOCKED!\n";
    -    }
    -}
    -
    -sub opp2
    -{
    -    # opp_punch == 2
    -    print "$Opp_name GETS $Your_name IN THE JAW (OUCH!)\n";
    -    $Your_damage += 7;
    -    print "....AND AGAIN!\n";
    -    $Your_damage += 5;
    -    if ($Your_damage > 35)
    -    {
    -        done("$Your_name IS KNOCKED COLD AND $Opp_name IS THE WINNER AND CHAMP!");
    -    }
    -    print "\n";
    -    # 2 continues into opp_punch == 3
    -    opp3();
    -}
    -
    -sub opp3()
    -{
    -    # opp_punch == 3
    -    print "$Your_name IS ATTACKED BY AN UPPERCUT (OH,OH)...\n";
    -    if ($Your_worst != 3 && int(200*rand(1)+1) > 75)
    -    {
    -        print " BLOCKS AND HITS $Opp_name WITH A HOOK.\n";
    -        $Opp_damage += 5;
    -    }
    -    else
    -    {
    -        print "AND $Opp_name CONNECTS...\n";
    -        $Your_damage += 8;
    -    }
    -}
    -
    -sub opp4
    -{
    -    # opp_punch == 4
    -    print "$Opp_name JABS AND ";
    -    if ($Your_worst == 4)
    -    {
    -        $Your_damage += 5;
    -    }
    -    elsif (int(7*rand(1)+1) > 4)
    -    {
    -        print " BLOOD SPILLS !!!\n";
    -        $Your_damage += 5;
    -    }
    -    else
    -    {
    -        print "IT'S BLOCKED!\n";
    -    }
    -}
    diff --git a/15_Boxing/python/boxing.py b/15_Boxing/python/boxing.py
    index 907f645c7..3db8d2647 100755
    --- a/15_Boxing/python/boxing.py
    +++ b/15_Boxing/python/boxing.py
    @@ -1,180 +1,148 @@
     #!/usr/bin/env python3
    -import json
     import random
    -from dataclasses import dataclass
    -from pathlib import Path
    -from typing import Dict, Literal, NamedTuple, Tuple, cast
     
    +QUESTION_PROMPT = '? '
     
    -class PunchProfile(NamedTuple):
    -    choices: int
    -    threshold: int
    -    hit_damage: int
    -    block_damage: int
    +def play():
    +    print('BOXING')
    +    print('CREATIVE COMPUTING   MORRISTOWN, NEW JERSEY')
    +    print('\n\n')
    +    print('BOXING OLYMPIC STYLE (3 ROUNDS -- 2 OUT OF 3 WINS)')
     
    -    pre_msg: str
    -    hit_msg: str
    -    blocked_msg: str
    +    opponent_score = 0
    +    player_score = 0
     
    -    knockout_possible: bool = False
    +    opponent_damage = 0
    +    player_damage = 0
     
    -    def is_hit(self) -> bool:
    -        return random.randint(1, self.choices) <= self.threshold
    -
    -
    -@dataclass
    -class Player:
    -    name: str
    -    best: int  # this hit guarantees 2 damage on opponent
    -    weakness: int  # you're always hit when your opponent uses this punch
    -    is_computer: bool
    -
    -    # for each of the 4 punch types, we have a probability of hitting
    -    punch_profiles: Dict[Literal[1, 2, 3, 4], PunchProfile]
    -
    -    damage: int = 0
    -    score: int = 0
    -    knockedout: bool = False
    -
    -    def get_punch_choice(self) -> Literal[1, 2, 3, 4]:
    -        if self.is_computer:
    -            return random.randint(1, 4)  # type: ignore
    -        punch = -1
    -        while punch not in [1, 2, 3, 4]:
    -            print(f"{self.name}'S PUNCH", end="? ")
    -            punch = int(input())
    -        return punch  # type: ignore
    -
    -
    -KNOCKOUT_THRESHOLD = 35
    -
    -QUESTION_PROMPT = "? "
    -KNOCKED_COLD = "{loser} IS KNOCKED COLD AND {winner} IS THE WINNER AND CHAMP"
    +    opponent_knockedout = False
    +    player_knockedout = False
     
    +    print('WHAT IS YOUR OPPONENT\'S NAME', end=QUESTION_PROMPT)
    +    opponent_name = input()
    +    print('WHAT IS YOUR MAN\'S NAME', end=QUESTION_PROMPT)
    +    player_name = input()
     
    -def get_vulnerability() -> int:
    -    print("WHAT IS HIS VULNERABILITY", end=QUESTION_PROMPT)
    -    return int(input())
    +    print('DIFFERENT PUNCHES ARE 1 FULL SWING 2 HOOK 3 UPPERCUT 4 JAB')
    +    print('WHAT IS YOUR MAN\'S BEST', end=QUESTION_PROMPT)
    +    player_best = int(input())
     
    +    print('WHAT IS HIS VULNERABILITY', end=QUESTION_PROMPT)
    +    player_weakness = int(input())
     
    -def get_opponent_stats() -> Tuple[int, int]:
         opponent_best = 0
    -    opponent_weakness = 0
    +    opponent_weakness = 0 
         while opponent_best == opponent_weakness:
             opponent_best = random.randint(1, 4)
             opponent_weakness = random.randint(1, 4)
    -    return opponent_best, opponent_weakness
    -
    -
    -def read_punch_profiles(filepath: Path) -> Dict[Literal[1, 2, 3, 4], PunchProfile]:
    -    with open(filepath) as f:
    -        punch_profile_dict = json.load(f)
    -    return {
    -        cast(Literal[1, 2, 3, 4], int(key)): PunchProfile(**value)
    -        for key, value in punch_profile_dict.items()
    -    }
    -
     
    -def main() -> None:
    -    print("BOXING")
    -    print("CREATIVE COMPUTING   MORRISTOWN, NEW JERSEY")
    -    print("\n\n")
    -    print("BOXING OLYMPIC STYLE (3 ROUNDS -- 2 OUT OF 3 WINS)")
    -
    -    print("WHAT IS YOUR OPPONENT'S NAME", end=QUESTION_PROMPT)
    -    opponent_name = input()
    -    print("WHAT IS YOUR MAN'S NAME", end=QUESTION_PROMPT)
    -    player_name = input()
    -
    -    print("DIFFERENT PUNCHES ARE 1 FULL SWING 2 HOOK 3 UPPERCUT 4 JAB")
    -    print("WHAT IS YOUR MAN'S BEST", end=QUESTION_PROMPT)
    -    player_best = int(input())  # noqa: TODO - this likely is a bug!
    -    player_weakness = get_vulnerability()
    -    player = Player(
    -        name=player_name,
    -        best=player_best,
    -        weakness=player_weakness,
    -        is_computer=False,
    -        punch_profiles=read_punch_profiles(
    -            Path(__file__).parent / "player-profile.json"
    -        ),
    -    )
    -
    -    opponent_best, opponent_weakness = get_opponent_stats()
    -    opponent = Player(
    -        name=opponent_name,
    -        best=opponent_best,
    -        weakness=opponent_weakness,
    -        is_computer=True,
    -        punch_profiles=read_punch_profiles(
    -            Path(__file__).parent / "opponent-profile.json"
    -        ),
    -    )
    -
    -    print(
    -        f"{opponent.name}'S ADVANTAGE is {opponent.weakness} AND VULNERABILITY IS SECRET."
    -    )
    -
    -    for round_number in (1, 2, 3):
    -        play_round(round_number, player, opponent)
    -
    -    if player.knockedout:
    -        print(KNOCKED_COLD.format(loser=player.name, winner=opponent.name))
    -    elif opponent.knockedout:
    -        print(KNOCKED_COLD.format(loser=opponent.name, winner=player.name))
    -    elif opponent.score > player.score:
    -        print(f"{opponent.name} WINS (NICE GOING), {player.name}")
    -    else:
    -        print(f"{player.name} AMAZINGLY WINS")
    -
    -    print("\n\nAND NOW GOODBYE FROM THE OLYMPIC ARENA.")
    -
    -
    -def is_opponents_turn() -> bool:
    -    return random.randint(1, 10) > 5
    -
    -
    -def play_round(round_number: int, player: Player, opponent: Player) -> None:
    -    print(f"ROUND {round_number} BEGINS...\n")
    -    if opponent.score >= 2 or player.score >= 2:
    -        return
    -
    -    for _action in range(7):
    -        if is_opponents_turn():
    -            punch = opponent.get_punch_choice()
    -            active = opponent
    -            passive = player
    -        else:
    -            punch = player.get_punch_choice()
    -            active = player
    -            passive = opponent
    -
    -        # Load the hit characteristics of the current player's punch
    -        punch_profile = active.punch_profiles[punch]
    -
    -        if punch == active.best:
    -            passive.damage += 2
    -
    -        print(punch_profile.pre_msg.format(active=active, passive=passive), end=" ")
    -        if passive.weakness == punch or punch_profile.is_hit():
    -            print(punch_profile.hit_msg.format(active=active, passive=passive))
    -            if punch_profile.knockout_possible and passive.damage > KNOCKOUT_THRESHOLD:
    -                passive.knockedout = True
    -                break
    -            passive.damage += punch_profile.hit_damage
    +    print('{}\'S ADVANTAGE is {} AND VULNERABILITY IS SECRET.'
    +          .format(opponent_name, opponent_weakness))
    +
    +    for round in (1, 2, 3):
    +        print('ROUND {} BEGINS...\n'.format(round))
    +        if opponent_score >= 2 or player_score >= 2:
    +            break
    +
    +        for action in range(7):
    +            if random.randint(1, 10) > 5:
    +                # opponent swings
    +                punch = random.randint(1, 4)
    +
    +                if punch == player_weakness:
    +                    player_damage += 2
    +
    +                if punch == 1:
    +                    print('{} TAKES A FULL SWING AND'.format(opponent_name), end = ' ')
    +                    if player_weakness == 1 or random.randint(1, 60) < 30:
    +                        print('POW!!!! HE HITS HIM RIGHT IN THE FACE!')
    +                        if player_damage > 35:
    +                            player_knockedout = True
    +                            break
    +                        player_damage += 15
    +                    else:
    +                        print('BUT IT\'S BLOCKED!')
    +                elif punch == 2:
    +                    print('{} GETS {} IN THE JAW (OUCH!)'.format(opponent_name, player_name), end = ' ')
    +                    player_damage += 7
    +                    print('....AND AGAIN')
    +                    if player_damage > 35:
    +                        player_knockedout = True
    +                        break
    +                    player_damage += 5
    +                elif punch == 3:
    +                    print('{} IS ATTACKED BY AN UPPERCUT (OH,OH)'.format(player_name))
    +                    if player_weakness == 3 or random.randint(1, 200) > 75:
    +                        print('{} BLOCKS AND HITS {} WITH A HOOK'.format(player_name, opponent_name))
    +                        opponent_damage += 5
    +                    else:
    +                        print('AND {} CONNECTS...'.format(opponent_name))
    +                        player_damage += 8
    +                else:
    +                    print('{} JABS AND'.format(opponent_name), end = ' ')
    +                    if player_weakness == 4 or random.randint(1, 7) > 4:
    +                        print('BLOOD SPILLS !!!')
    +                        player_damage += 3
    +                    else:
    +                        print('AND IT\'S BLOCKED (LUCKY BLOCK!)')
    +            else:
    +                print('{}\'S PUNCH'.format(player_name), end='? ')
    +                punch = int(input())
    +
    +                if punch == opponent_weakness:
    +                    opponent_damage += 2
    +
    +                if punch == 1:
    +                    print('{} SWINGS AND'.format(player_name), end = ' ')
    +                    if opponent_weakness == 1 or random.randint(1, 30) < 10:
    +                        print('HE CONNECTS!')
    +                        if opponent_damage > 35:
    +                            opponent_knockedout = True
    +                            break
    +                        opponent_damage += 15
    +                    else:
    +                        print('HE MISSES')
    +                elif punch == 2:
    +                    print('{} GIVES THE HOOK...'.format(player_name), end = ' ')
    +                    if opponent_weakness == 2 or random.randint(1, 2) == 1:
    +                        print('CONNECTS...')
    +                        opponent_damage += 7
    +                    else:
    +                        print('BUT IT\'S BLOCKED!!!!!!!!!!!!!')
    +                elif punch == 3:
    +                    print('{} TRIES AN UPPERCUT'.format(player_name), end = ' ')
    +                    if opponent_weakness == 3 or random.randint(1, 100) < 51:
    +                        print('AND HE CONNECTS!')
    +                        opponent_damage += 4
    +                    else:
    +                        print('AND IT\'S BLOCKED (LUCKY BLOCK!)')
    +                else:
    +                    print('{} JABS AT {}\'S HEAD'.format(player_name, opponent_name), end = ' ')
    +                    if opponent_weakness == 4 or random.randint(1, 8) < 4:
    +                        print('AND HE CONNECTS!')
    +                        opponent_damage += 3
    +                    else:
    +                        print('AND IT\'S BLOCKED (LUCKY BLOCK!)')
    +
    +        if player_knockedout or opponent_knockedout:
    +            break
    +        elif player_damage > opponent_damage:
    +            print('{} WINS ROUND {}'.format(opponent_name, round))
    +            opponent_score += 1
             else:
    -            print(punch_profile.blocked_msg.format(active=active, passive=passive))
    -            active.damage += punch_profile.block_damage
    -
    -    if player.knockedout or opponent.knockedout:
    -        return
    -    elif player.damage > opponent.damage:
    -        print(f"{opponent.name} WINS ROUND {round_number}")
    -        opponent.score += 1
    +            print('{} WINS ROUND {}'.format(player_name, round))
    +            player_score += 1
    +
    +    if player_knockedout:
    +        print('{} IS KNOCKED COLD AND {} IS THE WINNER AND CHAMP'.format(player_name, opponent_name))
    +    elif opponent_knockedout:
    +        print('{} IS KNOCKED COLD AND {} IS THE WINNER AND CHAMP'.format(opponent_name, player_name))
    +    elif opponent_score > player_score:
    +        print('{} WINS (NICE GOING), {}'.format(opponent_name, player_name))
         else:
    -        print(f"{player.name} WINS ROUND {round_number}")
    -        player.score += 1
    +        print('{} AMAZINGLY WINS'.format(player_name))
     
    +    print('\n\nAND NOW GOODBYE FROM THE OLYMPIC ARENA.')
     
    -if __name__ == "__main__":
    -    main()
    +if __name__ == '__main__':
    +    play()
    diff --git a/15_Boxing/python/opponent-profile.json b/15_Boxing/python/opponent-profile.json
    deleted file mode 100644
    index 83cc77d8e..000000000
    --- a/15_Boxing/python/opponent-profile.json
    +++ /dev/null
    @@ -1,40 +0,0 @@
    -{
    -    "1": {
    -        "choices": 60,
    -        "threshold": 29,
    -        "hit_damage": 15,
    -        "block_damage": 0,
    -        "knockout_possible": true,
    -        "pre_msg": "{active.name} TAKES A FULL SWING",
    -        "hit_msg": "AND POW!!!! HE HITS HIM RIGHT IN THE FACE!",
    -        "blocked_msg": "BUT IT'S BLOCKED!"
    -    },
    -    "2": {
    -        "choices": 1,
    -        "threshold": 1,
    -        "hit_damage": 12,
    -        "block_damage": 0,
    -        "knockout_possible": true,
    -        "pre_msg": "{active.name} GETS {passive.name} IN THE JAW (OUCH!)....AND AGAIN",
    -        "hit_msg": "CONNECTS...",
    -        "blocked_msg": "BUT IT'S BLOCKED!!!!!!!!!!!!!"
    -    },
    -    "3": {
    -        "choices": 200,
    -        "threshold": 125,
    -        "hit_damage": 8,
    -        "block_damage": 5,
    -        "pre_msg": "{passive.name} IS ATTACKED BY AN UPPERCUT (OH,OH)",
    -        "hit_msg": "AND {active.name} CONNECTS...",
    -        "blocked_msg": "{passive.name} BLOCKS AND HITS {active.name} WITH A HOOK"
    -    },
    -    "4": {
    -        "choices": 7,
    -        "threshold": 3,
    -        "hit_damage": 3,
    -        "block_damage": 0,
    -        "pre_msg": "{active.name} JABS AND",
    -        "hit_msg": "BLOOD SPILLS !!!",
    -        "blocked_msg": "AND IT'S BLOCKED (LUCKY BLOCK!)"
    -    }
    -}
    diff --git a/15_Boxing/python/player-profile.json b/15_Boxing/python/player-profile.json
    deleted file mode 100644
    index 9272bfa09..000000000
    --- a/15_Boxing/python/player-profile.json
    +++ /dev/null
    @@ -1,38 +0,0 @@
    -{
    -    "1": {
    -        "choices": 30,
    -        "threshold": 10,
    -        "hit_damage": 15,
    -        "block_damage": 0,
    -        "pre_msg": "{active.name} SWINGS AND",
    -        "hit_msg": "HE CONNECTS!",
    -        "blocked_msg": "HE MISSES"
    -    },
    -    "2": {
    -        "choices": 2,
    -        "threshold": 1,
    -        "hit_damage": 7,
    -        "block_damage": 0,
    -        "pre_msg": "{active.name} GIVES THE HOOK...",
    -        "hit_msg": "CONNECTS...",
    -        "blocked_msg": "BUT IT'S BLOCKED!!!!!!!!!!!!!"
    -    },
    -    "3": {
    -        "choices": 100,
    -        "threshold": 50,
    -        "hit_damage": 4,
    -        "block_damage": 0,
    -        "pre_msg": "{player_name} TRIES AN UPPERCUT",
    -        "hit_msg": "AND HE CONNECTS!",
    -        "blocked_msg": "AND IT'S BLOCKED (LUCKY BLOCK!)"
    -    },
    -    "4": {
    -        "choices": 8,
    -        "threshold": 3,
    -        "hit_damage": 3,
    -        "block_damage": 0,
    -        "pre_msg": "{active.name} JABS AT {passive.name}'S HEAD",
    -        "hit_msg": "AND HE CONNECTS!",
    -        "blocked_msg": "AND IT'S BLOCKED (LUCKY BLOCK!)"
    -    }
    -}
    diff --git a/15_Boxing/vbnet/Boxing.sln b/15_Boxing/vbnet/Boxing.sln
    deleted file mode 100644
    index 4cca8bb59..000000000
    --- a/15_Boxing/vbnet/Boxing.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index f6774e72c..000000000
    --- a/15_Boxing/vbnet/Boxing.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Boxing
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/16_Bug/README.md b/16_Bug/README.md
    index ea3204596..136123ce4 100644
    --- a/16_Bug/README.md
    +++ b/16_Bug/README.md
    @@ -16,7 +16,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/16_Bug/csharp/Bug.cs b/16_Bug/csharp/Bug.cs
    deleted file mode 100644
    index 42e686d4b..000000000
    --- a/16_Bug/csharp/Bug.cs
    +++ /dev/null
    @@ -1,21 +0,0 @@
    -using System.Text;
    -using BugGame.Parts;
    -using BugGame.Resources;
    -
    -namespace BugGame;
    -
    -internal class Bug
    -{
    -    private readonly Body _body = new();
    -
    -    public bool IsComplete => _body.IsComplete;
    -
    -    public bool TryAdd(IPart part, out Message message) => _body.TryAdd(part, out message);
    -
    -    public string ToString(string pronoun, char feelerCharacter)
    -    {
    -        var builder = new StringBuilder($"*****{pronoun} Bug*****").AppendLine().AppendLine().AppendLine();
    -        _body.AppendTo(builder, feelerCharacter);
    -        return builder.ToString();
    -    }
    -}
    \ No newline at end of file
    diff --git a/16_Bug/csharp/Bug.csproj b/16_Bug/csharp/Bug.csproj
    deleted file mode 100644
    index 91e759c0c..000000000
    --- a/16_Bug/csharp/Bug.csproj
    +++ /dev/null
    @@ -1,18 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    -  
    -    
    -  
    -
    -  
    -    
    -  
    -
    -
    diff --git a/16_Bug/csharp/Bug.sln b/16_Bug/csharp/Bug.sln
    deleted file mode 100644
    index 9024df5b4..000000000
    --- a/16_Bug/csharp/Bug.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/csharp/Game.cs b/16_Bug/csharp/Game.cs
    deleted file mode 100644
    index a8989a4c6..000000000
    --- a/16_Bug/csharp/Game.cs
    +++ /dev/null
    @@ -1,86 +0,0 @@
    -using BugGame.Parts;
    -using BugGame.Resources;
    -using Games.Common.IO;
    -using Games.Common.Randomness;
    -using static System.StringComparison;
    -namespace BugGame;
    -
    -internal class Game
    -{
    -    private readonly IReadWrite _io;
    -    private readonly IRandom _random;
    -
    -    public Game(IReadWrite io, IRandom random)
    -    {
    -        _io = io;
    -        _random = random;
    -    }
    -
    -    public void Play()
    -    {
    -        _io.Write(Resource.Streams.Introduction);
    -        if (!_io.ReadString("Do you want instructions").Equals("no", InvariantCultureIgnoreCase))
    -        {
    -            _io.Write(Resource.Streams.Instructions);
    -        }
    -
    -        BuildBugs();
    -
    -        _io.Write(Resource.Streams.PlayAgain);
    -    }
    -
    -    private void BuildBugs()
    -    {
    -        var yourBug = new Bug();
    -        var myBug = new Bug();
    -
    -        while (true)
    -        {
    -            var partAdded = TryBuild(yourBug, m => m.You);
    -            Thread.Sleep(500);
    -            _io.WriteLine();
    -            partAdded |= TryBuild(myBug, m => m.I);
    -
    -            if (partAdded)
    -            {
    -                if (yourBug.IsComplete) { _io.WriteLine("Your bug is finished."); }
    -                if (myBug.IsComplete) { _io.WriteLine("My bug is finished."); }
    -
    -                if (!_io.ReadString("Do you want the picture").Equals("no", InvariantCultureIgnoreCase))
    -                {
    -                    _io.Write(yourBug.ToString("Your", 'A'));
    -                    _io.WriteLine();
    -                    _io.WriteLine();
    -                    _io.WriteLine();
    -                    _io.WriteLine();
    -                    _io.Write(myBug.ToString("My", 'F'));
    -                }
    -            }
    -
    -            if (yourBug.IsComplete || myBug.IsComplete) { break; }
    -        }
    -    }
    -
    -    private bool TryBuild(Bug bug, Func messageTransform)
    -    {
    -        var roll = _random.Next(6) + 1;
    -        _io.WriteLine(messageTransform(Message.Rolled.ForValue(roll)));
    -
    -        IPart part = roll switch
    -        {
    -            1 => new Body(),
    -            2 => new Neck(),
    -            3 => new Head(),
    -            4 => new Feeler(),
    -            5 => new Tail(),
    -            6 => new Leg(),
    -            _ => throw new Exception("Unexpected roll value")
    -        };
    -        _io.WriteLine($"{roll}={part.GetType().Name}");
    -
    -        var partAdded = bug.TryAdd(part, out var message);
    -        _io.WriteLine(messageTransform.Invoke(message));
    -
    -        return partAdded;
    -    }
    -}
    \ No newline at end of file
    diff --git a/16_Bug/csharp/Parts/Body.cs b/16_Bug/csharp/Parts/Body.cs
    deleted file mode 100644
    index 58f80405a..000000000
    --- a/16_Bug/csharp/Parts/Body.cs
    +++ /dev/null
    @@ -1,44 +0,0 @@
    -using System.Text;
    -using BugGame.Resources;
    -
    -namespace BugGame.Parts;
    -
    -internal class Body : ParentPart
    -{
    -    private readonly Neck _neck = new();
    -    private readonly Tail _tail = new();
    -    private readonly Legs _legs = new();
    -
    -    public Body()
    -        : base(Message.BodyAdded, Message.BodyNotNeeded)
    -    {
    -    }
    -
    -    public override bool IsComplete => _neck.IsComplete && _tail.IsComplete && _legs.IsComplete;
    -
    -    protected override bool TryAddCore(IPart part, out Message message)
    -        => part switch
    -        {
    -            Neck => _neck.TryAdd(out message),
    -            Head or Feeler => _neck.TryAdd(part, out message),
    -            Tail => _tail.TryAdd(out message),
    -            Leg => _legs.TryAddOne(out message),
    -            _ => throw new NotSupportedException($"Can't add a {part.Name} to a {Name}.")
    -        };
    -
    -    public void AppendTo(StringBuilder builder, char feelerCharacter)
    -    {
    -        if (IsPresent)
    -        {
    -            _neck.AppendTo(builder, feelerCharacter);
    -            builder
    -                .AppendLine("     BBBBBBBBBBBB")
    -                .AppendLine("     B          B")
    -                .AppendLine("     B          B");
    -            _tail.AppendTo(builder);
    -            builder
    -                .AppendLine("     BBBBBBBBBBBB");
    -            _legs.AppendTo(builder);
    -        }
    -    }
    -}
    diff --git a/16_Bug/csharp/Parts/Feeler.cs b/16_Bug/csharp/Parts/Feeler.cs
    deleted file mode 100644
    index 9508d5410..000000000
    --- a/16_Bug/csharp/Parts/Feeler.cs
    +++ /dev/null
    @@ -1,6 +0,0 @@
    -namespace BugGame.Parts;
    -
    -internal class Feeler : IPart
    -{
    -    public string Name => nameof(Feeler);
    -}
    diff --git a/16_Bug/csharp/Parts/Feelers.cs b/16_Bug/csharp/Parts/Feelers.cs
    deleted file mode 100644
    index 165a073da..000000000
    --- a/16_Bug/csharp/Parts/Feelers.cs
    +++ /dev/null
    @@ -1,14 +0,0 @@
    -using System.Text;
    -using BugGame.Resources;
    -
    -namespace BugGame.Parts;
    -
    -internal class Feelers : PartCollection
    -{
    -    public Feelers()
    -        : base(2, Message.FeelerAdded, Message.FeelersFull)
    -    {
    -    }
    -
    -    public void AppendTo(StringBuilder builder, char character) => AppendTo(builder, 10, 4, character);
    -}
    diff --git a/16_Bug/csharp/Parts/Head.cs b/16_Bug/csharp/Parts/Head.cs
    deleted file mode 100644
    index d71355752..000000000
    --- a/16_Bug/csharp/Parts/Head.cs
    +++ /dev/null
    @@ -1,38 +0,0 @@
    -using System.Text;
    -using BugGame.Resources;
    -
    -namespace BugGame.Parts;
    -
    -internal class Head : ParentPart
    -{
    -    private Feelers _feelers = new();
    -
    -    public Head()
    -        : base(Message.HeadAdded, Message.HeadNotNeeded)
    -    {
    -    }
    -
    -    public override bool IsComplete => _feelers.IsComplete;
    -
    -    protected override bool TryAddCore(IPart part, out Message message)
    -        => part switch
    -        {
    -            Feeler => _feelers.TryAddOne(out message),
    -            _ => throw new NotSupportedException($"Can't add a {part.Name} to a {Name}.")
    -        };
    -
    -    public void AppendTo(StringBuilder builder, char feelerCharacter)
    -    {
    -        if (IsPresent)
    -        {
    -            _feelers.AppendTo(builder, feelerCharacter);
    -            builder
    -                .AppendLine("        HHHHHHH")
    -                .AppendLine("        H     H")
    -                .AppendLine("        H O O H")
    -                .AppendLine("        H     H")
    -                .AppendLine("        H  V  H")
    -                .AppendLine("        HHHHHHH");
    -        }
    -    }
    -}
    diff --git a/16_Bug/csharp/Parts/IPart.cs b/16_Bug/csharp/Parts/IPart.cs
    deleted file mode 100644
    index e325a7c17..000000000
    --- a/16_Bug/csharp/Parts/IPart.cs
    +++ /dev/null
    @@ -1,6 +0,0 @@
    -namespace BugGame.Parts;
    -
    -internal interface IPart
    -{
    -    string Name { get; }
    -}
    diff --git a/16_Bug/csharp/Parts/Leg.cs b/16_Bug/csharp/Parts/Leg.cs
    deleted file mode 100644
    index c2d4aaaf5..000000000
    --- a/16_Bug/csharp/Parts/Leg.cs
    +++ /dev/null
    @@ -1,6 +0,0 @@
    -namespace BugGame.Parts;
    -
    -internal class Leg : IPart
    -{
    -    public string Name => nameof(Leg);
    -}
    diff --git a/16_Bug/csharp/Parts/Legs.cs b/16_Bug/csharp/Parts/Legs.cs
    deleted file mode 100644
    index 0ed8d8fc7..000000000
    --- a/16_Bug/csharp/Parts/Legs.cs
    +++ /dev/null
    @@ -1,14 +0,0 @@
    -using System.Text;
    -using BugGame.Resources;
    -
    -namespace BugGame.Parts;
    -
    -internal class Legs : PartCollection
    -{
    -    public Legs()
    -        : base(6, Message.LegAdded, Message.LegsFull)
    -    {
    -    }
    -
    -    public void AppendTo(StringBuilder builder) => AppendTo(builder, 6, 2, 'L');
    -}
    diff --git a/16_Bug/csharp/Parts/Neck.cs b/16_Bug/csharp/Parts/Neck.cs
    deleted file mode 100644
    index 23dacfb79..000000000
    --- a/16_Bug/csharp/Parts/Neck.cs
    +++ /dev/null
    @@ -1,33 +0,0 @@
    -using System.Text;
    -using BugGame.Resources;
    -
    -namespace BugGame.Parts;
    -
    -internal class Neck : ParentPart
    -{
    -    private Head _head = new();
    -
    -    public Neck()
    -        : base(Message.NeckAdded, Message.NeckNotNeeded)
    -    {
    -    }
    -
    -    public override bool IsComplete => _head.IsComplete;
    -
    -    protected override bool TryAddCore(IPart part, out Message message)
    -        => part switch
    -        {
    -            Head => _head.TryAdd(out message),
    -            Feeler => _head.TryAdd(part, out message),
    -            _ => throw new NotSupportedException($"Can't add a {part.Name} to a {Name}.")
    -        };
    -
    -    public void AppendTo(StringBuilder builder, char feelerCharacter)
    -    {
    -        if (IsPresent)
    -        {
    -            _head.AppendTo(builder, feelerCharacter);
    -            builder.AppendLine("          N N").AppendLine("          N N");
    -        }
    -    }
    -}
    diff --git a/16_Bug/csharp/Parts/ParentPart.cs b/16_Bug/csharp/Parts/ParentPart.cs
    deleted file mode 100644
    index 1ca6682f3..000000000
    --- a/16_Bug/csharp/Parts/ParentPart.cs
    +++ /dev/null
    @@ -1,27 +0,0 @@
    -using BugGame.Resources;
    -
    -namespace BugGame.Parts;
    -
    -internal abstract class ParentPart : Part
    -{
    -    public ParentPart(Message addedMessage, Message duplicateMessage)
    -        : base(addedMessage, duplicateMessage)
    -    {
    -    }
    -
    -    public bool TryAdd(IPart part, out Message message)
    -        => (part.GetType() == GetType(), IsPresent) switch
    -        {
    -            (true, _) => TryAdd(out message),
    -            (false, false) => ReportDoNotHave(out message),
    -            _ => TryAddCore(part, out message)
    -        };
    -
    -    protected abstract bool TryAddCore(IPart part, out Message message);
    -
    -    private bool ReportDoNotHave(out Message message)
    -    {
    -        message = Message.DoNotHaveA(this);
    -        return false;
    -    }
    -}
    diff --git a/16_Bug/csharp/Parts/Part.cs b/16_Bug/csharp/Parts/Part.cs
    deleted file mode 100644
    index f29fbd81f..000000000
    --- a/16_Bug/csharp/Parts/Part.cs
    +++ /dev/null
    @@ -1,34 +0,0 @@
    -using BugGame.Resources;
    -
    -namespace BugGame.Parts;
    -
    -internal class Part : IPart
    -{
    -    private readonly Message _addedMessage;
    -    private readonly Message _duplicateMessage;
    -
    -    public Part(Message addedMessage, Message duplicateMessage)
    -    {
    -        _addedMessage = addedMessage;
    -        _duplicateMessage = duplicateMessage;
    -    }
    -
    -    public virtual bool IsComplete => IsPresent;
    -
    -    protected bool IsPresent { get; private set; }
    -
    -    public string Name => GetType().Name;
    -
    -    public bool TryAdd(out Message message)
    -    {
    -        if (IsPresent)
    -        {
    -            message = _duplicateMessage;
    -            return false;
    -        }
    -
    -        message = _addedMessage;
    -        IsPresent = true;
    -        return true;
    -    }
    -}
    diff --git a/16_Bug/csharp/Parts/PartCollection.cs b/16_Bug/csharp/Parts/PartCollection.cs
    deleted file mode 100644
    index 9a0fd2eee..000000000
    --- a/16_Bug/csharp/Parts/PartCollection.cs
    +++ /dev/null
    @@ -1,50 +0,0 @@
    -using System.Text;
    -using BugGame.Resources;
    -
    -namespace BugGame.Parts;
    -
    -internal class PartCollection
    -{
    -    private readonly int _maxCount;
    -    private readonly Message _addedMessage;
    -    private readonly Message _fullMessage;
    -    private int _count;
    -
    -    public PartCollection(int maxCount, Message addedMessage, Message fullMessage)
    -    {
    -        _maxCount = maxCount;
    -        _addedMessage = addedMessage;
    -        _fullMessage = fullMessage;
    -    }
    -
    -    public bool IsComplete => _count == _maxCount;
    -
    -    public bool TryAddOne(out Message message)
    -    {
    -        if (_count < _maxCount)
    -        {
    -            _count++;
    -            message = _addedMessage.ForValue(_count);
    -            return true;
    -        }
    -
    -        message = _fullMessage;
    -        return false;
    -    }
    -
    -    protected void AppendTo(StringBuilder builder, int offset, int length, char character)
    -    {
    -        if (_count == 0) { return; }
    -
    -        for (var i = 0; i < length; i++)
    -        {
    -            builder.Append(' ', offset);
    -
    -            for (var j = 0; j < _count; j++)
    -            {
    -                builder.Append(character).Append(' ');
    -            }
    -            builder.AppendLine();
    -        }
    -    }
    -}
    diff --git a/16_Bug/csharp/Parts/Tail.cs b/16_Bug/csharp/Parts/Tail.cs
    deleted file mode 100644
    index ebf4b28fa..000000000
    --- a/16_Bug/csharp/Parts/Tail.cs
    +++ /dev/null
    @@ -1,20 +0,0 @@
    -using System.Text;
    -using BugGame.Resources;
    -
    -namespace BugGame.Parts;
    -
    -internal class Tail : Part
    -{
    -    public Tail()
    -        : base(Message.TailAdded, Message.TailNotNeeded)
    -    {
    -    }
    -
    -    public void AppendTo(StringBuilder builder)
    -    {
    -        if (IsPresent)
    -        {
    -            builder.AppendLine("TTTTTB          B");
    -        }
    -    }
    -}
    \ No newline at end of file
    diff --git a/16_Bug/csharp/Program.cs b/16_Bug/csharp/Program.cs
    deleted file mode 100644
    index 883e62d18..000000000
    --- a/16_Bug/csharp/Program.cs
    +++ /dev/null
    @@ -1,5 +0,0 @@
    -using BugGame;
    -using Games.Common.IO;
    -using Games.Common.Randomness;
    -
    -new Game(new ConsoleIO(), new RandomNumberGenerator()).Play();
    diff --git a/16_Bug/csharp/Resources/Instructions.txt b/16_Bug/csharp/Resources/Instructions.txt
    deleted file mode 100644
    index bdbdadd35..000000000
    --- a/16_Bug/csharp/Resources/Instructions.txt
    +++ /dev/null
    @@ -1,18 +0,0 @@
    -The object of Bug is to finish your bug before I finish
    -mine. Each number stands for a part of the bug body.
    -I will roll the die for you, tell you what I rolled for you
    -what the number stands for, and if you can get the part.
    -If you can get the part I will give it to you.
    -The same will happen on my turn.
    -If there is a change in either bug I will give you the
    -option of seeing the pictures of the bugs.
    -The numbers stand for parts as follows:
    -Number        Part          Number of part needed
    - 1            Body           1
    - 2            Neck           1
    - 3            Head           1
    - 4            Feelers        2
    - 5            Tail           1
    - 6            Legs           6
    -
    -
    diff --git a/16_Bug/csharp/Resources/Introduction.txt b/16_Bug/csharp/Resources/Introduction.txt
    deleted file mode 100644
    index e74a833e7..000000000
    --- a/16_Bug/csharp/Resources/Introduction.txt
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -                                Bug
    -               Creative Computing  Morristown, New Jersey
    -
    -
    -
    -The Game Bug
    -I hope you enjoy this game.
    -
    diff --git a/16_Bug/csharp/Resources/Message.cs b/16_Bug/csharp/Resources/Message.cs
    deleted file mode 100644
    index 20a59d9a8..000000000
    --- a/16_Bug/csharp/Resources/Message.cs
    +++ /dev/null
    @@ -1,46 +0,0 @@
    -using BugGame.Parts;
    -
    -namespace BugGame.Resources;
    -
    -internal class Message
    -{
    -    public static Message Rolled = new("rolled a {0}");
    -
    -    public static Message BodyAdded = new("now have a body.");
    -    public static Message BodyNotNeeded = new("do not need a body.");
    -
    -    public static Message NeckAdded = new("now have a neck.");
    -    public static Message NeckNotNeeded = new("do not need a neck.");
    -
    -    public static Message HeadAdded = new("needed a head.");
    -    public static Message HeadNotNeeded = new("I do not need a head.", "You have a head.");
    -
    -    public static Message TailAdded = new("I now have a tail.", "I now give you a tail.");
    -    public static Message TailNotNeeded = new("I do not need a tail.", "You already have a tail.");
    -
    -    public static Message FeelerAdded = new("I get a feeler.", "I now give you a feeler");
    -    public static Message FeelersFull = new("I have 2 feelers already.", "You have two feelers already");
    -
    -    public static Message LegAdded = new("now have {0} legs");
    -    public static Message LegsFull = new("I have 6 feet.", "You have 6 feet already");
    -
    -    public static Message Complete = new("bug is finished.");
    -
    -    private Message(string common)
    -        : this("I " + common, "You " + common)
    -    {
    -    }
    -
    -    private Message(string i, string you)
    -    {
    -        I = i;
    -        You = you;
    -    }
    -
    -    public string I { get; }
    -    public string You { get; }
    -
    -    public static Message DoNotHaveA(Part part) => new($"do not have a {part.Name}");
    -
    -    public Message ForValue(int quantity) => new(string.Format(I, quantity), string.Format(You, quantity));
    -}
    \ No newline at end of file
    diff --git a/16_Bug/csharp/Resources/PlayAgain.txt b/16_Bug/csharp/Resources/PlayAgain.txt
    deleted file mode 100644
    index 2380e1308..000000000
    --- a/16_Bug/csharp/Resources/PlayAgain.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -I hope you enjoyed the game, play it again soon!!
    diff --git a/16_Bug/csharp/Resources/Resource.cs b/16_Bug/csharp/Resources/Resource.cs
    deleted file mode 100644
    index 2b34a4e67..000000000
    --- a/16_Bug/csharp/Resources/Resource.cs
    +++ /dev/null
    @@ -1,19 +0,0 @@
    -using System.Reflection;
    -using System.Runtime.CompilerServices;
    -
    -namespace BugGame.Resources;
    -
    -internal static class Resource
    -{
    -    internal static class Streams
    -    {
    -        public static Stream Introduction => GetStream();
    -        public static Stream Instructions => GetStream();
    -        public static Stream PlayAgain => GetStream();
    -    }
    -
    -    private static Stream GetStream([CallerMemberName] string? name = null) =>
    -        Assembly.GetExecutingAssembly()
    -            .GetManifestResourceStream($"Bug.Resources.{name}.txt")
    -            ?? throw new Exception($"Could not find embedded resource stream '{name}'.");
    -}
    \ No newline at end of file
    diff --git a/16_Bug/java/src/Bug.java b/16_Bug/java/src/Bug.java
    index 2fc06a494..861afc5a5 100644
    --- a/16_Bug/java/src/Bug.java
    +++ b/16_Bug/java/src/Bug.java
    @@ -250,4 +250,4 @@ private int randomNumber() {
             return (int) (Math.random()
                     * (SIX) + 1);
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/16_Bug/java/src/Insect.java b/16_Bug/java/src/Insect.java
    index 747cfbb6e..08e9414f0 100644
    --- a/16_Bug/java/src/Insect.java
    +++ b/16_Bug/java/src/Insect.java
    @@ -360,4 +360,4 @@ private String addSpaces(int number) {
             return new String(spaces);
     
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/16_Bug/java/src/PlayerBug.java b/16_Bug/java/src/PlayerBug.java
    index c8f735085..1a82e8b33 100644
    --- a/16_Bug/java/src/PlayerBug.java
    +++ b/16_Bug/java/src/PlayerBug.java
    @@ -15,3 +15,4 @@ public PlayerBug() {
     
     
     }
    +
    diff --git a/16_Bug/javascript/bug.html b/16_Bug/javascript/bug.html
    index 0ce1f8722..0e718cd5d 100644
    --- a/16_Bug/javascript/bug.html
    +++ b/16_Bug/javascript/bug.html
    @@ -1,10 +1,9 @@
     
     
     BUG
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/16_Bug/javascript/bug.js b/16_Bug/javascript/bug.js
    index 5f13657bc..2d99d90ce 100644
    --- a/16_Bug/javascript/bug.js
    +++ b/16_Bug/javascript/bug.js
    @@ -10,43 +10,38 @@ function print(str)
     
     function input()
     {
    +    var input_element;
    +    var input_str;
    +    
         return new Promise(function (resolve) {
    -                       const input_element = document.createElement("INPUT");
    -
    +                       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);
    -                                      }
    -                                  });
    +                       input_str = undefined;
    +                       input_element.addEventListener("keydown", function (event) {
    +                                                      if (event.keyCode == 13) {
    +                                                      input_str = input_element.value;
    +                                                      document.getElementById("output").removeChild(input_element);
    +                                                      print(input_str);
    +                                                      print("\n");
    +                                                      resolve(input_str);
    +                                                      }
    +                                                      });
                            });
     }
     
     function tab(space)
     {
    -    let str = "";
    +    var 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");
    @@ -57,58 +52,6 @@ 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()
     {
    @@ -117,26 +60,25 @@ async function main()
         print("\n");
         print("\n");
         print("\n");
    -    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;
    -
    +    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;
         print("THE GAME BUG\n");
         print("I HOPE YOU ENJOY THIS GAME.\n");
         print("\n");
         print("DO YOU WANT INSTRUCTIONS");
    -    const instructionsRequired = await input();
    -    if (instructionsRequired.toUpperCase() !== "NO") {
    +    str = await input();
    +    if (str != "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");
    @@ -156,32 +98,30 @@ async function main()
             print("\n");
             print("\n");
         }
    -
    -    let gameInProgress = true;
    -    while (gameInProgress) {
    -        let dieRoll = Math.floor(6 * Math.random() + 1);
    -        let partFound = false;
    -        print("YOU ROLLED A " + dieRoll + "\n");
    -        switch (dieRoll) {
    +    while (y == 0) {
    +        z = Math.floor(6 * Math.random() + 1);
    +        c = 1;
    +        print("YOU ROLLED A " + z + "\n");
    +        switch (z) {
                 case 1:
                     print("1=BODY\n");
    -                if (playerBodyCount === 0) {
    +                if (b == 0) {
                         print("YOU NOW HAVE A BODY.\n");
    -                    playerBodyCount = 1;
    -                    partFound = true;
    +                    b = 1;
    +                    c = 0;
                     } else {
                         print("YOU DO NOT NEED A BODY.\n");
                     }
                     break;
                 case 2:
                     print("2=NECK\n");
    -                if (playerNeckCount === 0) {
    -                    if (playerBodyCount === 0) {
    +                if (n == 0) {
    +                    if (b == 0) {
                             print("YOU DO NOT HAVE A BODY.\n");
                         } else {
                             print("YOU NOW HAVE A NECK.\n");
    -                        playerNeckCount = 1;
    -                        partFound = true;
    +                        n = 1;
    +                        c = 0;
                         }
                     } else {
                         print("YOU DO NOT NEED A NECK.\n");
    @@ -189,158 +129,219 @@ async function main()
                     break;
                 case 3:
                     print("3=HEAD\n");
    -                if (playerNeckCount === 0) {
    +                if (n == 0) {
                         print("YOU DO NOT HAVE A NECK.\n");
    -                } else if (playerHeadCount === 0) {
    +                } else if (h == 0) {
                         print("YOU NEEDED A HEAD.\n");
    -                    playerHeadCount = 1;
    -                    partFound = true;
    +                    h = 1;
    +                    c = 0;
                     } else {
                         print("YOU HAVE A HEAD.\n");
                     }
                     break;
                 case 4:
                     print("4=FEELERS\n");
    -                if (playerHeadCount === 0) {
    +                if (h == 0) {
                         print("YOU DO NOT HAVE A HEAD.\n");
    -                } else if (playerFeelerCount === 2) {
    +                } else if (a == 2) {
                         print("YOU HAVE TWO FEELERS ALREADY.\n");
                     } else {
                         print("I NOW GIVE YOU A FEELER.\n");
    -                    playerFeelerCount ++;
    -                    partFound = true;
    +                    a++;
    +                    c = 0;
                     }
                     break;
                 case 5:
                     print("5=TAIL\n");
    -                if (playerBodyCount === 0) {
    +                if (b == 0) {
                         print("YOU DO NOT HAVE A BODY.\n");
    -                } else if (playerTailCount === 1) {
    +                } else if (t == 1) {
                         print("YOU ALREADY HAVE A TAIL.\n");
                     } else {
                         print("I NOW GIVE YOU A TAIL.\n");
    -                    playerTailCount++;
    -                    partFound = true;
    +                    t++;
    +                    c = 0;
                     }
                     break;
                 case 6:
                     print("6=LEG\n");
    -                if (playerFeetCount === 6) {
    +                if (l == 6) {
                         print("YOU HAVE 6 FEET ALREADY.\n");
    -                } else if (playerBodyCount === 0) {
    +                } else if (b == 0) {
                         print("YOU DO NOT HAVE A BODY.\n");
                     } else {
    -                    playerFeetCount++;
    -                    partFound = true;
    -                    print("YOU NOW HAVE " + playerFeetCount + " LEGS.\n");
    +                    l++;
    +                    c = 0;
    +                    print("YOU NOW HAVE " + l + " LEGS.\n");
                     }
                     break;
             }
    -        dieRoll = Math.floor(6 * Math.random() + 1) ;
    +        x = Math.floor(6 * Math.random() + 1) ;
             print("\n");
    -        scrollToBottom();
    -        await waitNSeconds(1);
    -
    -        print("I ROLLED A " + dieRoll + "\n");
    -        switch (dieRoll) {
    +        date = new Date().valueOf;
    +        while (date - new Date().valueOf < 1000000) ;
    +        print("I ROLLED A " + x + "\n");
    +        switch (x) {
                 case 1:
                     print("1=BODY\n");
    -                if (computerBodyCount === 1) {
    +                if (p == 1) {
                         print("I DO NOT NEED A BODY.\n");
                     } else {
                         print("I NOW HAVE A BODY.\n");
    -                    partFound = true;
    -                    computerBodyCount = 1;
    +                    c = 0;
    +                    p = 1;
                     }
                     break;
                 case 2:
                     print("2=NECK\n");
    -                if (computerNeckCount === 1) {
    +                if (q == 1) {
                         print("I DO NOT NEED A NECK.\n");
    -                } else if (computerBodyCount === 0) {
    +                } else if (p == 0) {
                         print("I DO NOT HAVE A BODY.\n");
                     } else {
                         print("I NOW HAVE A NECK.\n");
    -                    computerNeckCount = 1;
    -                    partFound = true;
    +                    q = 1;
    +                    c = 0;
                     }
                     break;
                 case 3:
                     print("3=HEAD\n");
    -                if (computerNeckCount === 0) {
    +                if (q == 0) {
                         print("I DO NOT HAVE A NECK.\n");
    -                } else if (computerHeadCount === 1) {
    +                } else if (r == 1) {
                         print("I DO NOT NEED A HEAD.\n");
                     } else {
                         print("I NEEDED A HEAD.\n");
    -                    computerHeadCount = 1;
    -                    partFound = true;
    +                    r = 1;
    +                    c = 0;
                     }
                     break;
                 case 4:
                     print("4=FEELERS\n");
    -                if (computerHeadCount === 0) {
    +                if (r == 0) {
                         print("I DO NOT HAVE A HEAD.\n");
    -                } else if (computerFeelerCount === 2) {
    +                } else if (s == 2) {
                         print("I HAVE 2 FEELERS ALREADY.\n");
                     } else {
                         print("I GET A FEELER.\n");
    -                    computerFeelerCount++;
    -                    partFound = true;
    +                    s++;
    +                    c = 0;
                     }
                     break;
                 case 5:
                     print("5=TAIL\n");
    -                if (computerBodyCount === 0) {
    +                if (p == 0) {
                         print("I DO NOT HAVE A BODY.\n");
    -                } else if (computerTailCount === 1) {
    +                } else if (u == 1) {
                         print("I DO NOT NEED A TAIL.\n");
                     } else {
                         print("I NOW HAVE A TAIL.\n");
    -                    computerTailCount = 1;
    -                    partFound = true;
    +                    u = 1;
    +                    c = 0;
                     }
                     break;
                 case 6:
                     print("6=LEGS\n");
    -                if (computerFeetCount === 6) {
    +                if (v == 6) {
                         print("I HAVE 6 FEET.\n");
    -                } else if (computerBodyCount === 0) {
    +                } else if (p == 0) {
                         print("I DO NOT HAVE A BODY.\n");
                     } else {
    -                    computerFeetCount++;
    -                    partFound = true;
    -                    print("I NOW HAVE " + computerFeetCount + " LEGS.\n");
    +                    v++;
    +                    c = 0;
    +                    print("I NOW HAVE " + v + " LEGS.\n");
                     }
                     break;
             }
    -        if (playerFeelerCount === 2 && playerTailCount === 1 && playerFeetCount === 6) {
    +        if (a == 2 && t == 1 && l == 6) {
                 print("YOUR BUG IS FINISHED.\n");
    -            gameInProgress = false;
    +            y++;
             }
    -        if (computerFeelerCount === 2 && computerBodyCount === 1 && computerFeetCount === 6) {
    +        if (s == 2 && p == 1 && v == 6) {
                 print("MY BUG IS FINISHED.\n");
    -            gameInProgress = false;
    +            y += 2;
             }
    -        if (!partFound)
    +        if (c == 1)
                 continue;
             print("DO YOU WANT THE PICTURES");
    -        const showPictures = await input();
    -        if (showPictures.toUpperCase() === "NO")
    +        str = await input();
    +        if (str == "NO")
                 continue;
             print("*****YOUR BUG*****\n");
             print("\n");
             print("\n");
    -        drawBug(playerFeelerCount, playerHeadCount, playerNeckCount, playerBodyCount, playerTailCount, playerFeetCount, "A");
    +        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");
             print("*****MY BUG*****\n");
             print("\n");
             print("\n");
    -        drawBug(computerFeelerCount, computerHeadCount, computerNeckCount, computerBodyCount, computerTailCount, computerFeetCount, "F");
    -        for (let z = 1; z <= 4; z++)
    +        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++)
                 print("\n");
         }
         print("I HOPE YOU ENJOYED THE GAME, PLAY IT AGAIN SOON!!\n");
    -    scrollToBottom();
     }
     
     main();
    diff --git a/16_Bug/kotlin/README.md b/16_Bug/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/16_Bug/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/16_Bug/lua/README.md b/16_Bug/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/16_Bug/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/16_Bug/pascal/README.md b/16_Bug/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/16_Bug/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/16_Bug/python/bug.py b/16_Bug/python/bug.py
    deleted file mode 100644
    index 846002f8f..000000000
    --- a/16_Bug/python/bug.py
    +++ /dev/null
    @@ -1,228 +0,0 @@
    -import random
    -import time
    -from dataclasses import dataclass
    -from typing import Literal
    -
    -
    -@dataclass
    -class State:
    -    is_player: bool
    -    body: int = 0
    -    neck: int = 0
    -    head: int = 0
    -    feelers: int = 0
    -    tail: int = 0
    -    legs: int = 0
    -
    -    def is_finished(self) -> bool:
    -        return (
    -            self.feelers == 2
    -            and self.tail == 1
    -            and self.legs == 6
    -            and self.head == 1
    -            and self.neck == 1
    -        )
    -
    -    def display(self) -> None:
    -        if self.feelers != 0:
    -            print_feelers(self.feelers, is_player=self.is_player)
    -        if self.head != 0:
    -            print_head()
    -        if self.neck != 0:
    -            print_neck()
    -        if self.body != 0:
    -            print_body(True) if self.tail == 1 else print_body(False)
    -        if self.legs != 0:
    -            print_legs(self.legs)
    -
    -
    -def print_n_newlines(n: int) -> None:
    -    for _ in range(n):
    -        print()
    -
    -
    -def print_feelers(n_feelers: int, is_player: bool = True) -> None:
    -    for _ in range(4):
    -        print(" " * 10, end="")
    -        for _ in range(n_feelers):
    -            print("A " if is_player else "F ", end="")
    -        print()
    -
    -
    -def print_head() -> None:
    -    print("        HHHHHHH")
    -    print("        H     H")
    -    print("        H O O H")
    -    print("        H     H")
    -    print("        H  V  H")
    -    print("        HHHHHHH")
    -
    -
    -def print_neck() -> None:
    -    print("          N N")
    -    print("          N N")
    -
    -
    -def print_body(has_tail: bool = False) -> None:
    -    print("     BBBBBBBBBBBB")
    -    print("     B          B")
    -    print("     B          B")
    -    print("TTTTTB          B") if has_tail else ""
    -    print("     BBBBBBBBBBBB")
    -
    -
    -def print_legs(n_legs: int) -> None:
    -    for _ in range(2):
    -        print(" " * 5, end="")
    -        for _ in range(n_legs):
    -            print(" L", end="")
    -        print()
    -
    -
    -def handle_roll(diceroll: Literal[1, 2, 3, 4, 5, 6], state: State) -> bool:
    -    who = "YOU" if state.is_player else "I"
    -    changed = False
    -
    -    print(f"{who} ROLLED A", diceroll)
    -    if diceroll == 1:
    -        print("1=BODY")
    -        if state.body:
    -            print(f"{who} DO NOT NEED A BODY.")
    -        else:
    -            print(f"{who} NOW HAVE A BODY.")
    -            state.body = 1
    -            changed = True
    -    elif diceroll == 2:
    -        print("2=NECK")
    -        if state.neck:
    -            print(f"{who} DO NOT NEED A NECK.")
    -        elif state.body == 0:
    -            print(f"{who} DO NOT HAVE A BODY.")
    -        else:
    -            print(f"{who} NOW HAVE A NECK.")
    -            state.neck = 1
    -            changed = True
    -    elif diceroll == 3:
    -        print("3=HEAD")
    -        if state.neck == 0:
    -            print(f"{who} DO NOT HAVE A NECK.")
    -        elif state.head:
    -            print(f"{who} HAVE A HEAD.")
    -        else:
    -            print(f"{who} NEEDED A HEAD.")
    -            state.head = 1
    -            changed = True
    -    elif diceroll == 4:
    -        print("4=FEELERS")
    -        if state.head == 0:
    -            print(f"{who} DO NOT HAVE A HEAD.")
    -        elif state.feelers == 2:
    -            print(f"{who} HAVE TWO FEELERS ALREADY.")
    -        else:
    -            if state.is_player:
    -                print("I NOW GIVE YOU A FEELER.")
    -            else:
    -                print(f"{who} GET A FEELER.")
    -            state.feelers += 1
    -            changed = True
    -    elif diceroll == 5:
    -        print("5=TAIL")
    -        if state.body == 0:
    -            print(f"{who} DO NOT HAVE A BODY.")
    -        elif state.tail:
    -            print(f"{who} ALREADY HAVE A TAIL.")
    -        else:
    -            if state.is_player:
    -                print("I NOW GIVE YOU A TAIL.")
    -            else:
    -                print(f"{who} NOW HAVE A TAIL.")
    -            state.tail = 1
    -            changed = True
    -    elif diceroll == 6:
    -        print("6=LEG")
    -        if state.legs == 6:
    -            print(f"{who} HAVE 6 FEET ALREADY.")
    -        elif state.body == 0:
    -            print(f"{who} DO NOT HAVE A BODY.")
    -        else:
    -            state.legs += 1
    -            changed = True
    -            print(f"{who} NOW HAVE {state.legs} LEGS")
    -    return changed
    -
    -
    -def main() -> None:
    -    print(" " * 34 + "BUG")
    -    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
    -    print_n_newlines(3)
    -
    -    print("THE GAME BUG")
    -    print("I HOPE YOU ENJOY THIS GAME.")
    -    print()
    -    want_instructions = input("DO YOU WANT INSTRUCTIONS? ")
    -    if want_instructions != "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(f"{row[0]:<16}{row[1]:<16}{row[2]:<20}")
    -        print_n_newlines(2)
    -
    -    player = State(is_player=True)
    -    opponent = State(is_player=False)
    -    bugs_finished = 0
    -
    -    while bugs_finished <= 0:
    -        diceroll = random.randint(1, 6)
    -        print()
    -        changed = handle_roll(diceroll, player)  # type: ignore
    -
    -        diceroll = random.randint(1, 6)
    -        print()
    -        time.sleep(2)
    -
    -        changed_op = handle_roll(diceroll, opponent)  # type: ignore
    -
    -        changed = changed or changed_op
    -
    -        if player.is_finished():
    -            print("YOUR BUG IS FINISHED.")
    -            bugs_finished += 1
    -        if opponent.is_finished():
    -            print("MY BUG IS FINISHED.")
    -            bugs_finished += 1
    -        if not changed:
    -            continue
    -        want_pictures = input("DO YOU WANT THE PICTURES? ")
    -        if want_pictures != "NO":
    -            print("*****YOUR BUG*****")
    -            print_n_newlines(2)
    -            player.display()
    -            print_n_newlines(4)
    -            print("*****MY BUG*****")
    -            print_n_newlines(3)
    -            opponent.display()
    -
    -            if bugs_finished != 0:
    -                break
    -
    -    print("I HOPE YOU ENJOYED THE GAME, PLAY IT AGAIN SOON!!")
    -
    -
    -if __name__ == "__main__":
    -    main()
    diff --git a/16_Bug/ruby/Bug.rb b/16_Bug/ruby/Bug.rb
    deleted file mode 100644
    index 33f7f13a1..000000000
    --- a/16_Bug/ruby/Bug.rb
    +++ /dev/null
    @@ -1,196 +0,0 @@
    -class BugGame
    -  YES = ["Y", "y", "Yes", "YES"]
    -  NO  = ["N", "n", "No", "NO"]
    -
    -  YOU = { body: 0, neck: 0, head: 0, antennaes: 0, legs: 0, arms: 0, name: "YOU" }
    -  I   = { body: 0, neck: 0, head: 0, antennaes: 0, legs: 0, arms: 0, name: "I" }
    -  def initialize
    -    puts "The Game Bug"
    -    puts "I HOPE YOU ENJOY THIS GAME."
    -    instructions
    -  end
    -
    -  def run
    -    loop do
    -      # YOU FIRST
    -      play YOU
    -      if is_completed? YOU
    -        puts "\n\n\n\nYOU WON"
    -        break
    -      end
    -      puts "\n"
    -
    -      # I SECOND
    -      play I
    -      if is_completed? I
    -        puts "\n\n\n\nI WON"
    -        break
    -      end
    -
    -      loop do
    -        puts "Do you want the pictures? [Y,y,Yes,YES] [N,n,No,NO]"
    -        answer = gets.chomp!
    -        if YES.include?(answer) || NO.include?(answer)
    -          if YES.include?(answer)
    -            puts "--- YOUR BUG ---"
    -            print_bug YOU
    -            puts "\n\n--- MY BUG ---"
    -            print_bug I
    -          end
    -          break
    -        end
    -      end
    -    end
    -  end
    -
    -  private
    -    def play player
    -      number = Random.rand(1..6)
    -      case number
    -      when 1
    -        if player[:body].eql? 0
    -          player[:body] = 1
    -          puts "#{player[:name]} have acquired a body"
    -        else
    -          puts "#{player[:name]} already have a body"
    -        end
    -      when 2
    -        one_part player, :neck, :body
    -      when 3
    -        one_part player, :head, :neck
    -      when 4
    -        two_parts player, :antennaes, :head
    -      when 5
    -        two_parts player, :legs, :body
    -      when 6
    -        two_parts player, :arms, :body
    -      end
    -    end
    -
    -    def one_part player, part, part_needed
    -      if player[part].eql? 0
    -        if player[part_needed].eql? 0
    -          puts "#{player[:name]} need to have a #{part_needed.to_s} first"
    -        else
    -          player[part] = 1
    -          puts "#{player[:name]} have acquired a #{part.to_s}"
    -        end
    -      else
    -        puts "#{player[:name]} already have a #{part.to_s}"
    -      end
    -    end
    -
    -    def two_parts player, part, part_needed
    -      if player[part].eql? 0
    -        if player[part_needed].eql? 0
    -          puts "#{player[:name]} need to have a #{part_needed.to_s} first"
    -        else
    -          player[part] = 1
    -          puts "#{player[:name]} have acquired first #{part.to_s.chop}"
    -        end
    -      else
    -        if player[part].eql? 2
    -          puts "#{player[:name]} already have 2 #{part.to_s}"
    -        else
    -          player[part] = 2
    -          puts "#{player[:name]} have acquired second #{part.to_s.chop}"
    -        end
    -      end
    -    end
    -
    -    def is_completed? player
    -      player[:body].eql?(1) && player[:neck].eql?(1) && player[:head].eql?(1) && player[:antennaes].eql?(2) && player[:legs].eql?(2) && player[:arms].eql?(2)
    -    end
    -
    -    def print_bug player
    -      antennae_and_leg player, :antennaes
    -      head player
    -      neck player
    -      body player
    -      antennae_and_leg player, :legs
    -    end
    -
    -    def instructions
    -      loop do
    -        puts "Do you want an instruction? [Y,y,Yes,YES] [N,n,No,NO]"
    -        answer = gets.chomp!
    -
    -        if YES.include?(answer) || NO.include?(answer)
    -          if YES.include?(answer)
    -            puts "THE OBJECT OF BUG IS TO FINISH YOUR BUG BEFORE I FINISH"
    -            puts "MINE. EACH NUMBER STANDS FOR A PART OF THE BUG BODY."
    -            puts "I WILL ROLL THE DIE FOR YOU, TELL YOU WHAT I ROLLED FOR YOU"
    -            puts "WHAT THE NUMBER STANDS FOR, AND IF YOU CAN GET THE PART."
    -            puts "IF YOU CAN GET THE PART I WILL GIVE IT TO YOU."
    -            puts "THE SAME WILL HAPPEN ON MY TURN."
    -            puts "IF THERE IS A CHANGE IN EITHER BUG I WILL GIVE YOU THE"
    -            puts "OPTION OF SEEING THE PICTURES OF THE BUGS."
    -            puts "THE NUMBERS STAND FOR PARTS AS FOLLOWS:\n\n\n"
    -            puts "Number    Part          Required Part #"
    -            puts "1         Body          1"
    -            puts "2         Neck          1"
    -            puts "3         Head          2"
    -            puts "4      (2)antennaes     3"
    -            puts "5      (2)arms          1"
    -            puts "6      (2)Legs          1"
    -          end
    -          break
    -        end
    -      end
    -    end
    -
    -    def antennae_and_leg player, part
    -      if !player[part].eql? 0
    -        for i in (1...5) do
    -          if player[part].eql? 1
    -            puts "     N"
    -          else
    -            puts "     N    N"
    -          end
    -        end
    -      end
    -    end
    -
    -    def head player
    -      if !player[:head].eql? 0
    -        puts "     NNNNNNN"
    -        puts "     N     N"
    -        puts "     N O O N"
    -        puts "     N     N"
    -        puts "     N  V  N"
    -        puts "     NNNNNNN"
    -      end
    -    end
    -
    -    def neck player
    -      if !player[:neck].eql? 0
    -        puts "     N  N"
    -      end
    -    end
    -
    -    def body player
    -      if !player[:body].eql? 0
    -        puts "     NNNNNNNNN"
    -        for i in (1...5) do
    -          if i.eql? 2
    -            if player[:arms].eql? 1
    -              puts "NNNNNN       N"
    -            elsif player[:arms].eql? 2
    -              
    -              puts "NNNNNN       NNNNNN"
    -            end
    -          else
    -            puts "     N       N"
    -          end
    -        end
    -        puts "     NNNNNNNNN"
    -      end
    -    end
    -end
    -
    -
    -if __FILE__ == $0
    -  bug = BugGame.new
    -  puts "\n\nNOW WE START THE GAME\n\n"
    -  bug.run
    -end
    \ No newline at end of file
    diff --git a/16_Bug/vbnet/Bug.sln b/16_Bug/vbnet/Bug.sln
    deleted file mode 100644
    index f0ef35a45..000000000
    --- a/16_Bug/vbnet/Bug.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index dd4f74e48..000000000
    --- a/16_Bug/vbnet/Bug.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Bug
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/17_Bullfight/README.md b/17_Bullfight/README.md
    index b81aab0b7..d31bc4e2d 100644
    --- a/17_Bullfight/README.md
    +++ b/17_Bullfight/README.md
    @@ -23,9 +23,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -- There is a fundamental assumption in the pre-fight subroutine at line 1610, that the Picadores and Toreadores are more likely to do a bad job (and possibly get killed) with a low-quality bull. This appears to be a mistake in the original code, but should be retained.
    -
    -- Lines 1800-1820 (part of the pre-fight subroutine) can never be reached.
    diff --git a/17_Bullfight/csharp/Bullfight.sln b/17_Bullfight/csharp/Bullfight.sln
    index 8c819db1e..29f5276f4 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}") = "Bullfight", "Bullfight.csproj", "{502A672C-F7D7-4A85-973A-B5EA8761008A}"
    +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Game", "Game.csproj", "{8F7C450E-5F3A-45BA-9DB9-329744214931}"
     EndProject
     Global
     	GlobalSection(SolutionConfigurationPlatforms) = preSolution
    @@ -11,10 +11,10 @@ Global
     		Release|Any CPU = Release|Any CPU
     	EndGlobalSection
     	GlobalSection(ProjectConfigurationPlatforms) = postSolution
    -		{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
    +		{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
     	EndGlobalSection
     	GlobalSection(SolutionProperties) = preSolution
     		HideSolutionNode = FALSE
    diff --git a/17_Bullfight/csharp/Bullfight.csproj b/17_Bullfight/csharp/Game.csproj
    similarity index 100%
    rename from 17_Bullfight/csharp/Bullfight.csproj
    rename to 17_Bullfight/csharp/Game.csproj
    diff --git a/17_Bullfight/csharp/Action.cs b/17_Bullfight/csharp/src/Action.cs
    similarity index 100%
    rename from 17_Bullfight/csharp/Action.cs
    rename to 17_Bullfight/csharp/src/Action.cs
    diff --git a/17_Bullfight/csharp/ActionResult.cs b/17_Bullfight/csharp/src/ActionResult.cs
    similarity index 100%
    rename from 17_Bullfight/csharp/ActionResult.cs
    rename to 17_Bullfight/csharp/src/ActionResult.cs
    diff --git a/17_Bullfight/csharp/BullFight.cs b/17_Bullfight/csharp/src/BullFight.cs
    similarity index 100%
    rename from 17_Bullfight/csharp/BullFight.cs
    rename to 17_Bullfight/csharp/src/BullFight.cs
    diff --git a/17_Bullfight/csharp/Controller.cs b/17_Bullfight/csharp/src/Controller.cs
    similarity index 100%
    rename from 17_Bullfight/csharp/Controller.cs
    rename to 17_Bullfight/csharp/src/Controller.cs
    diff --git a/17_Bullfight/csharp/Events/BullCharging.cs b/17_Bullfight/csharp/src/Events/BullCharging.cs
    similarity index 100%
    rename from 17_Bullfight/csharp/Events/BullCharging.cs
    rename to 17_Bullfight/csharp/src/Events/BullCharging.cs
    diff --git a/17_Bullfight/csharp/Events/Event.cs b/17_Bullfight/csharp/src/Events/Event.cs
    similarity index 100%
    rename from 17_Bullfight/csharp/Events/Event.cs
    rename to 17_Bullfight/csharp/src/Events/Event.cs
    diff --git a/17_Bullfight/csharp/Events/MatchCompleted.cs b/17_Bullfight/csharp/src/Events/MatchCompleted.cs
    similarity index 100%
    rename from 17_Bullfight/csharp/Events/MatchCompleted.cs
    rename to 17_Bullfight/csharp/src/Events/MatchCompleted.cs
    diff --git a/17_Bullfight/csharp/Events/MatchStarted.cs b/17_Bullfight/csharp/src/Events/MatchStarted.cs
    similarity index 100%
    rename from 17_Bullfight/csharp/Events/MatchStarted.cs
    rename to 17_Bullfight/csharp/src/Events/MatchStarted.cs
    diff --git a/17_Bullfight/csharp/Events/PlayerGored.cs b/17_Bullfight/csharp/src/Events/PlayerGored.cs
    similarity index 100%
    rename from 17_Bullfight/csharp/Events/PlayerGored.cs
    rename to 17_Bullfight/csharp/src/Events/PlayerGored.cs
    diff --git a/17_Bullfight/csharp/Events/PlayerSurvived.cs b/17_Bullfight/csharp/src/Events/PlayerSurvived.cs
    similarity index 100%
    rename from 17_Bullfight/csharp/Events/PlayerSurvived.cs
    rename to 17_Bullfight/csharp/src/Events/PlayerSurvived.cs
    diff --git a/17_Bullfight/csharp/Mediator.cs b/17_Bullfight/csharp/src/Mediator.cs
    similarity index 100%
    rename from 17_Bullfight/csharp/Mediator.cs
    rename to 17_Bullfight/csharp/src/Mediator.cs
    diff --git a/17_Bullfight/csharp/Program.cs b/17_Bullfight/csharp/src/Program.cs
    similarity index 100%
    rename from 17_Bullfight/csharp/Program.cs
    rename to 17_Bullfight/csharp/src/Program.cs
    diff --git a/17_Bullfight/csharp/Quality.cs b/17_Bullfight/csharp/src/Quality.cs
    similarity index 100%
    rename from 17_Bullfight/csharp/Quality.cs
    rename to 17_Bullfight/csharp/src/Quality.cs
    diff --git a/17_Bullfight/csharp/Reward.cs b/17_Bullfight/csharp/src/Reward.cs
    similarity index 100%
    rename from 17_Bullfight/csharp/Reward.cs
    rename to 17_Bullfight/csharp/src/Reward.cs
    diff --git a/17_Bullfight/csharp/RiskLevel.cs b/17_Bullfight/csharp/src/RiskLevel.cs
    similarity index 100%
    rename from 17_Bullfight/csharp/RiskLevel.cs
    rename to 17_Bullfight/csharp/src/RiskLevel.cs
    diff --git a/17_Bullfight/csharp/View.cs b/17_Bullfight/csharp/src/View.cs
    similarity index 100%
    rename from 17_Bullfight/csharp/View.cs
    rename to 17_Bullfight/csharp/src/View.cs
    diff --git a/17_Bullfight/java/Bullfight.java b/17_Bullfight/java/Bullfight.java
    deleted file mode 100644
    index 16fe299c0..000000000
    --- a/17_Bullfight/java/Bullfight.java
    +++ /dev/null
    @@ -1,466 +0,0 @@
    -import java.util.Random;
    -import java.util.Scanner;
    -
    -/**
    - * BULLFIGHT
    - * 

    - * Converted from BASIC to Java by Aldrin Misquitta (@aldrinm) - */ -public class Bullfight { - - private static final int MAX_PASSES_BEFORE_CHARGE = 3; - - public static void main(String[] args) { - printHeader(); - - Scanner scanner = new Scanner(System.in); - System.out.print("\n\n"); - - var instructionsChoice = readInstructionsChoice(scanner); - if (instructionsChoice) { - printInstructions(); - } - - Random random = new Random(); - - //initialize the game with default values - GameState gameState = new GameState(); - - //Randomly select a bull grade - int randomGrade = (int) (random.nextFloat() * BullGrade.values().length + 1); - var bullGrade = BullGrade.fromValue(randomGrade); - - printBullGradeInfo(bullGrade); - - System.out.println(); - - //D[1] in the original - gameState.picadoresDamage = firstStage("PICADO", "RES", bullGrade, random); - - //D[2] in the original - gameState.toreadoresDamage = firstStage("TOREAD", "ORES", bullGrade, random); - - boolean done = false; //controls the main game loop - - while (!done) { - - gameState.passNumber++; - System.out.printf("\n\nPASS NUMBER %d \n", gameState.passNumber); - - if (gameState.passNumber < MAX_PASSES_BEFORE_CHARGE) { - System.out.println("THE BULL IS CHARGING AT YOU! YOU ARE THE MATADOR--"); - System.out.print("DO YOU WANT TO KILL THE BULL? "); - } else { - System.out.print("HERE COMES THE BULL. TRY FOR A KILL? "); - } - - BooleanAnswer yesOrNo = readYesOrNo(scanner); - if (yesOrNo.equals(BooleanAnswer.YES)) { - gameState = attemptKillBull(bullGrade, random, gameState, scanner); - done = true; - } else { - int capeMove; - if (gameState.passNumber < MAX_PASSES_BEFORE_CHARGE) { - capeMove = readCapeMove("WHAT MOVE DO YOU MAKE WITH THE CAPE", scanner); - } else { - capeMove = readCapeMove("CAPE MOVE", scanner); - } - - //handle cape move - gameState = handleCapeMove(capeMove, random, scanner, bullGrade, gameState); - - if (gameState.matadorStatus.equals(MatadorStatus.DEFEATED) || gameState.matadorStatus.equals(MatadorStatus.DEAD)) { - done = true; - } - } - - } - - crowdReaction(gameState, bullGrade, random); - - System.out.println("\nADIOS\n\n"); - } - - private static void printBullGradeInfo(BullGrade bullGrade) { - System.out.println("\n\nYOU HAVE DRAWN A " + bullGrade.name() + " BULL."); - if (bullGrade.equals(BullGrade.AWFUL)) { - System.out.println("YOU'RE LUCKY."); - } else if (bullGrade.equals(BullGrade.SUPERB)) { - System.out.println("GOOD LUCK. YOU'LL NEED IT."); - } - } - - private static void crowdReaction(GameState gameState, BullGrade bullGrade, Random random) { - System.out.println("\n\n"); - if (!gameState.matadorStatus.equals(MatadorStatus.DEFEATED)) { - if (!gameState.matadorStatus.equals(MatadorStatus.INJURED)) { - if (gameState.bullStatus.equals(BullStatus.DEAD)) { - System.out.println("THE CROWD CHEERS!"); - } - } else { - System.out.println("THE CROWD CHEERS WILDLY!"); - } - - System.out.println("\nTHE CROWD AWARDS YOU"); - var crowdReactionScore = calculateCrowdReactionScore(gameState, bullGrade, random); - if (crowdReactionScore < 2.4) { - System.out.println("NOTHING AT ALL."); - } else if (crowdReactionScore < 4.9) { - System.out.println("ONE EAR OF THE BULL."); - } else if (crowdReactionScore < 7.4) { - System.out.println("BOTH EARS OF THE BULL!"); - System.out.println("OLE!"); - } else { - System.out.println("OLE! YOU ARE 'MUY HOMBRE'!! OLE! OLE!"); - } - - } else { - System.out.println("THE CROWD BOOS FOR TEN MINUTES. IF YOU EVER DARE TO SHOW"); - System.out.println("YOUR FACE IN A RING AGAIN, THEY SWEAR THEY WILL KILL YOU--"); - System.out.println("UNLESS THE BULL DOES FIRST."); - } - } - - private static GameState handleCapeMove(int capeMove, Random random, Scanner scanner, BullGrade bullGrade, GameState gameState) { - double m; - if (capeMove == 0) { - m = 3; - } else if (capeMove == 1) { - m = 2; - } else { - //capeMove == 2 - m = 0.5; - } - gameState.capeMovesCumulative += m; - - double f = (6 - bullGrade.getValue() + m / 10) * random.nextFloat() / ((gameState.picadoresDamage + gameState.toreadoresDamage + gameState.passNumber / 10d) * 5); - if (f >= 0.51) { - System.out.println("THE BULL HAS GORED YOU!"); - gameState = stateAfterGoring(random, scanner, gameState, bullGrade); - } - return gameState; - } - - private static GameState stateAfterGoring(Random random, Scanner scanner, GameState gameState, BullGrade bullGrade) { - GameState newGameState = gameState.newCopy(); - if (random.nextBoolean()) { - System.out.println("YOU ARE DEAD."); - newGameState.matadorStatus = MatadorStatus.DEAD; - } else { - System.out.println("YOU ARE STILL ALIVE."); - newGameState = readAndHandleForfeitDecision(random, scanner, newGameState, bullGrade); - } - return newGameState; - } - - /** - * Calculate the crowd's reaction score based on the game state plus some randomness. - * (FNC in the original code on line 1390) - */ - private static double calculateCrowdReactionScore(GameState gameState, BullGrade bullGrade, Random random) { - return calculateGameScore(gameState, bullGrade) * random.nextFloat(); - } - - /** - * Calculates the ame score based on the current state and the selected bull grade. - * (FND in the original code on line 1395) - */ - private static double calculateGameScore(GameState gameState, BullGrade bullGrade) { - return (4.5 + gameState.capeMovesCumulative / 6 - (gameState.picadoresDamage + gameState.toreadoresDamage) * 2.5 + 4 * gameState.matadorStatus.getValue() + 2 * gameState.bullStatus.getValue() - Math.pow(gameState.passNumber, 2) / 120f - bullGrade.getValue()); - } - - private static int readInt(String prompt, Scanner scanner) { - System.out.print(prompt); - while (true) { - System.out.print("? "); - String input = scanner.nextLine(); - try { - return Integer.parseInt(input); - } catch (NumberFormatException e) { - System.out.println("!NUMBER EXPECTED - RETRY INPUT LINE"); - } - } - } - - private static int readCapeMove(String initialPrompt, Scanner scanner) { - String prompt = initialPrompt; - while (true) { - int capeMove = readInt(prompt, scanner); - if (capeMove <= 0 || capeMove > 3) { - System.out.println("DON'T PANIC, YOU IDIOT! PUT DOWN A CORRECT NUMBER"); - prompt = ""; - } else { - return capeMove; - } - } - } - - private static BooleanAnswer readYesOrNo(Scanner scanner) { - while (true) { - String answer = scanner.nextLine(); - if (answer.equalsIgnoreCase("YES")) { - return BooleanAnswer.YES; - } else if (answer.equalsIgnoreCase("NO")) { - return BooleanAnswer.NO; - } else { - System.out.println("INCORRECT ANSWER - - PLEASE TYPE 'YES' OR 'NO'."); - } - } - } - - private static void printInstructions() { - System.out.print("HELLO, ALL YOU BLOODLOVERS AND AFICIONADOS.\n"); - System.out.print("HERE IS YOUR BIG CHANCE TO KILL A BULL.\n\n"); - System.out.print("ON EACH PASS OF THE BULL, YOU MAY TRY\n"); - System.out.print("0 - VERONICA (DANGEROUS INSIDE MOVE OF THE CAPE)\n"); - System.out.print("1 - LESS DANGEROUS OUTSIDE MOVE OF THE CAPE\n"); - System.out.print("2 - ORDINARY SWIRL OF THE CAPE.\n\n"); - System.out.print("INSTEAD OF THE ABOVE, YOU MAY TRY TO KILL THE BULL\n"); - System.out.print("ON ANY TURN: 4 (OVER THE HORNS), 5 (IN THE CHEST).\n"); - System.out.print("BUT IF I WERE YOU,\n"); - System.out.print("I WOULDN'T TRY IT BEFORE THE SEVENTH PASS.\n\n"); - System.out.print("THE CROWD WILL DETERMINE WHAT AWARD YOU DESERVE\n"); - System.out.print("(POSTHUMOUSLY IF NECESSARY).\n"); - System.out.print("THE BRAVER YOU ARE, THE BETTER THE AWARD YOU RECEIVE.\n\n"); - System.out.print("THE BETTER THE JOB THE PICADORES AND TOREADORES DO,\n"); - System.out.print("THE BETTER YOUR CHANCES ARE.\n\n"); - } - - private static void printHeader() { - System.out.println(" BULL"); - System.out.println(" CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n"); - } - - /** - * Random number 1 or 2 - * FNA in the original - */ - private static int randomNumber1or2(Random random) { - return (int) (random.nextFloat() * 2 + 1); - } - - private static double firstStage(String horseType, String suffix, BullGrade bullGrade, Random random) { - double b = ((3d / bullGrade.getValue()) * random.nextFloat()); - double c; - - if (b < 0.37) { - c = 0.5; - } else if (b < 0.5) { - c = 0.4; - } else if (b < 0.63) { - c = 0.3; - } else if (b < 0.87) { - c = 0.2; - } else { - c = 0.1; - } - - int t = (int) (10 * c + 0.2); - - System.out.println("THE " + horseType + suffix + " DID A " + getPerformanceRating(t) + " JOB."); - - if (t >= 4) { - if (t == 5) { - if (!horseType.equals("TOREAD")) { - System.out.println(" " + randomNumber1or2(random) + " OF THE HORSES OF THE " + horseType + suffix + " KILLED."); - } - System.out.println(" " + randomNumber1or2(random) + " OF THE " + horseType + suffix + " KILLED."); - - } else { - if (random.nextBoolean()) { - System.out.println("ONE OF THE " + horseType + " " + suffix + " WAS KILLED."); - } else { - System.out.println("NO " + horseType + " " + suffix + " WERE KILLED."); - } - } - } - - System.out.println(); - return c; - } - - public static String getPerformanceRating(int t) { - switch (t) { - case 1: - return "SUPERB"; - case 2: - return "GOOD"; - case 3: - return "FAIR"; - case 4: - return "POOR"; - default: - return "AWFUL"; - } - } - - private static GameState attemptKillBull(BullGrade bullGrade, Random random, GameState gameState, Scanner scanner) { - GameState newGameState = gameState.newCopy(); - System.out.println("\nIT IS THE MOMENT OF TRUTH.\n"); - - int h = readInt("HOW DO YOU TRY TO KILL THE BULL", scanner); - if (h == 4 || h == 5) { - var K = (6 - bullGrade.getValue()) * 10 * random.nextFloat() / ((gameState.picadoresDamage + gameState.toreadoresDamage) * 5 * gameState.passNumber); - if (h == 4) { - if (K > 0.8) { - System.out.println("THE BULL HAS GORED YOU!"); - newGameState = stateAfterGoring(random, scanner, newGameState, bullGrade); - } else { - System.out.println("YOU KILLED THE BULL!"); - newGameState.bullStatus = BullStatus.DEAD; - return newGameState;//game over - } - } else { - if (K > 0.2) { - System.out.println("THE BULL HAS GORED YOU!"); - newGameState = stateAfterGoring(random, scanner, newGameState, bullGrade); - } else { - System.out.println("YOU KILLED THE BULL!"); - newGameState.bullStatus = BullStatus.DEAD; - return newGameState;//game over - } - } - - } else { - System.out.println("YOU PANICKED. THE BULL GORED YOU."); - if (random.nextBoolean()) { - System.out.println("YOU ARE DEAD."); - newGameState.matadorStatus = MatadorStatus.DEAD; - return newGameState; - } else { - return readAndHandleForfeitDecision(random, scanner, newGameState, bullGrade); - } - - } - - return newGameState; - } - - private static GameState readAndHandleForfeitDecision(Random random, Scanner scanner, GameState gameState, BullGrade bullGrade) { - GameState newGameState = gameState.newCopy(); - - System.out.print("\nDO YOU RUN FROM THE RING? "); - BooleanAnswer yesOrNo = readYesOrNo(scanner); - if (yesOrNo == BooleanAnswer.NO) { - System.out.println("\n\nYOU ARE BRAVE. STUPID, BUT BRAVE."); - if (random.nextBoolean()) { - newGameState.matadorStatus = MatadorStatus.INJURED; - return newGameState; - } else { - System.out.println("YOU ARE GORED AGAIN!"); - return stateAfterGoring(random, scanner, newGameState, bullGrade); - } - } else { - System.out.println("COWARD"); - newGameState.matadorStatus = MatadorStatus.DEFEATED; - return newGameState; - - } - } - - private static boolean readInstructionsChoice(Scanner scan) { - System.out.print("DO YOU WANT INSTRUCTIONS? "); - - String choice = scan.nextLine(); - return !choice.equalsIgnoreCase("NO"); - } - - - private enum BooleanAnswer { - YES, NO - } - - private enum BullGrade { - SUPERB(1), - GOOD(2), - FAIR(3), - POOR(4), - AWFUL(5); - - private final int value; - - BullGrade(int value) { - this.value = value; - } - - public int getValue() { - return value; - } - - public static BullGrade fromValue(int value) { - for (BullGrade grade : BullGrade.values()) { - if (grade.getValue() == value) { - return grade; - } - } - throw new IllegalArgumentException("Invalid value: " + value); - } - - } - - /** - * Represents the game state. - */ - private static class GameState { - private MatadorStatus matadorStatus; //D[4] in the original - private BullStatus bullStatus; //D[5] in the original - private double picadoresDamage; //D[1] in the original - private double toreadoresDamage; //D[2] in the original - private int passNumber; //D[3] in the original - private double capeMovesCumulative; //L in the original - - public GameState() { - picadoresDamage = 0; - toreadoresDamage = 0; - passNumber = 0; - matadorStatus = MatadorStatus.ALIVE; - bullStatus = BullStatus.ALIVE; - capeMovesCumulative = 1; - } - - public GameState newCopy() { - GameState newState = new GameState(); - newState.matadorStatus = this.matadorStatus; - newState.bullStatus = this.bullStatus; - newState.picadoresDamage = this.picadoresDamage; - newState.toreadoresDamage = this.toreadoresDamage; - newState.passNumber = this.passNumber; - newState.capeMovesCumulative = this.capeMovesCumulative; - return newState; - } - } - - private enum MatadorStatus { - ALIVE(1), - INJURED(2), - DEAD(1.5), - DEFEATED(0); - - private final double value; - - MatadorStatus(double value) { - this.value = value; - } - - public double getValue() { - return value; - } - } - - private enum BullStatus { - ALIVE(1), - DEAD(2); - - private final double value; - - BullStatus(double value) { - this.value = value; - } - - public double getValue() { - return value; - } - } - -} - diff --git a/17_Bullfight/javascript/bullfight.html b/17_Bullfight/javascript/bullfight.html index 3ea10aabd..8d23d40ee 100644 --- a/17_Bullfight/javascript/bullfight.html +++ b/17_Bullfight/javascript/bullfight.html @@ -1,10 +1,9 @@ BULLFIGHT - -

    
    +
    
     
     
     
    diff --git a/17_Bullfight/javascript/bullfight.js b/17_Bullfight/javascript/bullfight.js
    index d8355e1e4..c3e022521 100644
    --- a/17_Bullfight/javascript/bullfight.js
    +++ b/17_Bullfight/javascript/bullfight.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/17_Bullfight/kotlin/README.md b/17_Bullfight/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/17_Bullfight/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/17_Bullfight/kotlin/src/bullfight/Main.kt b/17_Bullfight/kotlin/src/bullfight/Main.kt
    deleted file mode 100644
    index 7a1a0681e..000000000
    --- a/17_Bullfight/kotlin/src/bullfight/Main.kt
    +++ /dev/null
    @@ -1,356 +0,0 @@
    -package bullfight
    -
    -import bullfight.Yorn.*
    -import kotlin.random.Random
    -import kotlin.system.exitProcess
    -
    -private val Boolean.asInteger get() = if (this) 1 else 2
    -private val Float.squared: Float
    -    get() = this * this
    -val fna: Boolean get() = RandomNumbers.nextBoolean()
    -
    -enum class Quality(private val typeName: String) {
    -    Superb("SUPERB"),
    -    Good("GOOD"),
    -    Fair("FAIR"),
    -    Poor("POOR"),
    -    Awful("AWFUL");
    -    override fun toString() = typeName
    -
    -    val level get() = (ordinal + 1).toFloat()
    -}
    -
    -enum class BullDeath(val factor: Float) {
    -    Alive(1f), Dead(2f);
    -}
    -
    -var l = 1f
    -lateinit var bullQuality: Quality
    -var momentOfTruth = false
    -var picadoresSuccess = 0f
    -var toreadoresSuccess = 0f
    -var passNumber = 0f
    -var honor = 0f
    -var bullDeath = BullDeath.Alive
    -
    -
    -interface RandomNumberSource {
    -    fun nextBoolean(): Boolean
    -    fun nextInt(from: Int, until: Int): Int
    -    fun nextFloat(): Float
    -}
    -
    -object RandomNumbers : RandomNumberSource {
    -    override fun nextBoolean() = Random.nextBoolean()
    -    override fun nextInt(from: Int, until: Int) = Random.nextInt(from, until)
    -    override fun nextFloat() = Random.nextFloat()
    -}
    -
    -
    -fun main() {
    -    intro()
    -    instructions()
    -    bullDeath = BullDeath.Alive
    -    honor = 1f
    -
    -    bullQuality = Quality.values()[RandomNumbers.nextInt(1, 6)]
    -    println("YOU HAVE DRAWN A $bullQuality BULL.")
    -    when (bullQuality) {
    -        Quality.Superb -> println("GOOD LUCK.  YOU'LL NEED IT.")
    -        Quality.Awful -> println("YOU'RE LUCKY.")
    -        else -> Unit
    -    }
    -
    -    picadoresSuccess = fight(FirstAct.picadores)
    -    toreadoresSuccess = fight(FirstAct.toreadores)
    -    println()
    -    println()
    -
    -    var gored: Boolean
    -
    -    gameLoop@ do {
    -        passNumber++
    -        println("PASS NUMBER ${passNumber.toInt()}")
    -        gored = if (passNumber >= 3) {
    -            print("HERE COMES THE BULL.  TRY FOR A KILL")
    -            killAttempt("CAPE MOVE")
    -        } else {
    -            println("THE BULL IS CHARGING AT YOU!  YOU ARE THE MATADOR--")
    -            print("DO YOU WANT TO KILL THE BULL")
    -            killAttempt("WHAT MOVE DO YOU MAKE WITH THE CAPE")
    -        }
    -
    -        if (!gored) {
    -            val move = restrictedInput(
    -                values = Cape.values(),
    -                errorMessage = "DON'T PANIC, YOU IDIOT!  PUT DOWN A CORRECT NUMBER"
    -            )
    -            val m = when (move) {
    -                Cape.Veronica -> 3f
    -                Cape.Outside -> 2f
    -                Cape.Swirl -> 0.5f
    -            }
    -
    -            l += m
    -            val f =
    -                (6 - bullQuality.level + m / 10f) * RandomNumbers.nextFloat() / ((picadoresSuccess + toreadoresSuccess + passNumber / 10f) * 5f)
    -            if (f < 0.51)
    -                continue
    -        }
    -
    -        println("THE BULL HAS GORED YOU!")
    -        goreLoop@ do {
    -            when (fna) {
    -                false -> {
    -                    println("YOU ARE DEAD.")
    -                    honor = 1.5f
    -                    gameResult()
    -                }
    -
    -                true -> {
    -                    println("YOU ARE STILL ALIVE.")
    -                    println()
    -                    print("DO YOU RUN FROM THE RING")
    -                    when (Yorn.input()) {
    -
    -                        YES -> {
    -                            println("COWARD")
    -                            honor = 0f
    -                        }
    -
    -                        NO -> {
    -                            println("YOU ARE BRAVE.  STUPID, BUT BRAVE.")
    -                            when (fna) {
    -                                true -> {
    -                                    honor = 2f
    -                                    continue@gameLoop
    -                                }
    -
    -                                false -> {
    -                                    println("YOU ARE GORED AGAIN!")
    -                                    continue@goreLoop
    -                                }
    -                            }
    -                        }
    -                    }
    -
    -                }
    -            }
    -        } while (true)
    -
    -    } while (true)
    -
    -}
    -
    -fun fnd() = 4.5 +
    -        l / 6 -
    -        (picadoresSuccess + toreadoresSuccess) * 2.5 +
    -        4 * honor +
    -        2 * bullDeath.factor -
    -        passNumber.squared / 120f -
    -        bullQuality.level
    -
    -fun fnc() = fnd() * RandomNumbers.nextFloat()
    -
    -private fun killAttempt(capeMessage: String): Boolean {
    -    when (Yorn.input()) {
    -
    -        YES ->
    -            when (momentOfTruth()) {
    -                KillResult.Success -> gameResult()
    -                KillResult.Fail -> return true
    -            }
    -
    -        NO ->
    -            print(capeMessage)
    -
    -    }
    -    return false
    -}
    -
    -private fun gameResult() {
    -    println()
    -    println()
    -    if (honor == 0f) {
    -        println(
    -            """
    -                            THE CROWD BOOS FOR TEN MINUTES.  IF YOU EVER DARE TO SHOW
    -                            YOUR FACE IN A RING AGAIN, THEY SWEAR THEY WILL KILL YOU--
    -                            UNLESS THE BULL DOES FIRST.
    -                            """.trimIndent()
    -        )
    -    } else {
    -        if (honor == 2f)
    -            println("THE CROWD CHEERS WILDLY!")
    -        else
    -            if (bullDeath == BullDeath.Dead) {
    -                println("THE CROWD CHEERS!")
    -                println()
    -            }
    -        println("THE CROWD AWARDS YOU")
    -        if (fnc() < 2.4)
    -            println("NOTHING AT ALL.")
    -        else if (fnc() < 4.9)
    -            println("ONE EAR OF THE BULL.")
    -        else
    -            if (fnc() < 7.4)
    -                println("BOTH EARS OF THE BULL!")
    -            else
    -                println("OLE!  YOU ARE 'MUY HOMBRE'!! OLE!  OLE!")
    -        println()
    -    }
    -    println()
    -    println("ADIOS")
    -    println()
    -    println()
    -    println()
    -    exitProcess(0)
    -}
    -
    -enum class KillResult { Success, Fail }
    -
    -fun momentOfTruth(): KillResult {
    -    momentOfTruth = true
    -    print(
    -        """
    -        
    -        IT IS THE MOMENT OF TRUTH.
    -        
    -        HOW DO YOU WANT TO KILL THE BULL
    -    """.trimIndent()
    -    )
    -
    -    val k =
    -        (6 - bullQuality.level) * 10 * RandomNumbers.nextFloat() / ((picadoresSuccess + toreadoresSuccess) * 5 * passNumber)
    -
    -    val chance = when (stdInput(KillMethod.values())) {
    -        KillMethod.OverHorns -> .8
    -        KillMethod.Chest -> .2
    -        null -> {
    -            println("YOU PANICKED.  THE BULL GORED YOU.")
    -            return KillResult.Fail
    -        }
    -    }
    -    return if (k <= chance) {
    -        println("YOU KILLED THE BULL!")
    -        bullDeath = BullDeath.Dead
    -        KillResult.Success
    -    } else {
    -        println("THE BULL HAS GORED YOU!")
    -        KillResult.Fail
    -    }
    -}
    -
    -interface InputOption {
    -    val input: String
    -}
    -
    -enum class Cape(override val input: String) : InputOption {
    -    Veronica("0"),
    -    Outside("1"),
    -    Swirl("2"),
    -}
    -
    -enum class KillMethod(override val input: String) : InputOption {
    -    OverHorns("4"),
    -    Chest("5"),
    -}
    -
    -private fun  restrictedInput(values: Array, errorMessage: String): T {
    -    do {
    -        stdInput(values)?.let { return it }
    -        println(errorMessage)
    -    } while (true)
    -}
    -
    -private fun  stdInput(values: Array): T? {
    -    print("? ")
    -    val z1 = readln()
    -    return values.firstOrNull { z1 == it.input }
    -}
    -
    -enum class Yorn(override val input: String) : InputOption {
    -    YES("YES"), NO("NO");
    -
    -    companion object {
    -        fun input(): Yorn {
    -            return restrictedInput(values(), "YES OR NO")
    -        }
    -    }
    -}
    -
    -enum class FirstAct(val str: String) {
    -    picadores("PICADORES"), toreadores("TOREADORES");
    -
    -    override fun toString() = str
    -}
    -
    -fun fight(firstAct: FirstAct): Float {
    -
    -    val b = 3.0 / bullQuality.level * RandomNumbers.nextFloat()
    -    val firstActQuality = when {
    -        b < .37 -> Quality.Awful
    -        b < .5 -> Quality.Poor
    -        b < .63 -> Quality.Fair
    -        b < .87 -> Quality.Good
    -        else -> Quality.Superb
    -    }
    -    val c = firstActQuality.level / 10f
    -    val t = firstActQuality.level
    -    println("THE $firstAct DID A $firstActQuality JOB.")
    -
    -    if (t >= 4f) {
    -        if (t == 5f) {
    -            if (firstAct != FirstAct.toreadores) {
    -                println("${fna.asInteger} OF THE HORSES OF THE $firstAct KILLED.")
    -            }
    -            println("${fna.asInteger} OF THE $firstAct KILLED.")
    -        } else {
    -            println(
    -                when (fna) {
    -                    true -> "ONE OF THE $firstAct WAS KILLED."
    -                    false -> "NO $firstAct WERE KILLED."
    -                }
    -            )
    -        }
    -    }
    -    println()
    -
    -    return c
    -}
    -
    -private fun instructions() {
    -    print("DO YOU WANT INSTRUCTIONS? ")
    -    if (readln().trim() != "NO") {
    -        println("HELLO, ALL YOU BLOODLOVERS AND AFICIONADOS.")
    -        println("HERE IS YOUR BIG CHANCE TO KILL A BULL.")
    -        println()
    -        println("ON EACH PASS OF THE BULL, YOU MAY TRY")
    -        println("0 - VERONICA (DANGEROUS INSIDE MOVE OF THE CAPE)")
    -        println("1 - LESS DANGEROUS OUTSIDE MOVE OF THE CAPE")
    -        println("2 - ORDINARY SWIRL OF THE CAPE.")
    -        println()
    -        println("INSTEAD OF THE ABOVE, YOU MAY TRY TO KILL THE BULL")
    -        println("ON ANY TURN: 4 (OVER THE HORNS), 5 (IN THE CHEST).")
    -        println("BUT IF I WERE YOU,")
    -        println("I WOULDN'T TRY IT BEFORE THE SEVENTH PASS.")
    -        println()
    -        println("THE CROWD WILL DETERMINE WHAT AWARD YOU DESERVE")
    -        println("(POSTHUMOUSLY IF NECESSARY).")
    -        println("THE BRAVER YOU ARE, THE BETTER THE AWARD YOU RECEIVE.")
    -        println()
    -        println("THE BETTER THE JOB THE PICADORES AND TOREADORES DO,")
    -        println("THE BETTER YOUR CHANCES ARE.")
    -    }
    -    repeat(2) {
    -        println()
    -    }
    -}
    -
    -fun intro() {
    -    println(" ".repeat(34) + "BULL")
    -    println(" ".repeat(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
    -    println()
    -    println()
    -    println()
    -}
    diff --git a/17_Bullfight/lua/README.md b/17_Bullfight/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/17_Bullfight/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/17_Bullfight/pascal/README.md b/17_Bullfight/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/17_Bullfight/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/17_Bullfight/python/bullfight.py b/17_Bullfight/python/bullfight.py
    deleted file mode 100644
    index cfe3ed7ed..000000000
    --- a/17_Bullfight/python/bullfight.py
    +++ /dev/null
    @@ -1,321 +0,0 @@
    -import math
    -import random
    -from typing import Dict, List, Literal, Tuple, Union
    -
    -
    -def print_n_newlines(n: int) -> None:
    -    for _ in range(n):
    -        print()
    -
    -
    -def determine_player_kills(
    -    bull_quality: int,
    -    player_type: Literal["TOREAD", "PICADO"],
    -    plural_form: Literal["ORES", "RES"],
    -    job_qualities: List[str],
    -) -> float:
    -    bull_performance = 3 / bull_quality * random.random()
    -    if bull_performance < 0.37:
    -        job_quality_factor = 0.5
    -    elif bull_performance < 0.5:
    -        job_quality_factor = 0.4
    -    elif bull_performance < 0.63:
    -        job_quality_factor = 0.3
    -    elif bull_performance < 0.87:
    -        job_quality_factor = 0.2
    -    else:
    -        job_quality_factor = 0.1
    -    job_quality = math.floor(10 * job_quality_factor + 0.2)  # higher is better
    -    print(f"THE {player_type}{plural_form} DID A {job_qualities[job_quality]} JOB.")
    -    if job_quality >= 4:
    -        if job_quality == 5:
    -            if random.choice([True, False]):
    -                print(f"ONE OF THE {player_type}{plural_form} WAS KILLED.")
    -        else:
    -            if player_type != "TOREAD":
    -                killed_horses = random.randint(1, 2)
    -                print(
    -                    f"{killed_horses} OF THE HORSES OF THE {player_type}{plural_form} KILLED."
    -                )
    -            killed_players = random.randint(1, 2)
    -            print(f"{killed_players} OF THE {player_type}{plural_form} KILLED.")
    -    print()
    -    return job_quality_factor
    -
    -
    -def calculate_final_score(
    -    move_risk_sum: float, job_quality_by_round: Dict[int, float], bull_quality: int
    -) -> float:
    -    quality = (
    -        4.5
    -        + move_risk_sum / 6
    -        - (job_quality_by_round[1] + job_quality_by_round[2]) * 2.5
    -        + 4 * job_quality_by_round[4]
    -        + 2 * job_quality_by_round[5]
    -        - (job_quality_by_round[3] ** 2) / 120
    -        - bull_quality
    -    ) * random.random()
    -    if quality < 2.4:
    -        return 0
    -    elif quality < 4.9:
    -        return 1
    -    elif quality < 7.4:
    -        return 2
    -    else:
    -        return 3
    -
    -
    -def print_header() -> None:
    -    print(" " * 34 + "BULL")
    -    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
    -    print_n_newlines(2)
    -
    -
    -def print_instructions() -> None:
    -    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.")
    -
    -
    -def print_intro() -> None:
    -    print_header()
    -    want_instructions = input("DO YOU WANT INSTRUCTIONS? ")
    -    if want_instructions != "NO":
    -        print_instructions()
    -    print_n_newlines(2)
    -
    -
    -def ask_bool(prompt: str) -> bool:
    -    while True:
    -        answer = input(prompt).lower()
    -        if answer == "yes":
    -            return True
    -        elif answer == "no":
    -            return False
    -        else:
    -            print("INCORRECT ANSWER - - PLEASE TYPE 'YES' OR 'NO'.")
    -
    -
    -def ask_int() -> int:
    -    while True:
    -        foo = float(input())
    -        if foo != float(int(abs(foo))):  # we actually want an integer
    -            print("DON'T PANIC, YOU IDIOT!  PUT DOWN A CORRECT NUMBER")
    -        elif foo < 3:
    -            break
    -    return int(foo)
    -
    -
    -def did_bull_hit(
    -    bull_quality: int,
    -    cape_move: int,
    -    job_quality_by_round: Dict[int, float],
    -    move_risk_sum: float,
    -) -> Tuple[bool, float]:
    -    # The bull quality is a grade: The lower the grade, the better the bull
    -    if cape_move == 0:
    -        move_risk: Union[int, float] = 3
    -    elif cape_move == 1:
    -        move_risk = 2
    -    else:
    -        move_risk = 0.5
    -    move_risk_sum += move_risk
    -    bull_strength = 6 - bull_quality
    -    bull_hit_factor = (  # the higher the factor, the more "likely" it hits
    -        (bull_strength + move_risk / 10)
    -        * random.random()
    -        / (
    -            (
    -                job_quality_by_round[1]
    -                + job_quality_by_round[2]
    -                + job_quality_by_round[3] / 10
    -            )
    -            * 5
    -        )
    -    )
    -    bull_hit = bull_hit_factor >= 0.51
    -    return bull_hit, move_risk_sum
    -
    -
    -def handle_bullkill_attempt(
    -    kill_method: int,
    -    job_quality_by_round: Dict[int, float],
    -    bull_quality: int,
    -    gore: int,
    -) -> int:
    -    if kill_method not in [4, 5]:
    -        print("YOU PANICKED.  THE BULL GORED YOU.")
    -        gore = 2
    -    else:
    -        bull_strength = 6 - bull_quality
    -        kill_probability = (
    -            bull_strength
    -            * 10
    -            * random.random()
    -            / (
    -                (job_quality_by_round[1] + job_quality_by_round[2])
    -                * 5
    -                * job_quality_by_round[3]
    -            )
    -        )
    -        if (
    -            kill_method == 4
    -            and kill_probability > 0.8
    -            or kill_method != 4
    -            and kill_probability > 0.2
    -        ):
    -            gore = 1
    -        if gore == 0:
    -            print("YOU KILLED THE BULL!")
    -            job_quality_by_round[5] = 2
    -            return gore
    -    return gore
    -
    -
    -def final_message(
    -    job_quality_by_round: Dict[int, float], bull_quality: int, move_risk_sum: float
    -) -> None:
    -    print_n_newlines(3)
    -    if job_quality_by_round[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 job_quality_by_round[4] == 2:
    -            print("THE CROWD CHEERS WILDLY!")
    -        elif job_quality_by_round[5] == 2:
    -            print("THE CROWD CHEERS!")
    -            print()
    -        print("THE CROWD AWARDS YOU")
    -        score = calculate_final_score(move_risk_sum, job_quality_by_round, bull_quality)
    -        if score == 0:
    -            print("NOTHING AT ALL.")
    -        elif score == 1:
    -            print("ONE EAR OF THE BULL.")
    -        elif score == 2:
    -            print("BOTH EARS OF THE BULL!")
    -            print("OLE!")
    -        else:
    -            print("OLE!  YOU ARE 'MUY HOMBRE'!! OLE!  OLE!")
    -        print()
    -        print("ADIOS")
    -        print_n_newlines(3)
    -
    -
    -def main() -> None:
    -    print_intro()
    -    move_risk_sum: float = 1
    -    job_quality_by_round: Dict[int, float] = {4: 1, 5: 1}
    -    job_quality = ["", "SUPERB", "GOOD", "FAIR", "POOR", "AWFUL"]
    -    bull_quality = random.randint(
    -        1, 5
    -    )  # the lower the number, the more powerful the bull
    -    print(f"YOU HAVE DRAWN A {job_quality[bull_quality]} BULL.")
    -    if bull_quality > 4:
    -        print("YOU'RE LUCKY.")
    -    elif bull_quality < 2:
    -        print("GOOD LUCK.  YOU'LL NEED IT.")
    -        print()
    -    print()
    -
    -    # Round 1: Run Picadores
    -    player_type: Literal["TOREAD", "PICADO"] = "PICADO"
    -    plural_form: Literal["ORES", "RES"] = "RES"
    -    job_quality_factor = determine_player_kills(
    -        bull_quality, player_type, plural_form, job_quality
    -    )
    -    job_quality_by_round[1] = job_quality_factor
    -
    -    # Round 2: Run Toreadores
    -    player_type = "TOREAD"
    -    plural_form = "ORES"
    -    determine_player_kills(bull_quality, player_type, plural_form, job_quality)
    -    job_quality_by_round[2] = job_quality_factor
    -    print_n_newlines(2)
    -
    -    # Round 3
    -    job_quality_by_round[3] = 0
    -    while True:
    -        job_quality_by_round[3] += 1
    -        print(f"PASS NUMBER {job_quality_by_round[3]}")
    -        if job_quality_by_round[3] >= 3:
    -            run_from_ring = ask_bool("HERE COMES THE BULL.  TRY FOR A KILL? ")
    -            if not run_from_ring:
    -                print("CAPE MOVE? ", end="")
    -        else:
    -            print("THE BULL IS CHARGING AT YOU!  YOU ARE THE MATADOR--")
    -            run_from_ring = ask_bool("DO YOU WANT TO KILL THE BULL? ")
    -            if not run_from_ring:
    -                print("WHAT MOVE DO YOU MAKE WITH THE CAPE? ", end="")
    -        gore = 0
    -        if not run_from_ring:
    -            cape_move = ask_int()
    -            bull_hit, move_risk_sum = did_bull_hit(
    -                bull_quality, cape_move, job_quality_by_round, move_risk_sum
    -            )
    -            if bull_hit:
    -                gore = 1
    -            else:
    -                continue
    -        else:
    -            print()
    -            print("IT IS THE MOMENT OF TRUTH.")
    -            print()
    -            kill_method = int(input("HOW DO YOU TRY TO KILL THE BULL? "))
    -            gore = handle_bullkill_attempt(
    -                kill_method, job_quality_by_round, bull_quality, gore
    -            )
    -            if gore == 0:
    -                break
    -        if gore > 0:
    -            if gore == 1:
    -                print("THE BULL HAS GORED YOU!")
    -            death = False
    -            while True:
    -                if random.randint(1, 2) == 1:
    -                    print("YOU ARE DEAD.")
    -                    job_quality_by_round[4] = 1.5
    -                    death = True
    -                    break
    -                else:
    -                    print("YOU ARE STILL ALIVE.")
    -                    print()
    -                    print("DO YOU RUN FROM THE RING? ", end="")
    -                    if run_from_ring := ask_bool("DO YOU RUN FROM THE RING? "):
    -                        print("COWARD")
    -                        job_quality_by_round[4] = 0
    -                        death = True
    -                        break
    -
    -                    else:
    -                        print("YOU ARE BRAVE.  STUPID, BUT BRAVE.")
    -                        if random.randint(1, 2) == 1:
    -                            job_quality_by_round[4] = 2
    -                            death = True
    -                            break
    -                        else:
    -                            print("YOU ARE GORED AGAIN!")
    -            if death:
    -                break
    -
    -    final_message(job_quality_by_round, bull_quality, move_risk_sum)
    -
    -
    -if __name__ == "__main__":
    -    main()
    diff --git a/17_Bullfight/vbnet/Bullfight.sln b/17_Bullfight/vbnet/Bullfight.sln
    deleted file mode 100644
    index 9fec219d9..000000000
    --- a/17_Bullfight/vbnet/Bullfight.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 016406fae..000000000
    --- a/17_Bullfight/vbnet/Bullfight.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Bullfight
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/18_Bullseye/README.md b/18_Bullseye/README.md
    index a4b951e89..0c42872eb 100644
    --- a/18_Bullseye/README.md
    +++ b/18_Bullseye/README.md
    @@ -34,8 +34,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    -
    diff --git a/18_Bullseye/javascript/bullseye.html b/18_Bullseye/javascript/bullseye.html
    index 1190687e9..82f133066 100644
    --- a/18_Bullseye/javascript/bullseye.html
    +++ b/18_Bullseye/javascript/bullseye.html
    @@ -1,10 +1,9 @@
     
     
     BULLSEYE
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/18_Bullseye/javascript/bullseye.js b/18_Bullseye/javascript/bullseye.js
    index b2ec905f0..0b8d061c1 100644
    --- a/18_Bullseye/javascript/bullseye.js
    +++ b/18_Bullseye/javascript/bullseye.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/18_Bullseye/kotlin/README.md b/18_Bullseye/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/18_Bullseye/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/18_Bullseye/lua/README.md b/18_Bullseye/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/18_Bullseye/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/18_Bullseye/pascal/README.md b/18_Bullseye/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/18_Bullseye/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/18_Bullseye/perl/bullseye.pl b/18_Bullseye/perl/bullseye.pl
    index 404807c0d..22405d30c 100755
    --- a/18_Bullseye/perl/bullseye.pl
    +++ b/18_Bullseye/perl/bullseye.pl
    @@ -48,10 +48,12 @@
     		}
     
     	for (my $I=1; $I<=$N; $I++) {
    -		if ($S[$I]>=200) { $M= $M+1; $W[$M]= $I; }
    +		if ($S[$I]>=200) { $M= $M+1; $W[$M]= $I; } 
     		}
     	} until ($M!=0);
     
     print "\n"; print "WE HAVE A WINNER!!\n\n";
     for (my $I=1; $I<=$M; $I++) { print $A[$W[$I]]." SCORED ".$S[$W[$I]]." POINTS.\n"; }
     print "\n"; print "THANKS FOR THE GAME.\n"; exit;
    +
    +
    diff --git a/18_Bullseye/python/bullseye.py b/18_Bullseye/python/bullseye.py
    deleted file mode 100644
    index df931f35c..000000000
    --- a/18_Bullseye/python/bullseye.py
    +++ /dev/null
    @@ -1,111 +0,0 @@
    -import random
    -from dataclasses import dataclass
    -from typing import List
    -
    -
    -@dataclass
    -class Player:
    -    name: str
    -    score: int = 0
    -
    -
    -def print_intro() -> None:
    -    print(" " * 32 + "BULLSEYE")
    -    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
    -    print("\n" * 3, end="")
    -    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(" " * 20 + "DESCRIPTION", end="")
    -    print(" " * 45 + "PROBABLE SCORE")
    -    print(" 1", end="")
    -    print(" " * 20 + "FAST OVERARM", end="")
    -    print(" " * 45 + "BULLSEYE OR COMPLETE MISS")
    -    print(" 2", end="")
    -    print(" " * 20 + "CONTROLLED OVERARM", end="")
    -    print(" " * 45 + "10, 20 OR 30 POINTS")
    -    print(" 3", end="")
    -    print(" " * 20 + "UNDERARM", end="")
    -    print(" " * 45 + "ANYTHING")
    -    print()
    -
    -
    -def print_outro(players: List[Player], winners: List[int]) -> None:
    -    print()
    -    print("WE HAVE A WINNER!!")
    -    print()
    -    for winner in winners:
    -        print(f"{players[winner].name} SCORED {players[winner].score} POINTS.")
    -    print()
    -    print("THANKS FOR THE GAME.")
    -
    -
    -def main() -> None:
    -    print_intro()
    -    players: List[Player] = []
    -
    -    winners: List[int] = []  # will point to indices of player_names
    -
    -    nb_players = int(input("HOW MANY PLAYERS? "))
    -    for _ in range(nb_players):
    -        player_name = input("NAME OF PLAYER #")
    -        players.append(Player(player_name))
    -
    -    round_number = 0
    -    while not winners:
    -        round_number += 1
    -        print()
    -        print(f"ROUND {round_number}---------")
    -        for player in players:
    -            print()
    -            while True:
    -                throw = int(input(f"{player.name}'S THROW? "))
    -                if throw in {1, 2, 3}:
    -                    break
    -                else:
    -                    print("INPUT 1, 2, OR 3!")
    -            if throw == 1:
    -                probability_1 = 0.65
    -                probability_2 = 0.55
    -                probability_3 = 0.5
    -                probability_4 = 0.5
    -            elif throw == 2:
    -                probability_1 = 0.99
    -                probability_2 = 0.77
    -                probability_3 = 0.43
    -                probability_4 = 0.01
    -            elif throw == 3:
    -                probability_1 = 0.95
    -                probability_2 = 0.75
    -                probability_3 = 0.45
    -                probability_4 = 0.05
    -            throwing_luck = random.random()
    -            if throwing_luck >= probability_1:
    -                print("BULLSEYE!!  40 POINTS!")
    -                points = 40
    -            elif throwing_luck >= probability_2:
    -                print("30-POINT ZONE!")
    -                points = 30
    -            elif throwing_luck >= probability_3:
    -                print("20-POINT ZONE")
    -                points = 20
    -            elif throwing_luck >= probability_4:
    -                print("WHEW!  10 POINTS.")
    -                points = 10
    -            else:
    -                print("MISSED THE TARGET!  TOO BAD.")
    -                points = 0
    -            player.score += points
    -            print(f"TOTAL SCORE = {player.score}")
    -        winners.extend(
    -            player_index
    -            for player_index, player in enumerate(players)
    -            if player.score > 200
    -        )
    -    print_outro(players, winners)
    -
    -
    -if __name__ == "__main__":
    -    main()
    diff --git a/18_Bullseye/rust/Cargo.lock b/18_Bullseye/rust/Cargo.lock
    deleted file mode 100644
    index 4fe2abbea..000000000
    --- a/18_Bullseye/rust/Cargo.lock
    +++ /dev/null
    @@ -1,75 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.10"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.147"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/18_Bullseye/rust/Cargo.toml b/18_Bullseye/rust/Cargo.toml
    deleted file mode 100644
    index 1c2935d47..000000000
    --- a/18_Bullseye/rust/Cargo.toml
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -[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"
    \ No newline at end of file
    diff --git a/18_Bullseye/rust/README.md b/18_Bullseye/rust/README.md
    deleted file mode 100644
    index f84e546c2..000000000
    --- a/18_Bullseye/rust/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Rust](https://www.rust-lang.org/) by Anthony Rubick [AnthonyMichaelTDM](https://github.com/AnthonyMichaelTDM)
    \ No newline at end of file
    diff --git a/18_Bullseye/rust/src/lib.rs b/18_Bullseye/rust/src/lib.rs
    deleted file mode 100644
    index cb70ea163..000000000
    --- a/18_Bullseye/rust/src/lib.rs
    +++ /dev/null
    @@ -1,223 +0,0 @@
    -/*
    - lib.rs contains all the logic of the program
    -*/
    -
    -use std::{error::Error, fmt::Display, str::FromStr, io::{self, Write}};
    -
    -use rand::Rng;
    -
    -/// handles setup for the game
    -pub struct Config {
    -    players: Vec,
    -}
    -impl Config {
    -    /// creates and returns a new Config from user input
    -    pub fn new() -> Result> {
    -        //DATA
    -        let mut config: Config = Config { players: Vec::new() };
    -        let num_players: usize;
    -
    -        //get data from user input
    -
    -        //get num players
    -        //input looop
    -        num_players = loop {
    -            match get_number_from_input("HOW MANY PLAYERS? ", 1, 0) {
    -                Ok(num) => break num,
    -                Err(e) => {
    -                    println!("{}",e);
    -                    continue;
    -                },
    -            }
    -        };
    -
    -        //get names of all players
    -        for id in 1..=num_players {
    -            let name = get_string_from_user_input( format!("NAME OF PLAYER#{}: ", id).as_str())?;
    -            config.players.push(Player::from(&name));
    -        }
    -
    -        //return new config
    -        return Ok(config);
    -    }
    -}
    -pub struct Player {
    -    name: String,
    -    score: usize,
    -}
    -impl Player {
    -    fn from(name: &str) -> Player {
    -        return Player { name: String::from(name), score: 0 };
    -    }
    -}
    -
    -/// run the program
    -pub fn run(config: &mut Config) -> Result<(), Box> {
    -    //DATA
    -    let mut round = 1;
    -    let mut rng = rand::thread_rng();
    -
    -    //gameloop
    -    loop {
    -        //print round
    -        println!("");
    -        println!("");
    -        println!("ROUND {}", round);
    -        println!("---------");
    -
    -        //each players play
    -        for player in config.players.iter_mut() {
    -            //prompt user for players move
    -            //input loop
    -            let throw = loop {
    -                match get_number_from_input( format!("{}'S THROW (input 1, 2, or 3): ", player.name).as_str(), 1, 3) {
    -                    Ok(t) => break t,
    -                    Err(err) => {
    -                        println!("{}", err);
    -                        continue;
    -                    },
    -                };
    -            };
    -
    -            //get probabilities of the various outcomes based on the throw
    -            let p_bullseye;
    -            let p_30_point_zone;
    -            let p_20_point_zone;
    -            let p_10_point_zone;
    -            match throw {
    -                1 => {
    -                    p_bullseye = 0.65;
    -                    p_30_point_zone = 0.55;
    -                    p_20_point_zone = 0.5;
    -                    p_10_point_zone = 0.5;
    -                },
    -                2 => {
    -                    p_bullseye = 0.99;
    -                    p_30_point_zone = 0.77;
    -                    p_20_point_zone = 0.43;
    -                    p_10_point_zone = 0.01;
    -                },
    -                _ => {
    -                    p_bullseye = 0.95;
    -                    p_30_point_zone = 0.75;
    -                    p_20_point_zone = 0.45;
    -                    p_10_point_zone = 0.05;
    -                },
    -            }
    -
    -            //determine results
    -            let roll = rng.gen::();
    -            if roll >= p_bullseye{
    -                println!("BULLSEYE!!  40 POINTS!");
    -                player.score += 40;
    -            } else if roll >= p_30_point_zone {
    -                println!("30-POINT ZONE!");
    -                player.score += 30;
    -            } else if roll >= p_20_point_zone {
    -                println!("20-POINT ZONE");
    -                player.score += 20;
    -            } else if roll >= p_10_point_zone {
    -                println!("WHEW!  10 POINTS.");
    -                player.score += 10;
    -            } else {
    -                println!("MISSED THE TARGET!  TOO BAD.");
    -            }
    -
    -            //print their score
    -            println!("TOTAL SCORE = {}", player.score);
    -        }
    -
    -        //stuff to do before next round
    -        if config.players.iter().any(|player| player.score >= 200) {
    -            //print congradulations and scores
    -            println!("\nWE HAVE A WINNER!!\n");
    -            for player in config.players.iter() {
    -                println!("{} SCORED {} POINTS", player.name, player.score);
    -            }
    -            //exit loop
    -            break;
    -        } else {
    -            //otherwise do another round
    -            round += 1;
    -        }
    -    }
    -
    -    
    -    
    -
    -    //return to main
    -    Ok(())
    -}
    -
    -/// gets a string from user input
    -fn get_string_from_user_input(prompt: &str) -> Result> {
    -    //DATA
    -    let mut raw_input = String::new();
    -
    -    //print prompt
    -    print!("{}", prompt);
    -    //make sure it's printed before getting input
    -    io::stdout().flush().unwrap();
    -
    -    //read user input from standard input, and store it to raw_input, then return it or an error as needed
    -    raw_input.clear(); //clear input
    -    match io::stdin().read_line(&mut raw_input) {
    -        Ok(_num_bytes_read) => return Ok(String::from(raw_input.trim())),
    -        Err(err) => return Err(format!("ERROR: CANNOT READ INPUT!: {}", err).into()),
    -    }
    -}
    -
    -/// generic function to get a number from the passed string (user input)
    -/// pass a min lower  than the max to have minimun and maximun bounds
    -/// pass a min higher than the max to only have a minumum bound
    -/// pass a min equal   to  the max to only have a maximun bound
    -/// 
    -/// Errors:
    -/// no number on user input
    -fn get_number_from_input(prompt: &str, min:T, max:T) -> Result> {
    -    //DATA
    -    let raw_input: String;
    -    let processed_input: String;
    -
    -    
    -    //input looop
    -    raw_input = loop {
    -        match get_string_from_user_input(prompt) {
    -            Ok(input) => break input,
    -            Err(e) => {
    -                eprintln!("{}",e);
    -                continue;
    -            },
    -        }
    -    };
    -
    -    //filter out num-numeric characters from user input
    -    processed_input = raw_input.chars().filter(|c| c.is_numeric()).collect();
    -
    -    //from input, try to read a number
    -    match processed_input.trim().parse() {
    -        Ok(i) => {
    -            //what bounds must the input fall into
    -            if min < max {  //have a min and max bound: [min,max]
    -                if i >= min && i <= max {//is input valid, within bounds
    -                    return Ok(i); //exit the loop with the value i, returning it
    -                } else { //print error message specific to this case
    -                    return Err(format!("ONLY BETWEEN {} AND {}, PLEASE!", min, max).into());
    -                } 
    -            } else if min > max { //only a min bound: [min, infinity)
    -                if i >= min {
    -                    return Ok(i);
    -                } else {
    -                    return Err(format!("NO LESS THAN {}, PLEASE!", min).into());
    -                }
    -            } else { //only a max bound: (-infinity, max]
    -                if i <= max {
    -                    return Ok(i);
    -                } else {
    -                    return Err(format!("NO MORE THAN {}, PLEASE!", max).into());
    -                }
    -            }
    -        },
    -        Err(_e) => return Err(format!("Error: couldn't find a valid number in {}",raw_input).into()),
    -    }
    -}
    diff --git a/18_Bullseye/rust/src/main.rs b/18_Bullseye/rust/src/main.rs
    deleted file mode 100644
    index 2e92f7506..000000000
    --- a/18_Bullseye/rust/src/main.rs
    +++ /dev/null
    @@ -1,54 +0,0 @@
    -/*
    -    The responsibilities that remain in the main function after separating concerns
    -    should be limited to the following:
    - - Setting up any configuration
    - - Calling a run function in lib.rs
    - - Handling the error if run returns an error
    -*/
    -
    -use std::process;       //allows for some better error handling
    -
    -mod lib;
    -use lib::Config;
    -
    -/// main function
    -fn main() {
    -    //greet user
    -    welcome();
    -
    -    // set up other configuration
    -    let mut config = Config::new().unwrap_or_else(|err| {
    -        eprintln!("Problem configuring program: {}", err);
    -        process::exit(1);
    -    });
    -
    -    // run the program
    -    if let Err(e) = lib::run(&mut config) {
    -        eprintln!("Application Error: {}", e); //use the eprintln! macro to output to standard error
    -        process::exit(1); //exit the program with an error code
    -    }
    -
    -    //end of program
    -    println!("THANKS FOR PLAYING!");
    -}
    -
    -/// prints the welcome/start message
    -fn welcome() {
    -    println!("
    -                               BULLSEYE
    -              CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY
    -
    -
    -
    -    IN THIS GAME, UP TO 20 PLAYERS THROW DARTS AT A TARGET
    -    WITH 10, 20, 30, AND 40 POINT ZONES.  THE OBJECTIVE IS
    -    TO GET 200 POINTS.
    -    
    -    | Throw | Description        | Probable Score            |
    -    |-------|--------------------|---------------------------|
    -    | 1     | Fast overarm       | Bullseye or complete miss |
    -    | 2     | Controlled overarm | 10, 20, or 30 points      |
    -    | 3     | Underarm           | Anything                  |
    -
    -    ");
    -}
    diff --git a/18_Bullseye/rust/src/note on separation of converns for rust projects.md b/18_Bullseye/rust/src/note on separation of converns for rust projects.md
    deleted file mode 100644
    index 04e540f4b..000000000
    --- a/18_Bullseye/rust/src/note on separation of converns for rust projects.md	
    +++ /dev/null
    @@ -1,16 +0,0 @@
    - # Separation of concerns for Binary Projects
    -
    -The organizational problem of allocating responsibility for multiple tasks to the main function is common to many projects. As a result, the Rust community has developed a process to use as a guideline for splitting the separate concerns of a binary program when main starts getting large. 
    -
    - ## The process has the following steps:
    - - Split your program into a main.rs and a lib.rs and move your program’s logic to lib.rs.
    - - As long as your command line logic is small, it can remain in main.rs.
    - - When the command line logic starts getting complicated, extract it from main.rs and move it to lib.rs.
    -
    - ## The responsibilities that remain in the main function after this process should be limited to the following:
    - - Calling the command line or input parsing logic with the argument values
    - - Setting up any other configuration
    - - Calling a run function in lib.rs
    - - Handling the error if run returns an error
    -
    -This pattern is about separating concerns: main.rs handles running the program, and lib.rs handles all the logic of the task at hand. Because you can’t test the main function directly, this structure lets you test all of your program’s logic by moving it into functions in lib.rs. The only code that remains in main.rs will be small enough to verify its correctness by reading it.
    \ No newline at end of file
    diff --git a/18_Bullseye/vbnet/Bullseye.sln b/18_Bullseye/vbnet/Bullseye.sln
    deleted file mode 100644
    index 03e2390ca..000000000
    --- a/18_Bullseye/vbnet/Bullseye.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 3f13676f7..000000000
    --- a/18_Bullseye/vbnet/Bullseye.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Bullseye
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/19_Bunny/README.md b/19_Bunny/README.md
    index c702867e2..8d9802871 100644
    --- a/19_Bunny/README.md
    +++ b/19_Bunny/README.md
    @@ -6,7 +6,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/19_Bunny/csharp/BasicData.cs b/19_Bunny/csharp/BasicData.cs
    deleted file mode 100644
    index 76647a56a..000000000
    --- a/19_Bunny/csharp/BasicData.cs
    +++ /dev/null
    @@ -1,25 +0,0 @@
    -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
    deleted file mode 100644
    index 4e3adf8ac..000000000
    --- a/19_Bunny/csharp/Bunny.cs
    +++ /dev/null
    @@ -1,87 +0,0 @@
    -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/Bunny.csproj b/19_Bunny/csharp/Bunny.csproj
    deleted file mode 100644
    index d3fe4757c..000000000
    --- a/19_Bunny/csharp/Bunny.csproj
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    diff --git a/19_Bunny/csharp/Bunny.sln b/19_Bunny/csharp/Bunny.sln
    deleted file mode 100644
    index c7f9f0083..000000000
    --- a/19_Bunny/csharp/Bunny.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/csharp/Program.cs b/19_Bunny/csharp/Program.cs
    deleted file mode 100644
    index 25604a51e..000000000
    --- a/19_Bunny/csharp/Program.cs
    +++ /dev/null
    @@ -1,16 +0,0 @@
    -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();
    -        }
    -    }
    -}
    diff --git a/19_Bunny/java/src/Bunny.java b/19_Bunny/java/src/Bunny.java
    index 00963a63f..d2fd16997 100644
    --- a/19_Bunny/java/src/Bunny.java
    +++ b/19_Bunny/java/src/Bunny.java
    @@ -164,4 +164,4 @@ public static void main(String[] args) {
             Bunny bunny = new Bunny();
             bunny.process();
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/19_Bunny/javascript/bunny.html b/19_Bunny/javascript/bunny.html
    index 927e916fe..3dca1a44e 100644
    --- a/19_Bunny/javascript/bunny.html
    +++ b/19_Bunny/javascript/bunny.html
    @@ -1,7 +1,6 @@
     
     
     BUNNY
    -
     
     
     
    
    diff --git a/19_Bunny/javascript/bunny.js b/19_Bunny/javascript/bunny.js
    index 97e0376ce..11342d8b8 100644
    --- a/19_Bunny/javascript/bunny.js
    +++ b/19_Bunny/javascript/bunny.js
    @@ -52,7 +52,7 @@ for (var pos = 0; bunny_data[pos] < 128; pos++) {
     	}
     	while (str.length < bunny_data[pos])
     		str += " ";
    -	for (var i = bunny_data[pos]; i <= bunny_data[pos + 1]; i++)
    +	for (var i = bunny_data[pos]; i <= bunny_data[pos + 1]; i++) 
     		str += bunny_string[i % 5];
     	pos++;
     }
    diff --git a/19_Bunny/kotlin/README.md b/19_Bunny/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/19_Bunny/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/19_Bunny/lua/README.md b/19_Bunny/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/19_Bunny/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/19_Bunny/pascal/README.md b/19_Bunny/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/19_Bunny/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/19_Bunny/python/bunny.py b/19_Bunny/python/bunny.py
    index 31b09eb39..c1c9a6976 100755
    --- a/19_Bunny/python/bunny.py
    +++ b/19_Bunny/python/bunny.py
    @@ -1,21 +1,38 @@
     #!/usr/bin/env python3
     
     
    -import json
    -
     # This data is meant to be read-only, so we are storing it in a tuple
    -with open("data.json") as f:
    -    DATA = tuple(json.load(f))
    +DATA = (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)
    +
    +
    +def display_intro():
    +    print(tab(33) + "BUNNY")
    +    print(tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
    +    print("\n\n")
     
     
    -def print_intro() -> None:
    -    print(" " * 33 + "BUNNY")
    -    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
    -    print("\n\n")
    +def tab(column):
    +    """ Emulates the TAB command in BASIC. Returns a string with ASCII
    +        codes for setting the cursor to the specified column. """
    +    return "\r\33[{}C".format(column)
     
     
    -def main() -> None:
    -    print_intro()
    +def play():
    +    display_intro()
     
         # Using an iterator will give us a similar interface to BASIC's READ
         # command. Instead of READ, we will call 'next(data)' to fetch the next element.
    @@ -49,16 +66,16 @@ def main() -> None:
             # position of a line segment.
             start = command
             # Position cursor at start
    -        print(" " * start, end="")
    +        print(tab(start), end="")
     
             # The following number, indicates the end of the segment.
             end = next(data)
             # Unlike FOR I=X TO Y, the 'stop' argument of 'range' is non-inclusive, so we must add 1
    -        for i in range(start, end + 1, 1):
    +        for i in range(start, end+1, 1):
                 # Cycle through the letters in "BUNNY" as we draw line
                 j = i - 5 * int(i / 5)
                 print(chr(L + bunny[j]), end="")
     
     
     if __name__ == "__main__":
    -    main()
    +    play()
    diff --git a/19_Bunny/python/data.json b/19_Bunny/python/data.json
    deleted file mode 100644
    index 9e6ae9025..000000000
    --- a/19_Bunny/python/data.json
    +++ /dev/null
    @@ -1,235 +0,0 @@
    -[
    -    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
    -]
    diff --git a/19_Bunny/ruby/README.md b/19_Bunny/ruby/README.md
    index 846a6e854..1b8e6e8f2 100644
    --- a/19_Bunny/ruby/README.md
    +++ b/19_Bunny/ruby/README.md
    @@ -8,3 +8,4 @@ There are two versions of this program here:
       BASIC program.
     * `bunny-modern.rb` takes more advantage of the features of modern
       tools and languages.
    +
    diff --git a/19_Bunny/ruby/bunny-faithful.rb b/19_Bunny/ruby/bunny-faithful.rb
    index 0aac2f71f..7f6681cb7 100644
    --- a/19_Bunny/ruby/bunny-faithful.rb
    +++ b/19_Bunny/ruby/bunny-faithful.rb
    @@ -19,7 +19,7 @@
     #           * 0,2 draws letters between columns 0 and 2
     #           * 45,50 draws letters between columns 45 and 50
     #           * -1 starts a new line
    -#
    +# 
     # ...and so on.
     #
     # We keep the data statements as they are and redraw the image using
    @@ -33,7 +33,7 @@
     # the data always draws from left to right so we just keep track of
     # the last column written to and then add some spaces to advance to
     # where we need to be.
    -#
    +# 
     
     
     # Do the thing.  (We put it in a function to keep from spewing global
    @@ -51,7 +51,7 @@ def main
       # The positions to write; this is ripped from the BASIC program's
       # DATA statements.
       positions = [
    -    1,2,-1,0,2,45,50,-1,0,5,43,52,-1,0,7,41,52,-1,
    +    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,
    @@ -80,7 +80,7 @@ def main
           puts
           last_pos = 0
           next
    -    end
    +    end      
     
         # Advance to start of the range
         print ' '*(first - last_pos)
    diff --git a/19_Bunny/ruby/bunny-modern.rb b/19_Bunny/ruby/bunny-modern.rb
    index d7d12fb4f..6bd778ddb 100644
    --- a/19_Bunny/ruby/bunny-modern.rb
    +++ b/19_Bunny/ruby/bunny-modern.rb
    @@ -114,7 +114,7 @@ def print_bunny_text(text)
         # Bonus hackery: we could replace the above with this one-liner,
         # but it's kind of hard to understand so it may or may not be wise
         # to use it.
    -    #
    +    # 
         #   line.gsub!(/(\S)/) {|m| bunny[$~.begin(0) % bunny.size] }
     
         puts line
    diff --git a/19_Bunny/rust/Cargo.toml b/19_Bunny/rust/Cargo.toml
    deleted file mode 100644
    index 7d75412a6..000000000
    --- a/19_Bunny/rust/Cargo.toml
    +++ /dev/null
    @@ -1,6 +0,0 @@
    -[package]
    -name = "rust"
    -version = "0.1.0"
    -edition = "2021"
    -
    -[dependencies]
    diff --git a/19_Bunny/rust/src/main.rs b/19_Bunny/rust/src/main.rs
    deleted file mode 100644
    index 4eb9b7316..000000000
    --- a/19_Bunny/rust/src/main.rs
    +++ /dev/null
    @@ -1,114 +0,0 @@
    -/** BUNNY GAME 
    - * https://github.com/coding-horror/basic-computer-games/tree/main/19_Bunny
    - * Direct conversion from BASIC to Rust by Pablo Marques (marquesrs).
    - * No additional features or improvements were added. As a faithful translation, 
    - * many of the code here are done in an unrecommended way by today's standards.
    - * 17/02/25
    -*/
    -
    -//290 DATA 2,21,14,14,25
    -//300 DATA 1,2,-1,0,2,45,50,-1,0,5,43,52,-1,0,7,41,52,-1
    -//310 DATA 1,9,37,50,-1,2,11,36,50,-1,3,13,34,49,-1,4,14,32,48,-1
    -//320 DATA 5,15,31,47,-1,6,16,30,45,-1,7,17,29,44,-1,8,19,28,43,-1
    -//330 DATA 9,20,27,41,-1,10,21,26,40,-1,11,22,25,38,-1,12,22,24,36,-1
    -//340 DATA 13,34,-1,14,33,-1,15,31,-1,17,29,-1,18,27,-1
    -//350 DATA 19,26,-1,16,28,-1,13,30,-1,11,31,-1,10,32,-1
    -//360 DATA 8,33,-1,7,34,-1,6,13,16,34,-1,5,12,16,35,-1
    -//370 DATA 4,12,16,35,-1,3,12,15,35,-1,2,35,-1,1,35,-1
    -//380 DATA 2,34,-1,3,34,-1,4,33,-1,6,33,-1,10,32,34,34,-1
    -//390 DATA 14,17,19,25,28,31,35,35,-1,15,19,23,30,36,36,-1
    -//400 DATA 14,18,21,21,24,30,37,37,-1,13,18,23,29,33,38,-1
    -//410 DATA 12,29,31,33,-1,11,13,17,17,19,19,22,22,24,31,-1
    -//420 DATA 10,11,17,18,22,22,24,24,29,29,-1
    -//430 DATA 22,23,26,29,-1,27,29,-1,28,29,-1,4096
    -
    -// 4096 is the end of file
    -// -1 is the end of line
    -const DATA: [i32;233] = [
    -    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,
    -];
    -
    -fn main() {
    -    let mut col = 0;
    -
    -    //10 PRINT TAB(33);"BUNNY"
    -    //20 PRINT TAB(15);"CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY"
    -    //30 PRINT: PRINT: PRINT
    -    //100 REM  "BUNNY" FROM DAVID AHL'S 'BASIC COMPUTER GAMES'
    -    print!("{}{}\n{}{}\n",
    -        " ".repeat(33),
    -        "BUNNY",
    -        " ".repeat(15),
    -        "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY"
    -    );
    -
    -    //120 FOR I=0 TO 4: READ B(I): NEXT I
    -    let mut b = [0;5];
    -    for i in 0..=4 {
    -        b[i] = DATA[col];
    -        col = col + 1;
    -    }
    -
    -    //130 GOSUB 260
    -    //260 FOR I=1 TO 6: PRINT CHR$(10);: NEXT I
    -    for _ in 1..=6 {
    -        println!();
    -    }
    -    //270 RETURN
    -    
    -    //140 L=64: REM  ASCII LETTER CODE...
    -    let l = 64;
    -    let mut prev = 0;
    -    loop {
    -        //170 READ X: IF X<0 THEN 160
    -        let x = DATA[col];
    -        col = col + 1;
    -        if x < 0 {
    -            //160 PRINT
    -            println!();
    -            prev = 0;
    -            continue;
    -        }
    -        //175 IF X>128 THEN 240
    -        else if x > 128 {
    -            //240 GOSUB 260: GOTO 450
    -            for _ in 1..=6 {
    -                println!();
    -            }
    -            break;
    -        }
    -        else {
    -            //180 PRINT TAB(X);: READ Y
    -            print!("{}", " ".repeat((x - prev) as usize)); // verificar
    -            prev = x;
    -            let y = DATA[col];
    -            col = col + 1;
    -            //190 FOR I=X TO Y: J=I-5*INT(I/5)
    -            for i in x..=y {
    -                let j = i - 5 * (i / 5);
    -                //200 PRINT CHR$(L+B(J));
    -                print!("{}", (l + b[j as usize]) as u8 as char);
    -                prev = prev + 1;
    -                //210 NEXT I
    -
    -            }
    -            //220 GOTO 170
    -        }
    -    }
    -    //450 END
    -}
    -
    diff --git a/19_Bunny/vbnet/Bunny.sln b/19_Bunny/vbnet/Bunny.sln
    deleted file mode 100644
    index b5d177ca5..000000000
    --- a/19_Bunny/vbnet/Bunny.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 49bd3df20..000000000
    --- a/19_Bunny/vbnet/Bunny.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Bunny
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/20_Buzzword/README.md b/20_Buzzword/README.md
    index 97dc41c1f..22e76f6f1 100644
    --- a/20_Buzzword/README.md
    +++ b/20_Buzzword/README.md
    @@ -12,7 +12,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/20_Buzzword/csharp/Program.cs b/20_Buzzword/csharp/Program.cs
    index 17b8a6b31..e9970d82f 100644
    --- a/20_Buzzword/csharp/Program.cs
    +++ b/20_Buzzword/csharp/Program.cs
    @@ -75,7 +75,7 @@ static string GeneratePhrase()
             }
     
             /// 
    -        /// Handles user input. On wrong input it displays information about
    +        /// Handles user input. On wrong input it displays information about 
             /// valid keys in infinite loop.
             /// 
             /// True if user pressed 'Y', false if 'N'.
    diff --git a/20_Buzzword/java/src/Buzzword.java b/20_Buzzword/java/src/Buzzword.java
    old mode 100644
    new mode 100755
    diff --git a/20_Buzzword/java/src/UserInterface.java b/20_Buzzword/java/src/UserInterface.java
    index 8115b2dac..103e88c8b 100644
    --- a/20_Buzzword/java/src/UserInterface.java
    +++ b/20_Buzzword/java/src/UserInterface.java
    @@ -35,7 +35,7 @@ public UserInterface(final Scanner input,
     			final Supplier buzzwords) {
     		this.input = input;
     		this.output = output;
    -		this.buzzwords = buzzwords;
    +		this.buzzwords = buzzwords;		
     	}
     
     	@Override
    diff --git a/20_Buzzword/javascript/buzzword.html b/20_Buzzword/javascript/buzzword.html
    index 87a6b9b05..e384b3fcf 100644
    --- a/20_Buzzword/javascript/buzzword.html
    +++ b/20_Buzzword/javascript/buzzword.html
    @@ -1,10 +1,9 @@
     
     
     BUZZWORD
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/20_Buzzword/javascript/buzzword.js b/20_Buzzword/javascript/buzzword.js
    index 55780b21c..80c4e51e9 100644
    --- a/20_Buzzword/javascript/buzzword.js
    +++ b/20_Buzzword/javascript/buzzword.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/20_Buzzword/kotlin/README.md b/20_Buzzword/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/20_Buzzword/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/20_Buzzword/lua/README.md b/20_Buzzword/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/20_Buzzword/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/20_Buzzword/lua/buzzword.lua b/20_Buzzword/lua/buzzword.lua
    deleted file mode 100644
    index aacfe5b29..000000000
    --- a/20_Buzzword/lua/buzzword.lua
    +++ /dev/null
    @@ -1,81 +0,0 @@
    ---- Buzzword
    ---- Ported by Brian Wilkins.
    ---- Updated for modern buzzwords and corporate-speak
    -
    -print [[
    -                        BUZZWORD GENERATOR
    -              CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY
    -
    -]]
    -
    -print [[
    -
    -
    -THIS PROGRAM PRINTS HIGHLY ACCEPTABLE PHRASES IN
    -'EDUCATOR-SPEAK' THAT YOU CAN WORK INTO REPORTS
    -AND SPEECHES.  WHENEVER A QUESTION MARK IS PRINTED,
    -TYPE A 'Y' FOR ANOTHER PHRASE OR 'N' TO QUIT.
    -]]
    -
    -local phraseList = {"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"}
    -
    ---- Credit to https://stackoverflow.com/a/33468353/19232282
    ---- for the pickPhrase function
    -local copyPhraseList = {}
    -
    -function pickPhrase()
    -   local i
    -   -- make a copy of the original table if we ran out of phrases
    -   if #copyPhraseList == 0 then
    -      for k,v in pairs(phraseList) do
    -         copyPhraseList[k] = v
    -      end
    -   end
    -               
    -   -- pick a random element from the copy  
    -   i = math.random(#copyPhraseList)
    -   phrase = copyPhraseList[i] 
    -               
    -   -- remove phrase from copy
    -   table.remove(copyPhraseList, i)
    -               
    -   return phrase
    -end
    -
    ---- Reused from Bagels.lua
    -function getInput(prompt)
    -    io.write(prompt)
    -    io.flush()
    -    local input = io.read("l") 
    -    if not input then  --- test for EOF
    -        print("COME BACK WHEN YOU NEED HELP WITH ANOTHER REPORT!")
    -        os.exit(0)
    -    end
    -    return input
    -end
    -
    -for i=1,3,1 do
    -    ::phrasepick::
    -    io.write (pickPhrase() .. " ")
    -    io.write (pickPhrase() .. " ")
    -    io.write (pickPhrase())
    -    print()
    -    io.stdin:flush()
    -    local response = getInput("? ")
    -    if response:match("[yY].*") then
    -       goto phrasepick
    -    else
    -       print("COME BACK WHEN YOU NEED HELP WITH ANOTHER REPORT!")
    -       os.exit(0)
    -    end
    -end
    -
    diff --git a/20_Buzzword/pascal/README.md b/20_Buzzword/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/20_Buzzword/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/20_Buzzword/perl/buzzword.pl b/20_Buzzword/perl/buzzword.pl
    index 41cd8e4d2..75f09b3c2 100755
    --- a/20_Buzzword/perl/buzzword.pl
    +++ b/20_Buzzword/perl/buzzword.pl
    @@ -15,13 +15,13 @@
     	"ABILITY","BASAL","BEHAVIORAL","CHILD-CENTERED",
     	"DIFFERENTIATED","DISCOVERY","FLEXIBLE","HETEROGENEOUS",
     	"HOMOGENEOUS","MANIPULATIVE","MODULAR","TAVISTOCK",
    -	"INDIVIDUALIZED","LEARNING","EVALUATIVE","OBJECTIVE",
    +	"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"
    +	"PERFORMANCE","REINFORCEMENT","OPEN CLASSROOM","RESOURCE", 
    +	"STRUCTURE","FACILITY","ENVIRONMENT" 
     	);
     
     my $Y;
    @@ -35,3 +35,5 @@
     
     print "COME BACK WHEN YOU NEED HELP WITH ANOTHER REPORT!\n";
     exit;
    +
    +
    diff --git a/20_Buzzword/python/buzzword.py b/20_Buzzword/python/buzzword.py
    index 48552edc1..4de33d297 100644
    --- a/20_Buzzword/python/buzzword.py
    +++ b/20_Buzzword/python/buzzword.py
    @@ -1,108 +1,76 @@
    -"""
    -Buzzword Generator
    -
    -From: BASIC Computer Games (1978)
    -      Edited by David H. Ahl
    -
    -"This program is an invaluable aid for preparing speeches and
    - briefings about education technology.  This buzzword generator
    - provides sets of three highly-acceptable words to work into your
    - material.  Your audience will never know that the phrases don't
    - really mean much of anything because they sound so great!  Full
    - instructions for running are given in the program.
    -
    -"This version of Buzzword was written by David Ahl."
    -
    -
    -Python port by Jeff Jetton, 2019
    -"""
    +######################################################################
    +#
    +# Buzzword Generator
    +#
    +# From: BASIC Computer Games (1978)
    +#       Edited by David H. Ahl
    +#
    +# "This program is an invaluable aid for preparing speeches and
    +#  briefings about education technology.  This buzzword generator
    +#  provides sets of three highly-acceptable words to work into your
    +#  material.  Your audience will never know that the phrases don't
    +#  really mean much of anything because they sound so great!  Full
    +#  instructions for running are given in the program.
    +#
    +# "This version of Buzzword was written by David Ahl."
    +#
    +#
    +# Python port by Jeff Jetton, 2019
    +#
    +######################################################################
     
     
     import random
     
     
    -def main() -> None:
    -    words = [
    -        [
    -            "Ability",
    -            "Basal",
    -            "Behavioral",
    -            "Child-centered",
    -            "Differentiated",
    -            "Discovery",
    -            "Flexible",
    -            "Heterogeneous",
    -            "Homogenous",
    -            "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",
    -        ],
    -    ]
    -
    -    # Display intro text
    -    print("\n           Buzzword Generator")
    -    print("Creative Computing  Morristown, New Jersey")
    -    print("\n\n")
    -    print("This program prints highly acceptable phrases in")
    -    print("'educator-speak' that you can work into reports")
    -    print("and speeches.  Whenever a question mark is printed,")
    -    print("type a 'Y' for another phrase or 'N' to quit.")
    -    print("\n\nHere's the first phrase:")
    -
    -    still_running = True
    -    while still_running:
    -        phrase = ""
    -        for section in words:
    -            if len(phrase) > 0:
    -                phrase += " "
    -            phrase += section[random.randint(0, len(section) - 1)]
    -
    -        print(phrase)
    -        print()
    -
    -        response = input("? ")
    -        try:
    -            if response.upper()[0] != "Y":
    -                still_running = False
    -        except Exception:
    +WORDS = [ ["Ability", "Basal", "Behavioral", "Child-centered",
    +           "Differentiated", "Discovery", "Flexible", "Heterogeneous",
    +           "Homogenous", "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"] ]
    +
    +
    +# Display intro text
    +print("\n           Buzzword Generator")
    +print("Creative Computing  Morristown, New Jersey")
    +print("\n\n")
    +print("This program prints highly acceptable phrases in")
    +print("'educator-speak' that you can work into reports")
    +print("and speeches.  Whenever a question mark is printed,")
    +print("type a 'Y' for another phrase or 'N' to quit.")
    +print("\n\nHere's the first phrase:")
    +
    +still_running = True
    +while still_running:
    +    phrase = ""
    +    for section in WORDS:
    +        if len(phrase) > 0:
    +            phrase += " "
    +        phrase += section[random.randint(0, len(section)-1)]
    +        
    +    print(phrase)
    +    print("")
    +    
    +    response = input("? ")
    +    try:
    +        if response.upper()[0] != 'Y':
                 still_running = False
    +    except:
    +        still_running = False
     
    -    print("Come back when you need help with another report!\n")
    +
    +print("Come back when you need help with another report!\n")
     
     
    -if __name__ == "__main__":
    -    main()
     
     ######################################################################
     #
    @@ -125,7 +93,7 @@ def main() -> None:
     #   newsletter named "EDU" that focused on using computers in an
     #   educational setting.  No surprise, then, that the buzzwords in
     #   this program were targeted towards educators!
    -#
    +#   
     #
     # Ideas for Modifications
     #
    @@ -136,3 +104,10 @@ def main() -> None:
     #   choose a field and pick the buzzwords accordingly.
     #
     ######################################################################
    +
    +
    +            
    +        
    +    
    +
    +    
    diff --git a/20_Buzzword/ruby/buzzword.rb b/20_Buzzword/ruby/buzzword.rb
    index a81e0790c..3ddcf0faf 100644
    --- a/20_Buzzword/ruby/buzzword.rb
    +++ b/20_Buzzword/ruby/buzzword.rb
    @@ -23,12 +23,12 @@
                "Differentiated", "Discovery", "Flexible", "Heterogeneous",
                "Homogenous", "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",
    @@ -54,13 +54,13 @@
         phrase << prefix[rand(prefix.length)]
         phrase << body[rand(body.length)]
         phrase << postfix[rand(postfix.length)]
    -
    +            
         puts phrase.join(' ')
         puts "\n"
    -
    +    
         print "?"
         response = gets
    -
    +    
         break unless response.upcase.start_with?('Y')
     end
     
    @@ -75,7 +75,7 @@
     #   built the buzzword phrases by randomly sampling from each of the
     #   three regions of the array (1-13, 14-26, and 27-39).
     #
    -#   Instead, we're storing the words for each section in three
    +#   Instead, we're storing the words for each section in three 
     #   separate arrays. That makes it easy to loop through the sections
     #   to stitch the phrase together, and it easily accomodates adding
     #   (or removing) elements from any section.  They don't all need to
    @@ -88,7 +88,7 @@
     #   newsletter named "EDU" that focused on using computers in an
     #   educational setting.  No surprise, then, that the buzzwords in
     #   this program were targeted towards educators!
    -#
    +#   
     #
     # Ideas for Modifications
     #
    diff --git a/20_Buzzword/rust/Cargo.lock b/20_Buzzword/rust/Cargo.lock
    deleted file mode 100644
    index 4fe2abbea..000000000
    --- a/20_Buzzword/rust/Cargo.lock
    +++ /dev/null
    @@ -1,75 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.10"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.147"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/20_Buzzword/rust/Cargo.toml b/20_Buzzword/rust/Cargo.toml
    deleted file mode 100644
    index 3b1d02f52..000000000
    --- a/20_Buzzword/rust/Cargo.toml
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -[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/20_Buzzword/rust/README.md b/20_Buzzword/rust/README.md
    deleted file mode 100644
    index fc6468b9f..000000000
    --- a/20_Buzzword/rust/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Rust](https://www.rust-lang.org/)
    diff --git a/20_Buzzword/rust/src/main.rs b/20_Buzzword/rust/src/main.rs
    deleted file mode 100644
    index dae4b8198..000000000
    --- a/20_Buzzword/rust/src/main.rs
    +++ /dev/null
    @@ -1,112 +0,0 @@
    -use rand::seq::SliceRandom;
    -use std::io::{self, Write};
    -
    -fn main() {
    -    let words = vec![
    -        vec![
    -            "Ability",
    -            "Basal",
    -            "Behavioral",
    -            "Child-centered",
    -            "Differentiated",
    -            "Discovery",
    -            "Flexible",
    -            "Heterogeneous",
    -            "Homogenous",
    -            "Manipulative",
    -            "Modular",
    -            "Tavistock",
    -            "Individualized",
    -        ],
    -        vec![
    -            "learning",
    -            "evaluative",
    -            "objective",
    -            "cognitive",
    -            "enrichment",
    -            "scheduling",
    -            "humanistic",
    -            "integrated",
    -            "non-graded",
    -            "training",
    -            "vertical age",
    -            "motivational",
    -            "creative",
    -        ],
    -        vec![
    -            "grouping",
    -            "modification",
    -            "accountability",
    -            "process",
    -            "core curriculum",
    -            "algorithm",
    -            "performance",
    -            "reinforcement",
    -            "open classroom",
    -            "resource",
    -            "structure",
    -            "facility",
    -            "environment",
    -        ],
    -    ];
    -
    -    // intro text
    -    println!("\n           Buzzword Generator");
    -    println!("Creative Computing  Morristown, New Jersey");
    -    println!("\n\n");
    -    println!("This program prints highly acceptable phrases in");
    -    println!("'educator-speak' that you can work into reports");
    -    println!("and speeches.  Whenever a question mark is printed,");
    -    println!("type a 'Y' for another phrase or 'N' to quit.");
    -    println!("\n\nHere's the first phrase:");
    -
    -    let mut continue_running: bool = true;
    -
    -    while continue_running {
    -        let mut first_word: bool = true;
    -        for section in &words {
    -            if !first_word {
    -                print!(" ");
    -            }
    -            first_word = false;
    -            print!("{}", section.choose(&mut rand::thread_rng()).unwrap());
    -        }
    -        print!("\n\n? ");
    -        io::stdout().flush().unwrap();
    -
    -        let mut cont_question: String = String::new();
    -        io::stdin()
    -            .read_line(&mut cont_question)
    -            .expect("Failed to read the line");
    -        if !cont_question.to_uppercase().starts_with("Y") {
    -            continue_running = false;
    -        }
    -    }
    -    println!("Come back when you need help with another report!\n");
    -
    -}
    -
    -
    -/////////////////////////////////////////////////////////////////////////
    -//
    -// Porting Notes
    -//
    -//   The original program stored all 39 words in one array, then
    -//   built the buzzword phrases by randomly sampling from each of the
    -//   three regions of the array (1-13, 14-26, and 27-39).
    -//
    -//   Here, we're storing the words for each section in separate
    -//   tuples.  That makes it easy to just loop through the sections
    -//   to stitch the phrase together, and it easily accommodates adding
    -//   (or removing) elements from any section.  They don't all need to
    -//   be the same length.
    -//
    -//   The author of this program (and founder of Creative Computing
    -//   magazine) first started working at DEC--Digital Equipment
    -//   Corporation--as a consultant helping the company market its
    -//   computers as educational products.  He later was editor of a DEC
    -//   newsletter named "EDU" that focused on using computers in an
    -//   educational setting.  No surprise, then, that the buzzwords in
    -//   this program were targeted towards educators!
    -//
    -/////////////////////////////////////////////////////////////////////////
    diff --git a/20_Buzzword/vbnet/Buzzword.sln b/20_Buzzword/vbnet/Buzzword.sln
    deleted file mode 100644
    index 2f8a8ef3a..000000000
    --- a/20_Buzzword/vbnet/Buzzword.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 945c5a630..000000000
    --- a/20_Buzzword/vbnet/Buzzword.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Buzzword
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/21_Calendar/README.md b/21_Calendar/README.md
    index 5f5b04eac..5a93d50d8 100644
    --- a/21_Calendar/README.md
    +++ b/21_Calendar/README.md
    @@ -21,9 +21,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -- While many modern environments have time/date functions that would make this program both easier and more automatic, in these ports we are choosing to do without them, as in the original program.
    -
    -- Some ports choose to ask the user the starting day of week, and whether it's a leap year, rather than force changes to the code to fit the desired year.
    diff --git a/21_Calendar/csharp/21_calendar.csproj b/21_Calendar/csharp/21_calendar.csproj
    new file mode 100644
    index 000000000..895f2f3f9
    --- /dev/null
    +++ b/21_Calendar/csharp/21_calendar.csproj
    @@ -0,0 +1,9 @@
    +
    +
    +  
    +    Exe
    +    net5.0
    +    _21_calendar
    +  
    +
    +
    diff --git a/21_Calendar/csharp/21_calendar.sln b/21_Calendar/csharp/21_calendar.sln
    new file mode 100644
    index 000000000..d8330a26b
    --- /dev/null
    +++ b/21_Calendar/csharp/21_calendar.sln
    @@ -0,0 +1,25 @@
    +
    +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}"
    +EndProject
    +Global
    +	GlobalSection(SolutionConfigurationPlatforms) = preSolution
    +		Debug|Any CPU = Debug|Any CPU
    +		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
    +	EndGlobalSection
    +	GlobalSection(SolutionProperties) = preSolution
    +		HideSolutionNode = FALSE
    +	EndGlobalSection
    +	GlobalSection(ExtensibilityGlobals) = postSolution
    +		SolutionGuid = {1B423C35-492F-4AF8-97FC-BEC69B44EC8D}
    +	EndGlobalSection
    +EndGlobal
    diff --git a/21_Calendar/csharp/Calendar.sln b/21_Calendar/csharp/Calendar.sln
    deleted file mode 100644
    index 8b2be04b9..000000000
    --- a/21_Calendar/csharp/Calendar.sln
    +++ /dev/null
    @@ -1,25 +0,0 @@
    -
    -Microsoft Visual Studio Solution File, Format Version 12.00
    -# Visual Studio Version 16
    -VisualStudioVersion = 16.0.31613.86
    -MinimumVisualStudioVersion = 10.0.40219.1
    -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Calendar", "Calendar.csproj", "{1EADFB6C-4496-42C2-A80F-84FEC3F061D1}"
    -EndProject
    -Global
    -	GlobalSection(SolutionConfigurationPlatforms) = preSolution
    -		Debug|Any CPU = Debug|Any CPU
    -		Release|Any CPU = Release|Any CPU
    -	EndGlobalSection
    -	GlobalSection(ProjectConfigurationPlatforms) = postSolution
    -		{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
    -	EndGlobalSection
    -	GlobalSection(ExtensibilityGlobals) = postSolution
    -		SolutionGuid = {1B423C35-492F-4AF8-97FC-BEC69B44EC8D}
    -	EndGlobalSection
    -EndGlobal
    diff --git a/21_Calendar/csharp/Program.cs b/21_Calendar/csharp/Program.cs
    index 8504c2e9c..4fd2b177a 100644
    --- a/21_Calendar/csharp/Program.cs
    +++ b/21_Calendar/csharp/Program.cs
    @@ -30,14 +30,14 @@ static void Main(string[] args)
                 // the usage of Write*Line* means we do not have to specify a newline (\n)
                 Console.WriteLine(Tab(32) + "CALENDAR");
                 Console.WriteLine(Tab(15) + "CREATE COMPUTING  MORRISTOWN, NEW JERSEY");
    -            //give us some space.
    +            //give us some space. 
                 Console.WriteLine("");
                 Console.WriteLine("");
                 Console.WriteLine("");
     
                 //establish some variables needed to print out a calculator
     
    -            //the length of each month in days. On a leap year, the start of this would be
    +            //the length of each month in days. On a leap year, the start of this would be 
                 // 0, 31, 29 to account for Feb. the 0 at the start is for days elapsed to work right in Jan.
                 int[] monthLengths = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; // m in original source
     
    @@ -89,9 +89,9 @@ static void Main(string[] args)
                     }
                     header += "  ";
                     // how many days left till the year's over?
    -                header += (365 - elapsed) + " **"; // on leap years 366
    +                header += (365 - elapsed) + " **"; // on leap years 366 
                     Console.WriteLine(header);
    -                //dates
    +                //dates 
                     Console.WriteLine("     S       M       T       W       T       F       S");
                     Console.WriteLine(" ");
     
    @@ -107,7 +107,7 @@ static void Main(string[] args)
                     for (int week = 1; week <= 6; week++)
                     {
                         Console.WriteLine(weekOutput);
    -                    weekOutput = "    ";
    +                    weekOutput = "    "; 
                         for (g = 1; g <= 7; g++)
                         {
                             //add one to the day
    diff --git a/21_Calendar/java/Calendar.java b/21_Calendar/java/Calendar.java
    index b27f8fbda..4202a4dc6 100644
    --- a/21_Calendar/java/Calendar.java
    +++ b/21_Calendar/java/Calendar.java
    @@ -6,64 +6,64 @@
      * 

    * Note: The idea was to create a version of the 1970's BASIC game in Java, without introducing * new features - no additional text, error checking, etc has been added. - * + * * Converted from BASIC to Java by Darren Cardenas. */ - -public class Calendar { + +public class Calendar { private static final int NUM_WEEK_ROWS = 6; private static final int NUM_DAYS_PER_WEEK = 7; - private static final int NUM_MONTHS_PER_YEAR = 12; - private static final int[] daysPerMonth = { 0, 31, 28, 31, 30, 31, 30, - 31, 31, 30, 31, 30, 31 }; - + private static final int NUM_MONTHS_PER_YEAR = 12; + private static final int[] daysPerMonth = { 0, 31, 28, 31, 30, 31, 30, + 31, 31, 30, 31, 30, 31 }; + public void play() { - + showIntro(); startGame(); - - } // End of method play - + + } // End of method play + private static void showIntro() { - + System.out.println(" ".repeat(31) + "CALENDAR"); System.out.println(" ".repeat(14) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); System.out.println("\n\n"); - } // End of method showIntro - - private void startGame() { + } // End of method showIntro + + private void startGame() { int dayOfMonth = 0; int dayOfWeek = 0; int dayOfYear = 0; - int daysTotal = 0; + int daysTotal = 0; int index = 0; int month = 0; - int row = 0; - + int row = 0; + String lineContent = ""; - - for (index = 1; index <= 6; index++) { - System.out.println(""); + + for (index = 1; index <= 6; index++) { + System.out.println(""); } - + daysTotal = -1; dayOfYear = 0; - + System.out.println(""); - + // Begin loop through all months for (month = 1; month <= NUM_MONTHS_PER_YEAR; month++) { System.out.println(""); - + dayOfYear = dayOfYear + daysPerMonth[month - 1]; - + lineContent = String.format("** %-3d" + "*".repeat(18), dayOfYear); - - switch (month) { + + switch (month) { case 1: lineContent += " JANUARY "; break; @@ -75,14 +75,14 @@ private void startGame() { break; case 4: lineContent += " APRIL "; - break; - case 5: + break; + case 5: lineContent += " MAY "; - break; - case 6: + break; + case 6: lineContent += " JUNE "; - break; - case 7: + break; + case 7: lineContent += " JULY "; break; case 8: @@ -103,73 +103,73 @@ private void startGame() { default: break; } - + lineContent += "*".repeat(18) + " " + (365 - dayOfYear) + "**"; - + System.out.println(lineContent); System.out.println(""); System.out.print(" S M T W"); System.out.println(" T F S"); System.out.println(""); - + System.out.println("*".repeat(59)); // Begin loop through each week row for (row = 1; row <= NUM_WEEK_ROWS; row++) { - + System.out.println(""); - + lineContent = " "; - + // Begin loop through days of the week for (dayOfWeek = 1; dayOfWeek <= NUM_DAYS_PER_WEEK; dayOfWeek++) { - + daysTotal++; - + dayOfMonth = daysTotal - dayOfYear; - + if (dayOfMonth > daysPerMonth[month]) { row = 6; - break; + break; } - if (dayOfMonth > 0) { + if (dayOfMonth > 0) { lineContent += dayOfMonth; } - - while (lineContent.length() < (4 + 8 * dayOfWeek)) { - lineContent += " "; - } - + + while (lineContent.length() < (4 + 8 * dayOfWeek)) { + lineContent += " "; + } + } // End loop through days of the week - - if (dayOfMonth == daysPerMonth[month]) { + + if (dayOfMonth == daysPerMonth[month]) { row = 6; daysTotal += dayOfWeek; System.out.println(lineContent); break; } - + System.out.println(lineContent); - + } // End loop through each week row - - daysTotal -= dayOfWeek; - + + daysTotal -= dayOfWeek; + } // End loop through all months - - for (index = 1; index <= 6; index++) { - System.out.println(""); - } - - } // End of method startGame - + + for (index = 1; index <= 6; index++) { + System.out.println(""); + } + + } // End of method startGame + public static void main(String[] args) { - + Calendar game = new Calendar(); game.play(); - + } // End of method main - + } // End of class Calendar diff --git a/21_Calendar/javascript/calendar.html b/21_Calendar/javascript/calendar.html index fcc2d4b66..ff9a36037 100644 --- a/21_Calendar/javascript/calendar.html +++ b/21_Calendar/javascript/calendar.html @@ -1,10 +1,9 @@ CALENDAR - -

    
    +
    
     
     
     
    diff --git a/21_Calendar/javascript/calendar.js b/21_Calendar/javascript/calendar.js
    index df6c90e67..288191986 100644
    --- a/21_Calendar/javascript/calendar.js
    +++ b/21_Calendar/javascript/calendar.js
    @@ -63,7 +63,7 @@ for (n = 1; n <= 12; n++) {
     	print("\n");
     	str = "";
     	for (i = 1; i <= 59; i++)
    -		str += "*";
    +		str += "*";    
     	for (week = 1; week <= 6; week++) {
     		print(str + "\n");
     		str = "    ";
    @@ -83,7 +83,7 @@ for (n = 1; n <= 12; n++) {
     			d += g;
     			break;
     		}
    -	}
    +	} 
     	d -= g;
     	print(str + "\n");
     }
    diff --git a/21_Calendar/kotlin/README.md b/21_Calendar/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/21_Calendar/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/21_Calendar/lua/README.md b/21_Calendar/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/21_Calendar/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/21_Calendar/pascal/README.md b/21_Calendar/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/21_Calendar/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/21_Calendar/python/calendar.py b/21_Calendar/python/calendar.py
    index 5c59e37e3..6f3f572b8 100644
    --- a/21_Calendar/python/calendar.py
    +++ b/21_Calendar/python/calendar.py
    @@ -1,28 +1,26 @@
    -"""
    -Calendar
    -
    -From: BASIC Computer Games (1978)
    -      Edited by David Ahl#
    -
    -   This program prints out a calendar
    -for any year. You must specify the
    -starting day of the week of the year in
    -statement 130. (Sunday(0), Monday
    -(-1), Tuesday(-2), etc.) You can determine
    -this by using the program WEEKDAY.
    -You must also make two changes
    -for leap years in statement 360 and 620.
    -The program listing describes the necessary
    -changes. Running the program produces a
    -nice 12-month calendar.
    -   The program was written by Geofrey
    -Chase of the Abbey, Portsmouth, Rhode Island.
    -"""
    -
    -from typing import Tuple
    -
    -
    -def parse_input() -> Tuple[int, bool]:
    +########################################################
    +# Calendar
    +#
    +# From: BASIC Computer Games (1978)
    +#       Edited by David Ahl#
    +#
    +#    This program prints out a calendar
    +# for any year. You must specify the
    +# starting day of the week of the year in
    +# statement 130. (Sunday(0), Monday
    +# (-1), Tuesday(-2), etc.) You can determine
    +# this by using the program WEEKDAY.
    +# You must also make two changes
    +# for leap years in statement 360 and 620.
    +# The program listing describes the necessary
    +# changes. Running the program produces a
    +# nice 12-month calendar.
    +#    The program was written by Geofrey
    +# Chase of the Abbey, Portsmouth, Rhode Island.
    +#
    +########################################################
    +
    +def parse_input():
         """
         function to parse input for weekday and leap year boolean
         """
    @@ -34,7 +32,7 @@ def parse_input() -> Tuple[int, bool]:
             "wednesday": -3,
             "thursday": -4,
             "friday": -5,
    -        "saturday": -6,
    +        "saturday": -6
         }
     
         day = 0
    @@ -44,7 +42,7 @@ def parse_input() -> Tuple[int, bool]:
         while not correct_day_input:
             weekday = input("INSERT THE STARTING DAY OF THE WEEK OF THE YEAR:")
     
    -        for day_k in days_mapping:
    +        for day_k in days_mapping.keys():
                 if weekday.lower() in day_k:
                     day = days_mapping[day_k]
                     correct_day_input = True
    @@ -53,27 +51,27 @@ def parse_input() -> Tuple[int, bool]:
         while True:
             leap = input("IS IT A LEAP YEAR?:")
     
    -        if "y" in leap.lower():
    +        if 'y' in leap.lower():
                 leap_day = True
                 break
     
    -        if "n" in leap.lower():
    +        if 'n' in leap.lower():
                 leap_day = False
                 break
     
         return day, leap_day
     
     
    -def calendar(weekday: int, leap_year: bool) -> None:
    +def calendar(weekday, leap_year):
         """
         function to print a year's calendar.
     
    -    input:
    +    input: 
             _weekday_: int - the initial day of the week (0=SUN, -1=MON, -2=TUES...)
             _leap_year_: bool - indicates if the year is a leap year
         """
         months_days = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    -    days = "S        M        T        W        T        F        S\n"
    +    days = 'S        M        T        W        T        F        S\n'
         sep = "*" * 59
         years_day = 365
         d = weekday
    @@ -82,36 +80,32 @@ def calendar(weekday: int, leap_year: bool) -> None:
             months_days[2] = 29
             years_day = 366
     
    -    months_names = [
    -        " JANUARY ",
    -        " FEBRUARY",
    -        "  MARCH  ",
    -        "  APRIL  ",
    -        "   MAY   ",
    -        "   JUNE  ",
    -        "   JULY  ",
    -        "  AUGUST ",
    -        "SEPTEMBER",
    -        " OCTOBER ",
    -        " NOVEMBER",
    -        " DECEMBER",
    -    ]
    +    months_names = [" JANUARY ",
    +                    " FEBRUARY",
    +                    "  MARCH  ",
    +                    "  APRIL  ",
    +                    "   MAY   ",
    +                    "   JUNE  ",
    +                    "   JULY  ",
    +                    "  AUGUST ",
    +                    "SEPTEMBER",
    +                    " OCTOBER ",
    +                    " NOVEMBER",
    +                    " DECEMBER"]
     
         days_count = 0  # S in the original program
     
         # main loop
         for n in range(1, 13):
    -        days_count += months_days[n - 1]
    -        print(
    -            f"** {days_count} ****************** {months_names[n - 1]} "
    -            f"****************** {years_day - days_count} **\n"
    -        )
    +        days_count += months_days[n-1]
    +        print("** {} ****************** {} ****************** {} **\n".format(days_count,
    +                                                                              months_names[n-1], years_day-days_count))
             print(days)
             print(sep)
     
    -        for _ in range(1, 7):
    +        for w in range(1, 7):
                 print("\n")
    -            for g in range(1, 8):  # noqa
    +            for g in range(1, 8):
                     d += 1
                     d2 = d - days_count
     
    @@ -119,11 +113,11 @@ def calendar(weekday: int, leap_year: bool) -> None:
                         break
     
                     if d2 <= 0:
    -                    print("  ", end="       ")
    +                    print("{}".format('  '), end='       ')
                     elif d2 < 10:
    -                    print(f" {d2}", end="       ")
    +                    print(" {}".format(d2), end='       ')
                     else:
    -                    print(f"{d2}", end="       ")
    +                    print("{}".format(d2), end='       ')
                 print()
     
                 if d2 >= months_days[n]:
    @@ -137,10 +131,10 @@ def calendar(weekday: int, leap_year: bool) -> None:
         print("\n")
     
     
    -def main() -> None:
    -    print(" " * 32 + "CALENDAR")
    -    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
    -    print("\n" * 11)
    +def main():
    +    print(" "*32 + "CALENDAR")
    +    print(" "*15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
    +    print("\n"*11)
     
         day, leap_year = parse_input()
         calendar(day, leap_year)
    @@ -149,6 +143,8 @@ def main() -> None:
     if __name__ == "__main__":
         main()
     
    +########################################################
    +#
     ########################################################
     #
     # Porting notes:
    diff --git a/21_Calendar/ruby/calendar.rb b/21_Calendar/ruby/calendar.rb
    deleted file mode 100644
    index 4f7061d74..000000000
    --- a/21_Calendar/ruby/calendar.rb
    +++ /dev/null
    @@ -1,113 +0,0 @@
    -class Calendar
    -  def parse_input
    -    days_mapping = {
    -      "sunday": 0,
    -      "monday": -1,
    -      "tuesday": -2,
    -      "wednesday": -3,
    -      "thursday": -4,
    -      "friday": -5,
    -      "saturday": -6,
    -    }
    -
    -    day = 0
    -    leap_day = false
    -    correct_day_input = false
    -
    -    while !correct_day_input 
    -      print "INSERT THE STARTING DAY OF THE WEEK OF THE YEAR: "
    -      weekday = gets.chomp!
    -
    -      days_mapping.each do |k, v|
    -        if k.to_s == weekday.downcase.to_s
    -          day = v
    -          correct_day_input = true
    -          break
    -        end
    -      end
    -    end
    -
    -    while true
    -      print "IS IT A LEAP YEAR?: "
    -      leap = gets.chomp!
    -      if "y" == leap.downcase.to_s
    -        leap_day = true
    -        break
    -      end
    -
    -      if "n" == leap.downcase.to_s
    -        leap_day = false
    -        break
    -      end
    -    end
    -
    -    return day, leap_day
    -  end
    -
    -  def start(weekday, leap_year)
    -    months_days = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    -    days = "S        M        T        W        T        F        S\n"
    -    sep = "*" * 59
    -    years_day = 365
    -    d = weekday
    -
    -    if leap_year
    -      months_days[2] = 29
    -      years_day = 366
    -    end
    -
    -    months_names = [
    -      " JANUARY ",
    -      " FEBRUARY",
    -      "  MARCH  ",
    -      "  APRIL  ",
    -      "   MAY   ",
    -      "   JUNE  ",
    -      "   JULY  ",
    -      "  AUGUST ",
    -      "SEPTEMBER",
    -      " OCTOBER ",
    -      " NOVEMBER",
    -      " DECEMBER",
    -    ]
    -
    -    days_count = 0
    -
    -    for n in (1..12) do
    -      days_count += months_days[n - 1]
    -      print "** #{days_count} ****************** #{months_names[n - 1]} ****************** #{years_day - days_count} **\n"
    -      print days
    -      print sep
    -      for nnn in (1..6) do
    -        print "\n"
    -        for g in (1..7) do
    -          d += 1
    -          d2 = d - days_count
    -
    -          break if d2 > months_days[n]
    -
    -          if d2 <= 0
    -            print "         "
    -          elsif d2 < 10
    -            print " #{d2}       "
    -          else
    -            print "#{d2}       "
    -          end
    -        end
    -
    -        print "\n\n"
    -
    -        break if d2 >= months_days[n]
    -      end
    -      d -= g if d2 > months_days[n]
    -      print "\n"
    -    end
    -    print "\n"
    -  end
    -end
    -
    -if __FILE__ == $0
    -  calendar = Calendar.new
    -  input = calendar.parse_input
    -  calendar.start(input[0], input[1])
    -end
    \ No newline at end of file
    diff --git a/21_Calendar/rust/Cargo.lock b/21_Calendar/rust/Cargo.lock
    deleted file mode 100644
    index b21cc6a2d..000000000
    --- a/21_Calendar/rust/Cargo.lock
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    diff --git a/21_Calendar/rust/Cargo.toml b/21_Calendar/rust/Cargo.toml
    deleted file mode 100644
    index 1ec696335..000000000
    --- a/21_Calendar/rust/Cargo.toml
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -[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]
    diff --git a/21_Calendar/rust/README.md b/21_Calendar/rust/README.md
    deleted file mode 100644
    index e616424e3..000000000
    --- a/21_Calendar/rust/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Rust](https://www.rust-lang.org/) by [Uğur Küpeli](https://github.com/ugurkupeli)
    \ No newline at end of file
    diff --git a/21_Calendar/rust/src/main.rs b/21_Calendar/rust/src/main.rs
    deleted file mode 100644
    index a279f95d4..000000000
    --- a/21_Calendar/rust/src/main.rs
    +++ /dev/null
    @@ -1,152 +0,0 @@
    -use std::io::stdin;
    -
    -const WIDTH: usize = 64;
    -const DAYS_WIDTH: usize = WIDTH / 8;
    -const MONTH_WIDTH: usize = WIDTH - (DAYS_WIDTH * 2);
    -const DAY_NUMS_WIDTH: usize = WIDTH / 7;
    -
    -const DAYS: [&str; 7] = [
    -    "SUNDAY",
    -    "MONDAY",
    -    "TUESDAY",
    -    "WEDNESDAY",
    -    "THURSDAY",
    -    "FRIDAY",
    -    "SATURDAY",
    -];
    -
    -fn main() {
    -    println!("\n\t\t CALENDAR");
    -    println!("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
    -
    -    let (starting_day, leap_year) = prompt();
    -    let (months, total_days) = get_months_and_days(leap_year);
    -
    -    let mut days_passed = 0;
    -    let mut current_day_index = DAYS.iter().position(|d| *d == starting_day).unwrap();
    -
    -    for (month, days) in months {
    -        print_header(month, days_passed, total_days - days_passed);
    -        print_days(&mut current_day_index, days);
    -        days_passed += days as u16;
    -        println!("\n");
    -    }
    -}
    -
    -fn prompt() -> (String, bool) {
    -    let mut day = String::new();
    -
    -    loop {
    -        println!("\nFirst day of the year?");
    -        if let Ok(_) = stdin().read_line(&mut day) {
    -            day = day.trim().to_uppercase();
    -            if DAYS.contains(&day.as_str()) {
    -                break;
    -            } else {
    -                day.clear();
    -            }
    -        }
    -    }
    -
    -    let mut leap = false;
    -
    -    loop {
    -        println!("Is this a leap year?");
    -        let mut input = String::new();
    -        if let Ok(_) = stdin().read_line(&mut input) {
    -            match input.to_uppercase().trim() {
    -                "Y" | "YES" => {
    -                    leap = true;
    -                    break;
    -                }
    -                "N" | "NO" => break,
    -                _ => (),
    -            }
    -        }
    -    }
    -
    -    println!();
    -    (day, leap)
    -}
    -
    -fn get_months_and_days(leap_year: bool) -> (Vec<(String, u8)>, u16) {
    -    let months = [
    -        "JANUARY",
    -        "FEBUARY",
    -        "MARCH",
    -        "APRIL",
    -        "MAY",
    -        "JUNE",
    -        "JULY",
    -        "AUGUST",
    -        "SEPTEMBER",
    -        "OCTOBER",
    -        "NOVEMBER",
    -        "DECEMBER",
    -    ];
    -
    -    let mut months_with_days = Vec::new();
    -    let mut total_days: u16 = 0;
    -
    -    for (i, month) in months.iter().enumerate() {
    -        let days = if i == 1 {
    -            if leap_year {
    -                29u8
    -            } else {
    -                28
    -            }
    -        } else if if i < 7 { (i % 2) == 0 } else { (i % 2) != 0 } {
    -            31
    -        } else {
    -            30
    -        };
    -
    -        total_days += days as u16;
    -        months_with_days.push((month.to_string(), days));
    -    }
    -
    -    (months_with_days, total_days)
    -}
    -
    -fn print_between(s: String, w: usize, star: bool) {
    -    let s = format!(" {s} ");
    -    if star {
    -        print!("{:*^w$}", s);
    -        return;
    -    }
    -    print!("{:^w$}", s);
    -}
    -
    -fn print_header(month: String, days_passed: u16, days_left: u16) {
    -    print_between(days_passed.to_string(), DAYS_WIDTH, true);
    -    print_between(month.to_string(), MONTH_WIDTH, true);
    -    print_between(days_left.to_string(), DAYS_WIDTH, true);
    -    println!();
    -
    -    for d in DAYS {
    -        let d = d.chars().nth(0).unwrap();
    -        print_between(d.to_string(), DAY_NUMS_WIDTH, false);
    -    }
    -    println!();
    -
    -    println!("{:*>WIDTH$}", "");
    -}
    -
    -fn print_days(current_day_index: &mut usize, days: u8) {
    -    let mut current_date = 1u8;
    -
    -    print!("{:>w$}", " ", w = DAY_NUMS_WIDTH * *current_day_index);
    -
    -    for _ in 1..=days {
    -        print_between(current_date.to_string(), DAY_NUMS_WIDTH, false);
    -
    -        if ((*current_day_index + 1) % 7) == 0 {
    -            *current_day_index = 0;
    -            println!();
    -        } else {
    -            *current_day_index += 1;
    -        }
    -
    -        current_date += 1;
    -    }
    -}
    diff --git a/21_Calendar/vbnet/Calendar.sln b/21_Calendar/vbnet/Calendar.sln
    deleted file mode 100644
    index c8e5c017b..000000000
    --- a/21_Calendar/vbnet/Calendar.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index ed6bd15a7..000000000
    --- a/21_Calendar/vbnet/Calendar.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Calendar
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/22_Change/README.md b/22_Change/README.md
    index 982c65c9e..840714a49 100644
    --- a/22_Change/README.md
    +++ b/22_Change/README.md
    @@ -10,7 +10,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/22_Change/csharp/Program.cs b/22_Change/csharp/Program.cs
    index 67c7e59b6..12804731f 100644
    --- a/22_Change/csharp/Program.cs
    +++ b/22_Change/csharp/Program.cs
    @@ -25,7 +25,7 @@ static void Header()
             /// 
    /// /// False if any input can't be parsed to double. Price and payment returned would be 0. - /// True if it was possible to parse inputs into doubles. Price and payment returned + /// True if it was possible to parse inputs into doubles. Price and payment returned /// would be as provided by the user. /// static (bool status, double price, double payment) GetInput() diff --git a/22_Change/javascript/change.html b/22_Change/javascript/change.html index ae51aecc4..0f1449b6b 100644 --- a/22_Change/javascript/change.html +++ b/22_Change/javascript/change.html @@ -1,10 +1,9 @@ CHANGE - -
    
    +
    
     
     
     
    diff --git a/22_Change/javascript/change.js b/22_Change/javascript/change.js
    index d29a41718..7c25bcbd3 100644
    --- a/22_Change/javascript/change.js
    +++ b/22_Change/javascript/change.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/22_Change/kotlin/README.md b/22_Change/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/22_Change/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/22_Change/lua/README.md b/22_Change/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/22_Change/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/22_Change/pascal/README.md b/22_Change/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/22_Change/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/22_Change/python/change.py b/22_Change/python/change.py
    index 14ee4d4f5..cb9e72e94 100644
    --- a/22_Change/python/change.py
    +++ b/22_Change/python/change.py
    @@ -9,27 +9,33 @@
     PAGE_WIDTH = 64
     
     
    -def print_centered(msg: str) -> None:
    +def print_centered(msg):
         spaces = " " * ((PAGE_WIDTH - len(msg)) // 2)
         print(spaces + msg)
     
     
    -def print_header(title: str) -> None:
    +def print_header(title):
         print_centered(title)
    -    print_centered("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n")
    +    print_centered("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
    +    print()
    +    print()
    +    print()
     
     
    -def print_introduction() -> None:
    +def print_introduction():
         print("I, YOUR FRIENDLY MICROCOMPUTER, WILL DETERMINE")
    -    print("THE CORRECT CHANGE FOR ITEMS COSTING UP TO $100.\n\n")
    +    print("THE CORRECT CHANGE FOR ITEMS COSTING UP TO $100.")
    +    print()
    +    print()
     
     
    -def pennies_to_dollar_string(p: float) -> str:
    +def pennies_to_dollar_string(p):
         d = p / 100
    -    return f"${d:0.2f}"
    +    ds = f"${d:0.2f}"
    +    return ds
     
     
    -def compute_change() -> None:
    +def compute_change():
         print("COST OF ITEM?")
         cost = float(input())
         print("AMOUNT OF PAYMENT?")
    @@ -88,13 +94,19 @@ def compute_change() -> None:
             print(f"{change_in_pennies} PENNY(S)")
     
     
    -def main() -> None:
    +def print_thanks():
    +    print("THANK YOU, COME AGAIN.")
    +    print()
    +    print()
    +
    +
    +def main():
         print_header("CHANGE")
         print_introduction()
     
         while True:
             compute_change()
    -        print("THANK YOU, COME AGAIN.\n\n")
    +        print_thanks()
     
     
     if __name__ == "__main__":
    diff --git a/22_Change/rust/Cargo.lock b/22_Change/rust/Cargo.lock
    deleted file mode 100644
    index b21cc6a2d..000000000
    --- a/22_Change/rust/Cargo.lock
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    diff --git a/22_Change/rust/Cargo.toml b/22_Change/rust/Cargo.toml
    deleted file mode 100644
    index 1ec696335..000000000
    --- a/22_Change/rust/Cargo.toml
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -[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]
    diff --git a/22_Change/rust/README.md b/22_Change/rust/README.md
    deleted file mode 100644
    index 7e85f9a15..000000000
    --- a/22_Change/rust/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Rust](https://www.rust-lang.org/) by Anthony Rubick [AnthonyMichaelTDM](https://github.com/AnthonyMichaelTDM)
    diff --git a/22_Change/rust/src/main.rs b/22_Change/rust/src/main.rs
    deleted file mode 100644
    index f5baf682b..000000000
    --- a/22_Change/rust/src/main.rs
    +++ /dev/null
    @@ -1,169 +0,0 @@
    -use std::io::{self, stdout, Write};
    -
    -fn main() {
    -    //DATA
    -    let mut cost_in_cents:i16;
    -    let mut payment_in_cents:i16;
    -    let mut amount_owed_in_cents:i16;
    -
    -    let mut hundred:i16;
    -    let mut fifty:i16;
    -    let mut twenty:i16;
    -    let mut ten:i16;
    -    let mut five:i16;
    -    let mut one:i16;
    -    let mut quarters:i16;
    -    let mut dimes:i16;
    -    let mut nickles:i16;
    -    let mut pennies:i16;
    -
    -    //print welcome message
    -    welcome();
    -
    -    //print prompt
    -    println!("I, YOUR FRIENDLY MICROCOMPUTER, WILL DETERMINE");
    -    println!("THE CORRECT CHANGE FOR ITEMS COSTING UP TO ${}.00.",i16::MAX/100);
    -
    -    //game loop 
    -    loop {
    -        //get cost of items
    -        cost_in_cents = get_dollar_value_in_cents_from_user("COST OF ITEM:\t\t$");
    -        //get amount they already paid
    -        payment_in_cents = get_dollar_value_in_cents_from_user("AMOUNT OF PAYMENT:\t$");
    -
    -        //calculate amount they owe
    -        amount_owed_in_cents = payment_in_cents - cost_in_cents;
    -
    -        //check whether the payment is equal to, less than, or greater than, the cost
    -        if cost_in_cents == payment_in_cents {
    -            println!("CORRECT AMOUNT, THANK YOU.");
    -            continue;
    -        }
    -        else if payment_in_cents < cost_in_cents{ //amount_owed_in_cents is less than 0
    -            println!(
    -                "SORRY, YOU HAVE SHORT-CHANGED ME ${}.{}",
    -                -amount_owed_in_cents/100,//leading digits
    -                -amount_owed_in_cents%100,//trailing digits
    -            );
    -            continue;
    -        }
    -        else {
    -            println!("YOUR CHANGE, ${}.{}", amount_owed_in_cents/100, amount_owed_in_cents%100);
    -        }
    -
    -        //calculate change due
    -        //hundred dollar bills owed
    -        hundred = amount_owed_in_cents / (100*100);
    -        if hundred > 0 {println!("HUNDRED DOLLAR BILL(S): {}", hundred);}
    -        amount_owed_in_cents = amount_owed_in_cents % (100*100);
    -
    -        //fifty dollar bills owed
    -        fifty = amount_owed_in_cents / (50*100);
    -        if fifty > 0 {println!("FIFTY DOLLAR BILL(S): {}", fifty);}
    -        amount_owed_in_cents = amount_owed_in_cents % (50*100);
    -
    -        //twenty dollar bills owed
    -        twenty = amount_owed_in_cents / (20*100);
    -        if twenty > 0 {println!("TWENTY DOLLAR BILL(S): {}", twenty);}
    -        amount_owed_in_cents = amount_owed_in_cents % (20*100);
    -
    -        //ten dollar bills owed
    -        ten = amount_owed_in_cents / (10*100);
    -        if ten > 0 {println!("TEN DOLLAR BILL(S): {}", ten);}
    -        amount_owed_in_cents = amount_owed_in_cents % (10*100);
    -
    -        //five dollar bills owed
    -        five = amount_owed_in_cents / (5*100);
    -        if five > 0 {println!("FIVE DOLLAR BILL(S): {}", five);}
    -        amount_owed_in_cents = amount_owed_in_cents % (5*100);
    -
    -        //one dollar bills owed
    -        one = amount_owed_in_cents / (1*100);
    -        if one > 0 {println!("ONE DOLLAR BILL(S): {}", one);}
    -        amount_owed_in_cents = amount_owed_in_cents % (1*100);
    -
    -        //quarters owed
    -        quarters = amount_owed_in_cents / 25;
    -        if quarters > 0 {println!("QUARTER(S): {}", quarters);}
    -        amount_owed_in_cents = amount_owed_in_cents % 25;
    -
    -        //dimes owed
    -        dimes = amount_owed_in_cents / 10;
    -        if dimes > 0 {println!("DIME(S): {}", dimes);}
    -        amount_owed_in_cents = amount_owed_in_cents % 10;
    -
    -        //nickles owed
    -        nickles = amount_owed_in_cents / 5;
    -        if nickles > 0 {println!("NICKEL(S): {}", nickles);}
    -        amount_owed_in_cents = amount_owed_in_cents % 5;
    -
    -        //pennies owed
    -        pennies = amount_owed_in_cents / 1;
    -        if pennies > 0 {println!("PENNY(S): {}", pennies);}
    -
    -        //print ending message
    -        println!("THANK YOU, COME AGAIN.\n\n");
    -    }
    -}
    -
    -/**
    - * print welcome message
    - */
    -fn welcome() {
    -    println!("\t\t\t\tCHANGE\n\t      CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n");
    -}
    -
    -/**
    - * get number of money from user input
    - */
    -fn get_dollar_value_in_cents_from_user(prompt:&str) -> i16 {
    -    let mut value:i16;
    -    //input loop
    -    loop {
    -        //data
    -        let mut raw_input = String::new();
    -
    -        //print prompt
    -        print!("{}",prompt);
    -        //flush std out // allows prompt to be on same line as input
    -        stdout().flush().expect("failed to flush");
    -
    -        //get input
    -        io::stdin().read_line(&mut raw_input).expect("failed to read input");
    -        //filter out characters that aren't numbers or '.'
    -        let mut no_prior_periods = true;
    -        raw_input = raw_input.chars().filter(|c| {
    -            if c.eq_ignore_ascii_case(&'.') && no_prior_periods {
    -                no_prior_periods = false;
    -                true
    -            } else {
    -                c.is_ascii_digit()
    -            }
    -        }).collect();
    -
    -        //should only be (at most) 1 .
    -        if !raw_input.contains(".") { raw_input += ".00";} //if there are none, add one
    -
    -        //ensure there are at least 2 trailing digits
    -        if raw_input[raw_input.find('.').unwrap_or(raw_input.len())..].len() <= 2 { //if a slice of the string from the . onwards is less than or equal to 2, add two 0's to the end
    -            raw_input += "00"
    -        }
    -        //truncate the trailing digits to 2 digits
    -        raw_input = raw_input[..=raw_input.find('.').unwrap_or(raw_input.len()-2)+2].to_string(); //raw_input = a slice of raw_input from the start to 2 past the . 
    -        
    -        //remove the '.' and convert the string to an integer
    -        raw_input = raw_input.chars().filter(|c| c.is_ascii_digit()).collect();
    -        match raw_input.parse::().ok() {
    -            Some(v) => {value = v;}
    -            None => {
    -                println!("INPUT OUTSIDE OF ACCEPTABLE RANGE, TRY AGAIN");
    -                continue;
    -            },
    -        }
    -
    -        //println!("{}",value);
    -
    -        if value <= 0 {continue;}
    -        else {return value;}
    -    }
    -}
    diff --git a/22_Change/vbnet/Change.sln b/22_Change/vbnet/Change.sln
    deleted file mode 100644
    index 4af8571a3..000000000
    --- a/22_Change/vbnet/Change.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index b6a5e3c1f..000000000
    --- a/22_Change/vbnet/Change.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Change
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/23_Checkers/README.md b/23_Checkers/README.md
    index f2263df51..d6936ea92 100644
    --- a/23_Checkers/README.md
    +++ b/23_Checkers/README.md
    @@ -2,7 +2,7 @@
     
     This program plays checkers. The pieces played by the computer are marked with an “X”, yours are marked “O”. A move is made by specifying the coordinates of the piece to be moved (X, Y). Home (0,0) is in the bottom left and X specifies distance to the right of home (i.e., column) and Y specifies distance above home (i.e. row). You then specify where you wish to move to.
     
    -The original version of the program by Alan Segal was not able to recognize (or permit) a double or triple jump. If you tried one, it was likely that your piece would disappear altogether!
    +THe original version of the program by Alan Segal was not able to recognize (or permit) a double or triple jump. If you tried one, it was likely that your piece would disappear altogether!
     
     Steve North of Creative Computing rectified this problem and Lawrence Neal contributed modifications to allow the program to tell which player has won the game. The computer does not play a particularly good game but we leave it to _you_ to improve that.
     
    @@ -19,11 +19,9 @@ The file `checkers.annotated.bas` contains an indented and annotated
     version of the source code.  This is no longer valid BASIC code but
     should be more readable.
     
    -#### Porting Notes
    -
    +## Known Issues In the Original BASIC Code
      - If the computer moves a checker to the bottom row, it promotes, but
        leaves the original checker in place. (See line 1240)
      - Human players may move non-kings as if they were kings. (See lines 1590 to 1810)
    - - Human players are not required to jump if it is possible, and may make a number
    -   other illegal moves (jumping their own pieces, jumping empty squares, etc.).
    + - Human players are not required to jump if it is possible.
      - Curious writing to "I" variable without ever reading it. (See lines 1700 and 1806)
    diff --git a/23_Checkers/checkers.annotated.bas b/23_Checkers/checkers.annotated.bas
    index 78e2e2d96..af8ffabcd 100644
    --- a/23_Checkers/checkers.annotated.bas
    +++ b/23_Checkers/checkers.annotated.bas
    @@ -121,7 +121,7 @@
     
                # Otherwise, consider u,v
                if s(u,v)=0 then gosub 910
    -       endif
    +       endif           
     870  return
     
          # Evaluate jumping (x,y) to (u,v).
    diff --git a/23_Checkers/csharp/Checkers.csproj b/23_Checkers/csharp/Checkers.csproj
    deleted file mode 100644
    index d3fe4757c..000000000
    --- a/23_Checkers/csharp/Checkers.csproj
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    diff --git a/23_Checkers/csharp/Checkers.sln b/23_Checkers/csharp/Checkers.sln
    deleted file mode 100644
    index f7cce0b66..000000000
    --- a/23_Checkers/csharp/Checkers.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/csharp/Program.cs b/23_Checkers/csharp/Program.cs
    deleted file mode 100644
    index 126235067..000000000
    --- a/23_Checkers/csharp/Program.cs
    +++ /dev/null
    @@ -1,635 +0,0 @@
    -/*********************************************************************************
    - * CHECKERS
    - * ported from BASIC https://www.atariarchives.org/basicgames/showpage.php?page=41
    - *
    - * Porting philosophy
    - * 1) Adhere to the original as much as possible
    - * 2) Attempt to be understandable by Novice progammers
    - *
    - * There are no classes or Object Oriented design patterns used in this implementation.
    - * Everything is written procedurally, using only top-level functions. Hopefully, this
    - * will be approachable for someone who wants to learn C# syntax without experience with
    - * Object Oriented concepts. Similarly, basic data structures have been chosen over more
    - * powerful collection types.  Linq/lambda syntax is also excluded.
    - *
    - * C# Concepts contained in this example:
    - *    Loops (for, foreach, while, and do)
    - *    Multidimensional arrays
    - *    Tuples
    - *    Nullables
    - *    IEnumerable (yield return / yield break)
    - *
    - * The original had multiple implementations of logic, like determining valid jump locations.
    - * This has been refactored to reduce unnecessary code duplication.
    - *********************************************************************************/
    -#region Display functions
    -void SkipLines(int count)
    -{
    -    for (int i = 0; i < count; i++)
    -    {
    -        Console.WriteLine();
    -    }
    -}
    -
    -void PrintBoard(int[,] state)
    -{
    -    SkipLines(3);
    -    for (int y = 7; y >= 0; y--)
    -    {
    -        for (int x = 0; x < 8; x++)
    -        {
    -            switch(state[x,y])
    -            {
    -                case -2:
    -                    Console.Write("X*");
    -                    break;
    -                case -1:
    -                    Console.Write("X ");
    -                    break;
    -                case 0:
    -                    Console.Write(". ");
    -                    break;
    -                case 1:
    -                    Console.Write("O ");
    -                    break;
    -                case 2:
    -                    Console.Write("O*");
    -                    break;
    -            }
    -            Console.Write("   ");
    -        }
    -        Console.WriteLine();
    -    }
    -}
    -
    -void WriteCenter(string text)
    -{
    -    const int LineLength = 80;
    -    var spaces = (LineLength - text.Length) / 2;
    -    Console.WriteLine($"{"".PadLeft(spaces)}{text}");
    -}
    -
    -void ComputerWins()
    -{
    -    Console.WriteLine("I WIN.");
    -}
    -void PlayerWins()
    -{
    -    Console.WriteLine("YOU WIN.");
    -}
    -
    -void WriteIntroduction()
    -{
    -    WriteCenter("CHECKERS");
    -    WriteCenter("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY");
    -    SkipLines(3);
    -    Console.WriteLine("THIS IS THE GAME OF CHECKERS. THE COMPUTER IS X,");
    -    Console.WriteLine("AND YOU ARE O.  THE COMPUTER WILL MOVE FIRST.");
    -    Console.WriteLine("SQUARES ARE REFERRED TO BY A COORDINATE SYSTEM.");
    -    Console.WriteLine("(0,0) IS THE LOWER LEFT CORNER");
    -    Console.WriteLine("(0,7) IS THE UPPER LEFT CORNER");
    -    Console.WriteLine("(7,0) IS THE LOWER RIGHT CORNER");
    -    Console.WriteLine("(7,7) IS THE UPPER RIGHT CORNER");
    -    Console.WriteLine("THE COMPUTER WILL TYPE '+TO' WHEN YOU HAVE ANOTHER");
    -    Console.WriteLine("JUMP.  TYPE TWO NEGATIVE NUMBERS IF YOU CANNOT JUMP.");
    -    SkipLines(3);
    -}
    -#endregion
    -
    -#region State validation functions
    -bool IsPointOutOfBounds(int x)
    -{
    -    return x < 0 || x > 7;
    -}
    -
    -bool IsOutOfBounds((int x, int y) position)
    -{
    -    return IsPointOutOfBounds(position.x) || IsPointOutOfBounds(position.y);
    -}
    -
    -bool IsJumpMove((int x, int y) from, (int x, int y) to)
    -{
    -    return Math.Abs(from.y - to.y) == 2;
    -}
    -
    -bool IsValidPlayerMove(int[,] state, (int x, int y) from, (int x, int y) to)
    -{
    -    if (state[to.x, to.y] != 0)
    -    {
    -        return false;
    -    }
    -    var deltaX = Math.Abs(to.x - from.x);
    -    var deltaY = Math.Abs(to.y - from.y);
    -    if (deltaX != 1 && deltaX != 2)
    -    {
    -        return false;
    -    }
    -    if (deltaX != deltaY)
    -    {
    -        return false;
    -    }
    -    if (state[from.x, from.y] == 1 && Math.Sign(to.y - from.y) <= 0)
    -    {
    -        // only kings can move downwards
    -        return false;
    -    }
    -    if (deltaX == 2)
    -    {
    -        var jump = GetJumpedPiece(from, to);
    -        if (state[jump.x, jump.y] >= 0)
    -        {
    -            // no valid piece to jump
    -            return false;
    -        }
    -    }
    -    return true;
    -}
    -
    -bool CheckForComputerWin(int[,] state)
    -{
    -    bool playerAlive = false;
    -    foreach (var piece in state)
    -    {
    -        if (piece > 0)
    -        {
    -            playerAlive = true;
    -            break;
    -        }
    -    }
    -    return !playerAlive;
    -}
    -
    -bool CheckForPlayerWin(int[,] state)
    -{
    -    bool computerAlive = false;
    -    foreach (var piece in state)
    -    {
    -        if (piece < 0)
    -        {
    -            computerAlive = true;
    -            break;
    -        }
    -    }
    -    return !computerAlive;
    -}
    -#endregion
    -
    -#region Board "arithmetic"
    -/// 
    -/// Get the Coordinates of a jumped piece
    -/// 
    -(int x, int y) GetJumpedPiece((int x, int y) from, (int x, int y) to)
    -{
    -    var midX = (to.x + from.x) / 2;
    -    var midY = (to.y + from.y) / 2;
    -    return (midX, midY);
    -}
    -/// 
    -/// Apply a directional vector "direction" to location "from"
    -/// return resulting location
    -/// direction will contain: (-1,-1), (-1, 1), ( 1,-1), ( 1, 1)
    -/// /// 
    -(int x, int y) GetLocation((int x , int y) from, (int x, int y) direction)
    -{
    -    return (x: from.x + direction.x, y: from.y + direction.y);
    -}
    -#endregion
    -
    -#region State change functions
    -/// 
    -/// Alter current "state" by moving a piece from "from" to "to"
    -/// This method does not verify that the move being made is valid
    -/// This method works for both player moves and computer moves
    -/// 
    -int[,] ApplyMove(int[,] state, (int x, int y) from, (int x, int y) to)
    -{
    -    state[to.x, to.y] = state[from.x, from.y];
    -    state[from.x, from.y] = 0;
    -
    -    if (IsJumpMove(from, to))
    -    {
    -        // a jump was made
    -        // remove the jumped piece from the board
    -        var jump = GetJumpedPiece(from, to);
    -        state[jump.x, jump.y] = 0;
    -    }
    -    return state;
    -}
    -/// 
    -/// At the end of a turn (either player or computer) check to see if any pieces
    -/// reached the final row.  If so, change them to kings (crown)
    -/// 
    -int[,] CrownKingPieces(int[,] state)
    -{
    -    for (int x = 0; x < 8; x++)
    -    {
    -        // check the bottom row if computer has a piece in it
    -        if (state[x, 0] == -1)
    -        {
    -            state[x, 0] = -2;
    -        }
    -        // check the top row if the player has a piece in it
    -        if (state[x, 7] == 1)
    -        {
    -            state[x, 7] = 2;
    -        }
    -    }
    -    return state;
    -}
    -#endregion
    -
    -#region Computer Logic
    -/// 
    -/// Given a current location "from", determine if a move exists in a given vector, "direction"
    -/// direction will contain: (-1,-1), (-1, 1), ( 1,-1), ( 1, 1)
    -/// return "null" if no move is possible in this direction
    -/// 
    -(int x, int y)? GetCandidateMove(int[,] state, (int x, int y) from, (int x, int y) direction)
    -{
    -    var to = GetLocation(from, direction);
    -    if (IsOutOfBounds(to))
    -        return null;
    -    if (state[to.x, to.y] > 0)
    -    {
    -        // potential jump
    -        to = GetLocation(to, direction);
    -        if (IsOutOfBounds(to))
    -            return null;
    -    }
    -    if (state[to.x, to.y] != 0)
    -        // space already occupied by another piece
    -        return null;
    -
    -    return to;
    -}
    -/// 
    -/// Calculate a rank for a given potential move
    -/// The higher the rank value, the better the move is considered to be
    -/// 
    -int RankMove(int[,] state, (int x, int y) from, (int x, int y) to)
    -{
    -    int rank = 0;
    -
    -    if (to.y == 0 && state[from.x, from.y] == -1)
    -    {
    -        // getting a king
    -        rank += 2;
    -    }
    -    if (IsJumpMove(from, to))
    -    {
    -        // making a jump
    -        rank += 5;
    -    }
    -    if (from.y == 7)
    -    {
    -        // leaving home row
    -        rank -= 2;
    -    }
    -    if (to.x == 0 || to.x == 7)
    -    {
    -        // move to edge of board
    -        rank += 1;
    -    }
    -    // look to the row in front of the potential destination for
    -    for (int c = -1; c <=1; c+=2)
    -    {
    -        var inFront = GetLocation(to, (c, -1));
    -        if (IsOutOfBounds(inFront))
    -            continue;
    -        if (state[inFront.x, inFront.y] < 0)
    -        {
    -            // protected by our piece in front
    -            rank++;
    -            continue;
    -        }
    -        var inBack = GetLocation(to, (-c, 1));
    -        if (IsOutOfBounds(inBack))
    -        {
    -            continue;
    -        }
    -        if ((state[inFront.x, inFront.y] > 0) &&
    -            (state[inBack.x, inBack.y] == 0) || (inBack == from))
    -        {
    -            // the player can jump us
    -            rank -= 2;
    -        }
    -    }
    -    return rank;
    -};
    -
    -/// 
    -/// Returns an enumeration of possible moves that can be made by the given piece "from"
    -/// If no moves, can be made, the enumeration will be empty
    -/// 
    -IEnumerable<(int x, int y)> GetPossibleMoves(int[,] state, (int x, int y) from)
    -{
    -    int maxB;
    -    switch (state[from.x, from.y])
    -    {
    -        case -2:
    -            // kings can go backwards too
    -            maxB = 1;
    -            break;
    -        case -1:
    -            maxB = -1;
    -            break;
    -        default:
    -            // not one of our pieces
    -            yield break;
    -    }
    -
    -    for (int a = -1; a <= 1; a += 2)
    -    {
    -        // a
    -        // -1 = left
    -        // +1 = right
    -        for (int b = -1; b <= maxB; b += 2)
    -        {
    -            // b
    -            // -1 = forwards
    -            // +1 = backwards (only kings allowed to make this move)
    -            var to = GetCandidateMove(state, from, (a, b));
    -            if (to == null)
    -            {
    -                // no valid move in this direction
    -                continue;
    -            }
    -            yield return to.Value;
    -        }
    -    }
    -}
    -/// 
    -/// Determine the best move from a list of candidate moves "possibleMoves"
    -/// Returns "null" if no move can be made
    -/// 
    -((int x, int y) from, (int x, int y) to)? GetBestMove(int[,] state, IEnumerable<((int x, int y) from, (int x, int y) to)> possibleMoves)
    -{
    -    int? bestRank = null;
    -    ((int x, int y) from, (int x, int y) to)? bestMove = null;
    -
    -    foreach (var move in possibleMoves)
    -    {
    -        int rank = RankMove(state, move.from, move.to);
    -
    -        if (bestRank == null || rank > bestRank)
    -        {
    -            bestRank = rank;
    -            bestMove = move;
    -        }
    -    }
    -
    -    return bestMove;
    -}
    -
    -/// 
    -/// Examine the entire board and record all possible moves
    -/// Return the best move found, if one exists
    -/// Returns "null" if no move found
    -/// 
    -((int x, int y) from, (int x, int y) to)? CalculateMove(int[,] state)
    -{
    -    var possibleMoves = new List<((int x, int y) from, (int x, int y) to)>();
    -    for (int x = 0; x < 8; x++)
    -    {
    -        for (int y = 0; y < 8; y++)
    -        {
    -            var from = (x, y);
    -            foreach (var to in GetPossibleMoves(state, from))
    -            {
    -                possibleMoves.Add((from, to));
    -            }
    -        }
    -    }
    -    var bestMove = GetBestMove(state, possibleMoves);
    -    return bestMove;
    -}
    -
    -/// 
    -/// The logic behind the Computer's turn
    -/// Look for valid moves and possible subsequent moves
    -/// 
    -(bool moveMade, int[,] state) ComputerTurn(int[,] state)
    -{
    -    // Get best move available
    -    var move = CalculateMove(state);
    -    if (move == null)
    -    {
    -        // No move can be made
    -        return (false, state);
    -    }
    -    var from = move.Value.from;
    -    Console.Write($"FROM {from.x} {from.y} ");
    -    // Continue to make moves until no more valid moves can be made
    -    while (move != null)
    -    {
    -        var to = move.Value.to;
    -        Console.WriteLine($"TO {to.x} {to.y}");
    -        state = ApplyMove(state, from, to);
    -        if (!IsJumpMove(from, to))
    -            break;
    -
    -        // check for double / triple / etc. jump
    -        var possibleMoves = new List<((int x, int y) from, (int x, int y) to)>();
    -        from = to;
    -        foreach (var candidate in GetPossibleMoves(state, from))
    -        {
    -            if (IsJumpMove(from, candidate))
    -            {
    -                possibleMoves.Add((from, candidate));
    -            }
    -        }
    -        // Get best jump move
    -        move = GetBestMove(state, possibleMoves);
    -    }
    -    // apply crowns to any new Kings
    -    state = CrownKingPieces(state);
    -    return (true, state);
    -}
    -#endregion
    -
    -#region Player Logic
    -/// 
    -/// Get input from the player in the form "x,y" where x and y are integers
    -/// If invalid input is received, return null
    -/// If input is valid, return the coordinate of the location
    -/// 
    -(int x, int y)? GetCoordinate(string prompt)
    -{
    -    Console.Write(prompt + "? ");
    -    var input = Console.ReadLine();
    -    // split the string into multiple parts
    -    var parts = input?.Split(",");
    -    if (parts?.Length != 2)
    -        // must be exactly 2 parts
    -        return null;
    -    int x;
    -    if (!int.TryParse(parts[0], out x))
    -        // first part is not a number
    -        return null;
    -    int y;
    -    if (!int.TryParse(parts[1], out y))
    -        //second part is not a number
    -        return null;
    -
    -    return (x, y);
    -}
    -
    -/// 
    -/// Get the move from the player.
    -/// return a tuple of "from" and "to" representing a valid move
    -///
    -/// 
    -((int x, int y) from, (int x,int y) to) GetPlayerMove(int[,] state)
    -{
    -    // The original program has some issues regarding user input
    -    // 1)  There are minimal data sanity checks in the original:
    -    //     a)  FROM piece must be owned by player
    -    //     b)  TO location must be empty
    -    //     c)  the FROM and TO x's must be less than 2 squares away
    -    //     d)  the FROM and TO y's must be same distance as x's
    -    //     No checks are made for direction, if a jump is valid, or
    -    //     if the piece even moves.
    -    // 2)  Once a valid FROM is selected, a TO must be selected.
    -    //     If there are no valid TO locations, you are soft-locked
    -    // This approach is intentionally different from the original
    -    // but maintains the original intent as much as possible
    -    // 1)  Select a FROM location
    -    // 2)  If FROM is invalid, return to step 1
    -    // 3)  Select a TO location
    -    // 4)  If TO is invalid or the implied move is invalid,
    -    //     return to step 1
    -
    -
    -    // There is still currently no way for the player to indicate that no move can be made
    -    // This matches the original logic, but is a candidate for a refactor
    -
    -    do
    -    {
    -        var from = GetCoordinate("FROM");
    -        if ((from != null)
    -            && !IsOutOfBounds(from.Value)
    -            && (state[from.Value.x, from.Value.y] > 0))
    -        {
    -            // we have a valid "from" location
    -            var to = GetCoordinate("TO");
    -            if ((to != null)
    -                && !IsOutOfBounds(to.Value)
    -                && IsValidPlayerMove(state, from.Value, to.Value))
    -            {
    -                // we have a valid "to" location
    -                return (from.Value, to.Value);
    -            }
    -        }
    -    } while (true);
    -}
    -
    -/// 
    -/// Get a subsequent jump from the player if they can / want to
    -/// returns a move ("from", "to") if a player jumps
    -/// returns null if a player does not make another move
    -/// The player must input negative numbers for the coordinates to indicate
    -/// that no more moves are to be made.  This matches the original implementation
    -/// 
    -((int x, int y) from, (int x, int y) to)? GetPlayerSubsequentJump(int[,] state, (int x, int y) from)
    -{
    -    do
    -    {
    -        var to = GetCoordinate("+TO");
    -        if ((to != null)
    -            && !IsOutOfBounds(to.Value)
    -            && IsValidPlayerMove(state, from, to.Value)
    -            && IsJumpMove(from, to.Value))
    -        {
    -            // we have a valid "to" location
    -            return (from, to.Value); ;
    -        }
    -
    -        if (to != null && to.Value.x < 0 && to.Value.y < 0)
    -        {
    -            // player has indicated to not make any more moves
    -            return null;
    -        }
    -    }
    -    while (true);
    -}
    -
    -/// 
    -/// The logic behind the Player's turn
    -/// Get the player input for a move
    -/// Get subsequent jumps, if possible
    -/// 
    -int [,] PlayerTurn(int[,] state)
    -{
    -    var move = GetPlayerMove(state);
    -    do
    -    {
    -        state = ApplyMove(state, move.from, move.to);
    -        if (!IsJumpMove(move.from, move.to))
    -        {
    -            // If player doesn't make a jump move, no further moves are possible
    -            break;
    -        }
    -        var nextMove = GetPlayerSubsequentJump(state, move.to);
    -        if (nextMove == null)
    -        {
    -            // another jump is not made
    -            break;
    -        }
    -        move = nextMove.Value;
    -    }
    -    while (true);
    -    // check to see if any kings need crowning
    -    state = CrownKingPieces(state);
    -    return state;
    -}
    -#endregion
    -
    -/*****************************************************************************
    - *
    - * Main program starts here
    - *
    - ****************************************************************************/
    -
    -WriteIntroduction();
    -
    -// initalize state -  empty spots initialize to 0
    -// set player pieces to 1, computer pieces to -1
    -// turn your head to the right to visualize the board.
    -// kings will be represented by -2 (for computer) and 2 (for player)
    -int[,] state = new int[8, 8] {
    -    { 1, 0, 1, 0, 0, 0,-1, 0 },
    -    { 0, 1, 0, 0, 0,-1, 0,-1 },
    -    { 1, 0, 1, 0, 0, 0,-1, 0 },
    -    { 0, 1, 0, 0, 0,-1, 0,-1 },
    -    { 1, 0, 1, 0, 0, 0,-1, 0 },
    -    { 0, 1, 0, 0, 0,-1, 0,-1 },
    -    { 1, 0, 1, 0, 0, 0,-1, 0 },
    -    { 0, 1, 0, 0, 0,-1, 0,-1 },
    -};
    -
    -while (true)
    -{
    -    bool moveMade;
    -    (moveMade, state) = ComputerTurn(state);
    -    if (!moveMade)
    -    {
    -        // In the original program the computer wins if it cannot make a move
    -        // I believe the player should win in this case, assuming the player can make a move.
    -        // if neither player can make a move, the game should be draw.
    -        // I have left it as the original logic for now.
    -        ComputerWins();
    -        break;
    -    }
    -    PrintBoard(state);
    -    if (CheckForComputerWin(state))
    -    {
    -        ComputerWins();
    -        break;
    -    }
    -    state = PlayerTurn(state);
    -    if (CheckForPlayerWin(state))
    -    {
    -        PlayerWins();
    -        break;
    -    }
    -}
    diff --git a/23_Checkers/javascript/checkers.html b/23_Checkers/javascript/checkers.html
    index be2b54f88..61839e25a 100644
    --- a/23_Checkers/javascript/checkers.html
    +++ b/23_Checkers/javascript/checkers.html
    @@ -1,10 +1,9 @@
     
     
     CHECKERS
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/23_Checkers/javascript/checkers.js b/23_Checkers/javascript/checkers.js
    index 14a7d3513..4d406e0e8 100644
    --- a/23_Checkers/javascript/checkers.js
    +++ b/23_Checkers/javascript/checkers.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    @@ -112,7 +112,7 @@ var s = [];
     
     for (x = 0; x <= 7; x++)
         s[x] = [];
    -
    +    
     var g = -1;
     var data = [1, 0, 1, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, -1, 0, -1, 15];
     var p = 0;
    diff --git a/23_Checkers/kotlin/README.md b/23_Checkers/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/23_Checkers/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/23_Checkers/lua/README.md b/23_Checkers/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/23_Checkers/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/23_Checkers/pascal/README.md b/23_Checkers/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/23_Checkers/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/23_Checkers/perl/README.md b/23_Checkers/perl/README.md
    index 4323cf4ad..e69c8b819 100644
    --- a/23_Checkers/perl/README.md
    +++ b/23_Checkers/perl/README.md
    @@ -1,9 +1,3 @@
     Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
     
     Conversion to [Perl](https://www.perl.org/)
    -
    -Note: This version has lines and columns numbers to help you with choosing the cell
    -to move from and to, so you don't have to continually count. It also puts a "." only for
    -blank cells you can move to, which I think makes for a more pleasing look and makes
    -it easier to play. If you want the original behavior, start the program with an arg
    -of "-o" for the original behavior.
    diff --git a/23_Checkers/perl/checkers.pl b/23_Checkers/perl/checkers.pl
    deleted file mode 100755
    index 46b8f2d4c..000000000
    --- a/23_Checkers/perl/checkers.pl
    +++ /dev/null
    @@ -1,351 +0,0 @@
    -#!/usr/bin/perl
    -
    -# Checkers program in Perl
    -#   Started with checkers.annotated.bas
    -# Translated by Kevin Brannen (kbrannen)
    -
    -use strict;
    -use warnings;
    -
    -# globals
    -#
    -# The current move: (rating, current x, current y, new x, new y)
    -# 'rating' represents how good the move is; higher is better.
    -my @ratings = (-99); # (4); # Start with minimum score
    -# The board.  Pieces are represented by numeric values:
    -#
    -#      - 0     = empty square
    -#      - -1,-2 = X (-1 for regular piece, -2 for king)
    -#      - 1,2   = O (1 for regular piece, 2 for king)
    -#
    -# This program's player ("me") plays X.
    -my @board; # (7,7)
    -# chars to print for the board, add 2 to the board value as an index to the char
    -my @chars = ("X*", "X", ".", "O", "O*");
    -my $neg1 = -1;          # constant holding -1
    -my $winner = "";
    -my $upgrade = shift(@ARGV) // "";
    -$upgrade = $upgrade eq "-o" ? 0 : 1;
    -
    -#####
    -
    -print "\n";
    -print " " x 32, "CHECKERS\n";
    -print " " x 15, "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n";
    -
    -
    -print "THIS IS THE GAME OF CHECKERS.  THE COMPUTER IS X,\n";
    -print "AND YOU ARE O.  THE COMPUTER WILL MOVE FIRST.\n";
    -print "SQUARES ARE REFERRED TO BY A COORDINATE SYSTEM.\n";
    -print "(0,0) IS THE LOWER LEFT CORNER\n";
    -print "(0,7) IS THE UPPER LEFT CORNER\n";
    -print "(7,0) IS THE LOWER RIGHT CORNER\n";
    -print "(7,7) IS THE UPPER RIGHT CORNER\n";
    -print "THE COMPUTER WILL TYPE '+TO' WHEN YOU HAVE ANOTHER\n";
    -print "JUMP.  TYPE TWO NEGATIVE NUMBERS IF YOU CANNOT JUMP.\n";
    -print "ENTER YOUR MOVE POSITION LIKE '0 0' OR '0,0'.\n\n\n";
    -
    -# Initialize the board.  Data is 2 length-wise strips repeated.
    -my @data = ();
    -for (1 .. 32) { push(@data, (1,0,1,0,0,0,-1,0, 0,1,0,0,0,-1,0,-1)); }
    -for my $x (0 .. 7)
    -{
    -    for my $y (0 .. 7)
    -    {
    -        $board[$x][$y] = shift(@data);
    -    }
    -}
    -
    -# Start of game loop.  First, my turn.
    -while (1)
    -{
    -
    -    # For each square on the board, search for one of my pieces
    -    # and if it can make the best move so far, store that move in 'r'
    -    for my $x (0 .. 7)
    -    {
    -        for my $y (0 .. 7)
    -        {
    -            # Skip if this is empty or an opponent's piece
    -            next if ($board[$x][$y] > -1);
    -
    -            # If this is one of my ordinary pieces, analyze possible
    -            # forward moves.
    -            if ($board[$x][$y] == -1)
    -            {
    -                for (my $a = -1 ; $a <= 1 ; $a +=2)
    -                {
    -                    $b = $neg1;
    -                    find_move($x, $y, $a, $b);
    -                }
    -            }
    -
    -            # If this is one of my kings, analyze possible forward
    -            # and backward moves.
    -            if ($board[$x][$y] == -2)
    -            {
    -                for (my $a = -1 ; $a <= 1 ; $a += 2)
    -                {
    -                    for (my $b = -1 ; $a <= 1 ; $b += 2) { find_move($x, $y, $a, $b); }
    -                }
    -            }
    -        }
    -    }
    -
    -
    -    if ($ratings[0] == -99) # Game is lost if no move could be found.
    -    {
    -        $winner = "you";
    -        last;
    -    }
    -
    -    # Print the computer's move.  (Note: chr$(30) is an ASCII RS
    -    # (record separator) code; probably no longer relevant.)
    -    print "FROM $ratings[1],$ratings[2] TO $ratings[3],$ratings[4] ";
    -    $ratings[0] = -99;
    -
    -    # Make the computer's move.  If the piece finds its way to the
    -    # end of the board, crown it.
    -    LOOP1240: {
    -        if ($ratings[4] == 0)
    -        {
    -            $board[$ratings[3]][$ratings[4]] = -2;
    -            last LOOP1240;
    -        }
    -        $board[$ratings[3]][$ratings[4]] = $board[$ratings[1]][$ratings[2]];
    -        $board[$ratings[1]][$ratings[2]] = 0;
    -
    -        # If the piece has jumped 2 squares, it means the computer has
    -        # taken an opponents' piece.
    -        if (abs($ratings[1] - $ratings[3]) == 2)
    -        {
    -            $board [($ratings[1]+$ratings[3])/2] [($ratings[2]+$ratings[4])/2] = 0;     # Delete the opponent's piece
    -
    -            # See if we can jump again.  Evaluate all possible moves.
    -            my $x = $ratings[3];
    -            my $y = $ratings[4];
    -            for (my $a = -2 ; $a <= 2 ; $a += 4)
    -            {
    -                if ($board[$x][$y] == -1)
    -                {
    -                    $b = -2;
    -                    eval_move($x, $y, $a, $b);
    -                }
    -                if ($board[$x][$y] == -2)
    -                {
    -                    for (my $b = -2 ; $b <= 2 ; $b += 4) { eval_move($x, $y, $a, $b); }
    -                }
    -            }
    -
    -            # If we've found a move, go back and make that one as well
    -            if ($ratings[0] != -99)
    -            {
    -                print "TO $ratings[3], $ratings[4] ";
    -                $ratings[0] = -99;
    -                next LOOP1240;
    -            }
    -        }
    -    } # LOOP1240
    -
    -    # Now, print the board
    -    print "\n\n\n";
    -    for (my $y = 7 ; $y >= 0 ; $y--)
    -    {
    -        my $line = "";
    -        $line = "$y|" if ($upgrade);
    -        for my $x (0 .. 7)
    -        {
    -            my $c = $chars[$board[$x][$y] + 2];
    -            $c = ' ' if ($upgrade && (($y % 2 == 0 && $x % 2 == 1) || ($y % 2 == 1 && $x % 2 == 0)));
    -            $line = tab($line, 5*$x+7, $c);
    -        }
    -        print $line;
    -        print " \n\n";
    -    }
    -    print "       _    _    _    _    _    _    _    _\n" if ($upgrade);
    -    print "       0    1    2    3    4    5    6    7\n" if ($upgrade);
    -    print "\n";
    -
    -    # Check if either player is out of pieces.  If so, announce the
    -    # winner.
    -    my ($z, $t) = (0, 0);
    -    for my $x (0 .. 7)
    -    {
    -        for my $y (0 .. 7)
    -        {
    -            if ($board[$x][$y] == 1  || $board[$x][$y] == 2)  { $z = 1; }
    -            if ($board[$x][$y] == -1 || $board[$x][$y] == -2) { $t = 1; }
    -        }
    -    }
    -    if ($z != 1) { $winner = "comp"; last; }
    -    if ($t != 1) { $winner = "you"; last; }
    -
    -    # Prompt the player for their move.
    -    ($z, $t) = (0, 0);
    -    my ($x, $y, $e, $h, $a, $b);
    -    do {
    -        ($e,$h) = get_pos("FROM:");
    -        $x = $e;
    -        $y = $h;
    -    } while ($board[$x][$y] <= 0);
    -    do {
    -        ($a,$b) = get_pos("TO:");
    -        $x = $a;
    -        $y = $b;
    -    } while (!($board[$x][$y] == 0 && abs($a-$e) <= 2 && abs($a-$e) == abs($b-$h)));
    -
    -    LOOP1750: {
    -        # Make the move and stop unless it might be a jump.
    -        $board[$a][$b] = $board[$e][$h];
    -        $board[$e][$h] = 0;
    -        if (abs($e-$a) != 2) { last LOOP1750; }
    -
    -        # Remove the piece jumped over
    -        $board[($e+$a)/2][($h+$b)/2] = 0;
    -
    -        # Prompt for another move; -1 means player can't, so I've won.
    -        # Keep prompting until there's a valid move or the player gives
    -        # up.
    -        my ($a1, $b1);
    -        do {
    -            ($a1,$b1) = get_pos("+TO:");
    -            if ($a1 < 0) { last LOOP1750; }
    -        } while ($board[$a1][$b1] != 0 || abs($a1-$a) != 2 || abs($b1-$b) != 2);
    -
    -        # Update the move variables to correspond to the next jump
    -        $e = $a;
    -        $h = $b;
    -        $a = $a1;
    -        $b = $b1;
    -    }
    -
    -    # If the player has reached the end of the board, crown this piece
    -    if ($b == 7) { $board[$a][$b] = 2; }
    -
    -    # And play the next turn.
    -}
    -
    -# Endgame:
    -print "\n", ($winner eq "you" ? "YOU" : "I"), " WIN\n";
    -exit(0);
    -
    -###########################################
    -
    -# make sure we get a 2 value position
    -sub get_pos
    -{
    -    my $prompt = shift;
    -    my ($p1, $p2);
    -    do {
    -        print "$prompt ";
    -        chomp(my $ans = <>);
    -        ($p1,$p2) = split(/[, ]/, $ans);
    -    } while (!defined($p1) || !defined($p2) || $p1 < -1 || $p2 < -1 || $p1 > 7 || $p2 > 7);
    -    return ($p1,$p2);
    -}
    -
    -# deal with basic's tab() for line positioning
    -#   line = line string we're starting with
    -#   pos = position to start writing
    -#   s = string to write
    -# returns the resultant string, which might not have been changed
    -sub tab
    -{
    -    my ($line, $pos, $str) = @_;
    -    my $len = length($line);
    -    # if curser is past position, do nothing
    -    if ($len <= $pos) { $line .= " " x ($pos - $len) . $str; }
    -    return $line;
    -}
    -
    -# Analyze a move from (x,y) to (x+a, y+b) and schedule it if it's
    -# the best candidate so far.
    -sub find_move
    -{
    -    my ($x, $y, $a, $b) = @_;
    -    my $u = $x+$a;
    -    my $v = $y+$b;
    -
    -    # Done if it's off the board
    -    return if ($u < 0 || $u > 7 || $v < 0 || $ v> 7);
    -
    -    # Consider the destination if it's empty
    -    eval_jump($x, $y, $u, $v) if ($board[$u][$v] == 0);
    -
    -    # If it's got an opponent's piece, jump it instead
    -    if ($board[$u][$v] > 0)
    -    {
    -
    -        # Restore u and v, then return if it's off the board
    -        $u += $a;
    -        $v += $b;
    -        return if ($u < 0 || $v < 0 || $u > 7 || $v > 7);
    -
    -        # Otherwise, consider u,v
    -        eval_jump($x, $y, $u, $v) if ($board[$u][$v] == 0);
    -    }
    -}
    -
    -# Evaluate jumping (x,y) to (u,v).
    -#
    -# Computes a score for the proposed move and if it's higher
    -# than the best-so-far move, uses that instead by storing it
    -# and its score in @ratings.
    -sub eval_jump
    -{
    -    my ($x, $y, $u, $v) = @_;
    -
    -    # q is the score; it starts at 0
    -    my $q = 0;
    -
    -    # +2 if it promotes this piece
    -    $q += 2 if ($v == 0 && $board[$x][$y] == -1);
    -
    -    # +5 if it takes an opponent's piece
    -    $q += 5 if (abs($y-$v) == 2);
    -
    -    # -2 if the piece is moving away from the top boundary
    -    $q -= 2 if ($y == 7);
    -
    -    # +1 for putting the piece against a vertical boundary
    -    $q++ if ($u == 0 || $u == 7);
    -
    -    for (my $c = -1 ; $c <= 1 ; $c += 2)
    -    {
    -        next if ($u+$c < 0 || $u+$c > 7 || $v+$neg1 < 0);
    -
    -        # +1 for each adjacent friendly piece
    -        if ($board[$u+$c][$v+$neg1] < 0)
    -        {
    -            $q++;
    -            next;
    -        }
    -
    -        # Prevent out-of-bounds testing
    -        next if ($u-$c < 0 || $u-$c > 7 || $v-$neg1 > 7);
    -
    -        # -2 for each opponent piece that can now take this piece here
    -        $q -= 2 if ($board[$u+$c][$v+$neg1] > 0 && ($board[$u-$c][$v-$neg1] == 0 || ($u-$c == $x && $v-$neg1 == $y)));
    -    }
    -
    -    # Use this move if it's better than the previous best
    -    if ($q > $ratings[0])
    -    {
    -        $ratings[0] = $q;
    -        $ratings[1] = $x;
    -        $ratings[2] = $y;
    -        $ratings[3] = $u;
    -        $ratings[4] = $v;
    -    }
    -}
    -
    -# If (u,v) is in the bounds, evaluate it as a move using
    -# the sub at 910, so storing eval in @ratings.
    -sub eval_move
    -{
    -    my ($x, $y, $a, $b) = @_;
    -    my $u = $x+$a;
    -    my $v = $y+$b;
    -    return if ($u < 0 || $u > 7 || $v < 0 || $v > 7);
    -    eval_jump($x, $y, $u, $v) if ($board[$u][$v] == 0 && $board[$x+$a/2][$y+$b/2] > 0);
    -}
    diff --git a/23_Checkers/python/checkers.py b/23_Checkers/python/checkers.py
    index 42ae48c8b..fc1008ae7 100644
    --- a/23_Checkers/python/checkers.py
    +++ b/23_Checkers/python/checkers.py
    @@ -6,7 +6,7 @@
     Ported by Dave LeCompte
     """
     
    -from typing import Iterator, NamedTuple, Optional, Tuple
    +import collections
     
     PAGE_WIDTH = 64
     
    @@ -21,26 +21,25 @@
     TOP_ROW = 7
     BOTTOM_ROW = 0
     
    +MoveRecord = collections.namedtuple(
    +    "MoveRecord", ["quality", "start_x", "start_y", "dest_x", "dest_y"]
    +)
     
    -class MoveRecord(NamedTuple):
    -    quality: int
    -    start_x: int
    -    start_y: int
    -    dest_x: int
    -    dest_y: int
     
    -
    -def print_centered(msg: str) -> None:
    +def print_centered(msg):
         spaces = " " * ((PAGE_WIDTH - len(msg)) // 2)
         print(spaces + msg)
     
     
    -def print_header(title: str) -> None:
    +def print_header(title):
         print_centered(title)
    -    print_centered("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n")
    +    print_centered("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
    +    print()
    +    print()
    +    print()
     
     
    -def get_coordinates(prompt: str) -> Tuple[int, int]:
    +def get_coordinates(prompt):
         err_msg = "ENTER COORDINATES in X,Y FORMAT"
         while True:
             print(prompt)
    @@ -50,21 +49,21 @@ def get_coordinates(prompt: str) -> Tuple[int, int]:
                 continue
     
             try:
    -            x, y = (int(c) for c in response.split(","))
    -        except ValueError:
    +            x, y = [int(c) for c in response.split(",")]
    +        except ValueError as ve:
                 print(err_msg)
                 continue
     
             return x, y
     
     
    -def is_legal_board_coordinate(x: int, y: int) -> bool:
    +def is_legal_board_coordinate(x, y):
         return (0 <= x <= 7) and (0 <= y <= 7)
     
     
     class Board:
    -    def __init__(self) -> None:
    -        self.spaces = [[0 for _ in range(8)] for _ in range(8)]
    +    def __init__(self):
    +        self.spaces = [[0 for y in range(8)] for x in range(8)]
             for x in range(8):
                 if (x % 2) == 0:
                     self.spaces[x][6] = COMPUTER_PIECE
    @@ -75,7 +74,7 @@ def __init__(self) -> None:
                     self.spaces[x][5] = COMPUTER_PIECE
                     self.spaces[x][1] = HUMAN_PIECE
     
    -    def __str__(self) -> str:
    +    def __str__(self):
             pieces = {
                 EMPTY_SPACE: ".",
                 HUMAN_PIECE: "O",
    @@ -95,40 +94,34 @@ def __str__(self) -> str:
     
             return s
     
    -    def get_spaces(self) -> Iterator[Tuple[int, int]]:
    +    def get_spaces(self):
             for x in range(0, 8):
                 for y in range(0, 8):
                     yield x, y
     
    -    def get_spaces_with_computer_pieces(self) -> Iterator[Tuple[int, int]]:
    +    def get_spaces_with_computer_pieces(self):
             for x, y in self.get_spaces():
                 contents = self.spaces[x][y]
                 if contents < 0:
                     yield x, y
     
    -    def get_spaces_with_human_pieces(self) -> Iterator[Tuple[int, int]]:
    +    def get_spaces_with_human_pieces(self):
             for x, y in self.get_spaces():
                 contents = self.spaces[x][y]
                 if contents > 0:
                     yield x, y
     
    -    def get_legal_deltas_for_space(self, x: int, y: int) -> Iterator[Tuple[int, int]]:
    +    def get_legal_deltas_for_space(self, x, y):
             contents = self.spaces[x][y]
    -        for delta_x in (-1, 1):
    -            if contents == COMPUTER_PIECE:
    +        if contents == COMPUTER_PIECE:
    +            for delta_x in (-1, 1):
                     yield (delta_x, -1)
    -            else:
    +        else:
    +            for delta_x in (-1, 1):
                     for delta_y in (-1, 1):
                         yield (delta_x, delta_y)
     
    -    def get_legal_moves(self, x: int, y: int) -> Iterator[MoveRecord]:
    -        for delta_x, delta_y in self.get_legal_deltas_for_space(x, y):
    -            new_move_record = self.check_move(x, y, delta_x, delta_y)
    -
    -            if new_move_record is not None:
    -                yield new_move_record
    -
    -    def pick_computer_move(self) -> Optional[MoveRecord]:
    +    def pick_computer_move(self):
             move_record = None
     
             for start_x, start_y in self.get_spaces_with_computer_pieces():
    @@ -145,9 +138,7 @@ def pick_computer_move(self) -> Optional[MoveRecord]:
     
             return move_record
     
    -    def check_move(
    -        self, start_x: int, start_y: int, delta_x: int, delta_y: int
    -    ) -> Optional[MoveRecord]:
    +    def check_move(self, start_x, start_y, delta_x, delta_y):
             new_x = start_x + delta_x
             new_y = start_y + delta_y
             if not is_legal_board_coordinate(new_x, new_y):
    @@ -167,11 +158,8 @@ def check_move(
                 return None
             if self.spaces[landing_x][landing_y] == EMPTY_SPACE:
                 return self.evaluate_move(start_x, start_y, landing_x, landing_y)
    -        return None
     
    -    def evaluate_move(
    -        self, start_x: int, start_y: int, dest_x: int, dest_y: int
    -    ) -> MoveRecord:
    +    def evaluate_move(self, start_x, start_y, dest_x, dest_y):
             quality = 0
             if dest_y == 0 and self.spaces[start_x][start_y] == COMPUTER_PIECE:
                 # promoting is good
    @@ -182,7 +170,7 @@ def evaluate_move(
             if start_y == 7:
                 # prefer to defend back row
                 quality -= 2
    -        if dest_x in {0, 7}:
    +        if dest_x in (0, 7):
                 # moving to edge column
                 quality += 1
             for delta_x in (-1, 1):
    @@ -205,7 +193,7 @@ def evaluate_move(
                     quality -= 2
             return MoveRecord(quality, start_x, start_y, dest_x, dest_y)
     
    -    def remove_r_pieces(self, move_record: MoveRecord) -> None:
    +    def remove_r_pieces(self, move_record):
             self.remove_pieces(
                 move_record.start_x,
                 move_record.start_y,
    @@ -213,9 +201,7 @@ def remove_r_pieces(self, move_record: MoveRecord) -> None:
                 move_record.dest_y,
             )
     
    -    def remove_pieces(
    -        self, start_x: int, start_y: int, dest_x: int, dest_y: int
    -    ) -> None:
    +    def remove_pieces(self, start_x, start_y, dest_x, dest_y):
             self.spaces[dest_x][dest_y] = self.spaces[start_x][start_y]
             self.spaces[start_x][start_y] = EMPTY_SPACE
     
    @@ -224,7 +210,7 @@ def remove_pieces(
                 mid_y = (start_y + dest_y) // 2
                 self.spaces[mid_x][mid_y] = EMPTY_SPACE
     
    -    def play_computer_move(self, move_record: MoveRecord) -> None:
    +    def play_computer_move(self, move_record):
             print(
                 f"FROM {move_record.start_x} {move_record.start_y} TO {move_record.dest_x} {move_record.dest_y}"
             )
    @@ -251,11 +237,11 @@ def play_computer_move(self, move_record: MoveRecord) -> None:
                     if self.spaces[landing_x][landing_y] == COMPUTER_PIECE:
                         for delta_x in (-2, 2):
                             test_record = self.try_extend(landing_x, landing_y, delta_x, -2)
    -                        if (move_record is not None) and (
    -                            (best_move is None)
    -                            or (move_record.quality > best_move.quality)
    -                        ):
    -                            best_move = test_record
    +                        if not (move_record is None):
    +                            if (best_move is None) or (
    +                                move_record.quality > best_move.quality
    +                            ):
    +                                best_move = test_record
                     else:
                         assert self.spaces[landing_x][landing_y] == COMPUTER_KING
                         for delta_x in (-2, 2):
    @@ -263,20 +249,19 @@ def play_computer_move(self, move_record: MoveRecord) -> None:
                                 test_record = self.try_extend(
                                     landing_x, landing_y, delta_x, delta_y
                                 )
    -                            if (move_record is not None) and (
    -                                (best_move is None)
    -                                or (move_record.quality > best_move.quality)
    -                            ):
    -                                best_move = test_record
    +                            if not (move_record is None):
    +                                if (best_move is None) or (
    +                                    move_record.quality > best_move.quality
    +                                ):
    +                                    best_move = test_record
     
                     if best_move is None:
                         return
    -                print(f"TO {best_move.dest_x} {best_move.dest_y}")
    -                move_record = best_move
    +                else:
    +                    print(f"TO {best_move.dest_x} {best_move.dest_y}")
    +                    move_record = best_move
     
    -    def try_extend(
    -        self, start_x: int, start_y: int, delta_x: int, delta_y: int
    -    ) -> Optional[MoveRecord]:
    +    def try_extend(self, start_x, start_y, delta_x, delta_y):
             new_x = start_x + delta_x
             new_y = start_y + delta_y
     
    @@ -290,18 +275,13 @@ def try_extend(
                 self.spaces[jumped_x][jumped_y] > 0
             ):
                 return self.evaluate_move(start_x, start_y, new_x, new_y)
    -        return None
     
    -    def get_human_move(self) -> Tuple[int, int, int, int]:
    +    def get_human_move(self):
             is_king = False
     
             while True:
                 start_x, start_y = get_coordinates("FROM?")
     
    -            legal_moves = list(self.get_legal_moves(start_x, start_y))
    -            if not legal_moves:
    -                print(f"({start_x}, {start_y}) has no legal moves. Choose again.")
    -                continue
                 if self.spaces[start_x][start_y] > 0:
                     break
     
    @@ -313,16 +293,15 @@ def get_human_move(self) -> Tuple[int, int, int, int]:
                 if (not is_king) and (dest_y < start_y):
                     # CHEATER! Trying to move non-king backwards
                     continue
    -            is_free = self.spaces[dest_x][dest_y] == 0
    -            within_reach = abs(dest_x - start_x) <= 2
    -            is_diagonal_move = abs(dest_x - start_x) == abs(dest_y - start_y)
    -            if is_free and within_reach and is_diagonal_move:
    +            if (
    +                (self.spaces[dest_x][dest_y] == 0)
    +                and (abs(dest_x - start_x) <= 2)
    +                and (abs(dest_x - start_x) == abs(dest_y - start_y))
    +            ):
                     break
             return start_x, start_y, dest_x, dest_y
     
    -    def get_human_extension(
    -        self, start_x: int, start_y: int
    -    ) -> Tuple[bool, Optional[Tuple[int, int, int, int]]]:
    +    def get_human_extension(self, start_x, start_y):
             is_king = self.spaces[start_x][start_y] == HUMAN_KING
     
             while True:
    @@ -340,26 +319,24 @@ def get_human_extension(
                 ):
                     return True, (start_x, start_y, dest_x, dest_y)
     
    -    def play_human_move(
    -        self, start_x: int, start_y: int, dest_x: int, dest_y: int
    -    ) -> None:
    +    def play_human_move(self, start_x, start_y, dest_x, dest_y):
             self.remove_pieces(start_x, start_y, dest_x, dest_y)
     
             if dest_y == TOP_ROW:
                 # KING ME
                 self.spaces[dest_x][dest_y] = HUMAN_KING
     
    -    def check_pieces(self) -> bool:
    -        if not list(self.get_spaces_with_computer_pieces()):
    +    def check_pieces(self):
    +        if len(list(self.get_spaces_with_computer_pieces())) == 0:
                 print_human_won()
                 return False
    -        if not list(self.get_spaces_with_computer_pieces()):
    +        if len(list(self.get_spaces_with_computer_pieces())) == 0:
                 print_computer_won()
                 return False
             return True
     
     
    -def print_instructions() -> None:
    +def print_instructions():
         print("THIS IS THE GAME OF CHECKERS.  THE COMPUTER IS X,")
         print("AND YOU ARE O.  THE COMPUTER WILL MOVE FIRST.")
         print("SQUARES ARE REFERRED TO BY A COORDINATE SYSTEM.")
    @@ -368,18 +345,23 @@ def print_instructions() -> None:
         print("(7,0) IS THE LOWER RIGHT CORNER")
         print("(7,7) IS THE UPPER RIGHT CORNER")
         print("THE COMPUTER WILL TYPE '+TO' WHEN YOU HAVE ANOTHER")
    -    print("JUMP.  TYPE TWO NEGATIVE NUMBERS IF YOU CANNOT JUMP.\n\n\n")
    +    print("JUMP.  TYPE TWO NEGATIVE NUMBERS IF YOU CANNOT JUMP.")
    +    print()
    +    print()
    +    print()
     
     
    -def print_human_won() -> None:
    -    print("\nYOU WIN.")
    +def print_human_won():
    +    print()
    +    print("YOU WIN.")
     
     
    -def print_computer_won() -> None:
    -    print("\nI WIN.")
    +def print_computer_won():
    +    print()
    +    print("I WIN.")
     
     
    -def play_game() -> None:
    +def play_game():
         board = Board()
     
         while True:
    @@ -399,14 +381,13 @@ def play_game() -> None:
             if abs(dest_x - start_x) == 2:
                 while True:
                     extend, move = board.get_human_extension(dest_x, dest_y)
    -                assert move is not None
                     if not extend:
                         break
                     start_x, start_y, dest_x, dest_y = move
                     board.play_human_move(start_x, start_y, dest_x, dest_y)
     
     
    -def main() -> None:
    +def main():
         print_header("CHECKERS")
         print_instructions()
     
    diff --git a/23_Checkers/vbnet/Checkers.sln b/23_Checkers/vbnet/Checkers.sln
    deleted file mode 100644
    index f5409425b..000000000
    --- a/23_Checkers/vbnet/Checkers.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index fb77091fd..000000000
    --- a/23_Checkers/vbnet/Checkers.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Checkers
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/24_Chemist/README.md b/24_Chemist/README.md
    index 8871a0acb..b93c1431d 100644
    --- a/24_Chemist/README.md
    +++ b/24_Chemist/README.md
    @@ -13,13 +13,5 @@ As published in Basic Computer Games (1978):
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
     
    -#### Known Bugs
    -
    -- There is a typo in the original Basic, "...DECIDE **WHO** MUCH WATER..." should be "DECIDE **HOW** MUCH WATER"
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    -
     #### External Links
      - C: https://github.com/ericfischer/basic-computer-games/blob/main/24%20Chemist/c/chemist.c
    diff --git a/24_Chemist/csharp/Chemist.sln b/24_Chemist/csharp/Chemist.sln
    deleted file mode 100644
    index bac784357..000000000
    --- a/24_Chemist/csharp/Chemist.sln
    +++ /dev/null
    @@ -1,25 +0,0 @@
    -
    -Microsoft Visual Studio Solution File, Format Version 12.00
    -# Visual Studio Version 16
    -VisualStudioVersion = 16.0.31005.135
    -MinimumVisualStudioVersion = 10.0.40219.1
    -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Chemist", "Chemist.csproj", "{C16545E8-E078-4C69-B7CA-9D821C944252}"
    -EndProject
    -Global
    -	GlobalSection(SolutionConfigurationPlatforms) = preSolution
    -		Debug|Any CPU = Debug|Any CPU
    -		Release|Any CPU = Release|Any CPU
    -	EndGlobalSection
    -	GlobalSection(ProjectConfigurationPlatforms) = postSolution
    -		{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
    -	EndGlobalSection
    -	GlobalSection(ExtensibilityGlobals) = postSolution
    -		SolutionGuid = {4AFDA581-82B1-42C7-9C9C-26F6B4288584}
    -	EndGlobalSection
    -EndGlobal
    diff --git a/24_Chemist/csharp/Chemist/Chemist.sln b/24_Chemist/csharp/Chemist/Chemist.sln
    new file mode 100644
    index 000000000..6dc7bfa28
    --- /dev/null
    +++ b/24_Chemist/csharp/Chemist/Chemist.sln
    @@ -0,0 +1,25 @@
    +
    +Microsoft Visual Studio Solution File, Format Version 12.00
    +# Visual Studio Version 16
    +VisualStudioVersion = 16.0.31005.135
    +MinimumVisualStudioVersion = 10.0.40219.1
    +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Chemist", "Chemist\Chemist.csproj", "{8CC70F80-F2D6-47B6-8976-079352AC6C85}"
    +EndProject
    +Global
    +	GlobalSection(SolutionConfigurationPlatforms) = preSolution
    +		Debug|Any CPU = Debug|Any CPU
    +		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
    +	EndGlobalSection
    +	GlobalSection(SolutionProperties) = preSolution
    +		HideSolutionNode = FALSE
    +	EndGlobalSection
    +	GlobalSection(ExtensibilityGlobals) = postSolution
    +		SolutionGuid = {4AFDA581-82B1-42C7-9C9C-26F6B4288584}
    +	EndGlobalSection
    +EndGlobal
    diff --git a/24_Chemist/csharp/Chemist.csproj b/24_Chemist/csharp/Chemist/Chemist/Chemist.csproj
    similarity index 100%
    rename from 24_Chemist/csharp/Chemist.csproj
    rename to 24_Chemist/csharp/Chemist/Chemist/Chemist.csproj
    diff --git a/24_Chemist/csharp/Program.cs b/24_Chemist/csharp/Chemist/Chemist/Program.cs
    similarity index 100%
    rename from 24_Chemist/csharp/Program.cs
    rename to 24_Chemist/csharp/Chemist/Chemist/Program.cs
    diff --git a/24_Chemist/javascript/chemist.html b/24_Chemist/javascript/chemist.html
    index 424f299f0..c65d7821e 100644
    --- a/24_Chemist/javascript/chemist.html
    +++ b/24_Chemist/javascript/chemist.html
    @@ -1,10 +1,9 @@
     
     
     CHEMIST
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/24_Chemist/javascript/chemist.js b/24_Chemist/javascript/chemist.js
    index b71292746..8d6aabf57 100644
    --- a/24_Chemist/javascript/chemist.js
    +++ b/24_Chemist/javascript/chemist.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/24_Chemist/kotlin/README.md b/24_Chemist/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/24_Chemist/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/24_Chemist/lua/README.md b/24_Chemist/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/24_Chemist/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/24_Chemist/pascal/README.md b/24_Chemist/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/24_Chemist/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/24_Chemist/perl/chemist.pl b/24_Chemist/perl/chemist.pl
    index 4565da5d5..9f75bfac4 100755
    --- a/24_Chemist/perl/chemist.pl
    +++ b/24_Chemist/perl/chemist.pl
    @@ -33,3 +33,5 @@
     print "YOUR 9 LIVES ARE USED, BUT YOU WILL BE LONG REMEMBERED FOR\n";
     print "YOUR CONTRIBUTIONS TO THE FIELD OF COMIC BOOK CHEMISTRY.\n";
     exit;
    +
    +
    diff --git a/24_Chemist/python/chemist.py b/24_Chemist/python/chemist.py
    index 561f67c39..73dfdc4ef 100644
    --- a/24_Chemist/python/chemist.py
    +++ b/24_Chemist/python/chemist.py
    @@ -11,7 +11,16 @@
     MAX_LIVES = 9
     
     
    -def play_scenario() -> bool:
    +def print_with_tab(space_count, msg):
    +    if space_count > 0:
    +        spaces = " " * space_count
    +    else:
    +        spaces = ""
    +
    +    print(spaces + msg)
    +
    +
    +def play_scenario():
         acid_amount = random.randint(1, 50)
     
         water_amount = 7 * acid_amount / 3
    @@ -34,23 +43,27 @@ def play_scenario() -> bool:
             return True
     
     
    -def show_failure() -> None:
    +def show_failure():
         print(" SIZZLE!  YOU HAVE JUST BEEN DESALINATED INTO A BLOB")
         print(" OF QUIVERING PROTOPLASM!")
     
     
    -def show_success() -> None:
    -    print(" GOOD JOB! YOU MAY BREATHE NOW, BUT DON'T INHALE THE FUMES!\n")
    +def show_success():
    +    print(" GOOD JOB! YOU MAY BREATHE NOW, BUT DON'T INHALE THE FUMES!")
    +    print()
     
     
    -def show_ending() -> None:
    +def show_ending():
         print(f" YOUR {MAX_LIVES} LIVES ARE USED, BUT YOU WILL BE LONG REMEMBERED FOR")
         print(" YOUR CONTRIBUTIONS TO THE FIELD OF COMIC BOOK CHEMISTRY.")
     
     
    -def main() -> None:
    -    print(" " * 33 + "CHEMIST")
    -    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n")
    +def main():
    +    print_with_tab(33, "CHEMIST")
    +    print_with_tab(15, "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
    +    print()
    +    print()
    +    print()
     
         print("THE FICTITIOUS CHEMICAL KRYPTOCYANIC ACID CAN ONLY BE")
         print("DILUTED BY THE RATIO OF 7 PARTS WATER TO 3 PARTS ACID.")
    diff --git a/24_Chemist/rust/Cargo.lock b/24_Chemist/rust/Cargo.lock
    deleted file mode 100644
    index 4fe2abbea..000000000
    --- a/24_Chemist/rust/Cargo.lock
    +++ /dev/null
    @@ -1,75 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.10"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.147"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/24_Chemist/rust/Cargo.toml b/24_Chemist/rust/Cargo.toml
    deleted file mode 100644
    index 3b1d02f52..000000000
    --- a/24_Chemist/rust/Cargo.toml
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -[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/24_Chemist/rust/README.md b/24_Chemist/rust/README.md
    deleted file mode 100644
    index 7e85f9a15..000000000
    --- a/24_Chemist/rust/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Rust](https://www.rust-lang.org/) by Anthony Rubick [AnthonyMichaelTDM](https://github.com/AnthonyMichaelTDM)
    diff --git a/24_Chemist/rust/src/lib.rs b/24_Chemist/rust/src/lib.rs
    deleted file mode 100644
    index b3618ccfb..000000000
    --- a/24_Chemist/rust/src/lib.rs
    +++ /dev/null
    @@ -1,158 +0,0 @@
    -/*
    - lib.rs contains all the logic of the program
    -*/
    -use rand::{Rng, prelude::thread_rng}; //rng
    -use std::error::Error; //better errors
    -use std::io::{self, Write}; //io interactions
    -use std::{str::FromStr, fmt::Display}; //traits
    -
    -//DATA
    -
    -/// handles setup for the game
    -pub struct Config {
    -}
    -impl Config {
    -    /// creates and returns a new Config from user input
    -    pub fn new() -> Result> {
    -        //DATA
    -        let config: Config = Config {
    -        };
    -        
    -        //return new config
    -        return Ok(config);
    -    }
    -}
    -
    -/// run the program
    -pub fn run(_config: &Config) -> Result<(), Box> {
    -    //DATA
    -    let mut rng = thread_rng();
    -    let mut lives: i8 = 9;
    -
    -    let mut amount_of_acid:i8;
    -
    -    let mut guess:f32;
    -    let mut answer:f32;
    -    
    -    let mut error:f32; 
    -
    -    //Game loop
    -    loop {
    -        //initialize variables
    -        amount_of_acid =  rng.gen_range(1..50);
    -        answer = 7.0 * (amount_of_acid as f32/3.0);
    -
    -        //print starting message / conditions
    -        println!();
    -        //get guess
    -        guess = loop {
    -            match get_number_from_input(&format!("{} Liters of Kryptocyanic acid.  How much water? ", amount_of_acid),0.0,-1.0) {
    -                Ok(num) => break num,
    -                Err(err) => {
    -                    eprintln!("{}",err);
    -                    continue;
    -                },
    -            }
    -        };
    -
    -        //calculate error
    -        error = (answer as f32 - guess).abs() / guess;
    -        
    -        println!("answer: {} | error: {}%", answer,error*100.);
    -
    -        //check guess against answer
    -        if error > 0.05 { //error > 5%
    -            println!(" Sizzle!  You may have just been desalinated into a blob");
    -            println!(" of quivering protoplasm!");
    -            //update lives
    -            lives -= 1;
    -
    -            if lives <= 0 {
    -                println!(" Your 9 lives are used, but you will be long remembered for");
    -                println!(" your contributions to the field of comic book chemistry.");
    -                break;
    -            }
    -            else {
    -                println!(" However, you may try again with another life.")
    -            } 
    -        } else {
    -            println!(" Good job!  You may breathe now, but don't inhale the fumes!");
    -            println!();
    -        }
    -    }
    -
    -    //return to main
    -    Ok(())
    -}
    -
    -/// gets a string from user input
    -fn get_string_from_user_input(prompt: &str) -> Result> {
    -    //DATA
    -    let mut raw_input = String::new();
    -
    -    //print prompt
    -    print!("{}", prompt);
    -    //make sure it's printed before getting input
    -    io::stdout().flush().expect("couldn't flush stdout");
    -
    -    //read user input from standard input, and store it to raw_input, then return it or an error as needed
    -    raw_input.clear(); //clear input
    -    match io::stdin().read_line(&mut raw_input) {
    -        Ok(_num_bytes_read) => return Ok(String::from(raw_input.trim())),
    -        Err(err) => return Err(format!("ERROR: CANNOT READ INPUT!: {}", err).into()),
    -    }
    -}
    -/// generic function to get a number from the passed string (user input)
    -/// pass a min lower  than the max to have minimum and maximum bounds
    -/// pass a min higher than the max to only have a minimum bound
    -/// pass a min equal   to  the max to only have a maximum bound
    -/// 
    -/// Errors:
    -/// no number on user input
    -fn get_number_from_input(prompt: &str, min:T, max:T) -> Result> {
    -    //DATA
    -    let raw_input: String;
    -    let processed_input: String;
    -
    -    
    -    //input loop
    -    raw_input = loop {
    -        match get_string_from_user_input(prompt) {
    -            Ok(input) => break input,
    -            Err(e) => {
    -                eprintln!("{}",e);
    -                continue;
    -            },
    -        }
    -    };
    -
    -    //filter out non-numeric characters from user input
    -    processed_input = raw_input.chars().filter(|c| c.is_numeric()).collect();
    -
    -    //from input, try to read a number
    -    match processed_input.trim().parse() {
    -        Ok(i) => {
    -            //what bounds must the input fall into
    -            if min < max {  //have a min and max bound: [min,max]
    -                if i >= min && i <= max {//is input valid, within bounds
    -                    return Ok(i); //exit the loop with the value i, returning it
    -                } else { //print error message specific to this case
    -                    return Err(format!("ONLY BETWEEN {} AND {}, PLEASE!", min, max).into());
    -                } 
    -            } else if min > max { //only a min bound: [min, infinity)
    -                if i >= min {
    -                    return Ok(i);
    -                } else {
    -                    return Err(format!("NO LESS THAN {}, PLEASE!", min).into());
    -                }
    -            } else { //only a max bound: (-infinity, max]
    -                if i <= max {
    -                    return Ok(i);
    -                } else {
    -                    return Err(format!("NO MORE THAN {}, PLEASE!", max).into());
    -                }
    -            }
    -        },
    -        Err(_e) => return Err(format!("Error: couldn't find a valid number in {}",raw_input).into()),
    -    }
    -}
    diff --git a/24_Chemist/rust/src/main.rs b/24_Chemist/rust/src/main.rs
    deleted file mode 100644
    index 91b1f86ac..000000000
    --- a/24_Chemist/rust/src/main.rs
    +++ /dev/null
    @@ -1,46 +0,0 @@
    -use std::process;//allows for some better error handling
    -
    -mod lib; //allows access to lib.rs
    -use lib::Config;
    -
    -/// main function
    -/// responsibilities:
    -/// - Calling the command line logic with the argument values
    -/// - Setting up any other configuration
    -/// - Calling a run function in lib.rs
    -/// - Handling the error if run returns an error
    -fn main() {
    -    //greet user
    -    welcome();
    -
    -    // set up other configuration
    -    let mut config = Config::new().unwrap_or_else(|err| {
    -        eprintln!("Problem configuring program: {}", err);
    -        process::exit(1);
    -    });
    -
    -    // run the program
    -    if let Err(e) = lib::run(&mut config) {
    -        eprintln!("Application Error: {}", e); //use the eprintln! macro to output to standard error
    -        process::exit(1); //exit the program with an error code
    -    }
    -
    -    //end of program
    -    println!("THANKS FOR PLAYING!");
    -}
    -
    -/// print the welcome message
    -fn welcome() {
    -    println!("
    -                                Chemist
    -              CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY
    -
    -
    -The fictitious chemical kryptocyanic acid can only be
    -diluted by the ratio of 7 parts water to 3 parts acid.
    -If any other ratio is attempted, the acid becomes unstable
    -and soon explodes.  Given the amount of acid, you must
    -decide how much water to add for dilution.  If you miss
    -you face the consequences.
    -    ");
    -}
    diff --git a/24_Chemist/vbnet/Chemist.sln b/24_Chemist/vbnet/Chemist.sln
    deleted file mode 100644
    index 1200eeff3..000000000
    --- a/24_Chemist/vbnet/Chemist.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 7990a9b7b..000000000
    --- a/24_Chemist/vbnet/Chemist.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Chemist
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/25_Chief/README.md b/25_Chief/README.md
    index 225430cb9..5cb044c0b 100644
    --- a/25_Chief/README.md
    +++ b/25_Chief/README.md
    @@ -14,7 +14,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/25_Chief/csharp/Chief.csproj b/25_Chief/csharp/Chief.csproj
    deleted file mode 100644
    index 3870320c9..000000000
    --- a/25_Chief/csharp/Chief.csproj
    +++ /dev/null
    @@ -1,17 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    -  
    -    
    -  
    -
    -  
    -    
    -  
    -
    diff --git a/25_Chief/csharp/Chief.sln b/25_Chief/csharp/Chief.sln
    deleted file mode 100644
    index 036992c3a..000000000
    --- a/25_Chief/csharp/Chief.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/csharp/Game.cs b/25_Chief/csharp/Game.cs
    deleted file mode 100644
    index 1884c9b51..000000000
    --- a/25_Chief/csharp/Game.cs
    +++ /dev/null
    @@ -1,49 +0,0 @@
    -using static Chief.Resources.Resource;
    -
    -namespace Chief;
    -
    -internal class Game
    -{
    -    private readonly IReadWrite _io;
    -
    -    public Game(IReadWrite io)
    -    {
    -        _io = io;
    -    }
    -
    -    internal void Play()
    -    {
    -        DoIntroduction();
    -
    -        var result = _io.ReadNumber(Prompts.Answer);
    -
    -        if (_io.ReadYes(Formats.Bet, Math.CalculateOriginal(result)))
    -        {
    -            _io.Write(Streams.Bye);
    -            return;
    -        }
    -
    -        var original = _io.ReadNumber(Prompts.Original);
    -
    -        _io.WriteLine(Math.ShowWorking(original));
    -
    -        if (_io.ReadYes(Prompts.Believe))
    -        {
    -            _io.Write(Streams.Bye);
    -            return;
    -        }
    -
    -        _io.Write(Streams.Lightning);
    -    }
    -
    -    private void DoIntroduction()
    -    {
    -        _io.Write(Streams.Title);
    -        if (!_io.ReadYes(Prompts.Ready))
    -        {
    -            _io.Write(Streams.ShutUp);
    -        }
    -
    -        _io.Write(Streams.Instructions);
    -    }
    -}
    diff --git a/25_Chief/csharp/IReadWriteExtensions.cs b/25_Chief/csharp/IReadWriteExtensions.cs
    deleted file mode 100644
    index ff190952c..000000000
    --- a/25_Chief/csharp/IReadWriteExtensions.cs
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -namespace Chief;
    -
    -internal static class IReadWriteExtensions
    -{
    -    internal static bool ReadYes(this IReadWrite io, string format, Number value) =>
    -        io.ReadYes(string.Format(format, value));
    -    internal static bool ReadYes(this IReadWrite io, string prompt) =>
    -        io.ReadString(prompt).Equals("Yes", StringComparison.InvariantCultureIgnoreCase);
    -}
    \ No newline at end of file
    diff --git a/25_Chief/csharp/Math.cs b/25_Chief/csharp/Math.cs
    deleted file mode 100644
    index a9bf7285e..000000000
    --- a/25_Chief/csharp/Math.cs
    +++ /dev/null
    @@ -1,18 +0,0 @@
    -using static Chief.Resources.Resource;
    -
    -namespace Chief;
    -
    -public static class Math
    -{
    -    public static float CalculateOriginal(float result) => (result + 1 - 5) * 5 / 8 * 5 - 3;
    -
    -    public static string ShowWorking(Number value) =>
    -        string.Format(
    -            Formats.Working,
    -            value,
    -            value += 3,
    -            value /= 5,
    -            value *= 8,
    -            value = value / 5 + 5,
    -            value - 1);
    -}
    \ No newline at end of file
    diff --git a/25_Chief/csharp/Program.cs b/25_Chief/csharp/Program.cs
    deleted file mode 100644
    index 0686ce1e7..000000000
    --- a/25_Chief/csharp/Program.cs
    +++ /dev/null
    @@ -1,4 +0,0 @@
    -global using Games.Common.IO;
    -global using Chief;
    -
    -new Game(new ConsoleIO()).Play();
    \ No newline at end of file
    diff --git a/25_Chief/csharp/Resources/Answer.txt b/25_Chief/csharp/Resources/Answer.txt
    deleted file mode 100644
    index 2ac8f3a63..000000000
    --- a/25_Chief/csharp/Resources/Answer.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -  What do you have
    \ No newline at end of file
    diff --git a/25_Chief/csharp/Resources/Believe.txt b/25_Chief/csharp/Resources/Believe.txt
    deleted file mode 100644
    index 01963221d..000000000
    --- a/25_Chief/csharp/Resources/Believe.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Now do you believe me
    \ No newline at end of file
    diff --git a/25_Chief/csharp/Resources/Bet.txt b/25_Chief/csharp/Resources/Bet.txt
    deleted file mode 100644
    index 724512fc2..000000000
    --- a/25_Chief/csharp/Resources/Bet.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -I bet your number was{0}. Am I right
    \ No newline at end of file
    diff --git a/25_Chief/csharp/Resources/Bye.txt b/25_Chief/csharp/Resources/Bye.txt
    deleted file mode 100644
    index 087bcf7a0..000000000
    --- a/25_Chief/csharp/Resources/Bye.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Bye!!!
    diff --git a/25_Chief/csharp/Resources/Instructions.txt b/25_Chief/csharp/Resources/Instructions.txt
    deleted file mode 100644
    index b4425be04..000000000
    --- a/25_Chief/csharp/Resources/Instructions.txt
    +++ /dev/null
    @@ -1,2 +0,0 @@
    - Take a number and add 3. Divide this number by 5 and
    -multiply by 8. Divide by 5 and add the same. Subtract 1.
    diff --git a/25_Chief/csharp/Resources/Lightning.txt b/25_Chief/csharp/Resources/Lightning.txt
    deleted file mode 100644
    index c2f564bd2..000000000
    --- a/25_Chief/csharp/Resources/Lightning.txt
    +++ /dev/null
    @@ -1,31 +0,0 @@
    -You have made me mad!!!
    -There must be a great lightning bolt!!
    -
    -
    -                              X X
    -                             X X
    -                            X X
    -                           X X
    -                          X X
    -                         X X
    -                        X X
    -                       X X
    -                      X X
    -                     X XXX
    -                    X   X
    -                   XX X
    -                    X X
    -                   X X
    -                  X X
    -                 X X
    -                X X
    -               X X
    -              X X
    -             X X
    -            XX
    -           X
    -          *
    -
    -#########################
    -
    -I hope you believe me now, for your sake!!
    diff --git a/25_Chief/csharp/Resources/Original.txt b/25_Chief/csharp/Resources/Original.txt
    deleted file mode 100644
    index 954b026d7..000000000
    --- a/25_Chief/csharp/Resources/Original.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -What was your original number
    \ No newline at end of file
    diff --git a/25_Chief/csharp/Resources/Ready.txt b/25_Chief/csharp/Resources/Ready.txt
    deleted file mode 100644
    index c57946cbc..000000000
    --- a/25_Chief/csharp/Resources/Ready.txt
    +++ /dev/null
    @@ -1,2 +0,0 @@
    -I am Chief Numbers Freek, the great Indian math god.
    -Are you ready to take the test you called me out for
    \ No newline at end of file
    diff --git a/25_Chief/csharp/Resources/Resource.cs b/25_Chief/csharp/Resources/Resource.cs
    deleted file mode 100644
    index 4255d6c6e..000000000
    --- a/25_Chief/csharp/Resources/Resource.cs
    +++ /dev/null
    @@ -1,41 +0,0 @@
    -using System.Reflection;
    -using System.Runtime.CompilerServices;
    -
    -namespace Chief.Resources;
    -
    -internal static class Resource
    -{
    -    internal static class Streams
    -    {
    -        public static Stream Bye => GetStream();
    -        public static Stream Instructions => GetStream();
    -        public static Stream Lightning => GetStream();
    -        public static Stream ShutUp => GetStream();
    -        public static Stream Title => GetStream();
    -    }
    -
    -    internal static class Formats
    -    {
    -        public static string Bet => GetString();
    -        public static string Working => GetString();
    -    }
    -
    -    internal static class Prompts
    -    {
    -        public static string Answer => GetString();
    -        public static string Believe => GetString();
    -        public static string Original => GetString();
    -        public static string Ready => GetString();
    -    }
    -
    -    private static string GetString([CallerMemberName] string? name = null)
    -    {
    -        using var stream = GetStream(name);
    -        using var reader = new StreamReader(stream);
    -        return reader.ReadToEnd();
    -    }
    -
    -    private static Stream GetStream([CallerMemberName] string? name = null)
    -        => Assembly.GetExecutingAssembly().GetManifestResourceStream($"Chief.Resources.{name}.txt")
    -            ?? throw new ArgumentException($"Resource stream {name} does not exist", nameof(name));
    -}
    \ No newline at end of file
    diff --git a/25_Chief/csharp/Resources/ShutUp.txt b/25_Chief/csharp/Resources/ShutUp.txt
    deleted file mode 100644
    index 0b36668c7..000000000
    --- a/25_Chief/csharp/Resources/ShutUp.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Shut up, pale face with wise tongue.
    \ No newline at end of file
    diff --git a/25_Chief/csharp/Resources/Title.txt b/25_Chief/csharp/Resources/Title.txt
    deleted file mode 100644
    index 980d407d2..000000000
    --- a/25_Chief/csharp/Resources/Title.txt
    +++ /dev/null
    @@ -1,5 +0,0 @@
    -                                  Chief
    -               Creative Computing  Morristown, New Jersey
    -
    -
    -
    diff --git a/25_Chief/csharp/Resources/Working.txt b/25_Chief/csharp/Resources/Working.txt
    deleted file mode 100644
    index 75f1bf7aa..000000000
    --- a/25_Chief/csharp/Resources/Working.txt
    +++ /dev/null
    @@ -1,5 +0,0 @@
    -So you think you're so smart, eh?
    -Now watch.
    -{0}plus 3 equals{1}. This divided by 5 equals{2};
    -This times by 8 equals{3}. If we divide by 5 and add 5,
    -we get{4}, which, minus 1, equals{5}.
    diff --git a/25_Chief/java/src/Chief.java b/25_Chief/java/src/Chief.java
    index fd9627fd0..1db2eb6cc 100644
    --- a/25_Chief/java/src/Chief.java
    +++ b/25_Chief/java/src/Chief.java
    @@ -203,4 +203,4 @@ private String displayTextAndGetInput(String text) {
             return kbScanner.next();
         }
     
    -}
    +}
    \ No newline at end of file
    diff --git a/25_Chief/java/src/ChiefGame.java b/25_Chief/java/src/ChiefGame.java
    index 000c7bc26..25ebc1bc6 100644
    --- a/25_Chief/java/src/ChiefGame.java
    +++ b/25_Chief/java/src/ChiefGame.java
    @@ -5,4 +5,4 @@ public static void main(String[] args) {
             Chief chief = new Chief();
             chief.play();
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/25_Chief/javascript/chief.html b/25_Chief/javascript/chief.html
    index 9527335b0..cf272f9b0 100644
    --- a/25_Chief/javascript/chief.html
    +++ b/25_Chief/javascript/chief.html
    @@ -1,10 +1,9 @@
     
     
     CHIEF
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/25_Chief/javascript/chief.js b/25_Chief/javascript/chief.js
    index 1125a98c1..98fde4198 100644
    --- a/25_Chief/javascript/chief.js
    +++ b/25_Chief/javascript/chief.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/25_Chief/kotlin/README.md b/25_Chief/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/25_Chief/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/25_Chief/lua/README.md b/25_Chief/lua/README.md
    deleted file mode 100644
    index 937d758c4..000000000
    --- a/25_Chief/lua/README.md
    +++ /dev/null
    @@ -1,24 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/) by Alex Conconi
    -
    ----
    -
    -### Lua porting notes
    -
    -- I did not like the old Western movie language style in the game introduction
    -and decided to tone it down, even if this deviates from the original BASIC
    -version.
    -
    -- The `craps_game` function contains the main game logic: it
    -  - prints the game credits and presents the intro question;
    -  - asks for the end result and computes the original numer;
    -  - calls `explain_solution` to print the various steps of the computation;
    -  - presents the outro question and prints a `bolt` if necessary.
    -
    -- Added basic input validation to accept only valid integers for numeric input.
    -
    -- Minor formatting edits (lowercase, punctuation).
    -
    -- Any answer to a "yes or no" question is regarded as "yes" if the input line
    -starts with 'y' or 'Y', else no.
    diff --git a/25_Chief/lua/chief.lua b/25_Chief/lua/chief.lua
    deleted file mode 100644
    index 6ac885b2e..000000000
    --- a/25_Chief/lua/chief.lua
    +++ /dev/null
    @@ -1,121 +0,0 @@
    ---[[
    -Chief
    -
    -From: BASIC Computer Games (1978)
    -Edited by David H. Ahl
    -
    -    In the words of the program author, John Graham, “CHIEF is designed to
    -    give people (mostly kids) practice in the four operations (addition,
    -    multiplication, subtraction, and division).
    -
    -    It does this while giving people some fun. And then, if the people are
    -    wrong, it shows them how they should have done it.
    -
    -    CHIEF was written by John Graham of Upper Brookville, New York.
    -
    -    
    -Lua port by Alex Conconi, 2022.
    -]]--
    -
    -
    ---- Helper function for tabulating messages.
    -local function space(n) return string.rep(" ", n) end
    -
    -
    ---- Generates a multi-line string representing a lightning bolt
    -local function bolt()
    -    local bolt_lines = {}
    -    for n = 29, 21, -1 do
    -        table.insert(bolt_lines, space(n) .. "x x")
    -    end
    -    table.insert(bolt_lines, space(20) .. "x xxx")
    -    table.insert(bolt_lines, space(19) .. "x   x")
    -    table.insert(bolt_lines, space(18) .. "xx x")
    -    for n = 19, 12, -1 do
    -        table.insert(bolt_lines, space(n) .. "x x")
    -    end
    -    table.insert(bolt_lines, space(11) .. "xx")
    -    table.insert(bolt_lines, space(10) .. "x")
    -    table.insert(bolt_lines, space(9) .. "*\n")
    -    table.insert(bolt_lines, string.rep("#", 25) .. "\n")
    -    return table.concat(bolt_lines, "\n")
    -end
    -
    -
    ---- Print the prompt and read a yes/no answer from stdin.
    -local function ask_yes_or_no(prompt)
    -    io.stdout:write(prompt .. " ")
    -    local answer = string.lower(io.stdin:read("*l"))
    -    -- any line starting with a 'y' or 'Y' is considered a 'yes'
    -    return answer:sub(1, 1) == "y"
    -end
    -
    -
    ---- Print the prompt and read a valid number from stdin.
    -local function ask_number(prompt)
    -    io.stdout:write(prompt .. " ")
    -    while true do
    -        local n = tonumber(io.stdin:read("*l"))
    -        if n then
    -            return n
    -        else
    -            print("Enter a valid number.")
    -        end
    -    end
    -end
    -
    -
    ---- Explain the solution to persuade the player.
    -local function explain_solution()
    -    local k = ask_number("What was your original number?")
    -    -- For clarity we kept the same variable names of the original BASIC version
    -    local f = k + 3
    -    local g = f / 5
    -    local h = g * 8
    -    local i = h / 5 + 5
    -    local j = i - 1
    -    print("So you think you're so smart, eh?")
    -    print("Now watch.")
    -    print(k .. " plus 3 equals " .. f .. ". This divided by 5 equals " .. g .. ";")
    -    print("this times 8 equals " .. h .. ". If we divide by 5 and add 5,")
    -    print("we get " .. i .. ", which, minus 1, equals " .. j .. ".")
    -end
    -
    -
    ---- Main game function.
    -local function chief_game()
    -    --- Print game introduction and challenge
    -    print(space(29) .. "Chief")
    -    print(space(14) .. "Creative Computing  Morristown, New Jersey\n\n")
    -    print("I am Chief Numbers Freek, the great math god.")
    -    if not ask_yes_or_no("Are you ready to take the test you called me out for?") then
    -        print("Shut up, wise tongue.")
    -    end
    -
    -    -- Print how to obtain the end result.
    -    print(" Take a number and add 3. Divide this number by 5 and")
    -    print("multiply by 8. Divide by 5 and add the same. Subtract 1.")
    -
    -    -- Ask the result end and reverse calculate the original number.
    -    local end_result = ask_number(" What do you have?")
    -    local original_number = (end_result + 1 - 5) * 5 / 8 * 5 - 3
    -
    -    -- If it is an integer we do not want to print any zero decimals.
    -    local int_part, dec_part = math.modf(original_number)
    -    if dec_part == 0 then original_number = int_part end
    -
    -    -- If the player challenges the answer, print the explanation.
    -    if not ask_yes_or_no("I bet your number was " .. original_number .. ". Am I right?") then
    -        explain_solution()
    -        -- If the player does not accept the explanation, zap them.
    -        if not ask_yes_or_no("Now do you believe me?") then
    -            print("YOU HAVE MADE ME MAD!!!")
    -            print("THERE MUST BE A GREAT LIGHTNING BOLT!\n\n")
    -            print(bolt())
    -            print("I hope you believe me now, for your sake!!")
    -        end
    -    end
    -end
    -
    ---- Run the game.
    -chief_game()
    diff --git a/25_Chief/pascal/README.md b/25_Chief/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/25_Chief/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/25_Chief/python/Chief.py b/25_Chief/python/Chief.py
    new file mode 100644
    index 000000000..67b4eab86
    --- /dev/null
    +++ b/25_Chief/python/Chief.py
    @@ -0,0 +1,77 @@
    +def print_lightning_bolt():
    +
    +  print('*'*36)
    +  n = 24
    +  while n > 16:
    +    print(' '*n + 'x x')
    +    n -=1
    +  print(' '*16 + 'x xxx')
    +  print(' '*15 + 'x   x')
    +  print(' '*14+ 'xxx x')
    +  n -=1
    +  while n > 8:
    +    print(' '*n + 'x x')
    +    n -=1
    +  print(' '*8 + 'xx')
    +  print(' '*7 +'x')
    +  print('*'*36)
    +
    +
    +def print_solution(n):
    +
    +  print('\n{} plus 3 gives {}. This Divided by 5 equals {}'.format(n, n+3, (n+3)/5))
    +  print('This times 8 gives {}. If we divide 5 and add 5.'.format(( (n+3)/5 )*8 ))
    +  print('We get {}, which, minus 1 equals {}'.format(( ((n+3)/5)*8)/5+5, ((((n+3)/5)*8)/5+5)-1 ))
    +
    +def Game():
    +  print('\nTake a Number and ADD 3. Now, Divide this number by 5 and')
    +  print('multiply by 8. Now, Divide by 5 and add the same. Subtract 1')
    +
    +  resp = float(input('\nWhat do you have? '))
    +  comp_guess = (((resp - 4)*5)/8)*5 -3
    +  resp2 = input('\nI bet your number was {} was i right(Yes or No)? '.format(comp_guess))
    +  
    +  if resp2 == 'Yes' or resp2 == 'YES' or resp2 == 'yes':
    +    print('\nHuh, I Knew I was unbeatable')
    +    print('And here is how i did it')
    +    print_solution(comp_guess)
    +    input('')
    +  
    +  else:
    +    resp3 = float(input('\nHUH!! what was you original number? '))
    +    
    +    if resp3 == comp_guess:
    +      print('\nThat was my guess, AHA i was right')
    +      print("Shamed to accept defeat i guess, don't worry you can master mathematics too")
    +      print('Here is how i did it')
    +      print_solution(comp_guess)
    +      input('')
    +    
    +    else:
    +      print('\nSo you think you\'re so smart, EH?')
    +      print('Now, Watch')
    +      print_solution(resp3)
    +
    +      resp4 = input('\nNow do you believe me? ')
    +
    +      if resp4 == 'Yes' or resp4 == 'YES' or resp4 == 'yes':
    +        print('\nOk, Lets play again sometime bye!!!!')
    +        input('')
    +
    +      else:
    +        print('\nYOU HAVE MADE ME VERY MAD!!!!!')
    +        print("BY THE WRATH OF THE MATHEMATICS AND THE RAGE OF THE GODS")
    +        print("THERE SHALL BE LIGHTNING!!!!!!!")
    +        print_lightning_bolt()
    +        print('\nI Hope you believe me now, for your own sake')
    +        input('')
    +
    +if __name__ == '__main__':
    +
    +  print('I am CHIEF NUMBERS FREEK, The GREAT INDIAN MATH GOD.')
    +  play = input('\nAre you ready to take the test you called me out for(Yes or No)? ')
    +  if play == 'Yes' or play == 'YES' or play == 'yes':
    +    Game()
    +  else:
    +    print('Ok, Nevermind. Let me go back to my great slumber, Bye')
    +    input('')
    diff --git a/25_Chief/python/chief.py b/25_Chief/python/chief.py
    deleted file mode 100644
    index 050e281f3..000000000
    --- a/25_Chief/python/chief.py
    +++ /dev/null
    @@ -1,78 +0,0 @@
    -def print_lightning_bolt() -> None:
    -    print("*" * 36)
    -    n = 24
    -    while n > 16:
    -        print(" " * n + "x x")
    -        n -= 1
    -    print(" " * 16 + "x xxx")
    -    print(" " * 15 + "x   x")
    -    print(" " * 14 + "xxx x")
    -    n -= 1
    -    while n > 8:
    -        print(" " * n + "x x")
    -        n -= 1
    -    print(" " * 8 + "xx")
    -    print(" " * 7 + "x")
    -    print("*" * 36)
    -
    -
    -def print_solution(n: float) -> None:
    -    print(f"\n{n} plus 3 gives {n + 3}. This Divided by 5 equals {(n + 3) / 5}")
    -    print(f"This times 8 gives {((n + 3) / 5) * 8}. If we divide 5 and add 5.")
    -    print(
    -        f"We get {(((n + 3) / 5) * 8) / 5 + 5}, "
    -        f"which, minus 1 equals {((((n + 3) / 5) * 8) / 5 + 5) - 1}"
    -    )
    -
    -
    -def game() -> None:
    -    print("\nTake a Number and ADD 3. Now, Divide this number by 5 and")
    -    print("multiply by 8. Now, Divide by 5 and add the same. Subtract 1")
    -
    -    you_have = float(input("\nWhat do you have? "))
    -    comp_guess = (((you_have - 4) * 5) / 8) * 5 - 3
    -    first_guess_right = input(
    -        f"\nI bet your number was {comp_guess} was I right(Yes or No)? "
    -    )
    -
    -    if first_guess_right.lower() == "yes":
    -        print("\nHuh, I Knew I was unbeatable")
    -        print("And here is how i did it")
    -        print_solution(comp_guess)
    -    else:
    -        original_number = float(input("\nHUH!! what was you original number? "))
    -
    -        if original_number == comp_guess:
    -            print("\nThat was my guess, AHA i was right")
    -            print(
    -                "Shamed to accept defeat i guess, don't worry you can master mathematics too"
    -            )
    -            print("Here is how i did it")
    -            print_solution(comp_guess)
    -        else:
    -            print("\nSo you think you're so smart, EH?")
    -            print("Now, Watch")
    -            print_solution(original_number)
    -
    -            believe_me = input("\nNow do you believe me? ")
    -
    -            if believe_me.lower() == "yes":
    -                print("\nOk, Lets play again sometime bye!!!!")
    -            else:
    -                print("\nYOU HAVE MADE ME VERY MAD!!!!!")
    -                print("BY THE WRATH OF THE MATHEMATICS AND THE RAGE OF THE GODS")
    -                print("THERE SHALL BE LIGHTNING!!!!!!!")
    -                print_lightning_bolt()
    -                print("\nI Hope you believe me now, for your own sake")
    -
    -    input()
    -
    -
    -if __name__ == "__main__":
    -    print("I am CHIEF NUMBERS FREEK, The GREAT INDIAN MATH GOD.")
    -    play = input("\nAre you ready to take the test you called me out for(Yes or No)? ")
    -    if play.lower() == "yes":
    -        game()
    -    else:
    -        print("Ok, Nevermind. Let me go back to my great slumber, Bye")
    -        input()
    diff --git a/25_Chief/rust/Cargo.lock b/25_Chief/rust/Cargo.lock
    deleted file mode 100644
    index b21cc6a2d..000000000
    --- a/25_Chief/rust/Cargo.lock
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    diff --git a/25_Chief/rust/Cargo.toml b/25_Chief/rust/Cargo.toml
    deleted file mode 100644
    index 1ec696335..000000000
    --- a/25_Chief/rust/Cargo.toml
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -[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]
    diff --git a/25_Chief/rust/README.md b/25_Chief/rust/README.md
    deleted file mode 100644
    index 8bdbf2e2b..000000000
    --- a/25_Chief/rust/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Rust](https://www.rust-lang.org/) by [Jadi](https://github.com/jadijadi)
    \ No newline at end of file
    diff --git a/25_Chief/rust/src/main.rs b/25_Chief/rust/src/main.rs
    deleted file mode 100644
    index 123f1a670..000000000
    --- a/25_Chief/rust/src/main.rs
    +++ /dev/null
    @@ -1,133 +0,0 @@
    -use std::io;
    -
    -fn print_center(text: String, width: usize) {
    -    let pad_size: usize = if width > text.len() {
    -        (width - text.len()) / 2
    -    } else {
    -        0
    -    };
    -    println!("{}{}", " ".repeat(pad_size), text);
    -}
    -
    -fn send_lightening() {
    -    println!(
    -        "YOU HAVE MADE ME MAD!!!
    -THERE MUST BE A GREAT LIGHTNING BOLT!
    -
    -                              X X
    -                             X X
    -                            X X
    -                           X X
    -                          X X
    -                         X X
    -                        X X
    -                       X X
    -                      X X
    -                     X XXX
    -                    X   X
    -                   XX X
    -                    X X
    -                   X X
    -                  X X
    -                 X X
    -                X X
    -               X X
    -              X X
    -             X X
    -            XX
    -           X
    -          *
    -
    -#########################
    -
    -I HOPE YOU BELIEVE ME NOW, FOR YOUR SAKE!!"
    -    );
    -}
    -
    -fn check_yes_answer() -> bool {
    -    // reads from input and return true if it starts with Y or y
    -
    -    let mut answer: String = String::new();
    -    io::stdin()
    -        .read_line(&mut answer)
    -        .expect("Error reading from stdin");
    -
    -    answer.to_uppercase().starts_with('Y')
    -}
    -
    -fn main() {
    -    const PAGE_WIDTH: usize = 64;
    -    print_center("CHIEF".to_string(), PAGE_WIDTH);
    -    print_center(
    -        "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY".to_string(),
    -        PAGE_WIDTH,
    -    );
    -    println!("\n\n\n");
    -
    -    println!("I AM CHIEF NUMBERS FREEK, THE GREAT INDIAN MATH GOD.");
    -    println!("ARE YOU READY TO TAKE THE TEST YOU CALLED ME OUT FOR?");
    -
    -    if !check_yes_answer() {
    -        println!("SHUT UP, PALE FACE WITH WISE TONGUE.");
    -    }
    -
    -    println!("TAKE A NUMBER AND ADD 3. DIVIDE THIS NUMBER BY 5 AND");
    -    println!("MULTIPLY BY 8. DIVIDE BY 5 AND ADD THE SAME. SUBTRACT 1.");
    -    println!("  WHAT DO YOU HAVE?");
    -
    -    // read a float number
    -    let mut answer: String = String::new();
    -    io::stdin()
    -        .read_line(&mut answer)
    -        .expect("Error reading from stdin");
    -    let guess: f32 = answer.trim().parse().expect("Input not a number");
    -
    -    let calculated_answer: f32 = (guess + 1.0 - 5.0) * 5.0 / 8.0 * 5.0 - 3.0;
    -
    -    println!("I BET YOUR NUMBER WAS {calculated_answer}. AM I RIGHT?");
    -
    -    if check_yes_answer() {
    -        println!("BYE!!!");
    -    } else {
    -        println!("WHAT WAS YOUR ORIGINAL NUMBER?");
    -
    -        // read a float number
    -        let mut answer: String = String::new();
    -        io::stdin()
    -            .read_line(&mut answer)
    -            .expect("Error reading from stdin");
    -        let claimed: f32 = answer.trim().parse().expect("Input not a number");
    -
    -        println!("SO YOU THINK YOU'RE SO SMART, EH?");
    -        println!("NOW WATCH.");
    -        println!(
    -            "{claimed} PLUS 3 EQUALS {}. THIS DIVIDED BY 5 EQUALS {};",
    -            claimed + 3.0,
    -            (claimed + 3.0) / 5.0
    -        );
    -        println!(
    -            "THIS TIMES 8 EQUALS {}. IF WE DIVIDE BY 5 AND ADD 5,",
    -            (claimed + 3.0) / 5.0 * 8.0
    -        );
    -        println!(
    -            "WE GET {} , WHICH, MINUS 1, EQUALS {}.",
    -            ((claimed + 3.0) / 5.0 * 8.0 / 5.0) + 5.0,
    -            ((claimed + 3.0) / 5.0 * 8.0 / 5.0) + 4.0
    -        );
    -        println!("NOW DO YOU BELIEVE ME?");
    -
    -        if check_yes_answer() {
    -            println!("BYE!!!");
    -        } else {
    -            send_lightening();
    -        }
    -    }
    -}
    -
    -////////////////////////////////////////////////////////////////////
    -// Porting notes:
    -// In floating point arithmetics in "modern" languages we might see
    -// unfamiliar situations such as 6.9999999 instead of 7 and such.
    -// resolving this needs using specific mathematical libraries which
    -// IMO is out of scope in these basic programs
    -///////////////////////////////////////////////////////////////////
    diff --git a/25_Chief/vbnet/Chief.sln b/25_Chief/vbnet/Chief.sln
    deleted file mode 100644
    index 579b0124b..000000000
    --- a/25_Chief/vbnet/Chief.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 09c229178..000000000
    --- a/25_Chief/vbnet/Chief.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Chief
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/26_Chomp/README.md b/26_Chomp/README.md
    index 3935a483f..e9a8b5ce3 100644
    --- a/26_Chomp/README.md
    +++ b/26_Chomp/README.md
    @@ -14,7 +14,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/26_Chomp/chomp.bas b/26_Chomp/chomp.bas
    index 2ca7a51f0..50e5e232a 100644
    --- a/26_Chomp/chomp.bas
    +++ b/26_Chomp/chomp.bas
    @@ -3,7 +3,7 @@
     30 PRINT:PRINT:PRINT
     40 DIM A(10,10)
     100 REM *** THE GAME OF CHOMP *** COPYRIGHT PCC 1973 ***
    -110 PRINT
    +110 PRINT 
     120 PRINT "THIS IS THE GAME OF CHOMP (SCIENTIFIC AMERICAN, JAN 1973)"
     130 PRINT "DO YOU WANT THE RULES (1=YES, 0=NO!)";
     140 INPUT R
    @@ -25,16 +25,16 @@
     300 PRINT "(INCLUDING THAT SQUARE, TOO) DISAPPEAR -- CHOMP!!"
     310 PRINT "NO FAIR CHOMPING SQUARES THAT HAVE ALREADY BEEN CHOMPED,"
     320 PRINT "OR THAT ARE OUTSIDE THE ORIGINAL DIMENSIONS OF THE COOKIE."
    -330 PRINT
    +330 PRINT 
     340 PRINT "HERE WE GO..."
    -350 REM
    +350 REM 
     360 F=0
     370 FOR I=1 TO 10
     372 FOR J=1 TO 10
     375 A(I,J)=0
     377 NEXT J
     379 NEXT I
    -380 PRINT
    +380 PRINT 
     390 PRINT "HOW MANY PLAYERS";
     400 INPUT P
     410 I1=0
    @@ -48,7 +48,7 @@
     490 IF C <= 9 THEN 530
     500 PRINT "TOO MANY COLUMNS (9 IS MAXIMUM). NOW, ";
     510 GOTO 470
    -530 PRINT
    +530 PRINT 
     540 FOR I=1 TO R
     550 FOR J=1 TO C
     560 A(I,J)=1
    @@ -56,7 +56,7 @@
     580 NEXT I
     590 A(1,1)=-1
     600 REM PRINT THE BOARD
    -610 PRINT
    +610 PRINT 
     620 PRINT TAB(7);"1 2 3 4 5 6 7 8 9"
     630 FOR I=1 TO R
     640 PRINT I;TAB(7);
    @@ -67,11 +67,11 @@
     690 GOTO 710
     700 PRINT "P ";
     710 NEXT J
    -720 PRINT
    +720 PRINT 
     730 NEXT I
    -740 PRINT
    +740 PRINT 
     750 IF F=0 THEN 770
    -760 RETURN
    +760 RETURN 
     770 REM GET CHOMPS FOR EACH PLAYER IN TURN
     780 LET I1=I1+1
     790 LET P1=I1-INT(I1/P)*P
    @@ -97,7 +97,7 @@
     990 GOTO 610
     1000 REM END OF GAME DETECTED IN LINE 900
     1010 PRINT "YOU LOSE, PLAYER";P1
    -1020 PRINT
    +1020 PRINT 
     1030 PRINT "AGAIN (1=YES, 0=NO!)";
     1040 INPUT R
     1050 IF R=1 THEN 340
    diff --git a/26_Chomp/csharp/Chomp.csproj b/26_Chomp/csharp/Chomp.csproj
    deleted file mode 100644
    index 3870320c9..000000000
    --- a/26_Chomp/csharp/Chomp.csproj
    +++ /dev/null
    @@ -1,17 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    -  
    -    
    -  
    -
    -  
    -    
    -  
    -
    diff --git a/26_Chomp/csharp/Chomp.sln b/26_Chomp/csharp/Chomp.sln
    deleted file mode 100644
    index 1567eb9dc..000000000
    --- a/26_Chomp/csharp/Chomp.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/csharp/Cookie.cs b/26_Chomp/csharp/Cookie.cs
    deleted file mode 100644
    index 725eadfeb..000000000
    --- a/26_Chomp/csharp/Cookie.cs
    +++ /dev/null
    @@ -1,56 +0,0 @@
    -using System.Text;
    -
    -namespace Chomp;
    -
    -internal class Cookie
    -{
    -    private readonly int _rowCount;
    -    private readonly int _columnCount;
    -    private readonly char[][] _bits;
    -
    -    public Cookie(int rowCount, int columnCount)
    -    {
    -        _rowCount = rowCount;
    -        _columnCount = columnCount;
    -
    -        // The calls to Math.Max here are to duplicate the original behaviour
    -        // when negative values are given for the row or column count.
    -        _bits = new char[Math.Max(_rowCount, 1)][];
    -        for (int row = 0; row < _bits.Length; row++)
    -        {
    -            _bits[row] = Enumerable.Repeat('*', Math.Max(_columnCount, 1)).ToArray();
    -        }
    -        _bits[0][0] = 'P';
    -    }
    -
    -    public bool TryChomp(int row, int column, out char chomped)
    -    {
    -        if (row < 1 || row > _rowCount || column < 1 || column > _columnCount || _bits[row - 1][column - 1] == ' ')
    -        {
    -            chomped = default;
    -            return false;
    -        }
    -
    -        chomped = _bits[row - 1][column - 1];
    -
    -        for (int r = row; r <= _rowCount; r++)
    -        {
    -            for (int c = column; c <= _columnCount; c++)
    -            {
    -                _bits[r - 1][c - 1] = ' ';
    -            }
    -        }
    -
    -        return true;
    -    }
    -
    -    public override string ToString()
    -    {
    -        var builder = new StringBuilder().AppendLine("       1 2 3 4 5 6 7 8 9");
    -        for (int row = 1; row <= _bits.Length; row++)
    -        {
    -            builder.Append(' ').Append(row).Append("     ").AppendLine(string.Join(' ', _bits[row - 1]));
    -        }
    -        return builder.ToString();
    -    }
    -}
    \ No newline at end of file
    diff --git a/26_Chomp/csharp/Game.cs b/26_Chomp/csharp/Game.cs
    deleted file mode 100644
    index 77a8ccd1e..000000000
    --- a/26_Chomp/csharp/Game.cs
    +++ /dev/null
    @@ -1,64 +0,0 @@
    -namespace Chomp;
    -
    -internal class Game
    -{
    -    private readonly IReadWrite _io;
    -
    -    public Game(IReadWrite io)
    -    {
    -        _io = io;
    -    }
    -
    -    internal void Play()
    -    {
    -        _io.Write(Resource.Streams.Introduction);
    -        if (_io.ReadNumber("Do you want the rules (1=Yes, 0=No!)") != 0)
    -        {
    -            _io.Write(Resource.Streams.Rules);
    -        }
    -
    -        while (true)
    -        {
    -            _io.Write(Resource.Streams.HereWeGo);
    -
    -            var (playerCount, rowCount, columnCount) = _io.ReadParameters();
    -
    -            var loser = Play(new Cookie(rowCount, columnCount), new PlayerNumber(playerCount));
    -
    -            _io.WriteLine(string.Format(Resource.Formats.YouLose, loser));
    -
    -            if (_io.ReadNumber("Again (1=Yes, 0=No!)") != 1) { break; }
    -        }
    -    }
    -
    -    private PlayerNumber Play(Cookie cookie, PlayerNumber player)
    -    {
    -        while (true)
    -        {
    -            _io.WriteLine(cookie);
    -
    -            var poisoned = Chomp(cookie, player);
    -
    -            if (poisoned) { return player; }
    -
    -            player++;
    -        }
    -    }
    -
    -    private bool Chomp(Cookie cookie, PlayerNumber player)
    -    {
    -        while (true)
    -        {
    -            _io.WriteLine(string.Format(Resource.Formats.Player, player));
    -
    -            var (row, column) = _io.Read2Numbers(Resource.Prompts.Coordinates);
    -
    -            if (cookie.TryChomp((int)row, (int)column, out char chomped))
    -            {
    -                return chomped == 'P';
    -            }
    -
    -            _io.Write(Resource.Streams.NoFair);
    -        }
    -    }
    -}
    diff --git a/26_Chomp/csharp/IOExtensions.cs b/26_Chomp/csharp/IOExtensions.cs
    deleted file mode 100644
    index c94053a90..000000000
    --- a/26_Chomp/csharp/IOExtensions.cs
    +++ /dev/null
    @@ -1,24 +0,0 @@
    -namespace Chomp;
    -
    -internal static class IOExtensions
    -{
    -    public static (float, int, int) ReadParameters(this IReadWrite io)
    -        => (
    -            (int)io.ReadNumber(Resource.Prompts.HowManyPlayers),
    -            io.ReadNumberWithMax(Resource.Prompts.HowManyRows, 9, Resource.Strings.TooManyRows),
    -            io.ReadNumberWithMax(Resource.Prompts.HowManyColumns, 9, Resource.Strings.TooManyColumns)
    -        );
    -
    -    private static int ReadNumberWithMax(this IReadWrite io, string initialPrompt, int max, string reprompt)
    -    {
    -        var prompt = initialPrompt;
    -
    -        while (true)
    -        {
    -            var response = io.ReadNumber(prompt);
    -            if (response <= 9) { return (int)response; }
    -
    -            prompt = $"{reprompt} {initialPrompt.ToLowerInvariant()}";
    -        }
    -    }
    -}
    \ No newline at end of file
    diff --git a/26_Chomp/csharp/PlayerNumber.cs b/26_Chomp/csharp/PlayerNumber.cs
    deleted file mode 100644
    index 16138a9be..000000000
    --- a/26_Chomp/csharp/PlayerNumber.cs
    +++ /dev/null
    @@ -1,32 +0,0 @@
    -namespace Chomp;
    -
    -internal class PlayerNumber
    -{
    -    private readonly float _playerCount;
    -    private int _counter;
    -    private float _number;
    -
    -    // The original code does not constrain playerCount to be an integer
    -    public PlayerNumber(float playerCount)
    -    {
    -        _playerCount = playerCount;
    -        _number = 0;
    -        Increment();
    -    }
    -
    -    public static PlayerNumber operator ++(PlayerNumber number) => number.Increment();
    -
    -    private PlayerNumber Increment()
    -    {
    -		if (_playerCount == 0) { throw new DivideByZeroException(); }
    -
    -        // The increment logic here is the same as the original program, and exhibits
    -        // interesting behaviour when _playerCount is not an integer.
    -        _counter++;
    -        _number = _counter - (float)Math.Floor(_counter / _playerCount) * _playerCount;
    -        if (_number == 0) { _number = _playerCount; }
    -        return this;
    -    }
    -
    -    public override string ToString() => (_number >= 0 ? " " : "") + _number.ToString();
    -}
    \ No newline at end of file
    diff --git a/26_Chomp/csharp/Program.cs b/26_Chomp/csharp/Program.cs
    deleted file mode 100644
    index f541259c1..000000000
    --- a/26_Chomp/csharp/Program.cs
    +++ /dev/null
    @@ -1,5 +0,0 @@
    -global using Games.Common.IO;
    -global using Chomp.Resources;
    -using Chomp;
    -
    -new Game(new ConsoleIO()).Play();
    \ No newline at end of file
    diff --git a/26_Chomp/csharp/Resources/Coordinates.txt b/26_Chomp/csharp/Resources/Coordinates.txt
    deleted file mode 100644
    index e78dd644d..000000000
    --- a/26_Chomp/csharp/Resources/Coordinates.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Coordinates of Chomp (row, column)
    \ No newline at end of file
    diff --git a/26_Chomp/csharp/Resources/HereWeGo.txt b/26_Chomp/csharp/Resources/HereWeGo.txt
    deleted file mode 100644
    index 00975d31a..000000000
    --- a/26_Chomp/csharp/Resources/HereWeGo.txt
    +++ /dev/null
    @@ -1,2 +0,0 @@
    -Here we go...
    -
    diff --git a/26_Chomp/csharp/Resources/HowManyColumns.txt b/26_Chomp/csharp/Resources/HowManyColumns.txt
    deleted file mode 100644
    index e323f959a..000000000
    --- a/26_Chomp/csharp/Resources/HowManyColumns.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -How many columns
    \ No newline at end of file
    diff --git a/26_Chomp/csharp/Resources/HowManyPlayers.txt b/26_Chomp/csharp/Resources/HowManyPlayers.txt
    deleted file mode 100644
    index 98ff0ad72..000000000
    --- a/26_Chomp/csharp/Resources/HowManyPlayers.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -How many players
    \ No newline at end of file
    diff --git a/26_Chomp/csharp/Resources/HowManyRows.txt b/26_Chomp/csharp/Resources/HowManyRows.txt
    deleted file mode 100644
    index 1ad9464ee..000000000
    --- a/26_Chomp/csharp/Resources/HowManyRows.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -How many rows
    \ No newline at end of file
    diff --git a/26_Chomp/csharp/Resources/Introduction.txt b/26_Chomp/csharp/Resources/Introduction.txt
    deleted file mode 100644
    index 7c95e7a6e..000000000
    --- a/26_Chomp/csharp/Resources/Introduction.txt
    +++ /dev/null
    @@ -1,6 +0,0 @@
    -                                 Chomp
    -               Creative Computing  Morristown, New Jersey
    -
    -
    -
    -This is the game of Chomp (Scientific American, Jan 1973)
    diff --git a/26_Chomp/csharp/Resources/NoFair.txt b/26_Chomp/csharp/Resources/NoFair.txt
    deleted file mode 100644
    index 9fe310eb2..000000000
    --- a/26_Chomp/csharp/Resources/NoFair.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -No fair. You're trying to chomp on empty space!
    diff --git a/26_Chomp/csharp/Resources/Player.txt b/26_Chomp/csharp/Resources/Player.txt
    deleted file mode 100644
    index f743df3a0..000000000
    --- a/26_Chomp/csharp/Resources/Player.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Player{0}
    \ No newline at end of file
    diff --git a/26_Chomp/csharp/Resources/Resource.cs b/26_Chomp/csharp/Resources/Resource.cs
    deleted file mode 100644
    index d080b1fba..000000000
    --- a/26_Chomp/csharp/Resources/Resource.cs
    +++ /dev/null
    @@ -1,48 +0,0 @@
    -using System.Reflection;
    -using System.Runtime.CompilerServices;
    -
    -namespace Chomp.Resources;
    -
    -internal static class Resource
    -{
    -    internal static class Streams
    -    {
    -        public static Stream HereWeGo => GetStream();
    -        public static Stream Introduction => GetStream();
    -        public static Stream Rules => GetStream();
    -        public static Stream NoFair => GetStream();
    -    }
    -
    -    internal static class Formats
    -    {
    -        public static string Player => GetString();
    -        public static string YouLose => GetString();
    -    }
    -
    -    internal static class Prompts
    -    {
    -        public static string Coordinates => GetString();
    -        public static string HowManyPlayers => GetString();
    -        public static string HowManyRows => GetString();
    -        public static string HowManyColumns => GetString();
    -        public static string TooManyColumns => GetString();
    -    }
    -
    -    internal static class Strings
    -    {
    -        public static string TooManyColumns => GetString();
    -        public static string TooManyRows => GetString();
    -    }
    -
    -    private static string GetString([CallerMemberName] string? name = null)
    -    {
    -        using var stream = GetStream(name);
    -        using var reader = new StreamReader(stream);
    -        return reader.ReadToEnd();
    -    }
    -
    -
    -    private static Stream GetStream([CallerMemberName] string? name = null) =>
    -        Assembly.GetExecutingAssembly().GetManifestResourceStream($"{typeof(Resource).Namespace}.{name}.txt")
    -            ?? throw new Exception($"Could not find embedded resource stream '{name}'.");
    -}
    \ No newline at end of file
    diff --git a/26_Chomp/csharp/Resources/Rules.txt b/26_Chomp/csharp/Resources/Rules.txt
    deleted file mode 100644
    index 2fd9177f4..000000000
    --- a/26_Chomp/csharp/Resources/Rules.txt
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -Chomp is for 1 or more players (humans only).
    -
    -Here's how a board looks (this one is 5 by 7):
    -
    -       1 2 3 4 5 6 7 8 9
    - 1     P * * * * * *
    - 2     * * * * * * *
    - 3     * * * * * * *
    - 4     * * * * * * *
    - 5     * * * * * * *
    -
    -
    -The board is a big cookie - R rows high and C columns
    -wide. You input R and C at the start. In the upper left
    -corner of the cookie is a poison square (P). The one who
    -chomps the poison square loses. To take a chomp, type the
    -row and column of one of the squares on the cookie.
    -All of the squares below and to the right of that square
    -(including that square, too) disappear -- Chomp!!
    -No fair chomping on squares that have already been chomped,
    -or that are outside the original dimensions of the cookie.
    -
    diff --git a/26_Chomp/csharp/Resources/TooManyColumns.txt b/26_Chomp/csharp/Resources/TooManyColumns.txt
    deleted file mode 100644
    index 1e8766a7f..000000000
    --- a/26_Chomp/csharp/Resources/TooManyColumns.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Too many rows (9 is maximum). Now,
    \ No newline at end of file
    diff --git a/26_Chomp/csharp/Resources/TooManyRows.txt b/26_Chomp/csharp/Resources/TooManyRows.txt
    deleted file mode 100644
    index 1e8766a7f..000000000
    --- a/26_Chomp/csharp/Resources/TooManyRows.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Too many rows (9 is maximum). Now,
    \ No newline at end of file
    diff --git a/26_Chomp/csharp/Resources/YouLose.txt b/26_Chomp/csharp/Resources/YouLose.txt
    deleted file mode 100644
    index 1015e2717..000000000
    --- a/26_Chomp/csharp/Resources/YouLose.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -You lose, player{0}
    diff --git a/26_Chomp/java/Chomp.java b/26_Chomp/java/Chomp.java
    index 82b4e3e1c..c11a5647b 100644
    --- a/26_Chomp/java/Chomp.java
    +++ b/26_Chomp/java/Chomp.java
    @@ -88,7 +88,7 @@ private void printBoard(){
     
     	private void move(int player){
     		System.out.println(String.format("Player %d",(player+1)));
    -
    +			
     		String input;
     		String [] coordinates;
     		int x=-1,y=-1;
    diff --git a/26_Chomp/javascript/chomp.html b/26_Chomp/javascript/chomp.html
    index 9b822bd2d..b749afe33 100644
    --- a/26_Chomp/javascript/chomp.html
    +++ b/26_Chomp/javascript/chomp.html
    @@ -1,10 +1,9 @@
     
     
     CHOMP
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/26_Chomp/javascript/chomp.js b/26_Chomp/javascript/chomp.js
    index 3a63bbc7a..652023e66 100644
    --- a/26_Chomp/javascript/chomp.js
    +++ b/26_Chomp/javascript/chomp.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/26_Chomp/kotlin/README.md b/26_Chomp/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/26_Chomp/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/26_Chomp/lua/README.md b/26_Chomp/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/26_Chomp/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/26_Chomp/pascal/README.md b/26_Chomp/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/26_Chomp/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/26_Chomp/perl/chomp.pl b/26_Chomp/perl/chomp.pl
    index 4a7bc4e59..34727626e 100644
    --- a/26_Chomp/perl/chomp.pl
    +++ b/26_Chomp/perl/chomp.pl
    @@ -13,7 +13,7 @@ sub main {
     }
     
     sub game_play {
    -
    +	
     	# the initial game set up
     	&print_intro;
     	my ($players,$rows,$cols) = &get_user_info;
    @@ -24,7 +24,7 @@ sub game_play {
     
     	# continuous loop until the poison pill is swallowed
     	until ($game_over == 1) {
    -		if ($player > ($players-1)) {		#checks to make sure we're just looping thru valid players
    +		if ($player > ($players-1)) {		#checks to make sure we're just looping thru valid players 
     			$player = 0;
     		}
     		$player++;
    @@ -39,7 +39,7 @@ sub game_play {
     		&modify_gameboard($rows,$cols,$user_row,$user_col);
     		&print_gameboard($rows,$cols);
     	}
    -
    +	
     }
     
     sub get_player_row_col {
    @@ -136,7 +136,7 @@ sub modify_gameboard {
     	my ($rows,$cols,$user_row,$user_col) = @_;
     	foreach my $row ($user_row..($rows)) {
     		foreach my $col ($user_col..($cols)) {
    -			$cookie[$row][$col]="  ";
    +			$cookie[$row][$col]="  ";	
     		}
     	}
     }
    diff --git a/26_Chomp/python/chomp.py b/26_Chomp/python/chomp.py
    index d7b67950e..56190a9e2 100755
    --- a/26_Chomp/python/chomp.py
    +++ b/26_Chomp/python/chomp.py
    @@ -1,31 +1,30 @@
     #!/usr/bin/env python3
    -
    -"""
    -CHOMP
    -
    -Converted from BASIC to Python by Trevor Hobson
    -"""
    +# CHOMP
    +#
    +# Converted from BASIC to Python by Trevor Hobson
     
     
     class Canvas:
    -    """For drawing the cookie"""
    +    """ For drawing the cookie """
     
    -    def __init__(self, width=9, height=9, fill="*") -> None:
    +    def __init__(self, width=9, height=9, fill="*"):
             self._buffer = []
             for _ in range(height):
    -            line = [fill for _ in range(width)]
    +            line = []
    +            for _ in range(width):
    +                line.append(fill)
                 self._buffer.append(line)
             self._buffer[0][0] = "P"
     
    -    def render(self) -> str:
    +    def render(self):
             lines = ["       1 2 3 4 5 6 7 8 9"]
    -        lines.extend(
    -            f" {str(row)}" + " " * 5 + " ".join(line)
    -            for row, line in enumerate(self._buffer, start=1)
    -        )
    +        row = 0
    +        for line in self._buffer:
    +            row += 1
    +            lines.append(" " + str(row) + " " * 5 + " ".join(line))
             return "\n".join(lines)
     
    -    def chomp(self, r, c) -> str:
    +    def chomp(self, r, c):
             if not 1 <= r <= len(self._buffer) or not 1 <= c <= len(self._buffer[0]):
                 return "Empty"
             elif self._buffer[r - 1][c - 1] == " ":
    @@ -39,7 +38,7 @@ def chomp(self, r, c) -> str:
                 return "Chomp"
     
     
    -def play_game() -> None:
    +def play_game():
         """Play one round of the game"""
         players = 0
         while players == 0:
    @@ -72,9 +71,9 @@ def play_game() -> None:
         player = 0
         alive = True
         while alive:
    -        print()
    +        print("")
             print(cookie.render())
    -        print()
    +        print("")
             player += 1
             if player > players:
                 player = 1
    @@ -84,12 +83,8 @@ def play_game() -> None:
                 player_column = -1
                 while player_row == -1 or player_column == -1:
                     try:
    -                    coordinates = [
    -                        int(item)
    -                        for item in input("Coordinates of chomp (Row, Column) ").split(
    -                            ","
    -                        )
    -                    ]
    +                    coordinates = [int(item) for item in input(
    +                        "Coordinates of chomp (Row, Column) ").split(",")]
                         player_row = coordinates[0]
                         player_column = coordinates[1]
     
    @@ -106,7 +101,7 @@ def play_game() -> None:
                     break
     
     
    -def main() -> None:
    +def main():
         print(" " * 33 + "CHOMP")
         print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n")
         print("THIS IS THE GAME OF CHOMP (SCIENTIFIC AMERICAN, JAN 1973)")
    @@ -128,6 +123,7 @@ def main() -> None:
     
         keep_playing = True
         while keep_playing:
    +
             play_game()
             keep_playing = input("\nAgain (1=Yes, 0=No!) ") == "1"
     
    diff --git a/26_Chomp/vbnet/Chomp.sln b/26_Chomp/vbnet/Chomp.sln
    deleted file mode 100644
    index 3b772010d..000000000
    --- a/26_Chomp/vbnet/Chomp.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index a3308b2a4..000000000
    --- a/26_Chomp/vbnet/Chomp.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Chomp
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/27_Civil_War/README.md b/27_Civil_War/README.md
    index 7cbd62e2a..17d6816f2 100644
    --- a/27_Civil_War/README.md
    +++ b/27_Civil_War/README.md
    @@ -1,6 +1,6 @@
     ### Civil War
     
    -This simulation is based on 14 battles in the Civil War. Facts and figures are based on the actual occurrence. If you follow the same strategy used in the actual battle, the results will be the same. Generally, this is a good strategy since the generals in the Civil War were fairly good military strategists. However, you can frequently outperform the Civil War generals, particularly in cases where they did not have good enemy intelligence and consequently followed a poor course of action. Naturally, it helps to know your Civil War history, although the computer gives you the rudiments.
    +This simulation is based on 14 battles in the Civil War. Facts and figures are based on the actual occurrence. If you follow the same strategy used in the actual battle, the results will be the same. Generally, this is a good strategy since the generals in the Civil War were fairly good military strategists. However, you can frequently outperform the Civil War generals, particularly in cases where they did not have good enemy intelligence and consequently followed a poor course of action. Naturally, it helps to know your Civil War history, although the computer gives yuo the rudiments.
     
     After each of the 14 battles, your casualties are compared to the actual casualties of the battle, and you are told whether you win or lose the battle.
     
    @@ -16,11 +16,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Known Bugs
    -
    -- At the end of a single-player game, the program reports strategies used by "THE SOUTH", but these are in fact strategies used by the North (the computer player) -- the South is always a human player.
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/27_Civil_War/civilwar.bas b/27_Civil_War/civilwar.bas
    index f8fe97018..63597944d 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 2530
    +2310  IF B$ <> "YES" THEN 2350
     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"
    diff --git a/27_Civil_War/csharp/CivilWar.sln b/27_Civil_War/csharp/CivilWar.sln
    deleted file mode 100644
    index d013f7ed9..000000000
    --- a/27_Civil_War/csharp/CivilWar.sln
    +++ /dev/null
    @@ -1,25 +0,0 @@
    -
    -Microsoft Visual Studio Solution File, Format Version 12.00
    -# Visual Studio Version 16
    -VisualStudioVersion = 16.0.31005.135
    -MinimumVisualStudioVersion = 10.0.40219.1
    -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CivilWar", "CivilWar.csproj", "{4EE5EFE7-2D60-464A-9F8D-4BBD2A14AAC7}"
    -EndProject
    -Global
    -	GlobalSection(SolutionConfigurationPlatforms) = preSolution
    -		Debug|Any CPU = Debug|Any CPU
    -		Release|Any CPU = Release|Any CPU
    -	EndGlobalSection
    -	GlobalSection(ProjectConfigurationPlatforms) = postSolution
    -		{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
    -	EndGlobalSection
    -	GlobalSection(ExtensibilityGlobals) = postSolution
    -		SolutionGuid = {59BCA2DE-D5C7-40F7-BB99-B5C8D2416D8B}
    -	EndGlobalSection
    -EndGlobal
    diff --git a/27_Civil_War/csharp/CivilWar/CivilWar.sln b/27_Civil_War/csharp/CivilWar/CivilWar.sln
    new file mode 100644
    index 000000000..17da385e7
    --- /dev/null
    +++ b/27_Civil_War/csharp/CivilWar/CivilWar.sln
    @@ -0,0 +1,25 @@
    +
    +Microsoft Visual Studio Solution File, Format Version 12.00
    +# Visual Studio Version 16
    +VisualStudioVersion = 16.0.31005.135
    +MinimumVisualStudioVersion = 10.0.40219.1
    +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CivilWar", "CivilWar\CivilWar.csproj", "{09C22BBE-8480-4B8C-9A07-E2DAA24B692B}"
    +EndProject
    +Global
    +	GlobalSection(SolutionConfigurationPlatforms) = preSolution
    +		Debug|Any CPU = Debug|Any CPU
    +		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
    +	EndGlobalSection
    +	GlobalSection(SolutionProperties) = preSolution
    +		HideSolutionNode = FALSE
    +	EndGlobalSection
    +	GlobalSection(ExtensibilityGlobals) = postSolution
    +		SolutionGuid = {59BCA2DE-D5C7-40F7-BB99-B5C8D2416D8B}
    +	EndGlobalSection
    +EndGlobal
    diff --git a/27_Civil_War/csharp/Army.cs b/27_Civil_War/csharp/CivilWar/CivilWar/Army.cs
    similarity index 100%
    rename from 27_Civil_War/csharp/Army.cs
    rename to 27_Civil_War/csharp/CivilWar/CivilWar/Army.cs
    diff --git a/27_Civil_War/csharp/Battle.cs b/27_Civil_War/csharp/CivilWar/CivilWar/Battle.cs
    similarity index 100%
    rename from 27_Civil_War/csharp/Battle.cs
    rename to 27_Civil_War/csharp/CivilWar/CivilWar/Battle.cs
    diff --git a/27_Civil_War/csharp/CivilWar.csproj b/27_Civil_War/csharp/CivilWar/CivilWar/CivilWar.csproj
    similarity index 100%
    rename from 27_Civil_War/csharp/CivilWar.csproj
    rename to 27_Civil_War/csharp/CivilWar/CivilWar/CivilWar.csproj
    diff --git a/27_Civil_War/csharp/ConsoleUtils.cs b/27_Civil_War/csharp/CivilWar/CivilWar/ConsoleUtils.cs
    similarity index 100%
    rename from 27_Civil_War/csharp/ConsoleUtils.cs
    rename to 27_Civil_War/csharp/CivilWar/CivilWar/ConsoleUtils.cs
    diff --git a/27_Civil_War/csharp/GameOptions.cs b/27_Civil_War/csharp/CivilWar/CivilWar/GameOptions.cs
    similarity index 100%
    rename from 27_Civil_War/csharp/GameOptions.cs
    rename to 27_Civil_War/csharp/CivilWar/CivilWar/GameOptions.cs
    diff --git a/27_Civil_War/csharp/CivilWar/CivilWar/Program.cs b/27_Civil_War/csharp/CivilWar/CivilWar/Program.cs
    new file mode 100644
    index 000000000..c79d1a3ad
    --- /dev/null
    +++ b/27_Civil_War/csharp/CivilWar/CivilWar/Program.cs
    @@ -0,0 +1,119 @@
    +using System;
    +using System.Collections.Generic;
    +using System.Linq;
    +using CivilWar;
    +
    +var options = GameOptions.Input();
    +var armies = new List { new Army(Side.Confederate), options.TwoPlayers ? new Army(Side.Union) : new ComputerArmy(Side.Union) };
    +
    +Battle? battle = null;
    +while (OneBattle(ref battle)) { }
    +DisplayResult();
    +
    +bool OneBattle(ref Battle? previous)
    +{
    +    var (option, selected) = Battle.SelectBattle();
    +    var (battle, isReplay, quit) = option switch
    +    {
    +        Option.Battle => (selected!, false, false),
    +        Option.Replay when previous != null => (previous, true, false), // can't replay if no previous battle
    +        _ => (null!, false, true),
    +    };
    +    if (quit)
    +        return false;
    +
    +    if (!isReplay)
    +    {
    +        Console.WriteLine($"This is the battle of {battle.Name}.");
    +        if (options.ShowDescriptions)
    +            ConsoleUtils.WriteWordWrap(battle.Description);
    +        armies.ForEach(a => a.PrepareBattle(battle.Men[(int)a.Side], battle.Casualties[(int)a.Side]));
    +    }
    +
    +    ConsoleUtils.WriteTable(armies, new()
    +    {
    +        new("", a => a.Side),
    +        new("Men", a => a.Men),
    +        new("Money", a => a.Money, Before: "$"),
    +        new("Inflation", a => a.InflationDisplay, After: "%")
    +    });
    +
    +    armies.ForEach(a => a.AllocateResources());
    +    armies.ForEach(a => a.DisplayMorale());
    +
    +    string offensive = battle.Offensive switch
    +    {
    +        Side.Confederate => "You are on the offensive",
    +        Side.Union => "You are on the defensive",
    +        _ => "Both sides are on the offensive"
    +    };
    +    Console.WriteLine($"Confederate general---{offensive}");
    +
    +    if (armies.Any(a => a.ChooseStrategy(isReplay)))
    +    {
    +        return false; // someone surrendered
    +    }
    +    armies[0].CalculateLosses(armies[1]);
    +    armies[1].CalculateLosses(armies[0]);
    +
    +    ConsoleUtils.WriteTable(armies, new()
    +    {
    +        new("", a => a.Side),
    +        new("Casualties", a => a.Casualties),
    +        new("Desertions", a => a.Desertions),
    +    });
    +    if (options.TwoPlayers)
    +    {
    +        var oneDataCol = new[] { 1 };
    +        Console.WriteLine($"Compared to the actual casualties at {battle.Name}");
    +        ConsoleUtils.WriteTable(oneDataCol, armies.Select(a => new ConsoleUtils.TableRow(
    +            a.Side.ToString(),
    +            _ => $"{(double)a.Casualties / battle.Casualties[(int)a.Side]}", After: "% of the original")
    +        ).ToList());
    +    }
    +
    +    Side winner;
    +    switch (armies[0].AllLost, armies[1].AllLost, armies[0].MenLost - armies[1].MenLost)
    +    {
    +        case (true, true, _) or (false, false, 0):
    +            Console.WriteLine("Battle outcome unresolved");
    +            winner = Side.Both; // Draw
    +            break;
    +        case (false, true, _) or (false, false, < 0):
    +            Console.WriteLine($"The Confederacy wins {battle.Name}");
    +            winner = Side.Confederate;
    +            break;
    +        case (true, false, _) or (false, false, > 0):
    +            Console.WriteLine($"The Union wins {battle.Name}");
    +            winner = Side.Union;
    +            break;
    +    }
    +    if (!isReplay)
    +    {
    +        armies.ForEach(a => a.RecordResult(winner));
    +    }
    +    Console.WriteLine("---------------");
    +    previous = battle;
    +    return true;
    +}
    +
    +void DisplayResult()
    +{
    +    armies[0].DisplayWarResult(armies[1]);
    +
    +    int battles = armies[0].BattlesFought;
    +    if (battles > 0)
    +    {
    +        Console.WriteLine($"For the {battles} battles fought (excluding reruns)");
    +
    +        ConsoleUtils.WriteTable(armies, new()
    +        {
    +            new("", a => a.Side),
    +            new("Historical Losses", a => a.CumulativeHistoricCasualties),
    +            new("Simulated Losses", a => a.CumulativeSimulatedCasualties),
    +            new("  % of original", a => ((double)a.CumulativeSimulatedCasualties / a.CumulativeHistoricCasualties).ToString("p2"))
    +        }, transpose: true);
    +
    +        armies[1].DisplayStrategies();
    +    }
    +}
    \ No newline at end of file
    diff --git a/27_Civil_War/csharp/Program.cs b/27_Civil_War/csharp/Program.cs
    deleted file mode 100644
    index b715ffebb..000000000
    --- a/27_Civil_War/csharp/Program.cs
    +++ /dev/null
    @@ -1,119 +0,0 @@
    -using System;
    -using System.Collections.Generic;
    -using System.Linq;
    -using CivilWar;
    -
    -var options = GameOptions.Input();
    -var armies = new List { new Army(Side.Confederate), options.TwoPlayers ? new Army(Side.Union) : new ComputerArmy(Side.Union) };
    -
    -Battle? battle = null;
    -while (OneBattle(ref battle)) { }
    -DisplayResult();
    -
    -bool OneBattle(ref Battle? previous)
    -{
    -    var (option, selected) = Battle.SelectBattle();
    -    var (battle, isReplay, quit) = option switch
    -    {
    -        Option.Battle => (selected!, false, false),
    -        Option.Replay when previous != null => (previous, true, false), // can't replay if no previous battle
    -        _ => (null!, false, true),
    -    };
    -    if (quit)
    -        return false;
    -
    -    if (!isReplay)
    -    {
    -        Console.WriteLine($"This is the battle of {battle.Name}.");
    -        if (options.ShowDescriptions)
    -            ConsoleUtils.WriteWordWrap(battle.Description);
    -        armies.ForEach(a => a.PrepareBattle(battle.Men[(int)a.Side], battle.Casualties[(int)a.Side]));
    -    }
    -
    -    ConsoleUtils.WriteTable(armies, new()
    -    {
    -        new("", a => a.Side),
    -        new("Men", a => a.Men),
    -        new("Money", a => a.Money, Before: "$"),
    -        new("Inflation", a => a.InflationDisplay, After: "%")
    -    });
    -
    -    armies.ForEach(a => a.AllocateResources());
    -    armies.ForEach(a => a.DisplayMorale());
    -
    -    string offensive = battle.Offensive switch
    -    {
    -        Side.Confederate => "You are on the offensive",
    -        Side.Union => "You are on the defensive",
    -        _ => "Both sides are on the offensive"
    -    };
    -    Console.WriteLine($"Confederate general---{offensive}");
    -
    -    if (armies.Any(a => a.ChooseStrategy(isReplay)))
    -    {
    -        return false; // someone surrendered
    -    }
    -    armies[0].CalculateLosses(armies[1]);
    -    armies[1].CalculateLosses(armies[0]);
    -
    -    ConsoleUtils.WriteTable(armies, new()
    -    {
    -        new("", a => a.Side),
    -        new("Casualties", a => a.Casualties),
    -        new("Desertions", a => a.Desertions),
    -    });
    -    if (options.TwoPlayers)
    -    {
    -        var oneDataCol = new[] { 1 };
    -        Console.WriteLine($"Compared to the actual casualties at {battle.Name}");
    -        ConsoleUtils.WriteTable(oneDataCol, armies.Select(a => new ConsoleUtils.TableRow(
    -            a.Side.ToString(),
    -            _ => $"{(double)a.Casualties / battle.Casualties[(int)a.Side]}", After: "% of the original")
    -        ).ToList());
    -    }
    -
    -    Side winner;
    -    switch (armies[0].AllLost, armies[1].AllLost, armies[0].MenLost - armies[1].MenLost)
    -    {
    -        case (true, true, _) or (false, false, 0):
    -            Console.WriteLine("Battle outcome unresolved");
    -            winner = Side.Both; // Draw
    -            break;
    -        case (false, true, _) or (false, false, < 0):
    -            Console.WriteLine($"The Confederacy wins {battle.Name}");
    -            winner = Side.Confederate;
    -            break;
    -        case (true, false, _) or (false, false, > 0):
    -            Console.WriteLine($"The Union wins {battle.Name}");
    -            winner = Side.Union;
    -            break;
    -    }
    -    if (!isReplay)
    -    {
    -        armies.ForEach(a => a.RecordResult(winner));
    -    }
    -    Console.WriteLine("---------------");
    -    previous = battle;
    -    return true;
    -}
    -
    -void DisplayResult()
    -{
    -    armies[0].DisplayWarResult(armies[1]);
    -
    -    int battles = armies[0].BattlesFought;
    -    if (battles > 0)
    -    {
    -        Console.WriteLine($"For the {battles} battles fought (excluding reruns)");
    -
    -        ConsoleUtils.WriteTable(armies, new()
    -        {
    -            new("", a => a.Side),
    -            new("Historical Losses", a => a.CumulativeHistoricCasualties),
    -            new("Simulated Losses", a => a.CumulativeSimulatedCasualties),
    -            new("  % of original", a => ((double)a.CumulativeSimulatedCasualties / a.CumulativeHistoricCasualties).ToString("p2"))
    -        }, transpose: true);
    -
    -        armies[1].DisplayStrategies();
    -    }
    -}
    diff --git a/27_Civil_War/java/.gitignore b/27_Civil_War/java/.gitignore
    deleted file mode 100644
    index 354c7850a..000000000
    --- a/27_Civil_War/java/.gitignore
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -*.class
    -*.iml
    -.idea/
    diff --git a/27_Civil_War/java/src/CivilWar.java b/27_Civil_War/java/src/CivilWar.java
    deleted file mode 100644
    index 34819ad09..000000000
    --- a/27_Civil_War/java/src/CivilWar.java
    +++ /dev/null
    @@ -1,707 +0,0 @@
    -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;
    -import static java.util.stream.IntStream.range;
    -
    -@SuppressWarnings("SpellCheckingInspection")
    -public class CivilWar {
    -
    -    private final PrintStream out;
    -    private final List data;
    -
    -    private final BattleResults results;
    -
    -    private BattleState currentBattle;
    -    private int numGenerals;
    -    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 final ArmyPair revenue;
    -    private final ArmyPair inflation;
    -    private final ArmyPair totalExpenditure;
    -    private final ArmyPair totalTroops;
    -
    -    private boolean excessiveConfederateLosses;
    -    private boolean excessiveUnionLosses;
    -
    -    private boolean confedSurrender;
    -    private boolean unionSurrender;
    -
    -    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
    -     */
    -    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? ");
    -
    -        if (isYes(inputString(YES_NO_CHECKER, YES_NO_REMINDER))) {
    -            x.showHelp();
    -        }
    -
    -        x.gameLoop();
    -    }
    -
    -    private void gameLoop() {
    -        out.println();
    -        out.println();
    -        out.println();
    -        out.print("ARE THERE TWO GENERALS PRESENT (ANSWER YES OR NO)? ");
    -
    -        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");
    -        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)? ");
    -
    -        this.wantBattleDescriptions = isYes(inputString(YES_NO_CHECKER, YES_NO_REMINDER));
    -
    -        while (true) {
    -            var battle = startBattle();
    -            if (battle == null) {
    -                break;
    -            }
    -
    -            this.currentBattle = battle;
    -
    -            offensiveLogic(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 battleNumber = inputInt(i -> i >= 1 || (i == 0 && this.currentBattle != null), i -> "BATTLE " + i + " NOT ALLOWED.");
    -
    -        if (battleNumber == 0) {
    -            out.println(this.currentBattle.data.name + " INSTANT REPLAY");
    -            return this.currentBattle;
    -        }
    -
    -        if (battleNumber > this.data.size()) {  // TYPE ANY OTHER NUMBER TO END THE SIMULATION
    -            return null;
    -        }
    -
    -        this.battleNumber = battleNumber;
    -
    -        var battle = this.data.get(this.battleNumber - 1);
    -        var battleState = new BattleState(battle);
    -
    -
    -        excessiveConfederateLosses = false;
    -
    -        // INFLATION CALC
    -        // REM - ONLY IN PRINTOUT IS CONFED INFLATION = I1+15%
    -        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
    -        battleState.F1 = 5 * battle.troops.confederate / 6.0;
    -
    -        if (this.numGenerals == 2) {
    -            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 {
    -            resources.union.budget = 100 * (int) Math.floor(battle.troops.union * (100.0 - inflation.union) / 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         " + getConfedTroops(battle) + "          " + getUnionTroops(battle));
    -        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
    -
    -        var terminalInput = new Scanner(System.in);
    -
    -        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;
    -            }
    -
    -            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;
    -                }
    -
    -                out.print("- SALARIES.. ? ");
    -                currentResources.salaries = terminalInput.nextInt();
    -
    -                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);
    -                } else {
    -                    validInputs = true;
    -                }
    -            }
    -        }
    -
    -        out.println();
    -
    -        // Record Morale
    -        out.println(range(0, numGenerals).mapToObj(i -> moraleForArmy(battleState, i)).collect(joining(", ")));
    -
    -        out.println();
    -
    -        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();
    -
    -        ArmyResources currentResources;
    -
    -        if (this.numGenerals == 1 || armyIdx == 0) {
    -            builder.append("CONFEDERATE ");
    -            currentResources = resources.confederate;
    -        } else {
    -            builder.append("UNION ");
    -            currentResources = resources.union;
    -        }
    -
    -        // FIND MORALE
    -        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 (currentResources.morale >= 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 ? ");
    -        }
    -
    -        confedStrategy = inputInt(i -> i >= 1 && i <= 5, i -> "STRATEGY " + i + " NOT ALLOWED.");
    -        if (confedStrategy == 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(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
    -        var moraleFactor = 100 / resources.union.morale;
    -
    -        if (Math.floor(losses + moraleFactor) >= getUnionTroops(battle)) {
    -            losses = Math.floor(13.0 * getUnionTroops(battle) / 20);
    -            moraleFactor = 7 * losses / 13;
    -            excessiveUnionLosses = true;
    -        }
    -
    -        return new UnionLosses((int) losses, (int) Math.floor(moraleFactor));
    -    }
    -
    -    // 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(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;
    -
    -        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 = true;
    -        }
    -
    -        /////  2270
    -
    -        final UnionLosses unionLosses;
    -
    -        if (this.numGenerals == 1) {
    -            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(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 * (unionLosses.losses / (double) battle.data.expectedCasualties.union) + 0.5) + " % OF THE ORIGINAL");
    -
    -            out.println();
    -
    -            // REM - 1 WHO WON
    -            var winner = findWinner(C5 + E, unionLosses.losses + unionLosses.desertions);
    -            switch (winner) {
    -                case UNION -> {
    -                    out.println("THE UNION WINS " + battle.data.name);
    -                    results.union++;
    -                }
    -                case CONFED -> {
    -                    out.println("THE CONFEDERACY WINS " + battle.data.name);
    -                    results.confederate++;
    -                }
    -                case INDECISIVE -> {
    -                    out.println("BATTLE OUTCOME UNRESOLVED");
    -                    results.indeterminate++;
    -                }
    -            }
    -        } 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) {
    -                out.println("YOU LOSE " + battle.data.name);
    -
    -                if (this.battleNumber != 0) {
    -                    results.union++;
    -                }
    -            } else {
    -                out.println("YOU WIN " + battle.data.name);
    -                // CUMULATIVE BATTLE FACTORS WHICH ALTER HISTORICAL RESOURCES AVAILABLE.IF A REPLAY DON'T UPDATE.
    -                results.confederate++;
    -            }
    -        }
    -
    -        if (this.battleNumber != 0) {
    -            totalCasualties.confederate += (int) (C5 + E);
    -            totalCasualties.union += unionLosses.losses + unionLosses.desertions;
    -            totalExpectedCasualties.confederate += battle.data.expectedCasualties.confederate;
    -            totalExpectedCasualties.union += battle.data.expectedCasualties.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.confedStrategy);
    -        }
    -    }
    -
    -    // 2790
    -    private void reset() {
    -        excessiveConfederateLosses = excessiveUnionLosses = false;
    -
    -        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 " + results.confederate + " BATTLES AND LOST " + results.union);
    -
    -        if (this.unionStrategy == 5) {
    -            out.println("THE CONFEDERACY HAS WON THE WAR");
    -        }
    -
    -        if (this.confedStrategy == 5 || results.confederate <= results.union) {
    -            out.println("THE UNION HAS WON THE WAR");
    -        }
    -
    -        out.println();
    -
    -        // FIXME 2960  IF R1=0 THEN 3100
    -
    -        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));
    -        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 && this.excessiveUnionLosses) {
    -            return Winner.INDECISIVE;
    -        }
    -
    -        if (this.excessiveConfederateLosses) {
    -            return Winner.UNION;
    -        }
    -
    -        if (this.excessiveUnionLosses || 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() {
    -        // 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);
    -            unionStrategy = terminalInput.nextInt();
    -            if (unionStrategy < 0) {
    -                out.println("ENTER 1, 2, 3, OR 4 (USUALLY PREVIOUS UNION STRATEGY)");
    -                // FIXME Retry Y2 input !!!
    -            }
    -
    -            if (unionStrategy < 5) {  // 3155
    -                return;
    -            }
    -        }
    -
    -        var S0 = 0;
    -        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) {
    -                break;
    -            }
    -        }
    -        // IF ACTUAL STRAT. IN,THEN HERE IS Y2= HIST. STRAT.
    -        out.println("UNION STRATEGY IS " + unionStrategy);
    -    }
    -
    -    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);
    -        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};
    -
    -        // 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 String inputString(Predicate validator, String reminder) {
    -        while (true) {
    -            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;
    -        }
    -        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;
    -
    -        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 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;
    -        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) {
    -    }
    -
    -    private record UnionLosses(int losses, int desertions) {
    -    }
    -}
    diff --git a/27_Civil_War/javascript/civilwar.html b/27_Civil_War/javascript/civilwar.html
    index c01b60e44..dcff69ff8 100644
    --- a/27_Civil_War/javascript/civilwar.html
    +++ b/27_Civil_War/javascript/civilwar.html
    @@ -1,10 +1,9 @@
     
     
     CIVIL WAR
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/27_Civil_War/javascript/civilwar.js b/27_Civil_War/javascript/civilwar.js
    index f783bb17c..c16306214 100644
    --- a/27_Civil_War/javascript/civilwar.js
    +++ b/27_Civil_War/javascript/civilwar.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/27_Civil_War/kotlin/README.md b/27_Civil_War/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/27_Civil_War/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/27_Civil_War/lua/README.md b/27_Civil_War/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/27_Civil_War/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/27_Civil_War/pascal/README.md b/27_Civil_War/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/27_Civil_War/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/27_Civil_War/python/Civilwar.py b/27_Civil_War/python/Civilwar.py
    deleted file mode 100644
    index 309a35172..000000000
    --- a/27_Civil_War/python/Civilwar.py
    +++ /dev/null
    @@ -1,582 +0,0 @@
    -"""
    -Original game design: Cram, Goodie, Hibbard Lexington H.S.
    -Modifications: G. Paul, R. Hess (Ties), 1973
    -"""
    -import enum
    -import math
    -import random
    -from dataclasses import dataclass
    -from typing import Dict, List, Literal, Tuple
    -
    -
    -class AttackState(enum.Enum):
    -    DEFENSIVE = 1
    -    BOTH_OFFENSIVE = 2
    -    OFFENSIVE = 3
    -
    -
    -CONF = 1
    -UNION = 2
    -
    -
    -@dataclass
    -class PlayerStat:
    -    food: float = 0
    -    salaries: float = 0
    -    ammunition: float = 0
    -
    -    desertions: float = 0
    -    casualties: float = 0
    -    morale: float = 0
    -    strategy: int = 0
    -    available_men: int = 0
    -    available_money: int = 0
    -
    -    army_c: float = 0
    -    army_m: float = 0  # available_men ????
    -    inflation: float = 0
    -
    -    r: float = 0
    -    t: float = 0  # casualties + desertions
    -    q: float = 0  # accumulated cost?
    -    p: float = 0
    -    m: float = 0
    -
    -    is_player = False
    -    excessive_losses = False
    -
    -    def set_available_money(self):
    -        factor = 1 + (self.r - self.q) / (self.r + 1) if self.is_player else 1
    -        self.available_money = 100 * math.floor(
    -            (self.army_m * (100 - self.inflation) / 2000) * factor + 0.5
    -        )
    -
    -    def get_cost(self) -> float:
    -        return self.food + self.salaries + self.ammunition
    -
    -    def get_army_factor(self) -> float:
    -        return 1 + (self.p - self.t) / (self.m + 1)
    -
    -    def get_present_men(self) -> float:
    -        return self.army_m * self.get_army_factor()
    -
    -
    -def simulate_losses(player1: PlayerStat, player2: PlayerStat) -> float:
    -    """Simulate losses of player 1"""
    -    tmp = (2 * player1.army_c / 5) * (
    -        1 + 1 / (2 * (abs(player1.strategy - player2.strategy) + 1))
    -    )
    -    tmp = tmp * (1.28 + (5 * player1.army_m / 6) / (player1.ammunition + 1))
    -    return math.floor(tmp * (1 + 1 / player1.morale) + 0.5)
    -
    -
    -def update_army(player: PlayerStat, enemy: PlayerStat, use_factor=False) -> None:
    -    player.casualties = simulate_losses(player, enemy)
    -    player.desertions = 100 / player.morale
    -
    -    loss = player.casualties + player.desertions
    -    if not use_factor:
    -        present_men: float = player.available_men
    -    else:
    -        present_men = player.get_present_men()
    -    if loss >= present_men:
    -        factor = player.get_army_factor()
    -        if not use_factor:
    -            factor = 1
    -        player.casualties = math.floor(13 * player.army_m / 20 * factor)
    -        player.desertions = 7 * player.casualties / 13
    -        player.excessive_losses = True
    -
    -
    -def get_choice(prompt: str, choices: List[str]) -> str:
    -    while True:
    -        choice = input(prompt)
    -        if choice in choices:
    -            break
    -    return choice
    -
    -
    -def get_morale(stat: PlayerStat, enemy: PlayerStat) -> float:
    -    """Higher is better"""
    -    enemy_strength = 5 * enemy.army_m / 6
    -    return (2 * math.pow(stat.food, 2) + math.pow(stat.salaries, 2)) / math.pow(
    -        enemy_strength, 2
    -    ) + 1
    -
    -
    -def main() -> None:
    -    battles = [
    -        [
    -            "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.",
    -        ],
    -        [
    -            "APRIL 6-7, 1862.  THE CONFEDERATE SURPRISE ATTACK AT",
    -            "SHILOH FAILED DUE TO POOR ORGANIZATION.",
    -        ],
    -        [
    -            "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.",
    -        ],
    -        [
    -            "AUG 29-30, 1862.  THE COMBINED CONFEDERATE FORCES UNDER LEE",
    -            "AND JACKSON DROVE THE UNION FORCES BACK INTO WASHINGTON.",
    -        ],
    -        [
    -            "SEPT 17, 1862.  THE SOUTH FAILED TO INCORPORATE MARYLAND",
    -            "INTO THE CONFEDERACY.",
    -        ],
    -        [
    -            "DEC 13, 1862.  THE CONFEDERACY UNDER LEE SUCCESSFULLY",
    -            "REPULSED AN ATTACK BY THE UNION UNDER GEN. BURNSIDE.",
    -        ],
    -        ["DEC 31, 1862.  THE SOUTH UNDER GEN. BRAGG WON A CLOSE BATTLE."],
    -        [
    -            "MAY 1-6, 1863.  THE SOUTH HAD A COSTLY VICTORY AND LOST",
    -            "ONE OF THEIR OUTSTANDING GENERALS, 'STONEWALL' JACKSON.",
    -        ],
    -        [
    -            "JULY 4, 1863.  VICKSBURG WAS A COSTLY DEFEAT FOR THE SOUTH",
    -            "BECAUSE IT GAVE THE UNION ACCESS TO THE MISSISSIPPI.",
    -        ],
    -        [
    -            "JULY 1-3, 1863.  A SOUTHERN MISTAKE BY GEN. LEE AT GETTYSBURG",
    -            "COST THEM ONE OF THE MOST CRUCIAL BATTLES OF THE WAR.",
    -        ],
    -        [
    -            "SEPT. 15, 1863. CONFUSION IN A FOREST NEAR CHICKAMAUGA LED",
    -            "TO A COSTLY SOUTHERN VICTORY.",
    -        ],
    -        [
    -            "NOV. 25, 1863. AFTER THE SOUTH HAD SIEGED GEN. ROSENCRANS'",
    -            "ARMY FOR THREE MONTHS, GEN. GRANT BROKE THE SIEGE.",
    -        ],
    -        [
    -            "MAY 5, 1864.  GRANT'S PLAN TO KEEP LEE ISOLATED BEGAN TO",
    -            "FAIL HERE, AND CONTINUED AT COLD HARBOR AND PETERSBURG.",
    -        ],
    -        [
    -            "AUGUST, 1864.  SHERMAN AND THREE VETERAN ARMIES CONVERGED",
    -            "ON ATLANTA AND DEALT THE DEATH BLOW TO THE CONFEDERACY.",
    -        ],
    -    ]
    -
    -    historical_data: List[Tuple[str, float, float, float, int, AttackState]] = [
    -        ("", 0, 0, 0, 0, AttackState.DEFENSIVE),
    -        ("BULL RUN", 18000, 18500, 1967, 2708, AttackState.DEFENSIVE),
    -        ("SHILOH", 40000.0, 44894.0, 10699, 13047, AttackState.OFFENSIVE),
    -        ("SEVEN DAYS", 95000.0, 115000.0, 20614, 15849, AttackState.OFFENSIVE),
    -        ("SECOND BULL RUN", 54000.0, 63000.0, 10000, 14000, AttackState.BOTH_OFFENSIVE),
    -        ("ANTIETAM", 40000.0, 50000.0, 10000, 12000, AttackState.OFFENSIVE),
    -        ("FREDERICKSBURG", 75000.0, 120000.0, 5377, 12653, AttackState.DEFENSIVE),
    -        ("MURFREESBORO", 38000.0, 45000.0, 11000, 12000, AttackState.DEFENSIVE),
    -        ("CHANCELLORSVILLE", 32000, 90000.0, 13000, 17197, AttackState.BOTH_OFFENSIVE),
    -        ("VICKSBURG", 50000.0, 70000.0, 12000, 19000, AttackState.DEFENSIVE),
    -        ("GETTYSBURG", 72500.0, 85000.0, 20000, 23000, AttackState.OFFENSIVE),
    -        ("CHICKAMAUGA", 66000.0, 60000.0, 18000, 16000, AttackState.BOTH_OFFENSIVE),
    -        ("CHATTANOOGA", 37000.0, 60000.0, 36700.0, 5800, AttackState.BOTH_OFFENSIVE),
    -        ("SPOTSYLVANIA", 62000.0, 110000.0, 17723, 18000, AttackState.BOTH_OFFENSIVE),
    -        ("ATLANTA", 65000.0, 100000.0, 8500, 3700, AttackState.DEFENSIVE),
    -    ]
    -    confederate_strategy_prob_distribution = {}
    -
    -    # What do you spend money on?
    -    stats: Dict[int, PlayerStat] = {
    -        CONF: PlayerStat(),
    -        UNION: PlayerStat(),
    -    }
    -
    -    print(" " * 26 + "CIVIL WAR")
    -    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n")
    -
    -    # Union info on likely confederate strategy
    -    confederate_strategy_prob_distribution[1] = 25
    -    confederate_strategy_prob_distribution[2] = 25
    -    confederate_strategy_prob_distribution[3] = 25
    -    confederate_strategy_prob_distribution[4] = 25
    -    print()
    -    show_instructions = get_choice(
    -        "DO YOU WANT INSTRUCTIONS? YES OR NO -- ", ["YES", "NO"]
    -    )
    -
    -    if show_instructions == "YES":
    -        print()
    -        print()
    -        print()
    -        print()
    -        print("THIS IS A CIVIL WAR SIMULATION.")
    -        print("TO PLAY TYPE A RESPONSE WHEN THE COMPUTER ASKS.")
    -        print("REMEMBER THAT ALL FACTORS ARE INTERRELATED AND THAT YOUR")
    -        print("RESPONSES COULD CHANGE HISTORY. FACTS AND FIGURES USED ARE")
    -        print("BASED ON THE ACTUAL OCCURRENCE. MOST BATTLES TEND TO RESULT")
    -        print("AS THEY DID IN THE CIVIL WAR, BUT IT ALL DEPENDS ON YOU!!")
    -        print()
    -        print("THE OBJECT OF THE GAME IS TO WIN AS MANY BATTLES AS ")
    -        print("POSSIBLE.")
    -        print()
    -        print("YOUR CHOICES FOR DEFENSIVE STRATEGY ARE:")
    -        print("        (1) ARTILLERY ATTACK")
    -        print("        (2) FORTIFICATION AGAINST FRONTAL ATTACK")
    -        print("        (3) FORTIFICATION AGAINST FLANKING MANEUVERS")
    -        print("        (4) FALLING BACK")
    -        print(" YOUR CHOICES FOR OFFENSIVE STRATEGY ARE:")
    -        print("        (1) ARTILLERY ATTACK")
    -        print("        (2) FRONTAL ATTACK")
    -        print("        (3) FLANKING MANEUVERS")
    -        print("        (4) ENCIRCLEMENT")
    -        print("YOU MAY SURRENDER BY TYPING A '5' FOR YOUR STRATEGY.")
    -
    -    print()
    -    print()
    -    print()
    -    print("ARE THERE TWO GENERALS PRESENT ", end="")
    -    two_generals = get_choice("(ANSWER YES OR NO) ", ["YES", "NO"]) == "YES"
    -    stats[CONF].is_player = True
    -    if two_generals:
    -        party: Literal[1, 2] = 2  # number of players in the game
    -        stats[UNION].is_player = True
    -    else:
    -        party = 1
    -        print()
    -        print("YOU ARE THE CONFEDERACY.   GOOD LUCK!")
    -        print()
    -
    -    print("SELECT A BATTLE BY TYPING A NUMBER FROM 1 TO 14 ON")
    -    print("REQUEST.  TYPE ANY OTHER NUMBER TO END THE SIMULATION.")
    -    print("BUT '0' BRINGS BACK EXACT PREVIOUS BATTLE SITUATION")
    -    print("ALLOWING YOU TO REPLAY IT")
    -    print()
    -    print("NOTE: A NEGATIVE FOOD$ ENTRY CAUSES THE PROGRAM TO ")
    -    print("USE THE ENTRIES FROM THE PREVIOUS BATTLE")
    -    print()
    -    print("AFTER REQUESTING A BATTLE, DO YOU WISH ", end="")
    -    print("BATTLE DESCRIPTIONS ", end="")
    -    xs = get_choice("(ANSWER YES OR NO) ", ["YES", "NO"])
    -    confederacy_lost = 0
    -    confederacy_win = 0
    -    for i in [CONF, UNION]:
    -        stats[i].p = 0
    -        stats[i].m = 0
    -        stats[i].t = 0
    -        stats[i].available_money = 0
    -        stats[i].food = 0
    -        stats[i].salaries = 0
    -        stats[i].ammunition = 0
    -        stats[i].strategy = 0
    -        stats[i].excessive_losses = False
    -    confederacy_unresolved = 0
    -    random_nb: float = 0
    -    while True:
    -        print()
    -        print()
    -        print()
    -        simulated_battle_index = int(
    -            get_choice(
    -                "WHICH BATTLE DO YOU WISH TO SIMULATE? (0-14) ",
    -                [str(i) for i in range(15)],
    -            )
    -        )
    -        if simulated_battle_index < 1 or simulated_battle_index > 14:
    -            break
    -        if simulated_battle_index != 0 or random_nb == 0:
    -            loaded_battle = historical_data[simulated_battle_index]
    -            battle_name = loaded_battle[0]
    -            stats[CONF].army_m = loaded_battle[1]
    -            stats[UNION].army_m = loaded_battle[2]
    -            stats[CONF].army_c = loaded_battle[3]
    -            stats[UNION].army_c = loaded_battle[4]
    -            stats[CONF].excessive_losses = False
    -
    -            # Inflation calc
    -            stats[CONF].inflation = 10 + (confederacy_lost - confederacy_win) * 2
    -            stats[UNION].inflation = 10 + (confederacy_win - confederacy_lost) * 2
    -
    -            # Money and Men available
    -            for i in [CONF, UNION]:
    -                stats[i].set_available_money()
    -                stats[i].available_men = math.floor(stats[i].get_army_factor())
    -            print()
    -            print()
    -            print()
    -            print()
    -            print()
    -            print(f"THIS IS THE BATTLE OF {battle_name}")
    -            if xs != "NO":
    -                print("\n".join(battles[simulated_battle_index - 1]))
    -
    -        else:
    -            print(f"{battle_name} INSTANT REPLAY")
    -
    -        print()
    -        print("          CONFEDERACY\t UNION")
    -        print(f"MEN       {stats[CONF].available_men}\t\t {stats[UNION].available_men}")
    -        print(
    -            f"MONEY    ${stats[CONF].available_money}\t${stats[UNION].available_money}"
    -        )
    -        print(f"INFLATION {stats[CONF].inflation + 15}%\t\t {stats[UNION].inflation}%")
    -        print()
    -        # ONLY IN PRINTOUT IS CONFED INFLATION = I1 + 15 %
    -        # IF TWO GENERALS, INPUT CONFED, FIRST
    -        for player_index in range(1, party + 1):
    -            if two_generals and player_index == 1:
    -                print("CONFEDERATE GENERAL---", end="")
    -            print("HOW MUCH DO YOU WISH TO SPEND FOR")
    -            while True:
    -                food_input = int(input(" - FOOD...... ? "))
    -                if food_input < 0:
    -                    if stats[CONF].r == 0:
    -                        print("NO PREVIOUS ENTRIES")
    -                        continue
    -                    print("ASSUME YOU WANT TO KEEP SAME ALLOCATIONS")
    -                    print()
    -                    break
    -                stats[player_index].food = food_input
    -                while True:
    -                    stats[player_index].salaries = int(input(" - SALARIES.. ? "))
    -                    if stats[player_index].salaries >= 0:
    -                        break
    -                    print("NEGATIVE VALUES NOT ALLOWED.")
    -                while True:
    -                    stats[player_index].ammunition = int(input(" - AMMUNITION ? "))
    -                    if stats[player_index].ammunition >= 0:
    -                        break
    -                    print("NEGATIVE VALUES NOT ALLOWED.")
    -                print()
    -                if stats[player_index].get_cost() > stats[player_index].available_money:
    -                    print(
    -                        f"THINK AGAIN! YOU HAVE ONLY ${stats[player_index].available_money}"
    -                    )
    -                else:
    -                    break
    -
    -            if not two_generals or player_index == 2:
    -                break
    -            print("UNION GENERAL---", end="")
    -
    -        for player_index in range(1, party + 1):
    -            if two_generals:
    -                if player_index == 1:
    -                    print("CONFEDERATE ", end="")
    -                else:
    -                    print("      UNION ", end="")
    -            morale = get_morale(stats[player_index], stats[1 + player_index % 2])
    -
    -            if morale >= 10:
    -                print("MORALE IS HIGH")
    -            elif morale >= 5:
    -                print("MORALE IS FAIR")
    -            else:
    -                print("MORALE IS POOR")
    -            if not two_generals:
    -                break
    -            stats[player_index].morale = morale  # type: ignore
    -
    -        stats[UNION].morale = get_morale(stats[UNION], stats[CONF])
    -        stats[CONF].morale = get_morale(stats[CONF], stats[UNION])
    -        print("CONFEDERATE GENERAL---")
    -        # Actual off/def battle situation
    -        if loaded_battle[5] == AttackState.OFFENSIVE:
    -            print("YOU ARE ON THE OFFENSIVE")
    -        elif loaded_battle[5] == AttackState.DEFENSIVE:
    -            print("YOU ARE ON THE DEFENSIVE")
    -        else:
    -            print("BOTH SIDES ARE ON THE OFFENSIVE")
    -
    -        print()
    -        # Choose strategies
    -        if not two_generals:
    -            while True:
    -                stats[CONF].strategy = int(input("YOUR STRATEGY "))
    -                if abs(stats[CONF].strategy - 3) < 3:
    -                    break
    -                print(f"STRATEGY {stats[CONF].strategy} NOT ALLOWED.")
    -            if stats[CONF].strategy == 5:
    -                print("THE CONFEDERACY HAS SURRENDERED.")
    -                break
    -            # Union strategy is computer chosen
    -            if simulated_battle_index == 0:
    -                while True:
    -                    stats[UNION].strategy = int(input("UNION STRATEGY IS "))
    -                    if stats[UNION].strategy > 0 and stats[UNION].strategy < 5:
    -                        break
    -                    print("ENTER 1, 2, 3, OR 4 (USUALLY PREVIOUS UNION STRATEGY)")
    -            else:
    -                s0 = 0
    -                random_nb = random.random() * 100
    -                for player_index in range(1, 5):
    -                    s0 += confederate_strategy_prob_distribution[player_index]
    -                    # If actual strategy info is in program data statements
    -                    # then r-100 is extra weight given to that strategy.
    -                    if random_nb < s0:
    -                        break
    -                stats[UNION].strategy = player_index
    -                print(stats[UNION].strategy)
    -        else:
    -            for player_index in [1, 2]:
    -                if player_index == 1:
    -                    print("CONFEDERATE STRATEGY ? ", end="")
    -                while True:
    -                    stats[CONF].strategy = int(input())
    -                    if abs(stats[CONF].strategy - 3) < 3:
    -                        break
    -                    print(f"STRATEGY {stats[CONF].strategy} NOT ALLOWED.")
    -                    print("YOUR STRATEGY ? ", end="")
    -                if player_index == 2:
    -                    stats[UNION].strategy = stats[CONF].strategy
    -                    stats[CONF].strategy = previous_strategy  # type: ignore # noqa: F821
    -                    if stats[UNION].strategy != 5:
    -                        break
    -                else:
    -                    previous_strategy = stats[CONF].strategy  # noqa: F841
    -                print("UNION STRATEGY ? ", end="")
    -
    -            update_army(stats[UNION], stats[CONF], use_factor=False)
    -
    -        # Calculate simulated losses
    -        print()
    -        print()
    -        print()
    -        print("\t\tCONFEDERACY\tUNION")
    -        update_army(stats[CONF], stats[UNION], use_factor=True)
    -
    -        if party == 1:
    -            stats[UNION].casualties = math.floor(
    -                17
    -                * stats[UNION].army_c
    -                * stats[CONF].army_c
    -                / (stats[CONF].casualties * 20)
    -            )
    -            stats[CONF].desertions = 5 * morale
    -
    -        print(
    -            "CASUALTIES\t"
    -            + str(stats[CONF].casualties)
    -            + "\t\t"
    -            + str(stats[UNION].casualties)
    -        )
    -        print(
    -            "DESERTIONS\t"
    -            + str(math.floor(stats[CONF].desertions))
    -            + "\t\t"
    -            + str(math.floor(stats[UNION].desertions))
    -        )
    -        print()
    -        if two_generals:
    -            print("COMPARED TO THE ACTUAL CASUALTIES AT " + str(battle_name))
    -            print(
    -                "CONFEDERATE: "
    -                + str(
    -                    math.floor(
    -                        100 * (stats[CONF].casualties / stats[CONF].army_c) + 0.5
    -                    )
    -                )
    -                + "% OF THE ORIGINAL"
    -            )
    -            print(
    -                "UNION:       "
    -                + str(
    -                    math.floor(
    -                        100 * (stats[UNION].casualties / stats[UNION].army_c) + 0.5
    -                    )
    -                )
    -                + "% OF THE ORIGINAL"
    -            )
    -
    -        print()
    -        # Find who won
    -        if (
    -            stats[CONF].excessive_losses
    -            and stats[UNION].excessive_losses
    -            or (
    -                not stats[CONF].excessive_losses
    -                and not stats[UNION].excessive_losses
    -                and stats[CONF].casualties + stats[CONF].desertions
    -                == stats[UNION].casualties + stats[CONF].desertions
    -            )
    -        ):
    -            print("BATTLE OUTCOME UNRESOLVED")
    -            confederacy_unresolved += 1
    -        elif stats[CONF].excessive_losses or (
    -            not stats[CONF].excessive_losses
    -            and not stats[UNION].excessive_losses
    -            and stats[CONF].casualties + stats[CONF].desertions
    -            > stats[UNION].casualties + stats[CONF].desertions
    -        ):
    -            print(f"THE UNION WINS {battle_name}")
    -            if simulated_battle_index != 0:
    -                confederacy_lost += 1
    -        else:
    -            print(f"THE CONFEDERACY WINS {battle_name}")
    -            if simulated_battle_index != 0:
    -                confederacy_win += 1
    -
    -        # Lines 2530 to 2590 from original are unreachable.
    -        if simulated_battle_index != 0:
    -            for i in [CONF, UNION]:
    -                stats[i].t += stats[i].casualties + stats[i].desertions
    -                stats[i].p += stats[i].army_c
    -                stats[i].q += stats[i].get_cost()
    -                stats[i].r += stats[i].army_m * (100 - stats[i].inflation) / 20
    -                stats[i].m += stats[i].army_m
    -            # Learn present strategy, start forgetting old ones
    -            # present strategy of south gains 3*s, others lose s
    -            # probability points, unless a strategy falls below 5 % .
    -            s = 3
    -            s0 = 0
    -            for player_index in range(1, 5):
    -                if confederate_strategy_prob_distribution[player_index] <= 5:
    -                    continue
    -                confederate_strategy_prob_distribution[player_index] -= 5
    -                s0 += s
    -            confederate_strategy_prob_distribution[stats[CONF].strategy] += s0
    -
    -        stats[CONF].excessive_losses = False
    -        stats[UNION].excessive_losses = False
    -        print("---------------")
    -        continue
    -
    -    print()
    -    print()
    -    print()
    -    print()
    -    print()
    -    print()
    -    print(
    -        f"THE CONFEDERACY HAS WON {confederacy_win} BATTLES AND LOST {confederacy_lost}"
    -    )
    -    if stats[CONF].strategy == 5 or (
    -        stats[UNION].strategy != 5 and confederacy_win <= confederacy_lost
    -    ):
    -        print("THE UNION HAS WON THE WAR")
    -    else:
    -        print("THE CONFEDERACY HAS WON THE WAR")
    -    print()
    -    if stats[CONF].r > 0:
    -        print(
    -            f"FOR THE {confederacy_win + confederacy_lost + confederacy_unresolved} BATTLES FOUGHT (EXCLUDING RERUNS)"
    -        )
    -        print(" \t \t ")
    -        print("CONFEDERACY\t UNION")
    -        print(
    -            f"HISTORICAL LOSSES\t{math.floor(stats[CONF].p + 0.5)}\t{math.floor(stats[UNION].p + 0.5)}"
    -        )
    -        print(
    -            f"SIMULATED LOSSES\t{math.floor(stats[CONF].t + 0.5)}\t{math.floor(stats[UNION].t + 0.5)}"
    -        )
    -        print()
    -        print(
    -            f"    % OF ORIGINAL\t{math.floor(100 * (stats[CONF].t / stats[CONF].p) + 0.5)}\t{math.floor(100 * (stats[UNION].t / stats[UNION].p) + 0.5)}"
    -        )
    -        if not two_generals:
    -            print()
    -            print("UNION INTELLIGENCE SUGGEST THAT THE SOUTH USED")
    -            print("STRATEGIES 1, 2, 3, 4 IN THE FOLLOWING PERCENTAGES")
    -            print(
    -                f"{confederate_strategy_prob_distribution[CONF]} {confederate_strategy_prob_distribution[UNION]} {confederate_strategy_prob_distribution[3]} {confederate_strategy_prob_distribution[4]}"
    -            )
    -
    -
    -if __name__ == "__main__":
    -    main()
    diff --git a/27_Civil_War/vbnet/CivilWar.sln b/27_Civil_War/vbnet/CivilWar.sln
    deleted file mode 100644
    index 3f696f6ff..000000000
    --- a/27_Civil_War/vbnet/CivilWar.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index d132bbbce..000000000
    --- a/27_Civil_War/vbnet/CivilWar.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    CivilWar
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/28_Combat/README.md b/28_Combat/README.md
    index e4463ab23..32b2af65c 100644
    --- a/28_Combat/README.md
    +++ b/28_Combat/README.md
    @@ -14,12 +14,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Known Bugs
    -
    -- The original game misspells "unguarded" on line 1751.
    -- In an initial army attack, the program claims that the computer loses 2/3 of its army, but it actually loses its entire army (lines 150-155).
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/28_Combat/combat.bas b/28_Combat/combat.bas
    index c5fdf9b3e..a42934981 100644
    --- a/28_Combat/combat.bas
    +++ b/28_Combat/combat.bas
    @@ -31,7 +31,7 @@
     150 PRINT "YOU LOST";INT(X/3);"MEN, BUT I LOST ";INT(2*D/3)
     155 A=INT(A-X/3)
     160 D=0
    -165 GOTO 500
    +165 GOTO 500 
     200 IF X>B THEN 20
     210 IF XB THEN 1030
    +1700 IF T>B THEN 1030 
     1710 IF TC THEN 1030
    -1810 IF T>F/2 THEN 1830
    +1800 IF T>C THEN 1030 
    +1810 IF T>F/2 THEN 1830 
     1820 GOTO 1850
     1830 PRINT "MY NAVY AND AIR FORCE IN A COMBINED ATTACK LEFT"
     1831 PRINT "YOUR COUNTRY IN SHAMBLES."
    diff --git a/28_Combat/csharp/Combat.sln b/28_Combat/csharp/Combat.sln
    index 992333163..522b680ef 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}") = "Combat", "Combat.csproj", "{F7CEEC00-CF2C-436C-883B-55A20C21AB93}"
    +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Game", "Game.csproj", "{054A1718-1B7D-4954-81A7-EEA390713439}"
     EndProject
     Global
     	GlobalSection(SolutionConfigurationPlatforms) = preSolution
    @@ -11,10 +11,10 @@ Global
     		Release|Any CPU = Release|Any CPU
     	EndGlobalSection
     	GlobalSection(ProjectConfigurationPlatforms) = postSolution
    -		{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
    +		{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
     	EndGlobalSection
     	GlobalSection(SolutionProperties) = preSolution
     		HideSolutionNode = FALSE
    diff --git a/28_Combat/csharp/Combat.csproj b/28_Combat/csharp/Game.csproj
    similarity index 100%
    rename from 28_Combat/csharp/Combat.csproj
    rename to 28_Combat/csharp/Game.csproj
    diff --git a/28_Combat/csharp/ArmedForces.cs b/28_Combat/csharp/src/ArmedForces.cs
    similarity index 100%
    rename from 28_Combat/csharp/ArmedForces.cs
    rename to 28_Combat/csharp/src/ArmedForces.cs
    diff --git a/28_Combat/csharp/Ceasefire.cs b/28_Combat/csharp/src/Ceasefire.cs
    similarity index 100%
    rename from 28_Combat/csharp/Ceasefire.cs
    rename to 28_Combat/csharp/src/Ceasefire.cs
    diff --git a/28_Combat/csharp/Controller.cs b/28_Combat/csharp/src/Controller.cs
    similarity index 100%
    rename from 28_Combat/csharp/Controller.cs
    rename to 28_Combat/csharp/src/Controller.cs
    diff --git a/28_Combat/csharp/FinalCampaign.cs b/28_Combat/csharp/src/FinalCampaign.cs
    similarity index 100%
    rename from 28_Combat/csharp/FinalCampaign.cs
    rename to 28_Combat/csharp/src/FinalCampaign.cs
    diff --git a/28_Combat/csharp/InitialCampaign.cs b/28_Combat/csharp/src/InitialCampaign.cs
    similarity index 100%
    rename from 28_Combat/csharp/InitialCampaign.cs
    rename to 28_Combat/csharp/src/InitialCampaign.cs
    diff --git a/28_Combat/csharp/MilitaryBranch.cs b/28_Combat/csharp/src/MilitaryBranch.cs
    similarity index 100%
    rename from 28_Combat/csharp/MilitaryBranch.cs
    rename to 28_Combat/csharp/src/MilitaryBranch.cs
    diff --git a/28_Combat/csharp/Program.cs b/28_Combat/csharp/src/Program.cs
    similarity index 100%
    rename from 28_Combat/csharp/Program.cs
    rename to 28_Combat/csharp/src/Program.cs
    diff --git a/28_Combat/csharp/View.cs b/28_Combat/csharp/src/View.cs
    similarity index 100%
    rename from 28_Combat/csharp/View.cs
    rename to 28_Combat/csharp/src/View.cs
    diff --git a/28_Combat/csharp/WarResult.cs b/28_Combat/csharp/src/WarResult.cs
    similarity index 100%
    rename from 28_Combat/csharp/WarResult.cs
    rename to 28_Combat/csharp/src/WarResult.cs
    diff --git a/28_Combat/csharp/WarState.cs b/28_Combat/csharp/src/WarState.cs
    similarity index 100%
    rename from 28_Combat/csharp/WarState.cs
    rename to 28_Combat/csharp/src/WarState.cs
    diff --git a/28_Combat/java/Combat.java b/28_Combat/java/Combat.java
    index e77f9ec64..11b4ae42e 100644
    --- a/28_Combat/java/Combat.java
    +++ b/28_Combat/java/Combat.java
    @@ -9,52 +9,52 @@
      * 

    * Note: The idea was to create a version of the 1970's BASIC game in Java, without introducing * new features - no additional text, error checking, etc has been added. - * + * * Converted from BASIC to Java by Darren Cardenas. */ public class Combat { - + private static final int MAX_UNITS = 72000; // Maximum number of total units per player - + private final Scanner scan; // For user input private boolean planeCrashWin = false; - + private int usrArmy = 0; // Number of user Army units private int usrNavy = 0; // Number of user Navy units private int usrAir = 0; // Number of user Air Force units private int cpuArmy = 30000; // Number of cpu Army units private int cpuNavy = 20000; // Number of cpu Navy units private int cpuAir = 22000; // Number of cpu Air Force units - + public Combat() { - - scan = new Scanner(System.in); - - } // End of constructor Combat - + + scan = new Scanner(System.in); + + } // End of constructor Combat + public void play() { - + showIntro(); getForces(); attackFirst(); attackSecond(); - - } // End of method play - + + } // End of method play + private static void showIntro() { - + System.out.println(" ".repeat(32) + "COMBAT"); System.out.println(" ".repeat(14) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); System.out.println("\n\n"); System.out.println("I AM AT WAR WITH YOU."); System.out.println("WE HAVE " + MAX_UNITS + " SOLDIERS APIECE.\n"); - - } // End of method showIntro - + + } // End of method showIntro + private void getForces() { - + do { System.out.println("DISTRIBUTE YOUR FORCES."); System.out.println(" ME YOU"); @@ -63,24 +63,24 @@ private void getForces() { System.out.print("NAVY " + cpuNavy + " ? "); usrNavy = scan.nextInt(); System.out.print("A. F. " + cpuAir + " ? "); - usrAir = scan.nextInt(); - + usrAir = scan.nextInt(); + } while ((usrArmy + usrNavy + usrAir) > MAX_UNITS); // Avoid exceeding the maximum number of total units - - } // End of method getForces - + + } // End of method getForces + private void attackFirst() { - + int numUnits = 0; - int unitType = 0; - + int unitType = 0; + do { System.out.println("YOU ATTACK FIRST. TYPE (1) FOR ARMY; (2) FOR NAVY;"); System.out.println("AND (3) FOR AIR FORCE."); System.out.print("? "); unitType = scan.nextInt(); } while ((unitType < 1) || (unitType > 3)); // Avoid out-of-range values - + do { System.out.println("HOW MANY MEN"); System.out.print("? "); @@ -93,15 +93,15 @@ private void attackFirst() { // Begin handling deployment type switch (unitType) { case 1: // Army deployed - + if (numUnits < (usrArmy / 3.0)) { // User deployed less than one-third of their Army units System.out.println("YOU LOST " + numUnits + " MEN FROM YOUR ARMY."); - usrArmy = usrArmy - numUnits; + usrArmy = usrArmy - numUnits; } else if (numUnits < (2.0 * usrArmy / 3.0)) { // User deployed less than two-thirds of their Army units System.out.println("YOU LOST " + (int) Math.floor(numUnits / 3.0) + " MEN, BUT I LOST " + (int) Math.floor(2.0 * cpuArmy / 3.0)); usrArmy = (int) Math.floor(usrArmy - numUnits / 3.0); - cpuArmy = 0; + cpuArmy = 0; } else { // User deployed two-thirds or more of their Army units System.out.println("YOU SUNK ONE OF MY PATROL BOATS, BUT I WIPED OUT TWO"); @@ -109,34 +109,34 @@ else if (numUnits < (2.0 * usrArmy / 3.0)) { // User deployed less than two-thi usrArmy = (int) Math.floor(usrArmy / 3.0); usrAir = (int) Math.floor(usrAir / 3.0); cpuNavy = (int) Math.floor(2.0 * cpuNavy / 3.0); - } + } break; - + case 2: // Navy deployed - + if (numUnits < (cpuNavy / 3.0)) { // User deployed less than one-third relative to cpu Navy units System.out.println("YOUR ATTACK WAS STOPPED!"); - usrNavy = usrNavy - numUnits; - } + usrNavy = usrNavy - numUnits; + } else if (numUnits < (2.0 * cpuNavy / 3.0)) { // User deployed less than two-thirds relative to cpu Navy units - System.out.println("YOU DESTROYED " + (int) Math.floor(2.0 * cpuNavy / 3.0) + " OF MY ARMY."); + System.out.println("YOU DESTROYED " + (int) Math.floor(2.0 * cpuNavy / 3.0) + " OF MY ARMY."); cpuNavy = (int) Math.floor(cpuNavy / 3.0); - } + } else { // User deployed two-thirds or more relative to cpu Navy units System.out.println("YOU SUNK ONE OF MY PATROL BOATS, BUT I WIPED OUT TWO"); System.out.println("OF YOUR AIR FORCE BASES AND 3 ARMY BASES."); usrArmy = (int) Math.floor(usrArmy / 3.0); usrAir = (int) Math.floor(usrAir / 3.0); cpuNavy = (int) Math.floor(2.0 * cpuNavy / 3.0); - } + } break; - + case 3: // Air Force deployed - + if (numUnits < (usrAir / 3.0)) { // User deployed less than one-third of their Air Force units System.out.println("YOUR ATTACK WAS WIPED OUT."); - usrAir = usrAir - numUnits; - } + usrAir = usrAir - numUnits; + } else if (numUnits < (2.0 * usrAir / 3.0)) { // User deployed less than two-thirds of their Air Force units System.out.println("WE HAD A DOGFIGHT. YOU WON - AND FINISHED YOUR MISSION."); cpuArmy = (int) Math.floor(2.0 * cpuArmy / 3.0); @@ -145,22 +145,22 @@ else if (numUnits < (2.0 * usrAir / 3.0)) { // User deployed less than two-thir } else { // User deployed two-thirds or more of their Air Force units System.out.println("YOU WIPED OUT ONE OF MY ARMY PATROLS, BUT I DESTROYED"); - System.out.println("TWO NAVY BASES AND BOMBED THREE ARMY BASES."); + System.out.println("TWO NAVY BASES AND BOMBED THREE ARMY BASES."); usrArmy = (int) Math.floor(usrArmy / 4.0); usrNavy = (int) Math.floor(usrNavy / 3.0); cpuArmy = (int) Math.floor(2.0 * cpuArmy / 3.0); - } - break; - + } + break; + } // End handling deployment type - + } // End of method attackFirst - + private void attackSecond() { - + int numUnits = 0; - int unitType = 0; - + int unitType = 0; + System.out.println(""); System.out.println(" YOU ME"); System.out.print("ARMY "); @@ -169,14 +169,14 @@ private void attackSecond() { System.out.format("%-14s%s\n", usrNavy, cpuNavy); System.out.print("A. F. "); System.out.format("%-14s%s\n", usrAir, cpuAir); - + do { System.out.println("WHAT IS YOUR NEXT MOVE?"); System.out.println("ARMY=1 NAVY=2 AIR FORCE=3"); System.out.print("? "); unitType = scan.nextInt(); } while ((unitType < 1) || (unitType > 3)); // Avoid out-of-range values - + do { System.out.println("HOW MANY MEN"); System.out.print("? "); @@ -184,85 +184,85 @@ private void attackSecond() { } while ((numUnits < 0) || // Avoid negative values ((unitType == 1) && (numUnits > usrArmy)) || // Avoid exceeding the number of available Army units ((unitType == 2) && (numUnits > usrNavy)) || // Avoid exceeding the number of available Navy units - ((unitType == 3) && (numUnits > usrAir))); // Avoid exceeding the number of available Air Force units + ((unitType == 3) && (numUnits > usrAir))); // Avoid exceeding the number of available Air Force units // Begin handling deployment type switch (unitType) { case 1: // Army deployed - + if (numUnits < (cpuArmy / 2.0)) { // User deployed less than half relative to cpu Army units System.out.println("I WIPED OUT YOUR ATTACK!"); - usrArmy = usrArmy - numUnits; + usrArmy = usrArmy - numUnits; } else { // User deployed half or more relative to cpu Army units System.out.println("YOU DESTROYED MY ARMY!"); cpuArmy = 0; - } + } break; - + case 2: // Navy deployed - + if (numUnits < (cpuNavy / 2.0)) { // User deployed less than half relative to cpu Navy units System.out.println("I SUNK TWO OF YOUR BATTLESHIPS, AND MY AIR FORCE"); System.out.println("WIPED OUT YOUR UNGUARDED CAPITOL."); usrArmy = (int) Math.floor(usrArmy / 4.0); - usrNavy = (int) Math.floor(usrNavy / 2.0); - } + usrNavy = (int) Math.floor(usrNavy / 2.0); + } else { // User deployed half or more relative to cpu Navy units System.out.println("YOUR NAVY SHOT DOWN THREE OF MY XIII PLANES,"); System.out.println("AND SUNK THREE BATTLESHIPS."); cpuAir = (int) Math.floor(2.0 * cpuAir / 3.0); - cpuNavy = (int) Math.floor(cpuNavy / 2.0); - } + cpuNavy = (int) Math.floor(cpuNavy / 2.0); + } break; - + case 3: // Air Force deployed - + if (numUnits > (cpuAir / 2.0)) { // User deployed more than half relative to cpu Air Force units System.out.println("MY NAVY AND AIR FORCE IN A COMBINED ATTACK LEFT"); System.out.println("YOUR COUNTRY IN SHAMBLES."); usrArmy = (int) Math.floor(usrArmy / 3.0); usrNavy = (int) Math.floor(usrNavy / 3.0); usrAir = (int) Math.floor(usrAir / 3.0); - } + } else { // User deployed half or less relative to cpu Air Force units System.out.println("ONE OF YOUR PLANES CRASHED INTO MY HOUSE. I AM DEAD."); System.out.println("MY COUNTRY FELL APART."); planeCrashWin = true; - } + } break; - + } // End handling deployment type - + // Suppress message for plane crashes if (planeCrashWin == false) { System.out.println(""); System.out.println("FROM THE RESULTS OF BOTH OF YOUR ATTACKS,"); } - + // User wins - if ((planeCrashWin == true) || + if ((planeCrashWin == true) || ((usrArmy + usrNavy + usrAir) > ((int) Math.floor((3.0 / 2.0 * (cpuArmy + cpuNavy + cpuAir)))))) { - System.out.println("YOU WON, OH! SHUCKS!!!!"); + System.out.println("YOU WON, OH! SHUCKS!!!!"); } // User loses - else if ((usrArmy + usrNavy + usrAir) < ((int) Math.floor((2.0 / 3.0 * (cpuArmy + cpuNavy + cpuAir))))) { // User loss + else if ((usrArmy + usrNavy + usrAir) < ((int) Math.floor((2.0 / 3.0 * (cpuArmy + cpuNavy + cpuAir))))) { // User loss System.out.println("YOU LOST-I CONQUERED YOUR COUNTRY. IT SERVES YOU"); System.out.println("RIGHT FOR PLAYING THIS STUPID GAME!!!"); } // Peaceful outcome - else { + else { System.out.println("THE TREATY OF PARIS CONCLUDED THAT WE TAKE OUR"); System.out.println("RESPECTIVE COUNTRIES AND LIVE IN PEACE."); - } - + } + } // End of method attackSecond - + public static void main(String[] args) { - + Combat combat = new Combat(); combat.play(); - + } // End of method main - -} // End of class Combat + +} // End of class Combat \ No newline at end of file diff --git a/28_Combat/javascript/combat.html b/28_Combat/javascript/combat.html index 2afee9752..8a75f8f4b 100644 --- a/28_Combat/javascript/combat.html +++ b/28_Combat/javascript/combat.html @@ -1,10 +1,9 @@ COMBAT - -

    
    +
    
     
     
     
    diff --git a/28_Combat/javascript/combat.js b/28_Combat/javascript/combat.js
    index ef2d3030e..a2e43c71c 100644
    --- a/28_Combat/javascript/combat.js
    +++ b/28_Combat/javascript/combat.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/28_Combat/kotlin/README.md b/28_Combat/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/28_Combat/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/28_Combat/lua/README.md b/28_Combat/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/28_Combat/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/28_Combat/pascal/README.md b/28_Combat/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/28_Combat/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/28_Combat/perl/combat.pl b/28_Combat/perl/combat.pl
    deleted file mode 100755
    index fc44a0e4c..000000000
    --- a/28_Combat/perl/combat.pl
    +++ /dev/null
    @@ -1,202 +0,0 @@
    -#!/usr/bin/perl
    -
    -# Combat program in Perl
    -# Translated by Kevin Brannen (kbrannen)
    -
    -use strict;
    -use warnings;
    -
    -# globals
    -my $User_army;
    -my $User_navy;
    -my $User_AF;
    -my $Comp_army = 30000;
    -my $Comp_navy = 20000;
    -my $Comp_AF = 22000;
    -my $Attack_type;
    -my $Attack_num;
    -
    -print "\n";
    -print " " x 33, "COMBAT\n";
    -print " " x 15, "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n";
    -
    -print "I AM AT WAR WITH YOU.\nWE HAVE 72000 SOLDIERS APIECE.\n\n";
    -
    -do {
    -    print "DISTRIBUTE YOUR FORCES.\n";
    -    print "\tME\t  YOU\n";
    -    print "ARMY\t$Comp_army\t";
    -    chomp($User_army = <>);
    -    print "NAVY\t$Comp_navy\t";
    -    chomp($User_navy = <>);
    -    print "A. F.\t$Comp_AF\t";
    -    chomp($User_AF = <>);
    -} while ($User_army + $User_navy + $User_AF > 72000);
    -
    -do {
    -    print "YOU ATTACK FIRST. TYPE (1) FOR ARMY; (2) FOR NAVY;\n";
    -    print "AND (3) FOR AIR FORCE.\n";
    -    chomp($Attack_num = <>);
    -} while ($Attack_type < 1 && $Attack_type > 3);
    -do {
    -    print "HOW MANY MEN\n";
    -    chomp($Attack_type = <>);
    -} while ($Attack_type < 0
    -         || ($Attack_num == 1 && $Attack_type > $User_army)
    -         || ($Attack_num == 2 && $Attack_type > $User_navy)
    -         || ($Attack_num == 3 && $Attack_type > $User_AF));
    -
    -if ($Attack_num == 1)
    -{
    -    if ($Attack_type<$User_army/3)
    -    {
    -        print "YOU LOST $Attack_type MEN FROM YOUR ARMY.\n";
    -        $User_army = int($User_army-$Attack_type);
    -    }
    -    if ($Attack_type<2*$User_army/3)
    -    {
    -        print "YOU LOST ", int($Attack_type/3), " MEN, BUT I LOST ", int(2*$Comp_army/3), "\n";
    -        $User_army = int($User_army-$Attack_type/3);
    -        $Comp_army = int(2*$Comp_army/3);
    -    }
    -    else
    -    {
    -        s270();
    -    }
    -}
    -elsif ($Attack_num == 2)
    -{
    -    if ($Attack_type < $Comp_navy/3)
    -    {
    -        print "YOUR ATTACK WAS STOPPED!\n";
    -        $User_navy = int($User_navy-$Attack_type);
    -    }
    -    if ($Attack_type < 2*$Comp_navy/3)
    -    {
    -        print "YOU DESTROYED ", int(2*$Comp_navy/3), " OF MY ARMY.\n";
    -        $Comp_navy = int(2*$Comp_navy/3);
    -    }
    -    else
    -    {
    -        s270();
    -    }
    -}
    -else # $Attack_num == 3
    -{
    -    if ($Attack_type < $User_AF/3)
    -    {
    -        print "YOUR ATTACK WAS WIPED OUT.\n";
    -        $User_AF = int($User_AF-$Attack_type);
    -    }
    -    if ($Attack_type < 2*$User_AF/3)
    -    {
    -        print "WE HAD A DOGFIGHT. YOU WON - AND FINISHED YOUR MISSION.\n";
    -        $Comp_army = int(2*$Comp_army/3);
    -        $Comp_navy = int($Comp_navy/3);
    -        $Comp_AF = int($Comp_AF/3);
    -    }
    -    else
    -    {
    -        print "YOU WIPED OUT ONE OF MY ARMY PATROLS, BUT I DESTROYED\n";
    -        print "TWO NAVY BASES AND BOMBED THREE ARMY BASES.\n";
    -        $User_army = int($User_army/4);
    -        $User_navy = int($User_navy/3);
    -        $User_AF = int(2*$User_AF/3);
    -    }
    -}
    -
    -print "\n\tYOU\tME\n";
    -print "ARMY\t$User_army\t$Comp_army\n";
    -print "NAVY\t$User_navy\t$Comp_navy\n";
    -print "A. F.\t$User_AF\t$Comp_AF\n";
    -do {
    -    print "WHAT IS YOUR NEXT MOVE?\n";
    -    print "ARMY=1  NAVY=2  AIR FORCE=3\n";
    -    chomp($Attack_type = <>);
    -} while ($Attack_type < 1 && $Attack_type > 3);
    -do {
    -    print "HOW MANY MEN\n";
    -    chomp($Attack_num = <>);
    -} while ($Attack_num < 0
    -         || ($Attack_type == 1 && $Attack_num > $User_army)
    -         || ($Attack_type == 2 && $Attack_num > $User_navy)
    -         || ($Attack_type == 3 && $Attack_num > $User_AF));
    -
    -if ($Attack_num == 1)
    -{
    -    if ($Attack_num < $Comp_army/2)
    -    {
    -        print "I WIPED OUT YOUR ATTACK!\n";
    -        $User_army -= $Attack_num;
    -    }
    -    else
    -    {
    -        print "YOU DESTROYED MY ARMY!\n";
    -        $Comp_army = 0;
    -    }
    -}
    -elsif ($Attack_num == 2)
    -{
    -    if ($Attack_num < $Comp_navy/2)
    -    {
    -        print "I SUNK TWO OF YOUR BATTLESHIPS, AND MY AIR FORCE\n";
    -        print "WIPED OUT YOUR UNGAURDED CAPITOL.\n";
    -        $User_army /= 4;
    -        $User_navy /= 2;
    -    }
    -    else
    -    {
    -        print "YOUR NAVY SHOT DOWN THREE OF MY XIII PLANES,\n";
    -        print "AND SUNK THREE BATTLESHIPS.\n";
    -        $Comp_AF = 2*$Comp_AF/3;
    -        $Comp_navy /= 2;
    -    }
    -}
    -else # $Attack_num == 3
    -{
    -    if ($Attack_num > $Comp_AF/2)
    -    {
    -        print "MY NAVY AND AIR FORCE IN A COMBINED ATTACK LEFT\n";
    -        print "YOUR COUNTRY IN SHAMBLES.\n";
    -        $User_army /= 3;
    -        $User_navy /= 3;
    -        $User_AF /= 3;
    -    }
    -    else
    -    {
    -        print "ONE OF YOUR PLANES CRASHED INTO MY HOUSE. I AM DEAD.\n";
    -        print "MY COUNTRY FELL APART.\n";
    -        $Comp_army = $Comp_navy = $Comp_AF = 0;
    -    }
    -}
    -
    -print "\nFROM THE RESULTS OF BOTH OF YOUR ATTACKS,\n";
    -my $total_user = $User_army+$User_navy+$User_AF;
    -my $total_comp = $Comp_army+$Comp_navy+$Comp_AF;
    -if ($total_user > 3/2*($total_comp))
    -{
    -    print "YOU WON, OH! SHUCKS!!!!\n";
    -}
    -elsif ($total_user < 2/3*($total_comp))
    -{
    -    print "YOU LOST-I CONQUERED YOUR COUNTRY.  IT SERVES YOU\n";
    -    print "RIGHT FOR PLAYING THIS STUPID GAME!!!\n";
    -}
    -else
    -{
    -    print "THE TREATY OF PARIS CONCLUDED THAT WE TAKE OUR\n";
    -    print "RESPECTIVE COUNTRIES AND LIVE IN PEACE.\n";
    -}
    -print "\n";
    -exit(0);
    -
    -#######################################################
    -
    -sub s270
    -{
    -    print "YOU SUNK ONE OF MY PATROL BOATS, BUT I WIPED OUT TWO\n";
    -    print "OF YOUR AIR FORCE BASES AND 3 ARMY BASES.\n";
    -    $User_army = int($User_army/3);
    -    $User_AF = int($User_AF/3);
    -    $Comp_navy = int(2*$Comp_navy/3);
    -}
    diff --git a/28_Combat/python/combat.py b/28_Combat/python/combat.py
    index 0543b205a..3d0f120e1 100644
    --- a/28_Combat/python/combat.py
    +++ b/28_Combat/python/combat.py
    @@ -1,184 +1,173 @@
     MAX_UNITS = 72000
    -plane_crash_win = False
    -usr_army = 0
    -usr_navy = 0
    -usr_air = 0
    -cpu_army = 30000
    -cpu_navy = 20000
    -cpu_air = 22000
    +planeCrashWin = False
    +usrArmy = 0
    +usrNavy = 0
    +usrAir = 0
    +cpuArmy = 30000
    +cpuNavy = 20000
    +cpuAir = 22000
     
     
    -def show_intro() -> None:
    +def showIntro():
         global MAX_UNITS
     
         print(" " * 32 + "COMBAT")
         print(" " * 14 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY")
         print("\n\n")
         print("I AM AT WAR WITH YOU.")
    -    print(f"WE HAVE {str(MAX_UNITS)} SOLDIERS APIECE.")
    +    print("WE HAVE " + str(MAX_UNITS) + " SOLDIERS APIECE.")
     
     
    -def get_forces() -> None:
    -    global usr_army, usr_navy, usr_air
    +def getForces():
    +    global usrArmy, usrNavy, usrAir
     
         while True:
             print("DISTRIBUTE YOUR FORCES.")
             print("              ME              YOU")
    -        print(f"ARMY           {str(cpu_army)}        ? ", end="")
    -        usr_army = int(input())
    -        print(f"NAVY           {str(cpu_navy)}        ? ", end="")
    -        usr_navy = int(input())
    -        print(f"A. F.          {str(cpu_air)}        ? ", end="")
    -        usr_air = int(input())
    -        if (usr_army + usr_navy + usr_air) <= MAX_UNITS:
    +        print("ARMY           " + str(cpuArmy) + "        ? ", end="")
    +        usrArmy = int(input())
    +        print("NAVY           " + str(cpuNavy) + "        ? ", end="")
    +        usrNavy = int(input())
    +        print("A. F.          " + str(cpuAir) + "        ? ", end="")
    +        usrAir = int(input())
    +        if not ((usrArmy + usrNavy + usrAir) > MAX_UNITS):
                 break
     
     
    -def attack_first() -> None:
    -    global usr_army, usr_navy, usr_air
    -    global cpu_army, cpu_navy, cpu_air
    +def attackFirst():
    +    global usrArmy, usrNavy, usrAir
    +    global cpuArmy, cpuNavy, cpuAir
     
    -    unit_type = 0
    +    numUnits = 0
    +    unitType = 0
     
         while True:
             print("YOU ATTACK FIRST. TYPE (1) FOR ARMY; (2) FOR NAVY;")
             print("AND (3) FOR AIR FORCE.")
    -        print("?", end=" ")
    -        unit_type = int(input())
    -        if unit_type >= 1 and unit_type <= 3:
    +        print("?", end=' ')
    +        unitType = int(input())
    +        if not (unitType < 1 or unitType > 3):
                 break
     
    -    num_units = 0
         while True:
             print("HOW MANY MEN")
    -        print("?", end=" ")
    -        num_units = int(input())
    -        if (
    -            num_units >= 0
    -            and (unit_type != 1 or num_units <= usr_army)
    -            and (unit_type != 2 or num_units <= usr_navy)
    -            and (unit_type != 3 or num_units <= usr_air)
    -        ):
    +        print("?", end=' ')
    +        numUnits = int(input())
    +        if not ((numUnits < 0) or ((unitType == 1) and (numUnits > usrArmy)) or (
    +                (unitType == 2) and (numUnits > usrNavy)) or ((unitType == 3) and (numUnits > usrAir))):
                 break
     
    -    if unit_type == 1:
    -        if num_units < (usr_army / 3):
    -            print(f"YOU LOST {str(num_units)} MEN FROM YOUR ARMY.")
    -            usr_army = usr_army - num_units
    -        elif num_units < (2 * usr_army / 3):
    -            print(f"YOU LOST {int(num_units / 3)} MEN, BUT I LOST {int(2 * cpu_army / 3)}")
    -            usr_army = int(usr_army - (num_units / 3))
    -            cpu_army = 0
    +    if unitType == 1:
    +        if numUnits < (usrArmy / 3):
    +            print("YOU LOST " + str(numUnits) + " MEN FROM YOUR ARMY.")
    +            usrArmy = usrArmy - numUnits
    +        elif numUnits < (2 * usrArmy / 3):
    +            print("YOU LOST " + str(int(numUnits / 3)) + " MEN, BUT I LOST " + str(int(2 * cpuArmy / 3)))
    +            usrArmy = int(usrArmy - (numUnits / 3))
    +            cpuArmy = 0
             else:
                 print("YOU SUNK ONE OF MY PATROL BOATS, BUT I WIPED OUT TWO")
                 print("OF YOUR AIR FORCE BASES AND 3 ARMY BASES.")
    -            usr_army = int(usr_army / 3)
    -            usr_air = int(usr_air / 3)
    -            cpu_navy = int(2 * cpu_navy / 3)
    -    elif unit_type == 2:
    -        if num_units < cpu_navy / 3:
    +            usrArmy = int(usrArmy / 3)
    +            usrAir = int(usrAir / 3)
    +            cpuNavy = int(2 * cpuNavy / 3)
    +    elif unitType == 2:
    +        if numUnits < cpuNavy / 3:
                 print("YOUR ATTACK WAS STOPPED!")
    -            usr_navy = usr_navy - num_units
    -        elif num_units < 2 * cpu_navy / 3:
    -            print(f"YOU DESTROYED {int(2 * cpu_navy / 3)} OF MY ARMY.")
    -            cpu_navy = int(cpu_navy / 3)
    +            usrNavy = usrNavy - numUnits
    +        elif numUnits < 2 * cpuNavy / 3:
    +            print("YOU DESTROYED " + str(int(2 * cpuNavy / 3)) + " OF MY ARMY.")
    +            cpuNavy = int(cpuNavy / 3)
             else:
                 print("YOU SUNK ONE OF MY PATROL BOATS, BUT I WIPED OUT TWO")
                 print("OF YOUR AIR FORCE BASES AND 3 ARMY BASES.")
    -            usr_army = int(usr_army / 3)
    -            usr_air = int(usr_air / 3)
    -            cpu_navy = int(2 * cpu_navy / 3)
    -    elif unit_type == 3:
    -        if num_units < usr_air / 3:
    +            usrArmy = int(usrArmy / 3)
    +            usrAir = int(usrAir / 3)
    +            cpuNavy = int(2 * cpuNavy / 3)
    +    elif unitType == 3:
    +        if numUnits < usrAir / 3:
                 print("YOUR ATTACK WAS WIPED OUT.")
    -            usr_air = usr_air - num_units
    -        elif num_units < 2 * usr_air / 3:
    +            usrAir = usrAir - numUnits
    +        elif numUnits < 2 * usrAir / 3:
                 print("WE HAD A DOGFIGHT. YOU WON - AND FINISHED YOUR MISSION.")
    -            cpu_army = int(2 * cpu_army / 3)
    -            cpu_navy = int(cpu_navy / 3)
    -            cpu_air = int(cpu_air / 3)
    +            cpuArmy = int(2 * cpuArmy / 3)
    +            cpuNavy = int(cpuNavy / 3)
    +            cpuAir = int(cpuAir / 3)
             else:
                 print("YOU WIPED OUT ONE OF MY ARMY PATROLS, BUT I DESTROYED")
                 print("TWO NAVY BASES AND BOMBED THREE ARMY BASES.")
    -            usr_army = int(usr_army / 4)
    -            usr_navy = int(usr_navy / 3)
    -            cpu_army = int(2 * cpu_army / 3)
    +            usrArmy = int(usrArmy / 4)
    +            usrNavy = int(usrNavy / 3)
    +            cpuArmy = int(2 * cpuArmy / 3)
     
     
    -def attack_second() -> None:
    -    global usr_army, usr_navy, usr_air, cpu_army, cpu_navy, cpu_air
    -    global plane_crash_win
    -    unit_type = 0
    +def attackSecond():
    +    global usrArmy, usrNavy, usrAir, cpuArmy, cpuNavy, cpuAir
    +    global planeCrashWin
    +    numUnits = 0
    +    unitType = 0
     
    -    print()
    +    print("")
         print("              YOU           ME")
         print("ARMY           ", end="")
    -    print("%-14s%s\n" % (usr_army, cpu_army), end="")
    +    print("%-14s%s\n" % (usrArmy, cpuArmy), end="")
         print("NAVY           ", end="")
    -    print("%-14s%s\n" % (usr_navy, cpu_navy), end="")
    +    print("%-14s%s\n" % (usrNavy, cpuNavy), end="")
         print("A. F.          ", end="")
    -    print("%-14s%s\n" % (usr_air, cpu_air), end="")
    +    print("%-14s%s\n" % (usrAir, cpuAir), end="")
     
         while True:
             print("WHAT IS YOUR NEXT MOVE?")
             print("ARMY=1  NAVY=2  AIR FORCE=3")
             print("? ", end="")
    -        unit_type = int(input())
    -        if unit_type >= 1 and unit_type <= 3:
    +        unitType = int(input())
    +        if not ((unitType < 1) or (unitType > 3)):
                 break
    -
    -    num_units = 0
    +        
         while True:
             print("HOW MANY MEN")
             print("? ", end="")
    -        num_units = int(input())
    -        if (
    -            num_units >= 0
    -            and (unit_type != 1 or num_units <= usr_army)
    -            and (unit_type != 2 or num_units <= usr_navy)
    -            and (unit_type != 3 or num_units <= usr_air)
    -        ):
    +        numUnits = int(input())
    +        if not((numUnits < 0) or ((unitType == 1) and (numUnits > usrArmy)) or ((unitType == 2) and (numUnits > usrNavy)) or ((unitType == 3) and (numUnits > usrAir))):
                 break
     
    -    if unit_type == 1:
    -        if num_units < (cpu_army / 2):
    +    if unitType == 1:
    +        if numUnits < (cpuArmy/2):
                 print("I WIPED OUT YOUR ATTACK!")
    -            usr_army = usr_army - num_units
    +            usrArmy = usrArmy - numUnits
             else:
                 print("YOU DESTROYED MY ARMY!")
    -            cpu_army = 0
    -    elif unit_type == 2:
    -        if num_units < (cpu_navy / 2):
    +            cpuArmy = 0
    +    elif unitType == 2:
    +        if numUnits < (cpuNavy/2):
                 print("I SUNK TWO OF YOUR BATTLESHIPS, AND MY AIR FORCE")
                 print("WIPED OUT YOUR UNGUARDED CAPITOL.")
    -            usr_army = int(usr_army / 4)
    -            usr_navy = int(usr_navy / 2)
    +            usrArmy = int(usrArmy/4)
    +            usrNavy = int(usrNavy/2)
             else:
                 print("YOUR NAVY SHOT DOWN THREE OF MY XIII PLANES,")
                 print("AND SUNK THREE BATTLESHIPS.")
    -            cpu_air = int(2 * cpu_air / 3)
    -            cpu_navy = int(cpu_navy / 2)
    -    elif unit_type == 3:
    -        if num_units > (cpu_air / 2):
    +            cpuAir = int(2*cpuAir/3)
    +            cpuNavy = int(cpuNavy/2)
    +    elif unitType == 3:
    +        if numUnits > (cpuAir/2):
                 print("MY NAVY AND AIR FORCE IN A COMBINED ATTACK LEFT")
                 print("YOUR COUNTRY IN SHAMBLES.")
    -            usr_army = int(usr_army / 3)
    -            usr_navy = int(usr_navy / 3)
    -            usr_air = int(usr_air / 3)
    +            usrArmy = int(usrArmy/3)
    +            usrNavy = int(usrNavy/3)
    +            usrAir = int(usrAir/3)
             else:
                 print("ONE OF YOUR PLANES CRASHED INTO MY HOUSE. I AM DEAD.")
                 print("MY COUNTRY FELL APART.")
    -            plane_crash_win = True
    +            planeCrashWin = True
     
    -    if not plane_crash_win:
    -        print()
    +    if planeCrashWin == False:
    +        print("")
             print("FROM THE RESULTS OF BOTH OF YOUR ATTACKS,")
     
    -    if plane_crash_win or (
    -        (usr_army + usr_navy + usr_air) > (int(3 / 2 * (cpu_army + cpu_navy + cpu_air)))
    -    ):
    +    if (planeCrashWin == True) or ((usrArmy + usrNavy + usrAir) > (int(3/2*(cpuArmy + cpuNavy + cpuAir)))):
             print("YOU WON, OH! SHUCKS!!!!")
    -    elif (usr_army + usr_navy + usr_air) < int(2 / 3 * (cpu_army + cpu_navy + cpu_air)):
    +    elif (usrArmy + usrNavy + usrAir) < int(2/3*(cpuArmy + cpuNavy + cpuAir)):
             print("YOU LOST-I CONQUERED YOUR COUNTRY.  IT SERVES YOU")
             print("RIGHT FOR PLAYING THIS STUPID GAME!!!")
         else:
    @@ -186,12 +175,11 @@ def attack_second() -> None:
             print("RESPECTIVE COUNTRIES AND LIVE IN PEACE.")
     
     
    -def main() -> None:
    -    show_intro()
    -    get_forces()
    -    attack_first()
    -    attack_second()
    -
    -
    -if __name__ == "__main__":
    -    main()
    +def main():
    +    showIntro()
    +    getForces()
    +    attackFirst()
    +    attackSecond()
    +    
    +if __name__ == '__main__':
    +    main()
    \ No newline at end of file
    diff --git a/28_Combat/vbnet/Combat.sln b/28_Combat/vbnet/Combat.sln
    deleted file mode 100644
    index f06a83661..000000000
    --- a/28_Combat/vbnet/Combat.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 19ba1b194..000000000
    --- a/28_Combat/vbnet/Combat.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Combat
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/29_Craps/README.md b/29_Craps/README.md
    index ace6d7b87..3c45c62bc 100644
    --- a/29_Craps/README.md
    +++ b/29_Craps/README.md
    @@ -17,13 +17,12 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    +          
    +### 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
    +`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
    @@ -32,14 +31,13 @@ much money as they want and we only track how much they lost or won.
           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
    +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.
    +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.
    +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
    @@ -47,38 +45,38 @@ 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 `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
    +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
    +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
    +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.
    +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)
    +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
    +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
    +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.
    +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
    +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.";
    @@ -87,19 +85,20 @@ the user input.
           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
    +      .... 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`
    +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
    +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:
    @@ -111,20 +110,20 @@ Here are the results:
           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
    +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
    +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.
    +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.**
    +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
    @@ -148,17 +147,17 @@ 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.
    +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
    +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"
    @@ -170,17 +169,17 @@ the same place, line 220. Line 125-170 could have simply been replaced with
           200 PRINT X " - CRAPS...YOU LOSE."
           205 PRINT "YOU LOSE"F"DOLLARS."
           206 LET F=0-F
    -      210 LET R= R+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
    +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.
    +`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))
    @@ -191,15 +190,15 @@ or losses with this bet.
           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
    +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
    +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.
    +due to duplicate code snippets. 
     
           260 IF O=X THEN 310
           270 PRINT O " - NO POINT. I WILL ROLL AGAIN"
    @@ -214,12 +213,15 @@ due to duplicate code snippets.
           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.
    +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
    +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/craps.bas b/29_Craps/craps.bas
    index 3a387059f..eb470b27e 100644
    --- a/29_Craps/craps.bas
    +++ b/29_Craps/craps.bas
    @@ -15,7 +15,7 @@
     40 LET E=INT(7*RND(1))
     41 LET S=INT(7*RND(1))
     42 LET X=E+S
    -50 IF X=7 THEN 180
    +50 IF X=7 THEN 180 
     55 IF X=11 THEN 180
     60 IF X=1 THEN 40
     62 IF X=2 THEN 195
    diff --git a/29_Craps/csharp/.gitignore b/29_Craps/csharp/.gitignore
    deleted file mode 100644
    index a518e3617..000000000
    --- a/29_Craps/csharp/.gitignore
    +++ /dev/null
    @@ -1,4 +0,0 @@
    -.vs
    -TestResults
    -bin
    -obj
    diff --git a/29_Craps/csharp/Craps/.gitignore b/29_Craps/csharp/Craps/.gitignore
    new file mode 100644
    index 000000000..c1cb0dced
    --- /dev/null
    +++ b/29_Craps/csharp/Craps/.gitignore
    @@ -0,0 +1,5 @@
    +.vs
    +TestResults
    +bin
    +obj
    +
    diff --git a/29_Craps/csharp/Craps.sln b/29_Craps/csharp/Craps/Craps.sln
    similarity index 100%
    rename from 29_Craps/csharp/Craps.sln
    rename to 29_Craps/csharp/Craps/Craps.sln
    diff --git a/29_Craps/csharp/Craps/Craps.csproj b/29_Craps/csharp/Craps/Craps/Craps.csproj
    similarity index 100%
    rename from 29_Craps/csharp/Craps/Craps.csproj
    rename to 29_Craps/csharp/Craps/Craps/Craps.csproj
    diff --git a/29_Craps/csharp/Craps/CrapsGame.cs b/29_Craps/csharp/Craps/Craps/CrapsGame.cs
    similarity index 100%
    rename from 29_Craps/csharp/Craps/CrapsGame.cs
    rename to 29_Craps/csharp/Craps/Craps/CrapsGame.cs
    diff --git a/29_Craps/csharp/Craps/Dice.cs b/29_Craps/csharp/Craps/Craps/Dice.cs
    similarity index 100%
    rename from 29_Craps/csharp/Craps/Dice.cs
    rename to 29_Craps/csharp/Craps/Craps/Dice.cs
    diff --git a/29_Craps/csharp/Craps/Craps/Program.cs b/29_Craps/csharp/Craps/Craps/Program.cs
    new file mode 100644
    index 000000000..d0aa59614
    --- /dev/null
    +++ b/29_Craps/csharp/Craps/Craps/Program.cs
    @@ -0,0 +1,51 @@
    +using System.Diagnostics;
    +
    +
    +
    +namespace Craps
    +{
    +    class Program
    +    {
    +        static void Main(string[] args)
    +        {
    +            var ui = new UserInterface();
    +            var game = new CrapsGame(ref ui);
    +            int winnings = 0;
    +
    +            ui.Intro();
    +
    +            do 
    +            {
    +	            var bet = ui.PlaceBet();
    +                var result = game.Play(out int diceRoll);
    +
    +                switch (result)
    +                {
    +                    case Result.naturalWin:
    +                        winnings += bet;
    +                        break;
    +
    +                    case Result.naturalLoss:
    +                    case Result.snakeEyesLoss:
    +                    case Result.pointLoss:
    +                        winnings -= bet;
    +                        break;
    +
    +                    case Result.pointWin:
    +                        winnings += (2 * bet);
    +                        break;
    +
    +                    // Include a default so that we will be warned if the values of the enum
    +                    // ever change and we forget to add code to handle the new value.
    +                    default:
    +                        Debug.Assert(false); // We should never get here.
    +                        break;
    +                }
    +
    +                ui.ShowResult(result, diceRoll, bet);
    +            } while (ui.PlayAgain(winnings));
    +
    +            ui.GoodBye(winnings);
    +        }
    +    }
    +}
    diff --git a/29_Craps/csharp/Craps/UserInterface.cs b/29_Craps/csharp/Craps/Craps/UserInterface.cs
    similarity index 99%
    rename from 29_Craps/csharp/Craps/UserInterface.cs
    rename to 29_Craps/csharp/Craps/Craps/UserInterface.cs
    index f320db864..149a3ecc5 100644
    --- a/29_Craps/csharp/Craps/UserInterface.cs
    +++ b/29_Craps/csharp/Craps/Craps/UserInterface.cs
    @@ -139,3 +139,5 @@ private int GetInt()
             }
         }
     }
    +
    +
    diff --git a/29_Craps/csharp/CrapsTester/CrapsTester.csproj b/29_Craps/csharp/Craps/CrapsTester/CrapsTester.csproj
    similarity index 100%
    rename from 29_Craps/csharp/CrapsTester/CrapsTester.csproj
    rename to 29_Craps/csharp/Craps/CrapsTester/CrapsTester.csproj
    diff --git a/29_Craps/csharp/CrapsTester/CrapsTests.cs b/29_Craps/csharp/Craps/CrapsTester/CrapsTests.cs
    similarity index 98%
    rename from 29_Craps/csharp/CrapsTester/CrapsTests.cs
    rename to 29_Craps/csharp/Craps/CrapsTester/CrapsTests.cs
    index 1d3ab60b9..576c2b820 100644
    --- a/29_Craps/csharp/CrapsTester/CrapsTests.cs
    +++ b/29_Craps/csharp/Craps/CrapsTester/CrapsTests.cs
    @@ -80,7 +80,7 @@ public void DiceRollsAreRandom()
                 }
     
                 // We'll assume that a variation of 10% in rolls for the different numbers is random enough.
    -            // Perfectly random rolling would produce 100000 rolls per side, +/- 5% of this gives the
    +            // Perfectly random rolling would produce 100000 rolls per side, +/- 5% of this gives the 
                 // range 90000..110000.
                 const int minRolls = 95000;
                 const int maxRolls = 105000;
    diff --git a/29_Craps/csharp/Craps/Program.cs b/29_Craps/csharp/Craps/Program.cs
    deleted file mode 100644
    index 9d800916b..000000000
    --- a/29_Craps/csharp/Craps/Program.cs
    +++ /dev/null
    @@ -1,51 +0,0 @@
    -using System.Diagnostics;
    -
    -
    -
    -namespace Craps
    -{
    -    class Program
    -    {
    -        static void Main(string[] args)
    -        {
    -            var ui = new UserInterface();
    -            var game = new CrapsGame(ref ui);
    -            int winnings = 0;
    -
    -            ui.Intro();
    -
    -            do
    -            {
    -	            var bet = ui.PlaceBet();
    -                var result = game.Play(out int diceRoll);
    -
    -                switch (result)
    -                {
    -                    case Result.naturalWin:
    -                        winnings += bet;
    -                        break;
    -
    -                    case Result.naturalLoss:
    -                    case Result.snakeEyesLoss:
    -                    case Result.pointLoss:
    -                        winnings -= bet;
    -                        break;
    -
    -                    case Result.pointWin:
    -                        winnings += (2 * bet);
    -                        break;
    -
    -                    // Include a default so that we will be warned if the values of the enum
    -                    // ever change and we forget to add code to handle the new value.
    -                    default:
    -                        Debug.Assert(false); // We should never get here.
    -                        break;
    -                }
    -
    -                ui.ShowResult(result, diceRoll, bet);
    -            } while (ui.PlayAgain(winnings));
    -
    -            ui.GoodBye(winnings);
    -        }
    -    }
    -}
    diff --git a/29_Craps/java/src/Craps.java b/29_Craps/java/src/Craps.java
    index 3a99c4481..483c16a98 100644
    --- a/29_Craps/java/src/Craps.java
    +++ b/29_Craps/java/src/Craps.java
    @@ -6,13 +6,13 @@
      */
     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;
    diff --git a/29_Craps/javascript/craps.html b/29_Craps/javascript/craps.html
    index 45414c5d0..50b2ca9b1 100644
    --- a/29_Craps/javascript/craps.html
    +++ b/29_Craps/javascript/craps.html
    @@ -1,10 +1,9 @@
     
     
     CRAPS
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/29_Craps/javascript/craps.js b/29_Craps/javascript/craps.js
    index 6a0ee90a5..933510114 100644
    --- a/29_Craps/javascript/craps.js
    +++ b/29_Craps/javascript/craps.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    @@ -42,11 +42,6 @@ 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()
     {
    @@ -57,11 +52,22 @@ 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");
    -        x = roll();
    +        do {
    +            e = Math.floor(7 * Math.random());
    +            s = Math.floor(7 * Math.random());
    +            x = e + s;
    +        } while (x == 0 || x == 1) ;
             if (x == 7 || x == 11) {
                 print(x + " - NATURAL....A WINNER!!!!\n");
                 print(x + " PAYS EVEN MONEY, YOU WIN " + f + " DOLLARS\n");
    @@ -77,7 +83,11 @@ async function main()
             } else {
                 print(x + " IS THE POINT. I WILL ROLL AGAIN\n");
                 while (1) {
    -                o = roll();
    +                do {
    +                    h = Math.floor(7 * Math.random());
    +                    q = Math.floor(7 * Math.random());
    +                    o = h + q;
    +                } while (o == 0 || o == 1) ;
                     if (o == 7) {
                         print(o + " - CRAPS, YOU LOSE.\n");
                         print("YOU LOSE $" + f + "\n");
    @@ -112,7 +122,7 @@ async function main()
         } else {
             print("CONGRATULATIONS---YOU CAME OUT EVEN, NOT BAD FOR AN AMATEUR\n");
         }
    -
    +    
     }
     
     main();
    diff --git a/29_Craps/kotlin/README.md b/29_Craps/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/29_Craps/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/29_Craps/lua/README.md b/29_Craps/lua/README.md
    deleted file mode 100644
    index aac11dd0b..000000000
    --- a/29_Craps/lua/README.md
    +++ /dev/null
    @@ -1,17 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/) by Alex Conconi
    -
    ----
    -
    -### Lua porting notes
    -
    --  The `craps_main` function contains the main game loop, which iteratively
    -plays craps rounds by calling `play_round` and tracks winnings and losings.
    -- Replaced the original routine that tries to scramble the random number
    -generator with a proper seed initializer in Lua: `math.randomseed(os.time())`
    -(as advised in the general porting notes). 
    -- Added basic input validation to accept only positive integers for the
    -wager and the answer to the "If you want to play again print 5" question.
    -- "If you want to play again print 5 if not print 2" reads a bit odd but
    -we decided to leave it as is and stay true to the BASIC original version.
    \ No newline at end of file
    diff --git a/29_Craps/lua/craps.lua b/29_Craps/lua/craps.lua
    deleted file mode 100644
    index ddd1ce30b..000000000
    --- a/29_Craps/lua/craps.lua
    +++ /dev/null
    @@ -1,149 +0,0 @@
    ---[[
    -Craps
    -
    -From: BASIC Computer Games (1978)
    -Edited by David H. Ahl
    -
    -    This game simulates the games of craps played according to standard
    -    Nevada craps table rules. That is:
    -    1. A 7 or 11 on the first roll wins
    -    2. A 2, 3, or 12 on the first roll loses
    -    3. Any other number rolled becomes your "point." You continue to roll;
    -    if you get your point you win. If you roll a 7, you lose and the dice
    -    change hands when this happens.
    -
    -    This version of craps was modified by Steve North of Creative Computing.
    -    It is based on an original which appeared one day one a computer at DEC.
    -
    -
    -Lua port by Alex Conconi, 2022
    ---]]
    -
    -
    ---- Throw two dice and return their sum.
    -local function throw_dice()
    -    return math.random(1, 6) + math.random(1, 6)
    -end
    -
    -
    ---- Print prompt and read a number > 0 from stdin.
    -local function input_number(prompt)
    -    while true do
    -        io.write(prompt)
    -        local number = tonumber(io.stdin:read("*l"))
    -        if number and number > 0 then
    -            return number
    -        else
    -            print("Please enter a number greater than zero.")
    -        end
    -    end
    -end
    -
    -
    ---- Print custom balance message depending on balance value
    -local function print_balance(balance, under_msg, ahead_msg, even_msg)
    -    if balance < 0 then
    -        print(under_msg)
    -    elseif balance > 0 then
    -        print(ahead_msg)
    -    else
    -        print(even_msg)
    -    end
    -end
    -
    -
    ---- Play a round and return winnings or losings.
    -local function play_round()
    -    -- Input the wager
    -    local wager = input_number("Input the amount of your wager: ")
    -
    -    -- Roll the die for the first time.
    -    print("I will now throw the dice")
    -    local first_roll = throw_dice()
    -
    -    -- A 7 or 11 on the first roll wins.
    -    if first_roll == 7 or first_roll == 11 then
    -        print(string.format("%d - natural.... a winner!!!!", first_roll))
    -        print(string.format("%d pays even money, you win %d dollars", first_roll, wager))
    -        return wager
    -    end
    -
    -    -- A 2, 3, or 12 on the first roll loses.
    -    if first_roll == 2 or first_roll == 3 or first_roll == 12 then
    -        if first_roll == 2 then
    -            -- Special 'you lose' message for 'snake eyes'
    -            print(string.format("%d - snake eyes.... you lose.", first_roll))
    -        else
    -            -- Default 'you lose' message
    -            print(string.format("%d - craps.... you lose.", first_roll))
    -        end
    -        print(string.format("You lose %d dollars", wager))
    -        return -wager
    -    end
    -
    -    -- Any other number rolled becomes the "point".
    -    -- Continue to roll until rolling a 7 or point.
    -    print(string.format("%d is the point. I will roll again", first_roll))
    -    while true do
    -        local second_roll = throw_dice()
    -        if second_roll == first_roll then
    -            -- Player gets point and wins
    -            print(string.format("%d - a winner.........congrats!!!!!!!!", first_roll))
    -            print(string.format("%d at 2 to 1 odds pays you...let me see... %d dollars", first_roll, 2 * wager))
    -            return 2 * wager
    -        end
    -        if second_roll == 7 then
    -            -- Player rolls a 7 and loses
    -            print(string.format("%d - craps. You lose.", second_roll))
    -            print(string.format("You lose $ %d", wager))
    -            return -wager
    -        end
    -        --  Continue to roll
    -        print(string.format("%d  - no point. I will roll again", second_roll))
    -    end
    -end
    -
    -
    ---- Main game function.
    -local function craps_main()
    -    -- Print the introduction to the game
    -    print(string.rep(" ", 32) .. "Craps")
    -    print(string.rep(" ", 14) .. "Creative Computing  Morristown, New Jersey\n\n")
    -    print("2,3,12 are losers; 4,5,6,8,9,10 are points; 7,11 are natural winners.")
    -
    -    -- Initialize random number generator seed
    -    math.randomseed(os.time())
    -
    -    -- Initialize balance to track winnings and losings
    -    local balance = 0
    -
    -    -- Main game loop
    -    local keep_playing = true
    -    while keep_playing do
    -        -- Play a round
    -        balance = balance + play_round()
    -
    -        -- If player's answer is 5, then stop playing
    -        keep_playing = (input_number("If you want to play again print 5 if not print 2: ") == 5)
    -
    -        -- Print an update on winnings or losings
    -        print_balance(
    -            balance,
    -            string.format("You are now under $%d", -balance),
    -            string.format("You are now ahead $%d", balance),
    -            "You are now even at 0"
    -        )
    -    end
    -
    -    -- Game over, print the goodbye message
    -    print_balance(
    -        balance,
    -        "Too bad, you are in the hole. Come again.",
    -        "Congratulations---you came out a winner. Come again.",
    -        "Congratulations---you came out even, not bad for an amateur"
    -    )
    -end
    -
    -
    ---- Run the game.
    -craps_main()
    diff --git a/29_Craps/pascal/README.md b/29_Craps/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/29_Craps/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/29_Craps/perl/craps.pl b/29_Craps/perl/craps.pl
    deleted file mode 100644
    index 7dd39856c..000000000
    --- a/29_Craps/perl/craps.pl
    +++ /dev/null
    @@ -1,113 +0,0 @@
    -#!/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";
    -}
    diff --git a/29_Craps/python/craps.py b/29_Craps/python/craps.py
    index dd01fa5e1..38faeed32 100644
    --- a/29_Craps/python/craps.py
    +++ b/29_Craps/python/craps.py
    @@ -14,70 +14,66 @@
     from random import randint
     
     
    -def throw_dice() -> int:
    +def throw_dice():
         return randint(1, 6) + randint(1, 6)
     
     
    -def main() -> None:
    -    print(" " * 33 + "Craps")
    -    print(" " * 15 + "Creative Computing  Morristown, New Jersey\n\n\n")
    +print(" " * 33 + "Craps")
    +print(" " * 15 + "Creative Computing  Morristown, New Jersey")
    +print()
    +print()
    +print()
     
    -    winnings = 0
    -    print("2,3,12 are losers; 4,5,6,8,9,10 are points; 7,11 are natural winners.")
    +winnings = 0
    +print("2,3,12 are losers; 4,5,6,8,9,10 are points; 7,11 are natural winners.")
     
    -    play_again = True
    -    while play_again:
    -        wager = int(input("Input the amount of your wager: "))
    +play_again = True
    +while play_again:
    +    wager = int(input("Input the amount of your wager: "))
     
    -        print("I will now throw the dice")
    -        roll_1 = throw_dice()
    +    print("I will now throw the dice")
    +    roll_1 = throw_dice()
     
    -        if roll_1 in [7, 11]:
    -            print(f"{roll_1} - natural.... a winner!!!!")
    -            print(f"{roll_1} pays even money, you win {wager} dollars")
    -            winnings += wager
    -        elif roll_1 == 2:
    -            print(f"{roll_1} - snake eyes.... you lose.")
    -            print(f"You lose {wager} dollars")
    -            winnings -= wager
    -        elif roll_1 in [3, 12]:
    -            print(f"{roll_1} - craps.... you lose.")
    -            print(f"You lose {wager} dollars")
    -            winnings -= wager
    -        else:
    -            print(f"{roll_1} is the point. I will roll again")
    -            roll_2 = 0
    -            while roll_2 not in [roll_1, 7]:
    -                roll_2 = throw_dice()
    -                if roll_2 == 7:
    -                    print(f"{roll_2} - craps. You lose.")
    -                    print(f"You lose $ {wager}")
    -                    winnings -= wager
    -                elif roll_2 == roll_1:
    -                    print(f"{roll_1} - a winner.........congrats!!!!!!!!")
    -                    print(
    -                        f"{roll_1} at 2 to 1 odds pays you...let me see... {2 * wager} dollars"
    -                    )
    -                    winnings += 2 * wager
    -                else:
    -                    print(f"{roll_2} - no point. I will roll again")
    -
    -        m = input("  If you want to play again print 5 if not print 2: ")
    -        if winnings < 0:
    -            print(f"You are now under ${-winnings}")
    -        elif winnings > 0:
    -            print(f"You are now ahead ${winnings}")
    -        else:
    -            print("You are now even at 0")
    -        play_again = m == "5"
    +    if roll_1 in [7, 11]:
    +        print(f"{roll_1} - natural.... a winner!!!!")
    +        print(f"{roll_1} pays even money, you win {wager} dollars")
    +        winnings += wager
    +    elif roll_1 == 2:
    +        print(f"{roll_1} - snake eyes.... you lose.")
    +        print(f"You lose {wager} dollars")
    +        winnings -= wager
    +    elif roll_1 in [3, 12]:
    +        print(f"{roll_1} - craps.... you lose.")
    +        print(f"You lose {wager} dollars")
    +        winnings -= wager
    +    else:
    +        print(f"{roll_1} is the point. I will roll again")
    +        roll_2 = 0
    +        while roll_2 not in [roll_1, 7]:
    +            roll_2 = throw_dice()
    +            if roll_2 == 7:
    +                print(f"{roll_2} - craps. You lose.")
    +                print(f"You lose $ {wager}")
    +                winnings -= wager
    +            elif roll_2 == roll_1:
    +                print(f"{roll_1} - a winner.........congrats!!!!!!!!")
    +                print(f"{roll_1} at 2 to 1 odds pays you...let me see... {2 * wager} dollars")
    +                winnings += 2 * wager
    +            else:
    +                print(f"{roll_2} - no point. I will roll again")
     
    +    m = input("  If you want to play again print 5 if not print 2: ")
         if winnings < 0:
    -        print("Too bad, you are in the hole. Come again.")
    +        print(f"You are now under ${-winnings}")
         elif winnings > 0:
    -        print("Congratulations---you came out a winner. Come again.")
    +        print(f"You are now ahead ${winnings}")
         else:
    -        print("Congratulations---you came out even, not bad for an amateur")
    -
    +        print("You are now even at 0")
    +    play_again = (m == "5")
     
    -if __name__ == "__main__":
    -    main()
    +if winnings < 0:
    +    print(f"Too bad, you are in the hole. Come again.")
    +elif winnings > 0:
    +    print(f"Congratulations---you came out a winner. Come again.")
    +else:
    +    print(f"Congratulations---you came out even, not bad for an amateur")
    diff --git a/29_Craps/ruby/craps.rb b/29_Craps/ruby/craps.rb
    deleted file mode 100644
    index 315f4ea07..000000000
    --- a/29_Craps/ruby/craps.rb
    +++ /dev/null
    @@ -1,124 +0,0 @@
    -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
    diff --git a/29_Craps/rust/Cargo.lock b/29_Craps/rust/Cargo.lock
    deleted file mode 100644
    index 4fe2abbea..000000000
    --- a/29_Craps/rust/Cargo.lock
    +++ /dev/null
    @@ -1,75 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.10"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.147"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/29_Craps/rust/Cargo.toml b/29_Craps/rust/Cargo.toml
    deleted file mode 100644
    index 3b1d02f52..000000000
    --- a/29_Craps/rust/Cargo.toml
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -[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/29_Craps/rust/src/craps_game.rs b/29_Craps/rust/src/craps_game.rs
    deleted file mode 100644
    index 1818c9c0f..000000000
    --- a/29_Craps/rust/src/craps_game.rs
    +++ /dev/null
    @@ -1,141 +0,0 @@
    -use crate::util;
    -
    -enum GameState {
    -    ComeOut,
    -    PointRolls,
    -    GameOver,
    -}
    -
    -pub struct CrapsGame {
    -    wallet: usize,
    -    bet: usize,
    -    point: u8,
    -    state: GameState,
    -}
    -
    -impl CrapsGame {
    -    pub fn new() -> Self {
    -        let wallet = util::read_numeric("\nHow much money do you want to start with?");
    -
    -        CrapsGame {
    -            wallet,
    -            bet: 0,
    -            point: 0,
    -            state: GameState::ComeOut,
    -        }
    -    }
    -
    -    pub fn tick(&mut self) -> bool {
    -        use GameState::*;
    -
    -        match self.state {
    -            ComeOut => self.new_round(),
    -            PointRolls => self.point_roll(),
    -            GameOver => false,
    -        }
    -    }
    -
    -    fn point_roll(&mut self) -> bool {
    -        let point = self.point;
    -
    -        println!("Rolling {point} wins. 7 loses.");
    -
    -        self.prompt_roll();
    -        let roll = CrapsGame::roll();
    -
    -        if roll == point {
    -            self.player_win();
    -        } else if roll == 7 {
    -            self.player_lose();
    -        }
    -
    -        true
    -    }
    -
    -    fn new_round(&mut self) -> bool {
    -        println!("\nCome out roll.");
    -        println!("7 and 11 win. 2, 3 and 12 lose.\n");
    -
    -        loop {
    -            self.bet = util::read_numeric("Enter your bet:");
    -
    -            if self.bet <= self.wallet {
    -                break;
    -            } else {
    -                println!("You don't have that much money!");
    -            }
    -        }
    -
    -        self.prompt_roll();
    -        let point = CrapsGame::roll();
    -
    -        match point {
    -            11 | 7 => {
    -                self.player_win();
    -            }
    -            2 | 3 | 12 => {
    -                self.player_lose();
    -            }
    -            _ => {
    -                self.point = point;
    -                self.state = GameState::PointRolls
    -            }
    -        }
    -
    -        true
    -    }
    -
    -    fn player_win(&mut self) {
    -        let bet = self.bet;
    -
    -        println!("You won ${bet}!");
    -
    -        self.wallet += bet;
    -        self.print_wallet();
    -
    -        self.state = GameState::ComeOut;
    -    }
    -
    -    fn player_lose(&mut self) {
    -        let bet = self.bet;
    -
    -        println!("You lost ${bet}!");
    -
    -        self.wallet -= bet;
    -        self.print_wallet();
    -
    -        if self.wallet == 0 {
    -            self.game_over();
    -        } else {
    -            self.state = GameState::ComeOut;
    -        }
    -    }
    -
    -    fn print_wallet(&self) {
    -        println!("\nYou have ${} in your wallet.", self.wallet);
    -    }
    -
    -    fn roll() -> u8 {
    -        use rand::Rng;
    -
    -        let roll = rand::thread_rng().gen_range(2..13);
    -        println!("\nYou rolled {}.", roll);
    -
    -        roll
    -    }
    -
    -    fn game_over(&mut self) {
    -        self.state = GameState::GameOver;
    -    }
    -
    -    fn prompt_roll(&mut self) {
    -        use util::Response::*;
    -
    -        let response = util::prompt("Ready to roll?");
    -
    -        match response {
    -            Yes => (),
    -            No => self.game_over(),
    -        }
    -    }
    -}
    diff --git a/29_Craps/rust/src/main.rs b/29_Craps/rust/src/main.rs
    deleted file mode 100644
    index f19e37182..000000000
    --- a/29_Craps/rust/src/main.rs
    +++ /dev/null
    @@ -1,27 +0,0 @@
    -mod craps_game;
    -mod util;
    -use crate::craps_game::CrapsGame;
    -
    -fn main() {
    -    println!("~~Craps~~");
    -    println!("Creative Computing Morristown, New Jersey\n");
    -
    -    let mut quit = false;
    -
    -    while !quit {
    -        let mut game = CrapsGame::new();
    -
    -        loop {
    -            if !game.tick() {
    -                use util::Response::*;
    -
    -                match util::prompt("New Game?") {
    -                    Yes => (),
    -                    No => quit = true,
    -                }
    -
    -                break;
    -            }
    -        }
    -    }
    -}
    diff --git a/29_Craps/rust/src/util.rs b/29_Craps/rust/src/util.rs
    deleted file mode 100644
    index 9fdd8b989..000000000
    --- a/29_Craps/rust/src/util.rs
    +++ /dev/null
    @@ -1,71 +0,0 @@
    -use std::io;
    -
    -pub enum Response {
    -    Yes,
    -    No,
    -}
    -
    -pub fn read_line() -> String {
    -    let mut input = String::new();
    -
    -    io::stdin()
    -        .read_line(&mut input)
    -        .expect("Error reading line.");
    -
    -    input
    -}
    -
    -pub fn read_numeric(message: &str) -> usize {
    -    loop {
    -        println!("{}", message);
    -
    -        let mut ok = true;
    -
    -        let input = read_line();
    -
    -        for c in input.trim().chars() {
    -            if !c.is_numeric() {
    -                println!("You can only enter a number!");
    -                ok = false;
    -                break;
    -            }
    -        }
    -
    -        if ok {
    -            let input = input.trim().parse();
    -
    -            let _ = match input {
    -                Ok(i) => return i,
    -                Err(e) => {
    -                    println!("please input a number ({})", e);
    -                }
    -            };
    -        }
    -    }
    -}
    -
    -pub fn prompt(msg: &str) -> Response {
    -    use Response::*;
    -
    -    let mut _r = Response::Yes;
    -
    -    loop {
    -        println!("\n{}", msg);
    -
    -        let response = read_line().trim().to_uppercase();
    -
    -        match response.as_str() {
    -            "YES" | "Y" => {
    -                _r = Yes;
    -                break;
    -            }
    -            "NO" | "N" => {
    -                _r = No;
    -                break;
    -            }
    -            _ => println!("Please input (Y)es or (N)o."),
    -        };
    -    }
    -
    -    _r
    -}
    diff --git a/29_Craps/vbnet/Craps.sln b/29_Craps/vbnet/Craps.sln
    deleted file mode 100644
    index 7d5645082..000000000
    --- a/29_Craps/vbnet/Craps.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index a1c6ee273..000000000
    --- a/29_Craps/vbnet/Craps.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Craps
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/30_Cube/README.md b/30_Cube/README.md
    index a257f1105..41973db17 100644
    --- a/30_Cube/README.md
    +++ b/30_Cube/README.md
    @@ -12,39 +12,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    -
    -##### Known Bugs
    -
    -This program does very little validation of its input, enabling the user to cheat in two ways:
    -- One can enter a large negative wager, purposely lose, and gain that much money.
    -- One can move outside the cube (using coordinates 0 or 4), then safely walk "around" the standard play volume to the destination square.
    -
    -It's remotely possible that these are clever solutions the user is intended to find, solving an otherwise purely random game.
    -
    -##### Randomization Logic
    -
    -The BASIC code uses an interesting technique for choosing the random coordinates for the mines. The first coordinate is
    -chosen like this:
    -
    -```basic
    -380 LET A=INT(3*(RND(X)))
    -390 IF A<>0 THEN 410
    -400 LET A=3
    -```
    -
    -where line 410 is the start of a similar block of code for the next coordinate. The behaviour of `RND(X)` depends on the
    -value of `X`. If `X` is greater than zero then it returns a random value between 0 and 1. If `X` is zero it returns the
    -last random value generated, or 0 if no value has yet been generated.
    -
    -If `X` is 1, therefore, the first line above set `A` to 0, 1, or 2. The next 2 lines replace a 0 with a 3. The
    -replacement values varies for the different coordinates with the result that the random selection is biased towards a
    -specific set of points. If `X` is 0, the `RND` calls all return 0, so the coordinates are the known. It appears that
    -this technique was probably used to allow testing the game with a well-known set of locations for the mines. However, in
    -the code as it comes to us, the value of `X` is never set and is thus 0, so the mine locations are never randomized.
    -
    -The C# port implements the biased randomized mine locations, as seems to be the original intent, but includes a
    -command-line switch to enable the deterministic execution as well.
    diff --git a/30_Cube/csharp/Cube.csproj b/30_Cube/csharp/Cube.csproj
    deleted file mode 100644
    index 3870320c9..000000000
    --- a/30_Cube/csharp/Cube.csproj
    +++ /dev/null
    @@ -1,17 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    -  
    -    
    -  
    -
    -  
    -    
    -  
    -
    diff --git a/30_Cube/csharp/Cube.sln b/30_Cube/csharp/Cube.sln
    deleted file mode 100644
    index be69dc761..000000000
    --- a/30_Cube/csharp/Cube.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/csharp/Game.cs b/30_Cube/csharp/Game.cs
    deleted file mode 100644
    index a06ec565e..000000000
    --- a/30_Cube/csharp/Game.cs
    +++ /dev/null
    @@ -1,104 +0,0 @@
    -namespace Cube;
    -
    -internal class Game
    -{
    -    private const int _initialBalance = 500;
    -    private readonly IEnumerable<(int, int, int)> _seeds = new List<(int, int, int)>
    -    {
    -        (3, 2, 3), (1, 3, 3), (3, 3, 2), (3, 2, 3), (3, 1, 3)
    -    };
    -    private readonly (float, float, float) _startLocation = (1, 1, 1);
    -    private readonly (float, float, float) _goalLocation = (3, 3, 3);
    -
    -    private readonly IReadWrite _io;
    -    private readonly IRandom _random;
    -
    -    public Game(IReadWrite io, IRandom random)
    -    {
    -        _io = io;
    -        _random = random;
    -    }
    -
    -    public void Play()
    -    {
    -        _io.Write(Streams.Introduction);
    -
    -        if (_io.ReadNumber("") != 0)
    -        {
    -            _io.Write(Streams.Instructions);
    -        }
    -
    -        PlaySeries(_initialBalance);
    -
    -        _io.Write(Streams.Goodbye);
    -    }
    -
    -    private void PlaySeries(float balance)
    -    {
    -        while (true)
    -        {
    -            var wager = _io.ReadWager(balance);
    -
    -            var gameWon = PlayGame();
    -
    -            if (wager.HasValue)
    -            {
    -                balance = gameWon ? (balance + wager.Value) : (balance - wager.Value);
    -                if (balance <= 0)
    -                {
    -                    _io.Write(Streams.Bust);
    -                    return;
    -                }
    -                _io.WriteLine(Formats.Balance, balance);
    -            }
    -
    -            if (_io.ReadNumber(Prompts.TryAgain) != 1) { return; }
    -        }
    -    }
    -
    -    private bool PlayGame()
    -    {
    -        var mineLocations = _seeds.Select(seed => _random.NextLocation(seed)).ToHashSet();
    -        var currentLocation = _startLocation;
    -        var prompt = Prompts.YourMove;
    -
    -        while (true)
    -        {
    -            var newLocation = _io.Read3Numbers(prompt);
    -
    -            if (!MoveIsLegal(currentLocation, newLocation)) { return Lose(Streams.IllegalMove); }
    -
    -            currentLocation = newLocation;
    -
    -            if (currentLocation == _goalLocation) { return Win(Streams.Congratulations); }
    -
    -            if (mineLocations.Contains(currentLocation)) { return Lose(Streams.Bang); }
    -
    -            prompt = Prompts.NextMove;
    -        }
    -    }
    -
    -    private bool Lose(Stream text)
    -    {
    -        _io.Write(text);
    -        return false;
    -    }
    -
    -    private bool Win(Stream text)
    -    {
    -        _io.Write(text);
    -        return true;
    -    }
    -
    -    private bool MoveIsLegal((float, float, float) from, (float, float, float) to)
    -        => (to.Item1 - from.Item1, to.Item2 - from.Item2, to.Item3 - from.Item3) switch
    -        {
    -            ( > 1, _, _) => false,
    -            (_, > 1, _) => false,
    -            (_, _, > 1) => false,
    -            (1, 1, _) => false,
    -            (1, _, 1) => false,
    -            (_, 1, 1) => false,
    -            _ => true
    -        };
    -}
    diff --git a/30_Cube/csharp/IOExtensions.cs b/30_Cube/csharp/IOExtensions.cs
    deleted file mode 100644
    index 14f2a85e1..000000000
    --- a/30_Cube/csharp/IOExtensions.cs
    +++ /dev/null
    @@ -1,20 +0,0 @@
    -namespace Cube;
    -
    -internal static class IOExtensions
    -{
    -    internal static float? ReadWager(this IReadWrite io, float balance)
    -    {
    -        io.Write(Streams.Wager);
    -        if (io.ReadNumber("") == 0) { return null; }
    -
    -        var prompt = Prompts.HowMuch;
    -
    -        while(true)
    -        {
    -            var wager = io.ReadNumber(prompt);
    -            if (wager <= balance) { return wager; }
    -
    -            prompt = Prompts.BetAgain;
    -        }
    -    }
    -}
    diff --git a/30_Cube/csharp/Program.cs b/30_Cube/csharp/Program.cs
    deleted file mode 100644
    index 803a569a5..000000000
    --- a/30_Cube/csharp/Program.cs
    +++ /dev/null
    @@ -1,10 +0,0 @@
    -global using Games.Common.IO;
    -global using Games.Common.Randomness;
    -
    -global using static Cube.Resources.Resource;
    -
    -using Cube;
    -
    -IRandom random = args.Contains("--non-random") ? new ZerosGenerator() : new RandomNumberGenerator();
    -
    -new Game(new ConsoleIO(), random).Play();
    diff --git a/30_Cube/csharp/README.md b/30_Cube/csharp/README.md
    index 7bea3d88b..4daabb5c1 100644
    --- a/30_Cube/csharp/README.md
    +++ b/30_Cube/csharp/README.md
    @@ -1,12 +1,3 @@
     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/)
    -
    -#### Execution
    -
    -As noted in the main Readme file, the randomization code in the BASIC program has a switch (the variable `X`) that
    -allows the game to be run in a deterministic (non-random) mode.
    -
    -Running the C# port without command-line parameters will play the game with random mine locations.
    -
    -Running the port with a `--non-random` command-line switch will run the game with non-random mine locations.
    diff --git a/30_Cube/csharp/RandomExtensions.cs b/30_Cube/csharp/RandomExtensions.cs
    deleted file mode 100644
    index ac05108e7..000000000
    --- a/30_Cube/csharp/RandomExtensions.cs
    +++ /dev/null
    @@ -1,14 +0,0 @@
    -namespace Cube;
    -
    -internal static class RandomExtensions
    -{
    -    internal static (float, float, float) NextLocation(this IRandom random, (int, int, int) bias)
    -        => (random.NextCoordinate(bias.Item1), random.NextCoordinate(bias.Item2), random.NextCoordinate(bias.Item3));
    -
    -    private static float NextCoordinate(this IRandom random, int bias)
    -    {
    -        var value = random.Next(3);
    -        if (value == 0) { value = bias; }
    -        return value;
    -    }
    -}
    \ No newline at end of file
    diff --git a/30_Cube/csharp/Resources/Balance.txt b/30_Cube/csharp/Resources/Balance.txt
    deleted file mode 100644
    index 1f6adffd8..000000000
    --- a/30_Cube/csharp/Resources/Balance.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -You now have {0} dollars.
    \ No newline at end of file
    diff --git a/30_Cube/csharp/Resources/Bang.txt b/30_Cube/csharp/Resources/Bang.txt
    deleted file mode 100644
    index 1d9247887..000000000
    --- a/30_Cube/csharp/Resources/Bang.txt
    +++ /dev/null
    @@ -1,4 +0,0 @@
    -******BANG******
    -You lose!
    -
    -
    diff --git a/30_Cube/csharp/Resources/BetAgain.txt b/30_Cube/csharp/Resources/BetAgain.txt
    deleted file mode 100644
    index 47c9fb8c4..000000000
    --- a/30_Cube/csharp/Resources/BetAgain.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Tried to fool me; bet again
    \ No newline at end of file
    diff --git a/30_Cube/csharp/Resources/Bust.txt b/30_Cube/csharp/Resources/Bust.txt
    deleted file mode 100644
    index cd753d988..000000000
    --- a/30_Cube/csharp/Resources/Bust.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -You bust.
    diff --git a/30_Cube/csharp/Resources/Congratulations.txt b/30_Cube/csharp/Resources/Congratulations.txt
    deleted file mode 100644
    index 3319c833a..000000000
    --- a/30_Cube/csharp/Resources/Congratulations.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Congratulations!
    diff --git a/30_Cube/csharp/Resources/Goodbye.txt b/30_Cube/csharp/Resources/Goodbye.txt
    deleted file mode 100644
    index 0aa641929..000000000
    --- a/30_Cube/csharp/Resources/Goodbye.txt
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Tough luck!
    -
    -Goodbye.
    diff --git a/30_Cube/csharp/Resources/HowMuch.txt b/30_Cube/csharp/Resources/HowMuch.txt
    deleted file mode 100644
    index ff2bea20b..000000000
    --- a/30_Cube/csharp/Resources/HowMuch.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -How much 
    \ No newline at end of file
    diff --git a/30_Cube/csharp/Resources/IllegalMove.txt b/30_Cube/csharp/Resources/IllegalMove.txt
    deleted file mode 100644
    index ca8f96ba1..000000000
    --- a/30_Cube/csharp/Resources/IllegalMove.txt
    +++ /dev/null
    @@ -1,2 +0,0 @@
    -
    -Illegal move. You lose.
    diff --git a/30_Cube/csharp/Resources/Instructions.txt b/30_Cube/csharp/Resources/Instructions.txt
    deleted file mode 100644
    index e82ae51e9..000000000
    --- a/30_Cube/csharp/Resources/Instructions.txt
    +++ /dev/null
    @@ -1,24 +0,0 @@
    -This is a game in which you will be playing against the
    -random decision od the computer. The field of play is a
    -cube of side 3. Any of the 27 locations can be designated
    -by inputing three numbers such as 2,3,1. At the start,
    -you are automatically at location 1,1,1. The object of
    -the game is to get to location 3,3,3. One minor detail:
    -the computer will pick, at random, 5 locations at which
    -it will play land mines. If you hit one of these locations
    -you lose. One other details: you may move only one space
    -in one direction each move. For example: from 1,1,2 you
    -may move to 2,1,2 or 1,1,3. You may not change
    -two of the numbers on the same move. If you make an illegal
    -move, you lose and the computer takes the money you may
    -have bet on that round.
    -
    -
    -All Yes or No questions will be answered by a 1 for Yes
    -or a 0 (zero) for no.
    -
    -When stating the amount of a wager, print only the number
    -of dollars (example: 250)  You are automatically started with
    -500 dollars in your account.
    -
    -Good luck!
    diff --git a/30_Cube/csharp/Resources/Introduction.txt b/30_Cube/csharp/Resources/Introduction.txt
    deleted file mode 100644
    index 6299d19bd..000000000
    --- a/30_Cube/csharp/Resources/Introduction.txt
    +++ /dev/null
    @@ -1,6 +0,0 @@
    -                                  Cube
    -               Creative Computing  Morristown, New Jersey
    -
    -
    -
    -Do you want to see the instructions? (Yes--1,No--0)
    diff --git a/30_Cube/csharp/Resources/NextMove.txt b/30_Cube/csharp/Resources/NextMove.txt
    deleted file mode 100644
    index 4cbe54967..000000000
    --- a/30_Cube/csharp/Resources/NextMove.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Next move: 
    \ No newline at end of file
    diff --git a/30_Cube/csharp/Resources/Resource.cs b/30_Cube/csharp/Resources/Resource.cs
    deleted file mode 100644
    index c3ed10c71..000000000
    --- a/30_Cube/csharp/Resources/Resource.cs
    +++ /dev/null
    @@ -1,44 +0,0 @@
    -using System.Reflection;
    -using System.Runtime.CompilerServices;
    -
    -namespace Cube.Resources;
    -
    -internal static class Resource
    -{
    -    internal static class Streams
    -    {
    -        public static Stream Introduction => GetStream();
    -        public static Stream Instructions => GetStream();
    -        public static Stream Wager => GetStream();
    -        public static Stream IllegalMove => GetStream();
    -        public static Stream Bang => GetStream();
    -        public static Stream Bust => GetStream();
    -        public static Stream Congratulations => GetStream();
    -        public static Stream Goodbye => GetStream();
    -    }
    -
    -    internal static class Prompts
    -    {
    -        public static string HowMuch => GetString();
    -        public static string BetAgain => GetString();
    -        public static string YourMove => GetString();
    -        public static string NextMove => GetString();
    -        public static string TryAgain => GetString();
    -    }
    -
    -    internal static class Formats
    -    {
    -        public static string Balance => GetString();
    -    }
    -
    -    private static string GetString([CallerMemberName] string? name = null)
    -    {
    -        using var stream = GetStream(name);
    -        using var reader = new StreamReader(stream);
    -        return reader.ReadToEnd();
    -    }
    -
    -    private static Stream GetStream([CallerMemberName] string? name = null) =>
    -        Assembly.GetExecutingAssembly().GetManifestResourceStream($"{typeof(Resource).Namespace}.{name}.txt")
    -            ?? throw new Exception($"Could not find embedded resource stream '{name}'.");
    -}
    \ No newline at end of file
    diff --git a/30_Cube/csharp/Resources/TryAgain.txt b/30_Cube/csharp/Resources/TryAgain.txt
    deleted file mode 100644
    index 9ccf358a5..000000000
    --- a/30_Cube/csharp/Resources/TryAgain.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Do you want to try again 
    \ No newline at end of file
    diff --git a/30_Cube/csharp/Resources/Wager.txt b/30_Cube/csharp/Resources/Wager.txt
    deleted file mode 100644
    index 04720a7a4..000000000
    --- a/30_Cube/csharp/Resources/Wager.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Want to make a wager
    diff --git a/30_Cube/csharp/Resources/YourMove.txt b/30_Cube/csharp/Resources/YourMove.txt
    deleted file mode 100644
    index 5ea0c5449..000000000
    --- a/30_Cube/csharp/Resources/YourMove.txt
    +++ /dev/null
    @@ -1,2 +0,0 @@
    -
    -It's your move:  
    \ No newline at end of file
    diff --git a/30_Cube/csharp/ZerosGenerator.cs b/30_Cube/csharp/ZerosGenerator.cs
    deleted file mode 100644
    index 4490f606f..000000000
    --- a/30_Cube/csharp/ZerosGenerator.cs
    +++ /dev/null
    @@ -1,10 +0,0 @@
    -namespace Cube;
    -
    -internal class ZerosGenerator : IRandom
    -{
    -    public float NextFloat() => 0;
    -
    -    public float PreviousFloat() => 0;
    -
    -    public void Reseed(int seed) { }
    -}
    \ No newline at end of file
    diff --git a/30_Cube/cube.bas b/30_Cube/cube.bas
    index b20198396..1e4462f66 100644
    --- a/30_Cube/cube.bas
    +++ b/30_Cube/cube.bas
    @@ -131,13 +131,13 @@
     1360 GOTO 1380
     1370 IF R=O THEN 1400
     1380 PRINT "NEXT MOVE: ";
    -1390 GOTO 930
    +1390 GOTO 930 
     1400 PRINT"******BANG******"
     1410 PRINT "YOU LOSE!"
     1420 PRINT
     1430 PRINT
     1440 IF   Z=0 THEN 1580
    -1450 PRINT
    +1450 PRINT 
     1460 LET Z2=A1-Z1
     1470 IF Z2>0 THEN 1500
     1480 PRINT "YOU BUST."
    diff --git a/30_Cube/javascript/cube.html b/30_Cube/javascript/cube.html
    index 85218e9b6..9951018d1 100644
    --- a/30_Cube/javascript/cube.html
    +++ b/30_Cube/javascript/cube.html
    @@ -1,10 +1,9 @@
     
     
     CUBE
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/30_Cube/javascript/cube.js b/30_Cube/javascript/cube.js
    index d2b54ff4d..edbaaedcd 100644
    --- a/30_Cube/javascript/cube.js
    +++ b/30_Cube/javascript/cube.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/30_Cube/kotlin/README.md b/30_Cube/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/30_Cube/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/30_Cube/lua/README.md b/30_Cube/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/30_Cube/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/30_Cube/pascal/README.md b/30_Cube/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/30_Cube/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/30_Cube/python/cube.py b/30_Cube/python/cube.py
    index 260882dd1..8bb540e09 100755
    --- a/30_Cube/python/cube.py
    +++ b/30_Cube/python/cube.py
    @@ -1,27 +1,19 @@
     #!/usr/bin/env python3
    -
    -"""
    -CUBE
    -
    -Converted from BASIC to Python by Trevor Hobson
    -"""
    +# CUBE
    +#
    +# Converted from BASIC to Python by Trevor Hobson
     
     import random
    -from typing import Tuple
    -
     
    -def mine_position() -> Tuple[int, int, int]:
    -    return (random.randint(1, 3), random.randint(1, 3), random.randint(1, 3))
     
    +def mine_position():
    +    mine = []
    +    for _ in range(3):
    +        mine.append(random.randint(1, 3))
    +    return mine
     
    -def parse_move(move: str) -> Tuple[int, int, int]:
    -    coordinates = [int(item) for item in move.split(",")]
    -    if len(coordinates) == 3:
    -        return tuple(coordinates)  # type: ignore
    -    raise ValueError
     
    -
    -def play_game() -> None:
    +def play_game():
         """Play one round of the game"""
     
         money = 500
    @@ -29,13 +21,10 @@ def play_game() -> None:
         while True:
             mines = []
             for _ in range(5):
    +            mine = []
                 while True:
                     mine = mine_position()
    -                if (
    -                    mine not in mines
    -                    and mine != (1, 1, 1)
    -                    and mine != (3, 3, 3)
    -                ):
    +                if not(mine in mines or mine == [1, 1, 1] or mine == [3, 3, 3]):
                         break
                 mines.append(mine)
             wager = -1
    @@ -48,31 +37,28 @@ def play_game() -> None:
                 except ValueError:
                     print("Please enter a number.")
             prompt = "\nIt's your move: "
    -        position = (1, 1, 1)
    +        position = [1, 1, 1]
             while True:
    -            move = (-1, -1, -1)
    -            while move == (-1, -1, -1):
    +            move = [-1, -1, -1]
    +            while move == [-1, -1, -1]:
                     try:
    -                    move = parse_move(input(prompt))
    +                    coordinates = [int(item)
    +                                   for item in input(prompt).split(",")]
    +                    if len(coordinates) == 3:
    +                        move = coordinates
    +                    else:
    +                        raise ValueError
                     except (ValueError, IndexError):
                         print("Please enter valid coordinates.")
    -            if (
    -                abs(move[0] - position[0])
    -                + abs(move[1] - position[1])
    -                + abs(move[2] - position[2])
    -            ) > 1:
    +            if (abs(move[0]-position[0]) + abs(move[1]-position[1]) + abs(move[2]-position[2])) > 1:
                     print("\nIllegal move. You lose")
                     money = money - wager
                     break
    -            elif (
    -                move[0] not in [1, 2, 3]
    -                or move[1] not in [1, 2, 3]
    -                or move[2] not in [1, 2, 3]
    -            ):
    +            elif not move[0] in [1, 2, 3] or not move[1] in [1, 2, 3] or not move[2] in [1, 2, 3]:
                     print("\nIllegal move. You lose")
                     money = money - wager
                     break
    -            elif move == (3, 3, 3):
    +            elif move == [3, 3, 3]:
                     print("\nCongratulations!")
                     money = money + wager
                     break
    @@ -94,37 +80,34 @@ def play_game() -> None:
         print("\nGoodbye.")
     
     
    -def print_instructions() -> None:
    -    print("\nThis is a game in which you will be playing against the")
    -    print("random decisions of the computer. The field of play is a")
    -    print("cube of side 3. Any of the 27 locations can be designated")
    -    print("by inputing three numbers such as 2,3,1. At the start,")
    -    print("you are automatically at location 1,1,1. The object of")
    -    print("the game is to get to location 3,3,3. One minor detail:")
    -    print("the computer will pick, at random, 5 locations at which")
    -    print("it will plant land mines. If you hit one of these locations")
    -    print("you lose. One other detail: You may move only one space")
    -    print("in one direction each move. For example: From 1,1,2 you")
    -    print("may move to 2,1,2 or 1,1,3. You may not change")
    -    print("two of the numbers on the same move. If you make an illegal")
    -    print("move, you lose and the computer takes the money you may")
    -    print("have bet on that round.\n")
    -    print("When stating the amount of a wager, print only the number")
    -    print("of dollars (example: 250) you are automatically started with")
    -    print("500 dollars in your account.\n")
    -    print("Good luck!")
    -
    -
    -def main() -> None:
    +def main():
         print(" " * 34 + "CUBE")
         print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n")
         if input("Do you want to see the instructions ").lower().startswith("y"):
    -        print_instructions()
    +        print("\nThis is a game in which you will be playing against the")
    +        print("random decisions of the computer. The field of play is a")
    +        print("cube of side 3. Any of the 27 locations can be designated")
    +        print("by inputing three numbers such as 2,3,1. At the start,")
    +        print("you are automatically at location 1,1,1. The object of")
    +        print("the game is to get to location 3,3,3. One minor detail:")
    +        print("the computer will pick, at random, 5 locations at which")
    +        print("it will plant land mines. If you hit one of these locations")
    +        print("you lose. One other detail: You may move only one space")
    +        print("in one direction each move. For example: From 1,1,2 you")
    +        print("may move to 2,1,2 or 1,1,3. You may not change")
    +        print("two of the numbers on the same move. If you make an illegal")
    +        print("move, you lose and the computer takes the money you may")
    +        print("have bet on that round.\n")
    +        print("When stating the amount of a wager, print only the number")
    +        print("of dollars (example: 250) you are automatically started with")
    +        print("500 dollars in your account.\n")
    +        print("Good luck!")
     
         keep_playing = True
         while keep_playing:
             play_game()
    -        keep_playing = input("\nPlay again? (yes or no) ").lower().startswith("y")
    +        keep_playing = input(
    +            "\nPlay again? (yes or no) ").lower().startswith("y")
     
     
     if __name__ == "__main__":
    diff --git a/30_Cube/ruby/cube.rb b/30_Cube/ruby/cube.rb
    deleted file mode 100644
    index 3badc8acd..000000000
    --- a/30_Cube/ruby/cube.rb
    +++ /dev/null
    @@ -1,260 +0,0 @@
    -$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
    diff --git a/30_Cube/rust/Cargo.lock b/30_Cube/rust/Cargo.lock
    deleted file mode 100644
    index 4fe2abbea..000000000
    --- a/30_Cube/rust/Cargo.lock
    +++ /dev/null
    @@ -1,75 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.10"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.147"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/30_Cube/rust/Cargo.toml b/30_Cube/rust/Cargo.toml
    deleted file mode 100644
    index 3b1d02f52..000000000
    --- a/30_Cube/rust/Cargo.toml
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -[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/30_Cube/rust/src/game.rs b/30_Cube/rust/src/game.rs
    deleted file mode 100644
    index 6b783b59e..000000000
    --- a/30_Cube/rust/src/game.rs
    +++ /dev/null
    @@ -1,106 +0,0 @@
    -use crate::util;
    -
    -pub type Position = (u8, u8, u8);
    -
    -pub struct Game {
    -    wallet: usize,
    -    bet: Option,
    -    landmines: Vec,
    -    player: Position,
    -}
    -
    -impl Game {
    -    pub fn new() -> Self {
    -        Game {
    -            wallet: 500,
    -            bet: None,
    -            landmines: util::get_landmines(),
    -            player: (1, 1, 1),
    -        }
    -    }
    -
    -    pub fn play(&mut self) -> bool {
    -        self.bet = self.get_bet();
    -
    -        let mut first_move = true;
    -        let mut result = (false, "******BANG!******\nYOU LOSE");
    -
    -        loop {
    -            let msg = if first_move {
    -                first_move = false;
    -                "ITS YOUR MOVE"
    -            } else {
    -                "NEXT MOVE"
    -            };
    -
    -            let (ok, p) = self.ask_position(msg);
    -
    -            if ok {
    -                if p == (3, 3, 3) {
    -                    result.0 = true;
    -                    result.1 = "CONGRATULATIONS!";
    -                    break;
    -                } else if self.landmines.contains(&p) {
    -                    break;
    -                } else {
    -                    self.player = p;
    -                }
    -            } else {
    -                result.1 = "ILLEGAL MOVE\nYOU LOSE.";
    -                break;
    -            }
    -        }
    -
    -        println!("{}", result.1);
    -        self.calculate_wallet(result.0);
    -        self.reset_game();
    -
    -        if self.wallet <= 0 {
    -            println!("YOU ARE BROKE!");
    -            return false;
    -        }
    -
    -        return util::prompt_bool("DO YOU WANT TO TRY AGAIN?");
    -    }
    -
    -    fn get_bet(&self) -> Option {
    -        loop {
    -            if util::prompt_bool("WANT TO MAKE A WAGER?") {
    -                let b = util::prompt_number("HOW MUCH?");
    -
    -                if b != 0 && b <= self.wallet {
    -                    return Some(b);
    -                } else {
    -                    println!("YOU CAN'T BET THAT!");
    -                }
    -            } else {
    -                return None;
    -            };
    -        }
    -    }
    -
    -    fn ask_position(&self, msg: &str) -> (bool, Position) {
    -        if let Some(p) = util::prompt_position(msg, self.player) {
    -            return (true, p);
    -        }
    -        return (false, (0, 0, 0));
    -    }
    -
    -    fn calculate_wallet(&mut self, win: bool) {
    -        if let Some(b) = self.bet {
    -            if win {
    -                self.wallet += b;
    -            } else {
    -                self.wallet -= b;
    -            }
    -            self.bet = None;
    -            println!("YOU NOW HAVE {} DOLLARS", self.wallet);
    -        }
    -    }
    -
    -    fn reset_game(&mut self) {
    -        self.player = (1, 1, 1);
    -        self.landmines.clear();
    -        self.landmines = util::get_landmines();
    -    }
    -}
    diff --git a/30_Cube/rust/src/main.rs b/30_Cube/rust/src/main.rs
    deleted file mode 100644
    index 94c3146e1..000000000
    --- a/30_Cube/rust/src/main.rs
    +++ /dev/null
    @@ -1,39 +0,0 @@
    -use crate::game::Game;
    -
    -mod game;
    -mod util;
    -
    -fn main() {
    -    println!("\n\n\t\tCUBE");
    -    println!("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
    -
    -    if util::prompt_bool("DO YOU WANT TO SEE THE INSTRUCTIONS? (YES--1,NO--0)") {
    -        println!("\nThis is a game in which you will be playing against the");
    -        println!("random decisions of the computer. The field of play is a");
    -        println!("cube of side 3. Any of the 27 locations can be designated");
    -        println!("by inputing three numbers such as 2,3,1. At the start,");
    -        println!("you are automatically at location 1,1,1. The object of");
    -        println!("the game is to get to location 3,3,3. One minor detail:");
    -        println!("the computer will pick, at random, 5 locations at which");
    -        println!("it will plant land mines. If you hit one of these locations");
    -        println!("you lose. One other detail: You may move only one space");
    -        println!("in one direction each move. For example: From 1,1,2 you");
    -        println!("may move to 2,1,2 or 1,1,3. You may not change");
    -        println!("two of the numbers on the same move. If you make an illegal");
    -        println!("move, you lose and the computer takes the money you may");
    -        println!("have bet on that round.\n");
    -        println!("When stating the amount of a wager, print only the number");
    -        println!("of dollars (example: 250) you are automatically started with");
    -        println!("500 dollars in your account.\n");
    -        println!("Good luck!\n");
    -    }
    -
    -    let mut game = Game::new();
    -
    -    loop {
    -        if !game.play() {
    -            println!("\nTOUGH LUCK\n\nGOODBYE!\n");
    -            break;
    -        }
    -    }
    -}
    diff --git a/30_Cube/rust/src/util.rs b/30_Cube/rust/src/util.rs
    deleted file mode 100644
    index cb854beb8..000000000
    --- a/30_Cube/rust/src/util.rs
    +++ /dev/null
    @@ -1,117 +0,0 @@
    -use std::num::ParseIntError;
    -
    -use crate::game::Position;
    -
    -pub fn get_random_position() -> Position {
    -    (get_random_axis(), get_random_axis(), get_random_axis())
    -}
    -
    -fn get_random_axis() -> u8 {
    -    rand::Rng::gen_range(&mut rand::thread_rng(), 1..=3)
    -}
    -
    -pub fn get_landmines() -> Vec {
    -    let mut landmines = Vec::new();
    -
    -    for _ in 0..5 {
    -        let mut m = get_random_position();
    -        while landmines.contains(&m) {
    -            m = get_random_position();
    -        }
    -        landmines.push(m);
    -    }
    -
    -    landmines
    -}
    -
    -fn read_line() -> Result {
    -    let mut input = String::new();
    -    std::io::stdin()
    -        .read_line(&mut input)
    -        .expect("~~Failed reading line!~~");
    -    input.trim().parse::()
    -}
    -
    -pub fn prompt_bool(msg: &str) -> bool {
    -    loop {
    -        println!("{}", msg);
    -
    -        if let Ok(n) = read_line() {
    -            if n == 1 {
    -                return true;
    -            } else if n == 0 {
    -                return false;
    -            }
    -        }
    -        println!("ENTER YES--1 OR NO--0\n");
    -    }
    -}
    -
    -pub fn prompt_number(msg: &str) -> usize {
    -    loop {
    -        println!("{}", msg);
    -
    -        if let Ok(n) = read_line() {
    -            return n;
    -        }
    -        println!("ENTER A NUMBER\n");
    -    }
    -}
    -
    -pub fn prompt_position(msg: &str, prev_pos: Position) -> Option {
    -    loop {
    -        println!("{}", msg);
    -
    -        let mut input = String::new();
    -        std::io::stdin()
    -            .read_line(&mut input)
    -            .expect("~~Failed reading line!~~");
    -
    -        let input: Vec<&str> = input.trim().split(",").collect();
    -
    -        let pp = [prev_pos.0, prev_pos.1, prev_pos.2];
    -        let mut pos = Vec::new();
    -
    -        if input.len() != 3 {
    -            println!("YOU MUST ENTER 3 AXES!");
    -        } else {
    -            for a in input {
    -                if let Ok(n) = a.parse::() {
    -                    if n == 0 || n > 3 {
    -                        println!("YOU MUST ENTER AN AXIS BETWEEN 1 AND 3!");
    -                    } else {
    -                        pos.push(n);
    -                    }
    -                } else {
    -                    println!("INVALID LOCATION.");
    -                }
    -            }
    -
    -            let mut moved = false;
    -            for (i, p) in pos.iter().enumerate() {
    -                let dt = ((*p as isize) - (pp[i] as isize)).abs();
    -
    -                if dt > 1 {
    -                    return None;
    -                }
    -
    -                if dt == 1 {
    -                    if moved {
    -                        return None;
    -                    } else {
    -                        moved = true;
    -                    }
    -                }
    -            }
    -        }
    -
    -        if pos.len() == 3 {
    -            let pos = (pos[0], pos[1], pos[2]);
    -            if pos == prev_pos {
    -                println!("YOU ARE ALREADY THERE!");
    -            } else {
    -                return Some(pos);
    -            }
    -        }
    -    }
    -}
    diff --git a/30_Cube/vbnet/Cube.sln b/30_Cube/vbnet/Cube.sln
    deleted file mode 100644
    index 36f7fc751..000000000
    --- a/30_Cube/vbnet/Cube.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 1cbe484d1..000000000
    --- a/30_Cube/vbnet/Cube.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Cube
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/31_Depth_Charge/README.md b/31_Depth_Charge/README.md
    index 36b29acd4..1a0ed7a4f 100644
    --- a/31_Depth_Charge/README.md
    +++ b/31_Depth_Charge/README.md
    @@ -14,7 +14,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/31_Depth_Charge/csharp/DepthCharge.sln b/31_Depth_Charge/csharp/DepthCharge.sln
    index 2f11d18c4..8d56c7172 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}") = "DepthCharge", "DepthCharge.csproj", "{15CF71F3-72F3-4C81-B54F-139F2A1E3920}"
    +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Game", "Game.csproj", "{CBC9D8D9-9EDE-4D34-A20E-C90D929ABF8F}"
     EndProject
     Global
     	GlobalSection(SolutionConfigurationPlatforms) = preSolution
    @@ -11,10 +11,10 @@ Global
     		Release|Any CPU = Release|Any CPU
     	EndGlobalSection
     	GlobalSection(ProjectConfigurationPlatforms) = postSolution
    -		{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
    +		{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
     	EndGlobalSection
     	GlobalSection(SolutionProperties) = preSolution
     		HideSolutionNode = FALSE
    diff --git a/31_Depth_Charge/csharp/DepthCharge.csproj b/31_Depth_Charge/csharp/Game.csproj
    similarity index 100%
    rename from 31_Depth_Charge/csharp/DepthCharge.csproj
    rename to 31_Depth_Charge/csharp/Game.csproj
    diff --git a/31_Depth_Charge/csharp/Controller.cs b/31_Depth_Charge/csharp/src/Controller.cs
    similarity index 100%
    rename from 31_Depth_Charge/csharp/Controller.cs
    rename to 31_Depth_Charge/csharp/src/Controller.cs
    diff --git a/31_Depth_Charge/csharp/Program.cs b/31_Depth_Charge/csharp/src/Program.cs
    similarity index 100%
    rename from 31_Depth_Charge/csharp/Program.cs
    rename to 31_Depth_Charge/csharp/src/Program.cs
    diff --git a/31_Depth_Charge/csharp/View.cs b/31_Depth_Charge/csharp/src/View.cs
    similarity index 100%
    rename from 31_Depth_Charge/csharp/View.cs
    rename to 31_Depth_Charge/csharp/src/View.cs
    diff --git a/31_Depth_Charge/java/DepthCharge.java b/31_Depth_Charge/java/DepthCharge.java
    index 72e943607..bf17acccc 100644
    --- a/31_Depth_Charge/java/DepthCharge.java
    +++ b/31_Depth_Charge/java/DepthCharge.java
    @@ -9,40 +9,40 @@
      * 

    * Note: The idea was to create a version of the 1970's BASIC game in Java, without introducing * new features - no additional text, error checking, etc has been added. - * + * * Converted from BASIC to Java by Darren Cardenas. */ - -public class DepthCharge { - + +public class DepthCharge { + private final Scanner scan; // For user input - + public DepthCharge() { - + scan = new Scanner(System.in); - - } // End of constructor DepthCharge + + } // End of constructor DepthCharge public void play() { - + showIntro(); startGame(); - - } // End of method play - + + } // End of method play + private static void showIntro() { - + System.out.println(" ".repeat(29) + "DEPTH CHARGE"); System.out.println(" ".repeat(14) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); System.out.println("\n\n"); - } // End of method showIntro - + } // End of method showIntro + private void startGame() { int searchArea = 0; int shotNum = 0; - int shotTotal = 0; + int shotTotal = 0; int shotX = 0; int shotY = 0; int shotZ = 0; @@ -52,135 +52,135 @@ private void startGame() { int tries = 0; String[] userCoordinates; String userResponse = ""; - + System.out.print("DIMENSION OF SEARCH AREA? "); searchArea = Integer.parseInt(scan.nextLine()); System.out.println(""); - - shotTotal = (int) (Math.log10(searchArea) / Math.log10(2)) + 1; - + + shotTotal = (int) (Math.log10(searchArea) / Math.log10(2)) + 1; + System.out.println("YOU ARE THE CAPTAIN OF THE DESTROYER USS COMPUTER"); System.out.println("AN ENEMY SUB HAS BEEN CAUSING YOU TROUBLE. YOUR"); System.out.println("MISSION IS TO DESTROY IT. YOU HAVE " + shotTotal + " SHOTS."); System.out.println("SPECIFY DEPTH CHARGE EXPLOSION POINT WITH A"); System.out.println("TRIO OF NUMBERS -- THE FIRST TWO ARE THE"); System.out.println("SURFACE COORDINATES; THE THIRD IS THE DEPTH."); - - // Begin outer while loop - while (true) { - + + // Begin outer while loop + while (true) { + System.out.println(""); System.out.println("GOOD LUCK !"); System.out.println(""); - + targetX = (int) ((searchArea + 1) * Math.random()); targetY = (int) ((searchArea + 1) * Math.random()); targetZ = (int) ((searchArea + 1) * Math.random()); - + // Begin loop through all shots for (shotNum = 1; shotNum <= shotTotal; shotNum++) { - + // Get user input System.out.println(""); - System.out.print("TRIAL # " + shotNum + "? "); + System.out.print("TRIAL # " + shotNum + "? "); userResponse = scan.nextLine(); - + // Split on commas userCoordinates = userResponse.split(","); - + // Assign to integer variables shotX = Integer.parseInt(userCoordinates[0].trim()); shotY = Integer.parseInt(userCoordinates[1].trim()); - shotZ = Integer.parseInt(userCoordinates[2].trim()); - + shotZ = Integer.parseInt(userCoordinates[2].trim()); + // Win condition - if (Math.abs(shotX - targetX) + Math.abs(shotY - targetY) + if (Math.abs(shotX - targetX) + Math.abs(shotY - targetY) + Math.abs(shotZ - targetZ) == 0) { System.out.println("B O O M ! ! YOU FOUND IT IN" + shotNum + " TRIES!"); break; - + } - + this.getReport(targetX, targetY, targetZ, shotX, shotY, shotZ); - - System.out.println(""); - + + System.out.println(""); + } // End loop through all shots - + if (shotNum > shotTotal) { - + System.out.println(""); System.out.println("YOU HAVE BEEN TORPEDOED! ABANDON SHIP!"); System.out.println("THE SUBMARINE WAS AT " + targetX + "," + targetY + "," + targetZ); } - + System.out.println(""); System.out.println(""); - System.out.print("ANOTHER GAME (Y OR N)? "); - userResponse = scan.nextLine(); - + System.out.print("ANOTHER GAME (Y OR N)? "); + userResponse = scan.nextLine(); + if (!userResponse.toUpperCase().equals("Y")) { - System.out.print("OK. HOPE YOU ENJOYED YOURSELF."); + System.out.print("OK. HOPE YOU ENJOYED YOURSELF."); return; } - + } // End outer while loop - - } // End of method startGame - + + } // End of method startGame + public void getReport(int a, int b, int c, int x, int y, int z) { - + System.out.print("SONAR REPORTS SHOT WAS "); - + // Handle y coordinate if (y > b) { - - System.out.print("NORTH"); - + + System.out.print("NORTH"); + } else if (y < b) { - + System.out.print("SOUTH"); } - + // Handle x coordinate if (x > a) { - + System.out.print("EAST"); - + } else if (x < a) { - - System.out.print("WEST"); + + System.out.print("WEST"); } - + if ((y != b) || (x != a)) { - + System.out.print(" AND"); } - + // Handle depth if (z > c) { - + System.out.println(" TOO LOW."); - + } else if (z < c) { - + System.out.println(" TOO HIGH."); - + } else { - - System.out.println(" DEPTH OK."); + + System.out.println(" DEPTH OK."); } - + return; - + } // End of method getReport - + public static void main(String[] args) { - + DepthCharge game = new DepthCharge(); game.play(); - + } // End of method main - + } // End of class DepthCharge diff --git a/31_Depth_Charge/javascript/depthcharge.html b/31_Depth_Charge/javascript/depthcharge.html index f72dc0780..7a1e3add2 100644 --- a/31_Depth_Charge/javascript/depthcharge.html +++ b/31_Depth_Charge/javascript/depthcharge.html @@ -1,10 +1,9 @@ DEPTH CHARGE - -

    
    +
    
     
     
     
    diff --git a/31_Depth_Charge/javascript/depthcharge.js b/31_Depth_Charge/javascript/depthcharge.js
    index 0c0d43f83..6b0a7813f 100644
    --- a/31_Depth_Charge/javascript/depthcharge.js
    +++ b/31_Depth_Charge/javascript/depthcharge.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/31_Depth_Charge/kotlin/README.md b/31_Depth_Charge/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/31_Depth_Charge/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/31_Depth_Charge/lua/README.md b/31_Depth_Charge/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/31_Depth_Charge/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/31_Depth_Charge/pascal/README.md b/31_Depth_Charge/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/31_Depth_Charge/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/31_Depth_Charge/perl/README.md b/31_Depth_Charge/perl/README.md
    index 71f275434..6c2756f80 100644
    --- a/31_Depth_Charge/perl/README.md
    +++ b/31_Depth_Charge/perl/README.md
    @@ -14,3 +14,4 @@ Perl makes life easy.
      * We use ternarys to generate the message if you miss the sub.
        * We use join to stitch the pieces of the string together.
        * If we have a ternary where we don't want to return anything we return an empty list rather than an empty string - if you return the latter you still get the padding spaces.
    +
    diff --git a/31_Depth_Charge/python/depth_charge.py b/31_Depth_Charge/python/depth_charge.py
    index 6134f8ce9..f367962ee 100644
    --- a/31_Depth_Charge/python/depth_charge.py
    +++ b/31_Depth_Charge/python/depth_charge.py
    @@ -1,34 +1,31 @@
    -"""
    -Original BASIC version as published in Basic Computer Games (1978)
    -https://www.atariarchives.org/basicgames/showpage.php?page=55
    -
    -Converted to Python by Anson VanDoren in 2021
    -"""
    +# Original BASIC version as published in Basic Computer Games (1978)
    +# https://www.atariarchives.org/basicgames/showpage.php?page=55
    +#
    +# Converted to Python by Anson VanDoren in 2021
     
     import math
     import random
    -from typing import Tuple
     
     
    -def show_welcome() -> None:
    +def show_welcome():
         # Clear screen. chr(27) is `Esc`, and the control sequence is
         # initiated by Ctrl+[
         # `J` is "Erase in Display" and `2J` means clear the entire screen
    -    print(f"{chr(27)}[2J")
    +    print(chr(27) + "[2J")
     
         # Show the intro text, centered
         print("DEPTH CHARGE".center(45))
         print("Creative Computing  Morristown, New Jersey\n\n".center(45))
     
     
    -def get_num_charges() -> Tuple[int, int]:
    +def get_num_charges():
         print("Depth Charge game\n")
         while True:
    -        search_area_str = input("Dimensions of search area? ")
    +        search_area = input("Dimensions of search area? ")
     
             # Make sure the input is an integer
             try:
    -            search_area = int(search_area_str)
    +            search_area = int(search_area)
                 break
             except ValueError:
                 print("Must enter an integer number. Please try again...")
    @@ -37,16 +34,16 @@ def get_num_charges() -> Tuple[int, int]:
         return search_area, num_charges
     
     
    -def ask_for_new_game() -> None:
    +def ask_for_new_game():
         answer = input("Another game (Y or N): ")
    -    if answer.lower().strip()[0] == "y":
    -        main()
    +    if answer.lower().strip()[0] == 'y':
    +        start_new_game()
         else:
             print("OK. Hope you enjoyed yourself")
             exit()
     
     
    -def show_shot_result(shot, location) -> None:
    +def show_shot_result(shot, location):
         result = "Sonar reports shot was "
         if shot[1] > location[1]:  # y-direction
             result += "north"
    @@ -61,7 +58,7 @@ def show_shot_result(shot, location) -> None:
     
         if shot[2] > location[2]:
             result += "too low."
    -    elif shot[2] < location[2]:
    +    elif shot[2] < location [2]:
             result += "too high."
         else:
             result += "depth OK."
    @@ -69,23 +66,23 @@ def show_shot_result(shot, location) -> None:
         return
     
     
    -def get_shot_input() -> Tuple[int, int, int]:
    +def get_shot_input():
         while True:
             raw_guess = input("Enter coordinates: ")
             try:
    -            xyz = raw_guess.split()
    +            x, y, z = raw_guess.split()
             except ValueError:
                 print("Please enter coordinates separated by spaces")
    -            print("Example: 3 2 1")
    +            print(f"Example: 3 2 1")
                 continue
             try:
    -            x, y, z = (int(num) for num in xyz)
    +            x, y, z = [int(num) for num in [x, y, z]]
                 return x, y, z
             except ValueError:
                 print("Please enter whole numbers only")
     
     
    -def play_game(search_area, num_charges) -> None:
    +def play_game(search_area, num_charges):
         print("\nYou are the captain of the destroyer USS Computer.")
         print("An enemy sub has been causing you trouble. Your")
         print(f"mission is to destroy it. You have {num_charges} shots.")
    @@ -95,7 +92,7 @@ def play_game(search_area, num_charges) -> None:
         print("\nGood luck!\n")
     
         # Generate position for submarine
    -    a, b, c = (random.randint(0, search_area) for _ in range(3))
    +    a, b, c = [random.randint(0, search_area) for _ in range(3)]
     
         # Get inputs until win or lose
         for i in range(num_charges):
    @@ -114,10 +111,10 @@ def play_game(search_area, num_charges) -> None:
         ask_for_new_game()
     
     
    -def main() -> None:
    +def start_new_game():
         search_area, num_charges = get_num_charges()
         play_game(search_area, num_charges)
     
     
    -if __name__ == "__main__":
    -    main()
    +if __name__ == '__main__':
    +    start_new_game()
    diff --git a/31_Depth_Charge/rust/Cargo.lock b/31_Depth_Charge/rust/Cargo.lock
    deleted file mode 100644
    index 8be5f5fa6..000000000
    --- a/31_Depth_Charge/rust/Cargo.lock
    +++ /dev/null
    @@ -1,243 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "bitflags"
    -version = "2.9.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
    -
    -[[package]]
    -name = "byteorder"
    -version = "1.5.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    - "windows-targets",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.170"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.20"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
    -dependencies = [
    - "zerocopy 0.7.35",
    -]
    -
    -[[package]]
    -name = "proc-macro2"
    -version = "1.0.94"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
    -dependencies = [
    - "unicode-ident",
    -]
    -
    -[[package]]
    -name = "quote"
    -version = "1.0.39"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "c1f1914ce909e1658d9907913b4b91947430c7d9be598b15a1912935b8c04801"
    -dependencies = [
    - "proc-macro2",
    -]
    -
    -[[package]]
    -name = "rand"
    -version = "0.9.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
    -dependencies = [
    - "rand_chacha",
    - "rand_core",
    - "zerocopy 0.8.21",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.9.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.9.3"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "syn"
    -version = "2.0.99"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e02e925281e18ffd9d640e234264753c43edc62d64b2d4cf898f1bc5e75f3fc2"
    -dependencies = [
    - "proc-macro2",
    - "quote",
    - "unicode-ident",
    -]
    -
    -[[package]]
    -name = "unicode-ident"
    -version = "1.0.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe"
    -
    -[[package]]
    -name = "wasi"
    -version = "0.13.3+wasi-0.2.2"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2"
    -dependencies = [
    - "wit-bindgen-rt",
    -]
    -
    -[[package]]
    -name = "windows-targets"
    -version = "0.52.6"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
    -dependencies = [
    - "windows_aarch64_gnullvm",
    - "windows_aarch64_msvc",
    - "windows_i686_gnu",
    - "windows_i686_gnullvm",
    - "windows_i686_msvc",
    - "windows_x86_64_gnu",
    - "windows_x86_64_gnullvm",
    - "windows_x86_64_msvc",
    -]
    -
    -[[package]]
    -name = "windows_aarch64_gnullvm"
    -version = "0.52.6"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
    -
    -[[package]]
    -name = "windows_aarch64_msvc"
    -version = "0.52.6"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
    -
    -[[package]]
    -name = "windows_i686_gnu"
    -version = "0.52.6"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
    -
    -[[package]]
    -name = "windows_i686_gnullvm"
    -version = "0.52.6"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
    -
    -[[package]]
    -name = "windows_i686_msvc"
    -version = "0.52.6"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
    -
    -[[package]]
    -name = "windows_x86_64_gnu"
    -version = "0.52.6"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
    -
    -[[package]]
    -name = "windows_x86_64_gnullvm"
    -version = "0.52.6"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
    -
    -[[package]]
    -name = "windows_x86_64_msvc"
    -version = "0.52.6"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
    -
    -[[package]]
    -name = "wit-bindgen-rt"
    -version = "0.33.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c"
    -dependencies = [
    - "bitflags",
    -]
    -
    -[[package]]
    -name = "zerocopy"
    -version = "0.7.35"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
    -dependencies = [
    - "byteorder",
    - "zerocopy-derive 0.7.35",
    -]
    -
    -[[package]]
    -name = "zerocopy"
    -version = "0.8.21"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "dcf01143b2dd5d134f11f545cf9f1431b13b749695cb33bcce051e7568f99478"
    -dependencies = [
    - "zerocopy-derive 0.8.21",
    -]
    -
    -[[package]]
    -name = "zerocopy-derive"
    -version = "0.7.35"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
    -dependencies = [
    - "proc-macro2",
    - "quote",
    - "syn",
    -]
    -
    -[[package]]
    -name = "zerocopy-derive"
    -version = "0.8.21"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "712c8386f4f4299382c9abee219bee7084f78fb939d88b6840fcc1320d5f6da2"
    -dependencies = [
    - "proc-macro2",
    - "quote",
    - "syn",
    -]
    diff --git a/31_Depth_Charge/rust/Cargo.toml b/31_Depth_Charge/rust/Cargo.toml
    deleted file mode 100644
    index 3a87396aa..000000000
    --- a/31_Depth_Charge/rust/Cargo.toml
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -[package]
    -name = "rust"
    -version = "0.1.0"
    -edition = "2021"
    -
    -[dependencies]
    -rand = "0.9.0"
    \ No newline at end of file
    diff --git a/31_Depth_Charge/rust/src/main.rs b/31_Depth_Charge/rust/src/main.rs
    deleted file mode 100644
    index f997fda36..000000000
    --- a/31_Depth_Charge/rust/src/main.rs
    +++ /dev/null
    @@ -1,145 +0,0 @@
    -/** DEPTH CHARGE GAME 
    - * https://github.com/marquesrs/basic-computer-games/blob/main/31_Depth_Charge/depthcharge.bas
    - * Direct conversion from BASIC to Rust by Pablo Marques (marquesrs).
    - * No additional features or improvements were added. As a faithful translation, 
    - * many of the code here are done in an unrecommended way by today's standards.
    - * 03/03/25
    -*/
    -
    -use std::io::Write;
    -use rand::Rng;
    -
    -fn input(msg: &str) -> String {
    -    print!("{}", msg);
    -    let _ =std::io::stdout().flush().unwrap();
    -    let mut input = String::new();
    -    std::io::stdin().read_line(&mut input).unwrap();
    -    return input.trim().to_uppercase();
    -}
    -
    -fn main() {
    -    // 2 PRINT TAB(30);"DEPTH CHARGE"
    -    // 4 PRINT TAB(15);"CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY"
    -    // 6 PRINT: PRINT: PRINT
    -    print!("{}", format!("{}{}\n{}{}\n\n\n\n",
    -        " ".repeat(29),
    -        "DEPTH CHARGE",
    -        " ".repeat(14),
    -        "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY"
    -    ));
    -
    -    // 20 INPUT "DIMENSION OF SEARCH AREA";G: PRINT
    -    let g = input("DIMENSION OF SEARCH AREA: ").parse::().unwrap();
    -
    -    // 30 N=INT(LOG(G)/LOG(2))+1
    -    let n = (f32::ln(g as f32) / f32::ln(2.0) + 1.0) as i32;
    -
    -    // 40 PRINT "YOU ARE THE CAPTAIN OF THE DESTROYER USS COMPUTER"
    -    // 50 PRINT "AN ENEMY SUB HAS BEEN CAUSING YOU TROUBLE.  YOUR"
    -    // 60 PRINT "MISSION IS TO DESTROY IT.  YOU HAVE";N;"SHOTS."
    -    // 70 PRINT "SPECIFY DEPTH CHARGE EXPLOSION POINT WITH A"
    -    // 80 PRINT "TRIO OF NUMBERS -- THE FIRST TWO ARE THE"
    -    // 90 PRINT "SURFACE COORDINATES; THE THIRD IS THE DEPTH."
    -    // 100 PRINT : PRINT "GOOD LUCK !": PRINT
    -    let a = (g * rand::rng().random_range(0..=1)) as i32;
    -    let b = (g * rand::rng().random_range(0..=1)) as i32;
    -    let c = (g * rand::rng().random_range(0..=1)) as i32;
    -    print!("{}", format!("{}{}{}{}{}{}{}{}{}{}{}",
    -        "\nYOU ARE THE CAPTAIN OF THE DESTROYER USS COMPUTER\n",
    -        "AN ENEMY SUB HAS BEEN CAUSING YOU TROUBLE. YOUR\n",
    -        "MISSION IS TO DESTROY IT. YOU HAVE ",
    -        n,
    -        " SHOTS.\n",
    -        "SPECIFY DEPTH CHARGE EXPLOSION POINT WITH A\n",
    -        "TRIO OF NUMBERS -- THE FIRST TWO ARE THE\n",
    -        "SURFACE COORDINATES; THE THIRD IS THE DEPTH.\n",
    -        format!("EXAMPLE FOR DIMENSION {}: ", g),
    -        format!("{}, {}, {}", a, b, c),
    -        "\nGOOD LUCK !\n"
    -    ));
    -
    -    'main: loop {
    -        // 110 A=INT(G*RND(1)) : B=INT(G*RND(1)) : C=INT(G*RND(1))
    -        let a = (g * rand::rng().random_range(0..=1)) as i32;
    -        let b = (g * rand::rng().random_range(0..=1)) as i32;
    -        let c = (g * rand::rng().random_range(0..=1)) as i32;
    -        // 120 FOR D=1 TO N : PRINT : PRINT "TRIAL #";D; : INPUT X,Y,Z
    -        let mut x;
    -        let mut y;
    -        let mut z;
    -        for d in 1..=n {
    -            print!("\nTRIAL #{}\n", d);
    -            x = input("X: ").parse::().unwrap();
    -            y = input("Y: ").parse::().unwrap();
    -            z = input("Z: ").parse::().unwrap();
    -            // 130 IF ABS(X-A)+ABS(Y-B)+ABS(Z-C)=0 THEN 300
    -            if i32::abs(x-a) + i32::abs(y-b) + i32::abs(z-c) == 0 {
    -                // 300 PRINT : PRINT "B O O M ! ! YOU FOUND IT IN";D;"TRIES!"
    -                print!("{}", format!("{}{}{}{}{}",
    -                    "\n",
    -                    "B O O M ! ! YOU FOUND IT IN ",
    -                    d,
    -                    " TRIES!\n",
    -                    "\n"
    -                ));
    -                // 400 PRINT : PRINT: INPUT "ANOTHER GAME (Y OR N)";A$
    -                if replay() { continue 'main; }
    -                else { break 'main; }
    -            }
    -        
    -            // 140 GOSUB 500 : PRINT : NEXT D
    -            subroutine(x, y, z, a, b, c);
    -            println!();
    -        }
    -        // 200 PRINT : PRINT "YOU HAVE BEEN TORPEDOED!  ABANDON SHIP!"
    -        // 210 PRINT "THE SUBMARINE WAS AT";A;",";B;",";C : GOTO 400
    -        print!("{}", format!("{}{}{}{}{}{}{}{}",
    -            "\nYOU HAVE BEEN TORPEDOED! ABANDON SHIP!\n",
    -            "THE SUBMARINE WAS AT ",
    -            a,
    -            ",",
    -            b,
    -            ",",
    -            c,
    -            "\n"
    -        ));
    -        
    -        replay();
    -    }
    -    // 600 END
    -}
    -
    -// 500 PRINT "SONAR REPORTS SHOT WAS ";
    -// 510 IF Y>B THEN PRINT "NORTH";
    -// 520 IF YA THEN PRINT "EAST";
    -// 540 IF XB OR X<>A THEN PRINT " AND";
    -// 560 IF Z>C THEN PRINT " TOO LOW."
    -// 570 IF Zb { print!("NORTH"); };
    -    if ya { print!("EAST"); };
    -    if xc { print!(" TOO LOW."); };
    -    if z bool {
    -    let r = input("ANOTHER GAME (Y OR N): ");
    -    // 410 IF A$="Y" THEN 100
    -    if r == "Y" {
    -        return true;
    -    }
    -    else {
    -        // 420 PRINT "OK.  HOPE YOU ENJOYED YOURSELF." : GOTO 600
    -        println!("OK. HOPE YOU ENJOYED YOURSELF.");
    -        return false; 
    -    }
    -}
    \ No newline at end of file
    diff --git a/31_Depth_Charge/vbnet/DepthCharge.sln b/31_Depth_Charge/vbnet/DepthCharge.sln
    deleted file mode 100644
    index b042eee02..000000000
    --- a/31_Depth_Charge/vbnet/DepthCharge.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index ee43c0351..000000000
    --- a/31_Depth_Charge/vbnet/DepthCharge.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    DepthCharge
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/32_Diamond/README.md b/32_Diamond/README.md
    index f8b9a5dc9..1f155ba3c 100644
    --- a/32_Diamond/README.md
    +++ b/32_Diamond/README.md
    @@ -12,7 +12,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/32_Diamond/csharp/Diamond.csproj b/32_Diamond/csharp/Diamond.csproj
    deleted file mode 100644
    index 3870320c9..000000000
    --- a/32_Diamond/csharp/Diamond.csproj
    +++ /dev/null
    @@ -1,17 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    -  
    -    
    -  
    -
    -  
    -    
    -  
    -
    diff --git a/32_Diamond/csharp/Diamond.sln b/32_Diamond/csharp/Diamond.sln
    deleted file mode 100644
    index 2af37dbd3..000000000
    --- a/32_Diamond/csharp/Diamond.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/csharp/Pattern.cs b/32_Diamond/csharp/Pattern.cs
    deleted file mode 100644
    index ce6d493ac..000000000
    --- a/32_Diamond/csharp/Pattern.cs
    +++ /dev/null
    @@ -1,57 +0,0 @@
    -using System.Text;
    -using static Diamond.Resources.Resource;
    -
    -namespace Diamond;
    -
    -internal class Pattern
    -{
    -    private readonly IReadWrite _io;
    -
    -    public Pattern(IReadWrite io)
    -    {
    -        _io = io;
    -        io.Write(Streams.Introduction);
    -    }
    -
    -    public void Draw()
    -    {
    -        var diamondSize = _io.ReadNumber(Prompts.TypeNumber);
    -        _io.WriteLine();
    -
    -        var diamondCount = (int)(60 / diamondSize);
    -
    -        var diamondLines = new List(GetDiamondLines(diamondSize)).AsReadOnly();
    -
    -        for (int patternRow = 0; patternRow < diamondCount; patternRow++)
    -        {
    -            for (int diamondRow = 0; diamondRow < diamondLines.Count; diamondRow++)
    -            {
    -                var line = new StringBuilder();
    -                for (int patternColumn = 0; patternColumn < diamondCount; patternColumn++)
    -                {
    -                    line.PadToLength((int)(patternColumn * diamondSize)).Append(diamondLines[diamondRow]);
    -                }
    -                _io.WriteLine(line);
    -            }
    -        }
    -    }
    -
    -    public static IEnumerable GetDiamondLines(float size)
    -    {
    -        for (var i = 1; i <= size; i += 2)
    -        {
    -            yield return GetLine(i);
    -        }
    -
    -        for (var i = size - 2; i >= 1; i -= 2)
    -        {
    -            yield return GetLine(i);
    -        }
    -
    -        string GetLine(float i) =>
    -            string.Concat(
    -                new string(' ', (int)(size - i) / 2),
    -                new string('C', Math.Min((int)i, 2)),
    -                new string('!', Math.Max(0, (int)i - 2)));
    -    }
    -}
    diff --git a/32_Diamond/csharp/Program.cs b/32_Diamond/csharp/Program.cs
    deleted file mode 100644
    index 46dd67c5a..000000000
    --- a/32_Diamond/csharp/Program.cs
    +++ /dev/null
    @@ -1,4 +0,0 @@
    -global using Games.Common.IO;
    -using Diamond;
    -
    -new Pattern(new ConsoleIO()).Draw();
    diff --git a/32_Diamond/csharp/Resources/Introduction.txt b/32_Diamond/csharp/Resources/Introduction.txt
    deleted file mode 100644
    index e983fc9f8..000000000
    --- a/32_Diamond/csharp/Resources/Introduction.txt
    +++ /dev/null
    @@ -1,5 +0,0 @@
    -                                 Diamond
    -               Creative Computing  Morristown, New Jersey
    -
    -
    -
    diff --git a/32_Diamond/csharp/Resources/Resource.cs b/32_Diamond/csharp/Resources/Resource.cs
    deleted file mode 100644
    index d7051f5ca..000000000
    --- a/32_Diamond/csharp/Resources/Resource.cs
    +++ /dev/null
    @@ -1,29 +0,0 @@
    -using System.Reflection;
    -using System.Runtime.CompilerServices;
    -
    -namespace Diamond.Resources;
    -
    -internal static class Resource
    -{
    -    internal static class Streams
    -    {
    -        public static Stream Introduction => GetStream();
    -    }
    -
    -    internal static class Prompts
    -    {
    -        public static string TypeNumber => GetString();
    -    }
    -
    -    private static string GetString([CallerMemberName] string? name = null)
    -    {
    -        using var stream = GetStream(name);
    -        using var reader = new StreamReader(stream);
    -        return reader.ReadToEnd();
    -    }
    -
    -
    -    private static Stream GetStream([CallerMemberName] string? name = null) =>
    -        Assembly.GetExecutingAssembly().GetManifestResourceStream($"{typeof(Resource).Namespace}.{name}.txt")
    -            ?? throw new Exception($"Could not find embedded resource stream '{name}'.");
    -}
    \ No newline at end of file
    diff --git a/32_Diamond/csharp/Resources/Rules.txt b/32_Diamond/csharp/Resources/Rules.txt
    deleted file mode 100644
    index 2fd9177f4..000000000
    --- a/32_Diamond/csharp/Resources/Rules.txt
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -Chomp is for 1 or more players (humans only).
    -
    -Here's how a board looks (this one is 5 by 7):
    -
    -       1 2 3 4 5 6 7 8 9
    - 1     P * * * * * *
    - 2     * * * * * * *
    - 3     * * * * * * *
    - 4     * * * * * * *
    - 5     * * * * * * *
    -
    -
    -The board is a big cookie - R rows high and C columns
    -wide. You input R and C at the start. In the upper left
    -corner of the cookie is a poison square (P). The one who
    -chomps the poison square loses. To take a chomp, type the
    -row and column of one of the squares on the cookie.
    -All of the squares below and to the right of that square
    -(including that square, too) disappear -- Chomp!!
    -No fair chomping on squares that have already been chomped,
    -or that are outside the original dimensions of the cookie.
    -
    diff --git a/32_Diamond/csharp/Resources/TypeNumber.txt b/32_Diamond/csharp/Resources/TypeNumber.txt
    deleted file mode 100644
    index d74d21fda..000000000
    --- a/32_Diamond/csharp/Resources/TypeNumber.txt
    +++ /dev/null
    @@ -1,2 +0,0 @@
    -For a pretty diamond pattern,
    -type in an odd number between 5 and 21
    \ No newline at end of file
    diff --git a/32_Diamond/csharp/StringBuilderExtensions.cs b/32_Diamond/csharp/StringBuilderExtensions.cs
    deleted file mode 100644
    index 3ada41460..000000000
    --- a/32_Diamond/csharp/StringBuilderExtensions.cs
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -using System.Text;
    -
    -namespace Diamond;
    -
    -internal static class StringBuilderExtensions
    -{
    -    internal static StringBuilder PadToLength(this StringBuilder builder, int length) => 
    -        builder.Append(' ', length - builder.Length);
    -}
    \ No newline at end of file
    diff --git a/32_Diamond/java/Diamond.java b/32_Diamond/java/Diamond.java
    index 2989ce2d6..da56efe46 100644
    --- a/32_Diamond/java/Diamond.java
    +++ b/32_Diamond/java/Diamond.java
    @@ -8,126 +8,126 @@
      * 

    * Note: The idea was to create a version of the 1970's BASIC game in Java, without introducing * new features - no additional text, error checking, etc has been added. - * + * * Converted from BASIC to Java by Darren Cardenas. */ - -public class Diamond { - + +public class Diamond { + private static final int LINE_WIDTH = 60; - + private static final String PREFIX = "CC"; - + private static final char SYMBOL = '!'; - - private final Scanner scan; // For user input - - + + private final Scanner scan; // For user input + + public Diamond() { - - scan = new Scanner(System.in); - - } // End of constructor Diamond - - + + scan = new Scanner(System.in); + + } // End of constructor Diamond + + public void play() { showIntro(); startGame(); - } // End of method play - - - private void showIntro() { - + } // End of method play + + + private void showIntro() { + System.out.println(" ".repeat(32) + "DIAMOND"); System.out.println(" ".repeat(14) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); System.out.println("\n\n"); - - } // End of method showIntro + + } // End of method showIntro - private void startGame() { - + private void startGame() { + int body = 0; int column = 0; int end = 0; int fill = 0; - int increment = 2; - int numPerSide = 0; + int increment = 2; + int numPerSide = 0; int prefixIndex = 0; - int row = 0; - int start = 1; - int userNum = 0; - + int row = 0; + int start = 1; + int userNum = 0; + String lineContent = ""; - + // Get user input System.out.println("FOR A PRETTY DIAMOND PATTERN,"); System.out.print("TYPE IN AN ODD NUMBER BETWEEN 5 AND 21? "); userNum = scan.nextInt(); System.out.println(""); - + // Calcuate number of diamonds to be drawn on each side of screen - numPerSide = (int) (LINE_WIDTH / userNum); - - end = userNum; + numPerSide = (int) (LINE_WIDTH / userNum); + end = userNum; + // Begin loop through each row of diamonds for (row = 1; row <= numPerSide; row++) { - + // Begin loop through top and bottom halves of each diamond for (body = start; increment < 0 ? body >= end : body <= end; body += increment) { lineContent = ""; - + // Add whitespace while (lineContent.length() < ((userNum - body) / 2)) { lineContent += " "; } - + // Begin loop through each column of diamonds for (column = 1; column <= numPerSide; column++) { - + prefixIndex = 1; - + // Begin loop that fills each diamond with characters for (fill = 1; fill <= body; fill++) { - + // Right side of diamond if (prefixIndex > PREFIX.length()) { - - lineContent += SYMBOL; - + + lineContent += SYMBOL; + } // Left side of diamond else { - + lineContent += PREFIX.charAt(prefixIndex - 1); prefixIndex++; - - } - + + } + } // End loop that fills each diamond with characters - + // Column finished if (column == numPerSide) { - + break; - + } // Column not finishd else { - + // Add whitespace while (lineContent.length() < (userNum * column + (userNum - body) / 2)) { lineContent += " "; } - - } - + + } + } // End loop through each column of diamonds - + System.out.println(lineContent); } // End loop through top and bottom half of each diamond @@ -136,28 +136,28 @@ private void startGame() { start = 1; end = userNum; - increment = 2; - + increment = 2; + } else { - + start = userNum - 2; end = 1; - increment = -2; + increment = -2; row--; - } + } } // End loop through each row of diamonds - + } // End of method startGame - - + + public static void main(String[] args) { - + Diamond diamond = new Diamond(); diamond.play(); - + } // End of method main } // End of class Diamond diff --git a/32_Diamond/javascript/diamond.html b/32_Diamond/javascript/diamond.html index 5e7f6e2f0..9756b2ab9 100644 --- a/32_Diamond/javascript/diamond.html +++ b/32_Diamond/javascript/diamond.html @@ -1,10 +1,9 @@ DIAMOND - -

    
    +
    
     
     
     
    diff --git a/32_Diamond/javascript/diamond.js b/32_Diamond/javascript/diamond.js
    index e454a2d55..bb6f0fe91 100644
    --- a/32_Diamond/javascript/diamond.js
    +++ b/32_Diamond/javascript/diamond.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/32_Diamond/kotlin/README.md b/32_Diamond/kotlin/README.md
    deleted file mode 100644
    index 83eaac65e..000000000
    --- a/32_Diamond/kotlin/README.md
    +++ /dev/null
    @@ -1,12 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/), structure inspired from [the Java port](https://github.com/coding-horror/basic-computer-games/blob/main/32_Diamond/java/Diamond.java).
    -
    -### How to Run
    -1. Install [kotlin command line](https://kotlinlang.org/docs/command-line.html) compiler from JetBrains.
    -2. Compile with `kotlinc diamond.kt -include-runtime -d diamond.jar`
    -3. Run with `java -jar diamond.jar`
    -
    -### Changes from Original
    -This version validates that user input is correct.
    -
    diff --git a/32_Diamond/kotlin/diamond.kt b/32_Diamond/kotlin/diamond.kt
    deleted file mode 100644
    index 9db6125fb..000000000
    --- a/32_Diamond/kotlin/diamond.kt
    +++ /dev/null
    @@ -1,154 +0,0 @@
    -
    -/**
    - * Game of Diamond
    - * 

    - * Based on the BASIC game of Diamond - * https://github.com/coding-horror/basic-computer-games/blob/main/32%20Diamond/diamond.bas - *

    - * - * Changes From Original: Input is validated. - * - * Converted from BASIC to Kotlin by Martin Marconcini (@Gryzor) - * Inspired in the Java code written by Darren Cardenas. - */ - - -fun main() { - Diamond().startGame() -} - -class Diamond { - init { - printIntro() - } - - fun startGame() { - var body: Int - var end: Int - var start: Int = 1 - var row: Int = 1 - var numPerRow: Int - var increment: Int = 2 - var lineContent: String - var prefixIndex: Int - - printPrompt() - - // Read the user input - val input = readLine() - - // Validate input - val userInput: Int = try { - input?.toInt() ?: -1 - } catch (e: NumberFormatException) { - -1 - } - if (!isValid(userInput)) { - printInvalidInput() - return - } - - // Calculate how many diamonds can horizontally fit in the given space - numPerRow = calculateDiamondsPerRow(userInput) - end = userInput - - // Loop throw rows of Diamonds - while (row <= numPerRow) { - body = start - while (canLoop(increment, body, end)) { - lineContent = "" - - // Add white spaces to the "left" of the leftmost diamond. - while (lineContent.length < ((userInput - body) / 2)) { - lineContent += " " - } - - // Begin loop through each column of diamonds - for (col in 1..numPerRow) { - prefixIndex = 1 - - // Begin loop that fills each diamond with characters (not whitespace) - for (fill in 1..body) { - // Right side of diamond, if the index is greater than the prefix, put a Symbol. - if (prefixIndex > PREFIX.length) { - lineContent += SYMBOL - } - // Left side of diamond, pick a Prefix character (-1 since it starts at 0) - else { - lineContent += PREFIX[prefixIndex - 1] - prefixIndex++ - } - }// End loop that fills each diamond with characters - - // Is Column finished? - if (col == numPerRow) { - break - } - // Column is not finished... - else { - // Add whitespace on the "right" side of the current diamond, and fill the "left" side of the - // next; doesn't fill the space to the right of the rightmost diamond. - while (lineContent.length < (userInput * col + (userInput - body) / 2)) { - lineContent += " " - } - - } - - }// End loop through each column of diamonds - - // Print the current Line - println(lineContent) - - // Increment the body that moves - body += increment - } //end While Loop throw rows of Diamonds - - // Increment the current Row of diamonds. - row++ - - if (start != 1) { - start = 1 - end = userInput - increment = 2 - } else { - // We're rendering the "bottom half" of the total rendering. - // Alter the parameters, and decrease the row number so the logic can loop again. - start = userInput - 2 - end = 1 - increment = -2 - row-- - } - } // End loop through each row of diamonds - } - - private fun canLoop(increment: Int, body: Int, end: Int): Boolean = if (increment < 0) body >= end else body <= end - - private fun calculateDiamondsPerRow(totalDiamonds: Int): Int = LINE_WIDTH / totalDiamonds - - private fun isValid(input: Int): Boolean = (input in 5..21) && (input % 2 != 0) - - private fun printInvalidInput() = println("Invalid input") - - private fun printPrompt() { - println( - """ - FOR A PRETTY DIAMOND PATTERN - TYPE IN AN ODD NUMBER BETWEEN 5 AND 21? - """.trimIndent() - ) - println() - } - - private fun printIntro() { - println(" ".repeat(32) + "DIAMOND") - println(" ".repeat(14) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") - println() - println() - } - - companion object { - const val LINE_WIDTH = 60 - const val PREFIX = "CC" - const val SYMBOL = "!" - } -} diff --git a/32_Diamond/lua/README.md b/32_Diamond/lua/README.md deleted file mode 100644 index c063f42fd..000000000 --- a/32_Diamond/lua/README.md +++ /dev/null @@ -1,3 +0,0 @@ -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) - -Conversion to [Lua](https://www.lua.org/) diff --git a/32_Diamond/pascal/README.md b/32_Diamond/pascal/README.md new file mode 100644 index 000000000..aa1b3ae5d --- /dev/null +++ b/32_Diamond/pascal/README.md @@ -0,0 +1,3 @@ +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) + +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language)) diff --git a/32_Diamond/perl/diamond.pl b/32_Diamond/perl/diamond.pl index fcd4dc402..62311c142 100755 --- a/32_Diamond/perl/diamond.pl +++ b/32_Diamond/perl/diamond.pl @@ -33,3 +33,5 @@ } exit; + + diff --git a/32_Diamond/python/diamond.py b/32_Diamond/python/diamond.py index 3b261d36c..a622eb58f 100644 --- a/32_Diamond/python/diamond.py +++ b/32_Diamond/python/diamond.py @@ -7,8 +7,16 @@ """ -def print_diamond(begin_width, end_width, step, width, count) -> None: - edge_string = "CC" +def print_with_tab(space_count, msg): + if space_count > 0: + spaces = " " * space_count + else: + spaces = "" + print(spaces + msg) + + +def print_diamond(begin_width, end_width, step, width, count): + edgeString = "CC" fill = "!" n = begin_width @@ -16,7 +24,10 @@ def print_diamond(begin_width, end_width, step, width, count) -> None: line_buffer = " " * ((width - n) // 2) for across in range(count): for a in range(n): - line_buffer += fill if a >= len(edge_string) else edge_string[a] + if a >= len(edgeString): + line_buffer += fill + else: + line_buffer += edgeString[a] line_buffer += " " * ( (width * (across + 1) + (width - n) // 2) - len(line_buffer) ) @@ -26,9 +37,12 @@ def print_diamond(begin_width, end_width, step, width, count) -> None: n += step -def main() -> None: - print(" " * 33, "DIAMOND") - print(" " * 15, "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n\n\n") +def main(): + print_with_tab(33, "DIAMOND") + print_with_tab(15, "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") + print() + print() + print() print("FOR A PRETTY DIAMOND PATTERN,") print("TYPE IN AN ODD NUMBER BETWEEN 5 AND 21") width = int(input()) @@ -36,9 +50,9 @@ def main() -> None: PAGE_WIDTH = 60 - count = PAGE_WIDTH // width + count = int(PAGE_WIDTH / width) - for _down in range(count): + for down in range(count): print_diamond(1, width, 2, width, count) print_diamond(width - 2, 1, -2, width, count) diff --git a/32_Diamond/ruby/diamond.rb b/32_Diamond/ruby/diamond.rb index a28f4e55d..251cee25c 100644 --- a/32_Diamond/ruby/diamond.rb +++ b/32_Diamond/ruby/diamond.rb @@ -42,4 +42,4 @@ def main trap "SIGINT" do puts; exit 130 end -main +main \ No newline at end of file diff --git a/32_Diamond/rust/Cargo.lock b/32_Diamond/rust/Cargo.lock deleted file mode 100644 index b21cc6a2d..000000000 --- a/32_Diamond/rust/Cargo.lock +++ /dev/null @@ -1,7 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "rust" -version = "0.1.0" diff --git a/32_Diamond/rust/Cargo.toml b/32_Diamond/rust/Cargo.toml deleted file mode 100644 index 1ec696335..000000000 --- a/32_Diamond/rust/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[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] diff --git a/32_Diamond/rust/README.md b/32_Diamond/rust/README.md deleted file mode 100644 index f84e546c2..000000000 --- a/32_Diamond/rust/README.md +++ /dev/null @@ -1,3 +0,0 @@ -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) - -Conversion to [Rust](https://www.rust-lang.org/) by Anthony Rubick [AnthonyMichaelTDM](https://github.com/AnthonyMichaelTDM) \ No newline at end of file diff --git a/32_Diamond/rust/src/lib.rs b/32_Diamond/rust/src/lib.rs deleted file mode 100644 index 3d2692c64..000000000 --- a/32_Diamond/rust/src/lib.rs +++ /dev/null @@ -1,182 +0,0 @@ -/* - lib.rs contains all the logic of the program -*/ - -use std::{error::Error, fmt::Display, str::FromStr, io::{self, Write}}; - -/// handles setup for the game -pub struct Config { - diamond_size: isize, -} -impl Config { - /// creates and returns a new Config from user input - pub fn new() -> Result> { - //DATA - let mut config: Config = Config { diamond_size: 0 }; - - //get data from user input - - //get num players - println!("FOR A PRETTY DIAMOND PATTERN,"); - //input looop - config.diamond_size = loop { - match get_number_from_input("TYPE IN AN ODD NUMBER BETWEEN 5 AND 31 ", 5, 31) { - Ok(num) => { - //ensure num is odd - if num%2 == 0 {continue;} - else {break num;} - }, - Err(e) => { - eprintln!("{}",e); - continue; - }, - } - }; - - //return new config - return Ok(config); - } -} - -/// run the program -pub fn run(config: &Config) -> Result<(), Box> { - //DATA - let line_width: isize = 60; - let padding: char = 'C'; - let pixel_width: isize = 1; - let filling: char = '!'; - let border: char = '#'; - - let width_of_full_diamonds_in_line = (line_width/config.diamond_size) * config.diamond_size; - - //print top border - println!("{}", n_chars(width_of_full_diamonds_in_line+2, border)); - - //print out diamonds - for row in 0..width_of_full_diamonds_in_line { - print_diamond_line(config.diamond_size, row, line_width, pixel_width, padding, filling, border); - } - - //print bottom border - println!("{}", n_chars(width_of_full_diamonds_in_line+2, border)); - - //return to main - Ok(()) -} - -/// prints the next line of diamonds -fn print_diamond_line(diamond_width: isize,row: isize, line_width:isize, pixel_width:isize, padding:char, filling:char, border:char) { - //DATA - let diamonds_per_row = (line_width/pixel_width) / diamond_width; - //let row = row % (diamonds_per_row - 1); - let padding_amount; //total amount of padding before and after the filling of each diamond in this row - let filling_amount; //amount of "diamond" in each diamond in this row - - //calculate padding - padding_amount = (2 * ( (row%(diamond_width-1)) - (diamond_width/2))).abs(); - //calculate filling - filling_amount = -padding_amount + diamond_width; - - //print border before every row - print!("{}", border); - - //for every diamond in this row: - for _diamond in 0..diamonds_per_row { - //print leading padding - print!("{}", n_chars( pixel_width * padding_amount/2, padding ) ); - //print filling - print!("{}", n_chars( pixel_width * filling_amount , filling ) ); - //print trailing padding - print!("{}", n_chars( pixel_width * padding_amount/2, padding ) ); - } - - //print border after every row - print!("{}", border); - //new line - println!(""); -} - -/// returns n of the passed character, put into a string -fn n_chars(n:isize, character: char) -> String { - let mut output = String::new(); - - for _i in 0..n { - output.push(character); - } - - output -} - - -/// gets a string from user input -fn get_string_from_user_input(prompt: &str) -> Result> { - //DATA - let mut raw_input = String::new(); - - //print prompt - print!("{}", prompt); - //make sure it's printed before getting input - io::stdout().flush().unwrap(); - - //read user input from standard input, and store it to raw_input, then return it or an error as needed - raw_input.clear(); //clear input - match io::stdin().read_line(&mut raw_input) { - Ok(_num_bytes_read) => return Ok(String::from(raw_input.trim())), - Err(err) => return Err(format!("ERROR: CANNOT READ INPUT!: {}", err).into()), - } -} - -/// generic function to get a number from the passed string (user input) -/// pass a min lower than the max to have minimun and maximun bounds -/// pass a min higher than the max to only have a minumum bound -/// pass a min equal to the max to only have a maximun bound -/// -/// Errors: -/// no number on user input -fn get_number_from_input(prompt: &str, min:T, max:T) -> Result> { - //DATA - let raw_input: String; - let processed_input: String; - - - //input looop - raw_input = loop { - match get_string_from_user_input(prompt) { - Ok(input) => break input, - Err(e) => { - eprintln!("{}",e); - continue; - }, - } - }; - - //filter out num-numeric characters from user input - processed_input = raw_input.chars().filter(|c| c.is_numeric()).collect(); - - //from input, try to read a number - match processed_input.trim().parse() { - Ok(i) => { - //what bounds must the input fall into - if min < max { //have a min and max bound: [min,max] - if i >= min && i <= max {//is input valid, within bounds - return Ok(i); //exit the loop with the value i, returning it - } else { //print error message specific to this case - return Err(format!("ONLY BETWEEN {} AND {}, PLEASE!", min, max).into()); - } - } else if min > max { //only a min bound: [min, infinity) - if i >= min { - return Ok(i); - } else { - return Err(format!("NO LESS THAN {}, PLEASE!", min).into()); - } - } else { //only a max bound: (-infinity, max] - if i <= max { - return Ok(i); - } else { - return Err(format!("NO MORE THAN {}, PLEASE!", max).into()); - } - } - }, - Err(_e) => return Err(format!("Error: couldn't find a valid number in {}",raw_input).into()), - } -} \ No newline at end of file diff --git a/32_Diamond/rust/src/main.rs b/32_Diamond/rust/src/main.rs deleted file mode 100644 index 8aab73500..000000000 --- a/32_Diamond/rust/src/main.rs +++ /dev/null @@ -1,40 +0,0 @@ -use std::process; //allows for some better error handling - -mod lib; -use lib::Config; - -/// main function -/// responsibilities: -/// - Calling the command line logic with the argument values -/// - Setting up any other configuration -/// - Calling a run function in lib.rs -/// - Handling the error if run returns an error -fn main() { - //greet user - welcome(); - - // set up other configuration - let config = Config::new().unwrap_or_else(|err| { - eprintln!("Problem configuring program: {}", err); - process::exit(1); - }); - - // run the program - if let Err(e) = lib::run(&config) { - eprintln!("Application Error: {}", e); //use the eprintln! macro to output to standard error - process::exit(1); //exit the program with an error code - } - - //end of program - println!("THANKS FOR PLAYING!"); -} - -/// welcome message -fn welcome() { - print!(" - DIAMOND - CREATIVE COMPUTING MORRISTOWN, NEW JERSEY - - - "); -} diff --git a/32_Diamond/vbnet/Diamond.sln b/32_Diamond/vbnet/Diamond.sln deleted file mode 100644 index 3f05715d8..000000000 --- a/32_Diamond/vbnet/Diamond.sln +++ /dev/null @@ -1,22 +0,0 @@ - -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 deleted file mode 100644 index 069fe872a..000000000 --- a/32_Diamond/vbnet/Diamond.vbproj +++ /dev/null @@ -1,8 +0,0 @@ - - - Exe - Diamond - net6.0 - 16.9 - - diff --git a/33_Dice/README.md b/33_Dice/README.md index 5de5f1899..71406a01d 100644 --- a/33_Dice/README.md +++ b/33_Dice/README.md @@ -19,7 +19,3 @@ As published in Basic Computer Games (1978): Downloaded from Vintage Basic at http://www.vintage-basic.net/games.html - -#### Porting Notes - -(please note any difficulties or challenges in porting here) diff --git a/33_Dice/csharp/Dice.sln b/33_Dice/csharp/Dice.sln deleted file mode 100644 index 738a8c1c9..000000000 --- a/33_Dice/csharp/Dice.sln +++ /dev/null @@ -1,22 +0,0 @@ - -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/csharp/Game.cs b/33_Dice/csharp/Game.cs index 0a21da35e..3938e4c41 100644 --- a/33_Dice/csharp/Game.cs +++ b/33_Dice/csharp/Game.cs @@ -109,4 +109,4 @@ private bool TryAgain() return (pressedKey == 'Y'); } } -} +} \ No newline at end of file diff --git a/33_Dice/csharp/README.md b/33_Dice/csharp/README.md index 3dba781c9..23ccd0fe0 100644 --- a/33_Dice/csharp/README.md +++ b/33_Dice/csharp/README.md @@ -1,3 +1,4 @@ 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/) by James Curran (http://www.noveltheory.com) + diff --git a/33_Dice/csharp/RollGenerator.cs b/33_Dice/csharp/RollGenerator.cs index e707d45f9..08f2df6b8 100644 --- a/33_Dice/csharp/RollGenerator.cs +++ b/33_Dice/csharp/RollGenerator.cs @@ -17,4 +17,4 @@ public class RollGenerator } } } -} +} \ No newline at end of file diff --git a/33_Dice/javascript/dice.html b/33_Dice/javascript/dice.html index eb14e84e9..420dbc5d7 100644 --- a/33_Dice/javascript/dice.html +++ b/33_Dice/javascript/dice.html @@ -1,10 +1,9 @@ DICE - -

    
    +
    
     
     
     
    diff --git a/33_Dice/javascript/dice.js b/33_Dice/javascript/dice.js
    index d570ea8a3..e33e538a3 100644
    --- a/33_Dice/javascript/dice.js
    +++ b/33_Dice/javascript/dice.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/33_Dice/kotlin/README.md b/33_Dice/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/33_Dice/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/33_Dice/lua/README.md b/33_Dice/lua/README.md
    deleted file mode 100644
    index 610e38737..000000000
    --- a/33_Dice/lua/README.md
    +++ /dev/null
    @@ -1,16 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/) by Alex Conconi
    -
    ----
    -
    -### Porting notes for Lua
    -
    -- This is a straightfoward port with only minor modifications for input
    -validation and text formatting.
    -
    -- The "Try again?" question accepts 'y', 'yes', 'n', 'no' (case insensitive),
    -whereas the original BASIC version defaults to no unless 'YES' is typed.
    -
    -- The "How many rolls?" question presents a more user friendly message
    -in case of invalid input.
    diff --git a/33_Dice/lua/dice.lua b/33_Dice/lua/dice.lua
    deleted file mode 100644
    index 17f9b8a6a..000000000
    --- a/33_Dice/lua/dice.lua
    +++ /dev/null
    @@ -1,112 +0,0 @@
    ---[[
    -Dice
    -
    -From: BASIC Computer Games (1978)
    -Edited by David H. Ahl
    -
    -    "Not exactly a game, this program simulates rolling
    -    a pair of dice a large number of times and prints out
    -    the frequency distribution.  You simply input the
    -    number of rolls.  It is interesting to see how many
    -    rolls are necessary to approach the theoretical
    -    distribution:
    -
    -    2  1/36  2.7777...%
    -    3  2/36  5.5555...%
    -    4  3/36  8.3333...%
    -    etc.
    -
    -    "Daniel Freidus wrote this program while in the
    -     seventh grade at Harrison Jr-Sr High School,
    -    Harrison, New York."
    -
    -
    -Lua port by Alex Conconi, 2022.
    -]]--
    -
    -
    -local function print_intro()
    -    print("\n" .. string.rep(" ", 19) .. "Dice")
    -    print("Creative Computing  Morristown, New Jersey\n\n")
    -    print("This program simulates the rolling of a")
    -    print("pair of dice.")
    -    print("You enter the number of times you want the computer to")
    -    print("'roll' the dice.   Watch out, very large numbers take")
    -    print("a long time.  In particular, numbers over 5000.")
    -end
    -
    -
    -local function ask_how_many_rolls()
    -    while true do
    -        -- Print prompt and read a valid number from stdin
    -        print("\nHow many rolls?")
    -        local num_rolls = tonumber(io.stdin:read("*l"))
    -        if num_rolls then
    -            return num_rolls
    -        else
    -            print("Please enter a valid number.")
    -        end
    -    end
    -end
    -
    -
    -local function ask_try_again()
    -    while true do
    -        -- Print prompt and read a yes/no answer from stdin,
    -        -- accepting only 'yes', 'y', 'no' or 'n' (case insensitive)
    -        print("\nTry again? ([y]es / [n]o)")
    -        local answer = string.lower(io.stdin:read("*l"))
    -        if answer == "yes" or  answer == "y" then
    -            return true
    -        elseif answer == "no" or answer == "n" then
    -            return false
    -        else
    -            print("Please answer '[y]es' or '[n]o'.")
    -        end
    -    end
    -end
    -
    -
    -local function roll_dice(num_rolls)
    -    -- Initialize a table to track counts of roll outcomes
    -    local counts = {}
    -    for i=2, 12 do
    -        counts[i] = 0
    -    end
    -
    -    -- Roll the dice num_rolls times and update outcomes counts accordingly
    -    for _=1, num_rolls do
    -        local roll_total = math.random(1, 6) + math.random(1, 6)
    -        counts[roll_total] = counts[roll_total] + 1
    -    end
    -
    -    return counts
    -end
    -
    -
    -local function print_results(counts)
    -    print("\nTotal Spots   Number of Times")
    -    for roll_total, count in pairs(counts) do
    -        print(string.format(" %-14d%d", roll_total, count))
    -    end
    -end
    -
    -
    -local function dice_main()
    -    print_intro()
    -
    -    -- initialize the random number generator
    -    math.randomseed(os.time())
    -
    -    -- main game loop
    -    local keep_playing = true
    -    while keep_playing do
    -        local num_rolls = ask_how_many_rolls()
    -        local counts = roll_dice(num_rolls)
    -        print_results(counts)
    -        keep_playing = ask_try_again()
    -    end
    -end
    -
    -
    -dice_main()
    diff --git a/33_Dice/pascal/README.md b/33_Dice/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/33_Dice/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/33_Dice/perl/dice.pl b/33_Dice/perl/dice.pl
    index 2683b7a3a..cb051b0a9 100755
    --- a/33_Dice/perl/dice.pl
    +++ b/33_Dice/perl/dice.pl
    @@ -38,3 +38,5 @@
     	print "? "; chomp($Z = );
     	} until (uc($Z) ne "YES");
     exit;
    +
    +
    diff --git a/33_Dice/python/dice.py b/33_Dice/python/dice.py
    index 5c47f2b61..94cdab6bd 100644
    --- a/33_Dice/python/dice.py
    +++ b/33_Dice/python/dice.py
    @@ -1,78 +1,80 @@
    -"""
    -Dice
    -
    -From: BASIC Computer Games (1978)
    -      Edited by David H. Ahl
    -
    -"Not exactly a game, this program simulates rolling
    - a pair of dice a large number of times and prints out
    - the frequency distribution.  You simply input the
    - number of rolls.  It is interesting to see how many
    - rolls are necessary to approach the theoretical
    - distribution:
    +########################################################
    +#
    +# Dice
    +#
    +# From: BASIC Computer Games (1978)
    +#       Edited by David H. Ahl
    +#
    +# "Not exactly a game, this program simulates rolling
    +#  a pair of dice a large number of times and prints out
    +#  the frequency distribution.  You simply input the
    +#  number of rolls.  It is interesting to see how many
    +#  rolls are necessary to approach the theoretical
    +#  distribution:
    +#
    +#  2  1/36  2.7777...%
    +#  3  2/36  5.5555...%
    +#  4  3/36  8.3333...%
    +#    etc.
    +#
    +# "Daniel Freidus wrote this program while in the
    +#  seventh grade at Harrison Jr-Sr High School,
    +#  Harrison, New York."
    +#
    +# Python port by Jeff Jetton, 2019
    +#
    +########################################################
     
    - 2  1/36  2.7777...%
    - 3  2/36  5.5555...%
    - 4  3/36  8.3333...%
    -   etc.
     
    -"Daniel Freidus wrote this program while in the
    - seventh grade at Harrison Jr-Sr High School,
    - Harrison, New York."
    +import random
     
    -Python port by Jeff Jetton, 2019
    -"""
     
    -import random
    +# We'll track counts of roll outcomes in a 13-element list.
    +# The first two indices (0 & 1) are ignored, leaving just
    +# the indices that match the roll values (2 through 12).
    +freq = [0] * 13
    +
    +
    +# Display intro text
    +print("\n                   Dice")
    +print("Creative Computing  Morristown, New Jersey")
    +print("\n\n")
    +# "Danny Freidus"
    +print("This program simulates the rolling of a")
    +print("pair of dice.")
    +print("You enter the number of times you want the computer to")
    +print("'roll' the dice.   Watch out, very large numbers take")
    +print("a long time.  In particular, numbers over 5000.")
    +
    +still_playing = True
    +while still_playing:
    +    print("")
    +    n = int(input("How many rolls? "))
    +
    +    # Roll the dice n times
    +    for i in range(n):
    +        die1 = random.randint(1, 6)
    +        die2 = random.randint(1, 6)
    +        roll_total = die1 + die2
    +        freq[roll_total] += 1
    +
    +    # Display final results
    +    print("\nTotal Spots   Number of Times")
    +    for i in range(2, 13):
    +        print(" %-14d%d" % (i, freq[i]))
    +
    +    # Keep playing?
    +    print("")
    +    response = input("Try again? ")
    +    if len(response) > 0 and response.upper()[0] == 'Y':
    +        # Clear out the frequency list
    +        freq = [0]*13
    +    else:
    +        # Exit the game loop
    +        still_playing = False
    +    
     
     
    -def main() -> None:
    -    # We'll track counts of roll outcomes in a 13-element list.
    -    # The first two indices (0 & 1) are ignored, leaving just
    -    # the indices that match the roll values (2 through 12).
    -    freq = [0] * 13
    -
    -    # Display intro text
    -    print("\n                   Dice")
    -    print("Creative Computing  Morristown, New Jersey")
    -    print("\n\n")
    -    # "Danny Freidus"
    -    print("This program simulates the rolling of a")
    -    print("pair of dice.")
    -    print("You enter the number of times you want the computer to")
    -    print("'roll' the dice.   Watch out, very large numbers take")
    -    print("a long time.  In particular, numbers over 5000.")
    -
    -    still_playing = True
    -    while still_playing:
    -        print()
    -        n = int(input("How many rolls? "))
    -
    -        # Roll the dice n times
    -        for _ in range(n):
    -            die1 = random.randint(1, 6)
    -            die2 = random.randint(1, 6)
    -            roll_total = die1 + die2
    -            freq[roll_total] += 1
    -
    -        # Display final results
    -        print("\nTotal Spots   Number of Times")
    -        for i in range(2, 13):
    -            print(" %-14d%d" % (i, freq[i]))
    -
    -        # Keep playing?
    -        print()
    -        response = input("Try again? ")
    -        if len(response) > 0 and response.upper()[0] == "Y":
    -            # Clear out the frequency list
    -            freq = [0] * 13
    -        else:
    -            # Exit the game loop
    -            still_playing = False
    -
    -
    -if __name__ == "__main__":
    -    main()
     
     ########################################################
     #
    @@ -112,3 +114,10 @@ def main() -> None:
     #   rolled each time?
     #
     ########################################################
    +
    +
    +            
    +        
    +    
    +
    +    
    diff --git a/33_Dice/ruby/dice.rb b/33_Dice/ruby/dice.rb
    index ea1911e79..583809283 100644
    --- a/33_Dice/ruby/dice.rb
    +++ b/33_Dice/ruby/dice.rb
    @@ -48,4 +48,4 @@ def main
     
     trap "SIGINT" do puts; exit 130 end
     
    -main
    +main
    \ No newline at end of file
    diff --git a/33_Dice/rust/Cargo.lock b/33_Dice/rust/Cargo.lock
    deleted file mode 100644
    index 4fe2abbea..000000000
    --- a/33_Dice/rust/Cargo.lock
    +++ /dev/null
    @@ -1,75 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.10"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.147"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/33_Dice/rust/Cargo.toml b/33_Dice/rust/Cargo.toml
    deleted file mode 100644
    index 3b1d02f52..000000000
    --- a/33_Dice/rust/Cargo.toml
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -[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/33_Dice/rust/README.md b/33_Dice/rust/README.md
    deleted file mode 100644
    index fc6468b9f..000000000
    --- a/33_Dice/rust/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Rust](https://www.rust-lang.org/)
    diff --git a/33_Dice/rust/src/main.rs b/33_Dice/rust/src/main.rs
    deleted file mode 100644
    index 8c7e5885d..000000000
    --- a/33_Dice/rust/src/main.rs
    +++ /dev/null
    @@ -1,85 +0,0 @@
    -////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    -//
    -// Dice
    -//
    -// From: BASIC Computer Games (1978)
    -//       Edited by David H. Ahl
    -//
    -// "Not exactly a game, this program simulates rolling
    -//  a pair of dice a large number of times and prints out
    -//  the frequency distribution.  You simply input the
    -//  number of rolls.  It is interesting to see how many
    -//  rolls are necessary to approach the theoretical
    -//  distribution:
    -//
    -//  2  1/36  2.7777...%
    -//  3  2/36  5.5555...%
    -//  4  3/36  8.3333...%
    -//    etc.
    -//
    -// "Daniel Freidus wrote this program while in the
    -//  seventh grade at Harrison Jr-Sr High School,
    -//  Harrison, New York."
    -//
    -// Rust Port by Jay, 2022
    -//
    -////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    -
    -use rand::Rng;
    -use std::io::{self, Write};
    -
    -fn main() {
    -    let mut frequency: [i32; 13] = [0; 13];
    -    println!(
    -        "{: >38}\n{: >57}\n\n",
    -        "DICE", "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY"
    -    );
    -    // DANNY FREIDUS
    -    println!("THIS PROGRAM SIMULATES THE ROLLING OF A");
    -    println!("PAIR OF DICE.");
    -    println!("YOU ENTER THE NUMBER OF TIMES YOU WANT THE COMPUTER TO");
    -    println!("'ROLL' THE DICE.  WATCH OUT, VERY LARGE NUMBERS TAKE");
    -    println!("A LONG TIME.  IN PARTICULAR, NUMBERS OVER 5000.");
    -    let mut playing = true;
    -    while playing {
    -        let n = match readinput(&"HOW MANY ROLLS").trim().parse::() {
    -            Ok(num) => num,
    -            Err(_) => {
    -                println!("PLEASE ENTER A NUMBER");
    -                continue;
    -            }
    -        };
    -        // Dice Rolled n times
    -        for _i in 0..n {
    -            let die_1 = rand::thread_rng().gen_range(1..=6);
    -            let die_2 = rand::thread_rng().gen_range(1..=6);
    -            let total = die_1 + die_2;
    -            frequency[total] += 1;
    -        }
    -
    -        // Results tabel
    -        println!("\nTOTAL SPOTS    NUMBER OF TIMES");
    -        for i in 2..13 {
    -            println!("{:^4}\t\t{}", i, frequency[i]);
    -        }
    -
    -        // Continue the game
    -        let reply = readinput("TRY AGAIN").to_ascii_uppercase();
    -        if reply.starts_with("Y") || reply.eq("YES") {
    -            frequency = [0; 13];
    -        } else {
    -            playing = false;
    -        }
    -    }
    -}
    -
    -// function for getting input on same line
    -fn readinput(str: &str) -> String {
    -    print!("\n{}? ", str);
    -    let mut input = String::new();
    -    io::stdout().flush().unwrap();
    -    io::stdin()
    -        .read_line(&mut input)
    -        .expect("Failed to get Input");
    -    input
    -}
    diff --git a/33_Dice/vbnet/Dice.sln b/33_Dice/vbnet/Dice.sln
    deleted file mode 100644
    index afb7b912e..000000000
    --- a/33_Dice/vbnet/Dice.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 16929f96c..000000000
    --- a/33_Dice/vbnet/Dice.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Dice
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/34_Digits/README.md b/34_Digits/README.md
    index 6e82efda5..b1c968190 100644
    --- a/34_Digits/README.md
    +++ b/34_Digits/README.md
    @@ -15,8 +15,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -- The program contains a lot of mysterious and seemingly arbitrary constants.  It's not clear there is any logic or rationality behind it.
    -- The key equation involved in the guess (line 700) involves a factor of `A`, but `A` is always 0, making that term meaningless.  As a result, all the work to build and update array K and value Z2 appear to be meaningless, too.
    diff --git a/34_Digits/csharp/Digits.csproj b/34_Digits/csharp/Digits.csproj
    deleted file mode 100644
    index 3870320c9..000000000
    --- a/34_Digits/csharp/Digits.csproj
    +++ /dev/null
    @@ -1,17 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    -  
    -    
    -  
    -
    -  
    -    
    -  
    -
    diff --git a/34_Digits/csharp/Digits.sln b/34_Digits/csharp/Digits.sln
    deleted file mode 100644
    index 04b944964..000000000
    --- a/34_Digits/csharp/Digits.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/csharp/Game.cs b/34_Digits/csharp/Game.cs
    deleted file mode 100644
    index 19f225b33..000000000
    --- a/34_Digits/csharp/Game.cs
    +++ /dev/null
    @@ -1,80 +0,0 @@
    -namespace Digits;
    -
    -internal class GameSeries
    -{
    -    private readonly IReadOnlyList _weights = new List { 0, 1, 3 }.AsReadOnly();
    -
    -    private readonly IReadWrite _io;
    -    private readonly IRandom _random;
    -
    -    public GameSeries(IReadWrite io, IRandom random)
    -    {
    -        _io = io;
    -        _random = random;
    -    }
    -
    -    internal void Play()
    -    {
    -        _io.Write(Streams.Introduction);
    -
    -        if (_io.ReadNumber(Prompts.ForInstructions) != 0)
    -        {
    -            _io.Write(Streams.Instructions);
    -        }
    -
    -        do
    -        {
    -            new Game(_io, _random).Play();
    -        } while (_io.ReadNumber(Prompts.WantToTryAgain) == 1);
    -
    -        _io.Write(Streams.Thanks);
    -    }
    -}
    -
    -internal class Game
    -{
    -    private readonly IReadWrite _io;
    -    private readonly Guesser _guesser;
    -
    -    public Game(IReadWrite io, IRandom random)
    -    {
    -        _io = io;
    -        _guesser = new Guesser(random);
    -    }
    -
    -    public void Play()
    -    {
    -        var correctGuesses = 0;
    -
    -        for (int round = 0; round < 3; round++)
    -        {
    -            var digits = _io.Read10Digits(Prompts.TenNumbers, Streams.TryAgain);
    -
    -            correctGuesses = GuessDigits(digits, correctGuesses);
    -        }
    -
    -        _io.Write(correctGuesses switch
    -        {
    -            < 10 => Streams.YouWin,
    -            10 => Streams.ItsATie,
    -            > 10 => Streams.IWin
    -        });
    -    }
    -
    -    private int GuessDigits(IEnumerable digits, int correctGuesses)
    -    {
    -        _io.Write(Streams.Headings);
    -
    -        foreach (var digit in digits)
    -        {
    -            var guess = _guesser.GuessNextDigit();
    -            if (guess == digit) { correctGuesses++; }
    -
    -            _io.WriteLine(Formats.GuessResult, guess, digit, guess == digit ? "Right" : "Wrong", correctGuesses);
    -
    -            _guesser.ObserveActualDigit(digit);
    -        }
    -
    -        return correctGuesses;
    -    }
    -}
    diff --git a/34_Digits/csharp/Guesser.cs b/34_Digits/csharp/Guesser.cs
    deleted file mode 100644
    index 9cda59e91..000000000
    --- a/34_Digits/csharp/Guesser.cs
    +++ /dev/null
    @@ -1,32 +0,0 @@
    -namespace Digits;
    -
    -internal class Guesser
    -{
    -    private readonly Memory _matrices = new();
    -    private readonly IRandom _random;
    -
    -    public Guesser(IRandom random)
    -    {
    -        _random = random;
    -    }
    -
    -    public int GuessNextDigit()
    -    {
    -        var currentSum = 0;
    -        var guess = 0;
    -
    -        for (int i = 0; i < 3; i++)
    -        {
    -            var sum = _matrices.GetWeightedSum(i);
    -            if (sum > currentSum || _random.NextFloat() >= 0.5)
    -            {
    -                currentSum = sum;
    -                guess = i;
    -            }
    -        }
    -
    -        return guess;
    -    }
    -
    -    public void ObserveActualDigit(int digit) => _matrices.ObserveDigit(digit);
    -}
    diff --git a/34_Digits/csharp/IOExtensions.cs b/34_Digits/csharp/IOExtensions.cs
    deleted file mode 100644
    index cd6af7add..000000000
    --- a/34_Digits/csharp/IOExtensions.cs
    +++ /dev/null
    @@ -1,20 +0,0 @@
    -namespace Digits;
    -
    -internal static class IOExtensions
    -{
    -    internal static IEnumerable Read10Digits(this IReadWrite io, string prompt, Stream retryText)
    -    {
    -        while (true)
    -        {
    -            var numbers = new float[10];
    -            io.ReadNumbers(prompt, numbers);
    -
    -            if (numbers.All(n => n == 0 || n == 1 || n == 2))
    -            {
    -                return numbers.Select(n => (int)n);
    -            }    
    -
    -            io.Write(retryText);
    -        }
    -    }
    -}
    \ No newline at end of file
    diff --git a/34_Digits/csharp/Matrix.cs b/34_Digits/csharp/Matrix.cs
    deleted file mode 100644
    index c07b45538..000000000
    --- a/34_Digits/csharp/Matrix.cs
    +++ /dev/null
    @@ -1,27 +0,0 @@
    -namespace Digits;
    -
    -internal class Matrix
    -{
    -    private readonly int _weight;
    -    private readonly int[,] _values;
    -
    -    public Matrix(int width, int weight, Func seedFactory)
    -    {
    -        _weight = weight;
    -        _values = new int[width, 3];
    -        
    -        for (int i = 0; i < width; i++)
    -        for (int j = 0; j < 3; j++)
    -        {
    -            _values[i, j] = seedFactory.Invoke(i, j);
    -        }
    -
    -        Index = width - 1;
    -    }
    -
    -    public int Index { get; set; }
    -
    -    public int GetWeightedValue(int row) => _weight * _values[Index, row];
    -
    -    public int IncrementValue(int row) => _values[Index, row]++;
    -}
    \ No newline at end of file
    diff --git a/34_Digits/csharp/Memory.cs b/34_Digits/csharp/Memory.cs
    deleted file mode 100644
    index a3023351a..000000000
    --- a/34_Digits/csharp/Memory.cs
    +++ /dev/null
    @@ -1,30 +0,0 @@
    -namespace Digits;
    -
    -public class Memory
    -{
    -    private readonly Matrix[] _matrices;
    -
    -    public Memory()
    -    {
    -        _matrices = new[] 
    -        {
    -            new Matrix(27, 3, (_, _) => 1),
    -            new Matrix(9, 1, (i, j) => i == 4 * j ? 2 : 3),
    -            new Matrix(3, 0, (_, _) => 9)
    -        };
    -    }
    -
    -    public int GetWeightedSum(int row) => _matrices.Select(m => m.GetWeightedValue(row)).Sum();
    -
    -    public void ObserveDigit(int digit)
    -    {
    -        for (int i = 0; i < 3; i++)
    -        {
    -            _matrices[i].IncrementValue(digit);
    -        }
    -
    -        _matrices[0].Index = _matrices[0].Index % 9 * 3 + digit;
    -        _matrices[1].Index = _matrices[0].Index % 9;
    -        _matrices[2].Index = digit;
    -    }
    -}
    \ No newline at end of file
    diff --git a/34_Digits/csharp/Program.cs b/34_Digits/csharp/Program.cs
    deleted file mode 100644
    index 1b5dd2e0e..000000000
    --- a/34_Digits/csharp/Program.cs
    +++ /dev/null
    @@ -1,6 +0,0 @@
    -global using Digits;
    -global using Games.Common.IO;
    -global using Games.Common.Randomness;
    -global using static Digits.Resources.Resource;
    -
    -new GameSeries(new ConsoleIO(), new RandomNumberGenerator()).Play();
    \ No newline at end of file
    diff --git a/34_Digits/csharp/Resources/ForInstructions.txt b/34_Digits/csharp/Resources/ForInstructions.txt
    deleted file mode 100644
    index 1c16d5f4f..000000000
    --- a/34_Digits/csharp/Resources/ForInstructions.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -For instructions, type '1', else type '0'
    \ No newline at end of file
    diff --git a/34_Digits/csharp/Resources/GuessResult.txt b/34_Digits/csharp/Resources/GuessResult.txt
    deleted file mode 100644
    index 4e233e037..000000000
    --- a/34_Digits/csharp/Resources/GuessResult.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -   {0}              {1}          {2}         {3}
    \ No newline at end of file
    diff --git a/34_Digits/csharp/Resources/Headings.txt b/34_Digits/csharp/Resources/Headings.txt
    deleted file mode 100644
    index 8289cdf64..000000000
    --- a/34_Digits/csharp/Resources/Headings.txt
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -
    -My guess      Your no.      Result        No. right
    -
    diff --git a/34_Digits/csharp/Resources/IWin.txt b/34_Digits/csharp/Resources/IWin.txt
    deleted file mode 100644
    index 491f69cf8..000000000
    --- a/34_Digits/csharp/Resources/IWin.txt
    +++ /dev/null
    @@ -1,4 +0,0 @@
    -
    -I guessed more than 1/3 of your numbers.
    -I win.
    -
    diff --git a/34_Digits/csharp/Resources/Instructions.txt b/34_Digits/csharp/Resources/Instructions.txt
    deleted file mode 100644
    index f9ff2a16e..000000000
    --- a/34_Digits/csharp/Resources/Instructions.txt
    +++ /dev/null
    @@ -1,11 +0,0 @@
    -
    -Please take a piece of paper and write down
    -the digits '0', '1', or '2' thirty times at random.
    -Arrange them in three lines of ten digits each.
    -I will ask for then ten at a time.
    -I will always guess them first and then look at your
    -next number to see if I was right. By pure luck,
    -I ought to be right ten times. But I hope to do better
    -than that *****
    -
    -
    diff --git a/34_Digits/csharp/Resources/Introduction.txt b/34_Digits/csharp/Resources/Introduction.txt
    deleted file mode 100644
    index e4d2d93ee..000000000
    --- a/34_Digits/csharp/Resources/Introduction.txt
    +++ /dev/null
    @@ -1,6 +0,0 @@
    -                                 Digits
    -               Creative Computing  Morristown, New Jersey
    -
    -
    -
    -This is a game of guessing.
    diff --git a/34_Digits/csharp/Resources/ItsATie.txt b/34_Digits/csharp/Resources/ItsATie.txt
    deleted file mode 100644
    index 0e92fbf62..000000000
    --- a/34_Digits/csharp/Resources/ItsATie.txt
    +++ /dev/null
    @@ -1,4 +0,0 @@
    -
    -I guessed exactly 1/3 of your numbers.
    -It's a tie game.
    -
    diff --git a/34_Digits/csharp/Resources/Resource.cs b/34_Digits/csharp/Resources/Resource.cs
    deleted file mode 100644
    index 2e9359557..000000000
    --- a/34_Digits/csharp/Resources/Resource.cs
    +++ /dev/null
    @@ -1,43 +0,0 @@
    -using System.Reflection;
    -using System.Runtime.CompilerServices;
    -
    -namespace Digits.Resources;
    -
    -internal static class Resource
    -{
    -    internal static class Streams
    -    {
    -        public static Stream Introduction => GetStream();
    -        public static Stream Instructions => GetStream();
    -        public static Stream TryAgain => GetStream();
    -        public static Stream ItsATie => GetStream();
    -        public static Stream IWin => GetStream();
    -        public static Stream YouWin => GetStream();
    -        public static Stream Thanks => GetStream();
    -        public static Stream Headings => GetStream();
    -    }
    -
    -    internal static class Prompts
    -    {
    -        public static string ForInstructions => GetString();
    -        public static string TenNumbers => GetString();
    -        public static string WantToTryAgain => GetString();
    -    }
    -
    -    internal static class Formats
    -    {
    -        public static string GuessResult => GetString();
    -    }
    -
    -    private static string GetString([CallerMemberName] string? name = null)
    -    {
    -        using var stream = GetStream(name);
    -        using var reader = new StreamReader(stream);
    -        return reader.ReadToEnd();
    -    }
    -
    -
    -    private static Stream GetStream([CallerMemberName] string? name = null) =>
    -        Assembly.GetExecutingAssembly().GetManifestResourceStream($"{typeof(Resource).Namespace}.{name}.txt")
    -            ?? throw new Exception($"Could not find embedded resource stream '{name}'.");
    -}
    \ No newline at end of file
    diff --git a/34_Digits/csharp/Resources/TenNumbers.txt b/34_Digits/csharp/Resources/TenNumbers.txt
    deleted file mode 100644
    index ad03893a6..000000000
    --- a/34_Digits/csharp/Resources/TenNumbers.txt
    +++ /dev/null
    @@ -1,2 +0,0 @@
    -
    -Ten numbers, please
    \ No newline at end of file
    diff --git a/34_Digits/csharp/Resources/Thanks.txt b/34_Digits/csharp/Resources/Thanks.txt
    deleted file mode 100644
    index 15d42e1b9..000000000
    --- a/34_Digits/csharp/Resources/Thanks.txt
    +++ /dev/null
    @@ -1,2 +0,0 @@
    -
    -Thanks for the game
    diff --git a/34_Digits/csharp/Resources/TryAgain.txt b/34_Digits/csharp/Resources/TryAgain.txt
    deleted file mode 100644
    index 74bdca683..000000000
    --- a/34_Digits/csharp/Resources/TryAgain.txt
    +++ /dev/null
    @@ -1,2 +0,0 @@
    -Only use the digits '0', '1', or '2'.
    -Let's try again.
    diff --git a/34_Digits/csharp/Resources/WantToTryAgain.txt b/34_Digits/csharp/Resources/WantToTryAgain.txt
    deleted file mode 100644
    index 38f4509db..000000000
    --- a/34_Digits/csharp/Resources/WantToTryAgain.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Do you want to try again (1 for yes, 0 for no)
    \ No newline at end of file
    diff --git a/34_Digits/csharp/Resources/YouWin.txt b/34_Digits/csharp/Resources/YouWin.txt
    deleted file mode 100644
    index 87b26b381..000000000
    --- a/34_Digits/csharp/Resources/YouWin.txt
    +++ /dev/null
    @@ -1,4 +0,0 @@
    -
    -I guessed less than 1/3 of your numbers.
    -You beat me.  Congratulations *****
    -
    diff --git a/34_Digits/java/Digits.java b/34_Digits/java/Digits.java
    index 71c39d95a..36ee58aef 100644
    --- a/34_Digits/java/Digits.java
    +++ b/34_Digits/java/Digits.java
    @@ -183,3 +183,4 @@ private static void printIntro() {
     	}
     
     }
    +
    diff --git a/34_Digits/javascript/digits.html b/34_Digits/javascript/digits.html
    index 6b70aa9ad..c6db808f2 100644
    --- a/34_Digits/javascript/digits.html
    +++ b/34_Digits/javascript/digits.html
    @@ -1,10 +1,9 @@
     
     
     DIGITS
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/34_Digits/javascript/digits.js b/34_Digits/javascript/digits.js
    index 31fd1e2c7..8f2be6ded 100644
    --- a/34_Digits/javascript/digits.js
    +++ b/34_Digits/javascript/digits.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/34_Digits/kotlin/README.md b/34_Digits/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/34_Digits/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/34_Digits/lua/README.md b/34_Digits/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/34_Digits/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/34_Digits/pascal/README.md b/34_Digits/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/34_Digits/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/34_Digits/perl/digits.pl b/34_Digits/perl/digits.pl
    deleted file mode 100755
    index 2f49bd0e9..000000000
    --- a/34_Digits/perl/digits.pl
    +++ /dev/null
    @@ -1,125 +0,0 @@
    -#!/usr/bin/perl
    -
    -# Digits program in Perl
    -# Translated by Kevin Brannen (kbrannen)
    -
    -use strict;
    -use warnings;
    -
    -# globals
    -my $Answer;
    -
    -print "\n";
    -print " " x 33, "DIGITS";
    -print " " x 15, "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n";
    -
    -print "THIS IS A GAME OF GUESSING.\n";
    -print "FOR INSTRUCTIONS, TYPE '1', ELSE TYPE '0': ";
    -chomp($Answer = <>);
    -if ($Answer == 1)
    -{
    -    print "\nPLEASE TAKE A PIECE OF PAPER AND WRITE DOWN\n";
    -    print "THE DIGITS '0', '1', OR '2' THIRTY TIMES AT RANDOM.\n";
    -    print "ARRANGE THEM IN THREE LINES OF TEN DIGITS EACH.\n";
    -    print "I WILL ASK FOR THEN TEN AT A TIME.\n";
    -    print "I WILL ALWAYS GUESS THEM FIRST AND THEN LOOK AT YOUR\n";
    -    print "NEXT NUMBER TO SEE IF I WAS RIGHT. BY PURE LUCK,\n";
    -    print "I OUGHT TO BE RIGHT TEN TIMES. BUT I HOPE TO DO BETTER\n";
    -    print "THAN THAT. *****\n\n\n";
    -}
    -
    -my ($A, $B, $C) = (0, 1, 3);
    -my (@M, @K, @L); # DIM M(26,2),K(2,2),L(8,2)
    -while (1)
    -{
    -    for my $i (0 .. 26) { for my $j (0 .. 2) { $M[$i][$j] = 1; } }
    -    for my $i (0 .. 2)  { for my $j (0 .. 2) { $K[$i][$j] = 9; } }
    -    for my $i (0 .. 8)  { for my $j (0 .. 2) { $L[$i][$j] = 3; } }
    -    $L[0][0] = $L[4][1] = $L[8][2] = 2;
    -    my $Z = 26;
    -    my $Z1 = 8;
    -    my $Z2 = 2;
    -    my $X = 0;
    -    my @N;
    -
    -    for my $T (1 .. 3)
    -    {
    -        my $have_input = 0;
    -        while (!$have_input)
    -        {
    -            $have_input = 1;
    -            print "\nTEN NUMBERS, PLEASE: ";
    -            chomp($Answer = <>);
    -            $Answer = "0 " . $Answer; # need to be 1-based, so prepend a throw-away value for [0]
    -            @N = split(/\s+/, $Answer);
    -            for my $i (1 .. 10)
    -            {
    -                if (!defined($N[$i]) || ($N[$i] != 0 && $N[$i] != 1 && $N[$i] != 2))
    -                {
    -                    print "ONLY USE THE DIGITS '0', '1', OR '2'.\n";
    -                    print "LET'S TRY AGAIN.";
    -                    $have_input = 0;
    -                    last;
    -                }
    -            }
    -        }
    -
    -        print "\nMY GUESS\tYOUR NO.\tRESULT\tNO. RIGHT\n\n";
    -        for my $U (1 .. 10)
    -        {
    -            my $num = $N[$U];
    -            my $S = 0;
    -            my $G;
    -            for my $J (0 .. 2)
    -            {
    -                my $S1 = $A * $K[$Z2][$J] + $B * $L[$Z1][$J] + $C * $M[$Z][$J];
    -                next if ($S > $S1);
    -                if ($S >= $S1)
    -                {
    -                    next if (rand(1) < .5);
    -                }
    -                $S = $S1;
    -                $G = $J;
    -            } # NEXT J
    -            print "  $G\t\t$N[$U]\t\t";
    -            if ($G == $N[$U])
    -            {
    -                $X++;
    -                print "RIGHT\t$X\n";
    -                $M[$Z][$num]++;
    -                $L[$Z1][$num]++;
    -                $K[$Z2][$num]++;
    -                $Z -= int($Z / 9) * 9;
    -                $Z = 3 * $Z + $N[$U];
    -            }
    -            else
    -            {
    -                print "WRONG\t$X\n";
    -            }
    -            $Z1 = $Z - int($Z / 9) * 9;
    -            $Z2 = $N[$U];
    -        } # NEXT U
    -    } # NEXT T
    -
    -    print "\n";
    -    if ($X == 10)
    -    {
    -        print "I GUESSED EXACTLY 1/3 OF YOUR NUMBERS.\n";
    -        print "IT'S A TIE GAME.\n";
    -    }
    -    elsif ($X > 10)
    -    {
    -        print "I GUESSED MORE THAN 1/3, OR $X, OF YOUR NUMBERS.\n";
    -        print "I WIN.\a\a\a\a\a\a\a\a\a\a"
    -    }
    -    else
    -    {
    -        print "I GUESSED LESS THAN 1/3, OR $X, OF YOUR NUMBERS.\n";
    -        print "YOU BEAT ME.  CONGRATULATIONS *****\n";
    -    }
    -
    -    print "\nDO YOU WANT TO TRY AGAIN (1 FOR YES, 0 FOR NO): ";
    -    chomp($Answer = <>);
    -    last if ($Answer != 1);
    -}
    -print "\nTHANKS FOR THE GAME.\n";
    diff --git a/34_Digits/python/Digits.py b/34_Digits/python/Digits.py
    index 16e2db7d8..48647c129 100644
    --- a/34_Digits/python/Digits.py
    +++ b/34_Digits/python/Digits.py
    @@ -1,24 +1,22 @@
     import random
    -from typing import List
     
    -
    -def print_intro() -> None:
    +def printIntro():
         print("                                DIGITS")
         print("              CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
         print("\n\n")
         print("THIS IS A GAME OF GUESSING.")
     
     
    -def read_instruction_choice() -> bool:
    +def readInstructionChoice():
         print("FOR INSTRUCTIONS, TYPE '1', ELSE TYPE '0' ? ")
         try:
             choice = int(input())
             return choice == 1
    -    except (ValueError, TypeError):
    +    except (ValueError, TypeError) as m:
             return False
     
     
    -def print_instructions() -> None:
    +def printInstructions():
         print("\n")
         print("PLEASE TAKE A PIECE OF PAPER AND WRITE DOWN")
         print("THE DIGITS '0', '1', OR '2' THIRTY TIMES AT RANDOM.")
    @@ -31,126 +29,113 @@ def print_instructions() -> None:
         print()
     
     
    -def read_10_numbers() -> List[int]:
    +def read10Numbers():
         print("TEN NUMBERS, PLEASE ? ")
         numbers = []
     
    -    for _ in range(10):
    -        valid_input = False
    -        while not valid_input:
    +    for i in range(10):
    +        validInput = False
    +        while not validInput:
                 try:
                     n = int(input())
    -                valid_input = True
    +                validInput = True
                     numbers.append(n)
    -            except (TypeError, ValueError):
    +            except (TypeError, ValueError) as e:
                     print("!NUMBER EXPECTED - RETRY INPUT LINE")
     
         return numbers
     
    -
    -def read_continue_choice() -> bool:
    +def readContinueChoice():
         print("\nDO YOU WANT TO TRY AGAIN (1 FOR YES, 0 FOR NO) ? ")
         try:
             choice = int(input())
             return choice == 1
    -    except (ValueError, TypeError):
    +    except (ValueError, TypeError) as m:
             return False
     
    -
    -def print_summary_report(running_correct: int) -> None:
    -    print()
    -    if running_correct > 10:
    -        print()
    -        print("I GUESSED MORE THAN 1/3 OF YOUR NUMBERS.")
    -        print("I WIN.\u0007")
    -    elif running_correct < 10:
    -        print("I GUESSED LESS THAN 1/3 OF YOUR NUMBERS.")
    -        print("YOU BEAT ME.  CONGRATULATIONS *****")
    -    else:
    -        print("I GUESSED EXACTLY 1/3 OF YOUR NUMBERS.")
    -        print("IT'S A TIE GAME.")
    -
    -
    -def main() -> None:
    -    print_intro()
    -    if read_instruction_choice():
    -        print_instructions()
    +if __name__ == '__main__':
    +    printIntro()
    +    if readInstructionChoice():
    +        printInstructions()
     
         a = 0
         b = 1
         c = 3
     
    -    m = [[1] * 3 for _ in range(27)]
    -    k = [[9] * 3 for _ in range(3)]
    -    l = [[3] * 3 for _ in range(9)]  # noqa: E741
    +    m = [[1] * 3 for i in range(27)]
    +    k = [[9] * 3 for i in range(3)]
    +    l = [[3] * 3 for i in range(9)]
     
    -    continue_game = True
    -    while continue_game:
    +    continueGame = True
    +    while continueGame:
             l[0][0] = 2
             l[4][1] = 2
             l[8][2] = 2
    -        z: float = 26
    -        z1: float = 8
    +        z = 26
    +        z1 = 8
             z2 = 2
    -        running_correct = 0
    +        runningCorrect = 0
     
    -        for _round in range(1, 4):
    -            valid_numbers = False
    +        for t in range(1, 4):
    +            validNumbers = False
                 numbers = []
    -            while not valid_numbers:
    +            while not validNumbers:
                     print()
    -                numbers = read_10_numbers()
    -                valid_numbers = True
    +                numbers = read10Numbers()
    +                validNumbers = True
                     for number in numbers:
                         if number < 0 or number > 2:
                             print("ONLY USE THE DIGITS '0', '1', OR '2'.")
                             print("LET'S TRY AGAIN.")
    -                        valid_numbers = False
    +                        validNumbers = False
                             break
     
    -            print(
    -                "\n%-14s%-14s%-14s%-14s"
    -                % ("MY GUESS", "YOUR NO.", "RESULT", "NO. RIGHT")
    -            )
    +            print("\n%-14s%-14s%-14s%-14s" % ("MY GUESS", "YOUR NO.", "RESULT", "NO. RIGHT"))
     
                 for number in numbers:
                     s = 0
    -                my_guess = 0
    +                myGuess = 0
                     for j in range(0, 3):
                         # What did the original author have in mind ?
                         # The first expression always results in 0 because a is always 0
                         s1 = a * k[z2][j] + b * l[int(z1)][j] + c * m[int(z)][j]
                         if s < s1:
                             s = s1
    -                        my_guess = j
    -                    elif s1 == s and random.random() >= 0.5:
    -                        my_guess = j
    +                        myGuess = j
    +                    elif s1 == s:
    +                        if random.random() >= 0.5:
    +                            myGuess = j
     
                     result = ""
     
    -                if my_guess != number:
    +                if myGuess != number:
                         result = "WRONG"
                     else:
    -                    running_correct += 1
    +                    runningCorrect += 1
                         result = "RIGHT"
                         m[int(z)][number] = m[int(z)][number] + 1
                         l[int(z1)][number] = l[int(z1)][number] + 1
                         k[int(z2)][number] = k[int(z2)][number] + 1
                         z = z - (z / 9) * 9
                         z = 3 * z + number
    -                print(
    -                    "\n%-14d%-14d%-14s%-14d"
    -                    % (my_guess, number, result, running_correct)
    -                )
    +                print("\n%-14d%-14d%-14s%-14d" % (myGuess, number, result, runningCorrect))
     
                     z1 = z - (z / 9) * 9
                     z2 = number
     
    -        print_summary_report(running_correct)
    -        continue_game = read_continue_choice()
    -
    -    print("\nTHANKS FOR THE GAME.")
    -
    -
    -if __name__ == "__main__":
    -    main()
    +        # print summary report
    +        print()
    +        if runningCorrect > 10:
    +            print()
    +            print("I GUESSED MORE THAN 1/3 OF YOUR NUMBERS.")
    +            print("I WIN." + u"\u0007")
    +        elif runningCorrect < 10:
    +            print("I GUESSED LESS THAN 1/3 OF YOUR NUMBERS.")
    +            print("YOU BEAT ME.  CONGRATULATIONS *****")
    +        else:
    +            print("I GUESSED EXACTLY 1/3 OF YOUR NUMBERS.")
    +            print("IT'S A TIE GAME.")
    +
    +        continueGame = readContinueChoice()
    +
    +    print("\nTHANKS FOR THE GAME.")
    \ No newline at end of file
    diff --git a/34_Digits/vbnet/Digits.sln b/34_Digits/vbnet/Digits.sln
    deleted file mode 100644
    index 2d5733a94..000000000
    --- a/34_Digits/vbnet/Digits.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index d8f673e17..000000000
    --- a/34_Digits/vbnet/Digits.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Digits
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/35_Even_Wins/README.md b/35_Even_Wins/README.md
    index 4f4a18a12..9db7654b3 100644
    --- a/35_Even_Wins/README.md
    +++ b/35_Even_Wins/README.md
    @@ -16,7 +16,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/35_Even_Wins/csharp/EvenWins.csproj b/35_Even_Wins/csharp/EvenWins.csproj
    deleted file mode 100644
    index d3fe4757c..000000000
    --- a/35_Even_Wins/csharp/EvenWins.csproj
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    diff --git a/35_Even_Wins/csharp/EvenWins.sln b/35_Even_Wins/csharp/EvenWins.sln
    deleted file mode 100644
    index b384c20c6..000000000
    --- a/35_Even_Wins/csharp/EvenWins.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/evenwins.bas b/35_Even_Wins/evenwins.bas
    index 4e663c681..b1d0365da 100644
    --- a/35_Even_Wins/evenwins.bas
    +++ b/35_Even_Wins/evenwins.bas
    @@ -8,7 +8,7 @@
     40 PRINT "TO PLAY THE GAME, THE PLAYERS NEED 27 MARBLES OR"
     50 PRINT "OTHER OBJECTS ON A TABLE."
     60 PRINT
    -70 PRINT
    +70 PRINT 
     80 PRINT "     THE 2 PLAYERS ALTERNATE TURNS, WITH EACH PLAYER"
     90 PRINT "REMOVING FROM 1 TO 4 MARBLES ON EACH MOVE.  THE GAME"
     100 PRINT "ENDS WHEN THERE ARE NO MARBLES LEFT, AND THE WINNER"
    diff --git a/35_Even_Wins/javascript/evenwins.html b/35_Even_Wins/javascript/evenwins.html
    index d06c3e181..c39d09ba9 100644
    --- a/35_Even_Wins/javascript/evenwins.html
    +++ b/35_Even_Wins/javascript/evenwins.html
    @@ -1,10 +1,9 @@
     
     
     EVEN WINS
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/35_Even_Wins/javascript/evenwins.js b/35_Even_Wins/javascript/evenwins.js
    index 3ccaa9ad6..90f273f1e 100644
    --- a/35_Even_Wins/javascript/evenwins.js
    +++ b/35_Even_Wins/javascript/evenwins.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    @@ -122,7 +122,7 @@ async function main()
                         break;
                     }
                 }
    -
    +            
                 y1 += y;
                 t -= y;
                 if (t == 0)
    diff --git a/35_Even_Wins/javascript/gameofevenwins.html b/35_Even_Wins/javascript/gameofevenwins.html
    index 2c948cec5..9359f077f 100644
    --- a/35_Even_Wins/javascript/gameofevenwins.html
    +++ b/35_Even_Wins/javascript/gameofevenwins.html
    @@ -1,10 +1,9 @@
     
     
     GAME OF EVEN WINS
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/35_Even_Wins/javascript/gameofevenwins.js b/35_Even_Wins/javascript/gameofevenwins.js
    index b807a260e..945bc0bad 100644
    --- a/35_Even_Wins/javascript/gameofevenwins.js
    +++ b/35_Even_Wins/javascript/gameofevenwins.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/35_Even_Wins/kotlin/README.md b/35_Even_Wins/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/35_Even_Wins/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/35_Even_Wins/lua/README.md b/35_Even_Wins/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/35_Even_Wins/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/35_Even_Wins/pascal/README.md b/35_Even_Wins/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/35_Even_Wins/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/35_Even_Wins/perl/evenwins.pl b/35_Even_Wins/perl/evenwins.pl
    index 0eb37bdb6..c2fdc2d89 100644
    --- a/35_Even_Wins/perl/evenwins.pl
    +++ b/35_Even_Wins/perl/evenwins.pl
    @@ -8,7 +8,7 @@
     sub main {
     	&print_intro;
     	&game_play;
    -}
    +} 
     
     sub game_play {
     	my $marbles = 27;
    @@ -26,7 +26,7 @@ sub game_play {
     			$computer_total = $computer_total + $computer_choice;
     			print "MY TOTAL IS $computer_total\n";
     
    -			print "TOTAL= $marbles\n";
    +			print "TOTAL= $marbles\n";	
     
     			if ($marbles == 0) {&determine_winner($computer_total,$player_total)};
     
    @@ -35,7 +35,7 @@ sub game_play {
     			$player_total = $player_total + $player_choice;
     			print "YOUR TOTAL IS $player_total\n";
     			$turn++;
    -			print "TOTAL= $marbles\n";
    +			print "TOTAL= $marbles\n";	
     			if ($marbles == 0) {&determine_winner($computer_total,$player_total)};
     		}
     	}
    @@ -48,8 +48,8 @@ sub game_play {
     			$turn++;
     			print "YOUR TOTAL IS $player_total\n";
     
    -			print "TOTAL= $marbles\n";
    -
    +			print "TOTAL= $marbles\n";	
    +			
     			if ($marbles == 0) {&determine_winner($computer_total,$player_total)};
     
     			my $computer_choice = &computer_select($marbles,$turn,$player_total);
    @@ -57,7 +57,7 @@ sub game_play {
     			$computer_total = $computer_total + $computer_choice;
     			print "MY TOTAL IS $computer_total\n";
     
    -			print "TOTAL= $marbles\n";
    +			print "TOTAL= $marbles\n";	
     
     			if ($marbles == 0) {&determine_winner($computer_total,$player_total)};
     
    @@ -123,7 +123,7 @@ sub computer_select {
     	else {
     		until ($validity eq "valid") {
     			my $R=$marbles-6*int(($marbles/6));
    -
    +			
     			if (int($player_total/2) == $player_total/2) {
     				if ($R < 1.5 || $R > 5.3) {
     					$num = 1;
    @@ -132,7 +132,7 @@ sub computer_select {
     					$num = $R - 1;
     				}
     			}
    -
    +			 
     			elsif ($marbles < 4.2) {
     				$num = $marbles;
     			}
    diff --git a/35_Even_Wins/python/evenwins.py b/35_Even_Wins/python/evenwins.py
    index b5a198298..3fb9d4afa 100644
    --- a/35_Even_Wins/python/evenwins.py
    +++ b/35_Even_Wins/python/evenwins.py
    @@ -1,181 +1,221 @@
    -"""
    -This version of evenwins.bas based on game decscription and does *not*
    -follow the source. The computer chooses marbles at random.
    -
    -For simplicity, global variables are used to store the game state.
    -A good exercise would be to replace this with a class.
    -The code is not short, but hopefully it is easy for beginners to understand
    -and modify.
    -
    -Infinite loops of the style "while True:" are used to simplify some of the
    -code. The "continue" keyword is used in a few places to jump back to the top
    -of the loop. The "return" keyword is also used to break out of functions.
    -This is generally considered poor style, but in this case it simplifies the
    -code and makes it easier to read (at least in my opinion). A good exercise
    -would be to remove these infinite loops, and uses of continue, to follow a
    -more structured style.
    -"""
    -
    -
    -from dataclasses import dataclass
    -from typing import Literal, Tuple
    -
    -PlayerType = Literal["human", "computer"]
    -
    -
    -@dataclass
    -class MarbleCounts:
    -    middle: int
    -    human: int
    -    computer: int
    -
    -
    -def print_intro() -> None:
    -    print("Welcome to Even Wins!")
    -    print("Based on evenwins.bas from Creative Computing")
    +# evenwins.py 
    +
    +#
    +# This version of evenwins.bas based on game decscription and does *not*
    +# follow the source. The computer chooses marbles at random.
    +#
    +# For simplicity, global variables are used to store the game state.
    +# A good exercise would be to replace this with a class.
    +#
    +# The code is not short, but hopefully it is easy for beginners to understand
    +# and modify.
    +#
    +# Infinite loops of the style "while True:" are used to simplify some of the
    +# code. The "continue" keyword is used in a few places to jump back to the top
    +# of the loop. The "return" keyword is also used to break out of functions.
    +# This is generally considered poor style, but in this case it simplifies the
    +# code and makes it easier to read (at least in my opinion). A good exercise
    +# would be to remove these infinite loops, and uses of continue, to follow a
    +# more structured style.
    +#
    +
    +import random
    +
    +# global variables
    +marbles_in_middle = -1
    +human_marbles     = -1
    +computer_marbles  = -1
    +whose_turn        = ''
    +
    +# Only called during development for serious errors that are due to mistakes
    +# in the program. Should never be called during a regular game.
    +def serious_error(msg):
    +    print('serious_error: ' + msg)
    +    exit(1)
    +
    +def welcome_screen():
    +    print('Welcome to Even Wins!')
    +    print('Based on evenwins.bas from Creative Computing')
         print()
    -    print("Even Wins is a two-person game. You start with")
    -    print("27 marbles in the middle of the table.")
    +    print('Even Wins is a two-person game. You start with')
    +    print('27 marbles in the middle of the table.')
         print()
    -    print("Players alternate taking marbles from the middle.")
    -    print("A player can take 1 to 4 marbles on their turn, and")
    -    print("turns cannot be skipped. The game ends when there are")
    -    print("no marbles left, and the winner is the one with an even")
    -    print("number of marbles.")
    +    print('Players alternate taking marbles from the middle.')
    +    print('A player can take 1 to 4 marbles on their turn, and')
    +    print('turns cannot be skipped. The game ends when there are')
    +    print('no marbles left, and the winner is the one with an even')
    +    print('number of marbles.')
         print()
     
    +def marbles_str(n):
    +    if n == 1: return '1 marble'
    +    return f'{n} marbles'
     
    -def marbles_str(n: int) -> str:
    -    return "1 marble" if n == 1 else f"{n} marbles"
    -
    -
    -def choose_first_player() -> PlayerType:
    +def choose_first_player():
    +    global whose_turn
         while True:
    -        ans = input("Do you want to play first? (y/n) --> ")
    -        if ans == "y":
    -            return "human"
    -        elif ans == "n":
    -            return "computer"
    +        ans = input('Do you want to play first? (y/n) --> ')
    +        if ans == 'y': 
    +            whose_turn = 'human'
    +            return
    +        elif ans == 'n':
    +            whose_turn = 'computer'
    +            return
             else:
                 print()
                 print('Please enter "y" if you want to play first,')
                 print('or "n" if you want to play second.')
                 print()
     
    +def next_player():
    +    global whose_turn
    +    if whose_turn == 'human':
    +        whose_turn = 'computer'
    +    elif whose_turn == 'computer':
    +        whose_turn = 'human'
    +    else:
    +        serious_error(f'play_game: unknown player {whose_turn}')
     
    -def toggle_player(whose_turn: PlayerType) -> PlayerType:
    -    return "computer" if whose_turn == "human" else "human"
    -
    -
    -def to_int(s: str) -> Tuple[bool, int]:
    -    """Convert a string s to an int, if possible."""
    +# Converts a string s to an int, if possible.
    +def to_int(s):
         try:
             n = int(s)
             return True, n
    -    except Exception:
    +    except:
             return False, 0
     
    -
    -def print_board(marbles: MarbleCounts) -> None:
    +def print_board():
    +    global marbles_in_middle
    +    global human_marbles
    +    global computer_marbles
         print()
    -    print(f" marbles in the middle: {marbles.middle} " + marbles.middle * "*")
    -    print(f"    # marbles you have: {marbles.human}")
    -    print(f"# marbles computer has: {marbles.computer}")
    +    print(f' marbles in the middle: {marbles_in_middle} ' + marbles_in_middle*'*')
    +    print(f'    # marbles you have: {human_marbles}')
    +    print(f'# marbles computer has: {computer_marbles}')
         print()
     
    +def human_turn():
    +    global marbles_in_middle
    +    global human_marbles
     
    -def human_turn(marbles: MarbleCounts) -> None:
    -    """get number in range 1 to min(4, marbles.middle)"""
    -    max_choice = min(4, marbles.middle)
    +    # get number in range 1 to min(4, marbles_in_middle)
    +    max_choice = min(4, marbles_in_middle)
         print("It's your turn!")
         while True:
    -        s = input(f"Marbles to take? (1 - {max_choice}) --> ")
    +        s = input(f'Marbles to take? (1 - {max_choice}) --> ')
             ok, n = to_int(s)
             if not ok:
    -            print(f"\n  Please enter a whole number from 1 to {max_choice}\n")
    +            print()
    +            print(f'  Please enter a whole number from 1 to {max_choice}')
    +            print()
                 continue
             if n < 1:
    -            print("\n  You must take at least 1 marble!\n")
    +            print()
    +            print('  You must take at least 1 marble!')
    +            print()
                 continue
             if n > max_choice:
    -            print(f"\n  You can take at most {marbles_str(max_choice)}\n")
    +            print()
    +            print(f'  You can take at most {marbles_str(max_choice)}')
    +            print()
                 continue
    -        print(f"\nOkay, taking {marbles_str(n)} ...")
    -        marbles.middle -= n
    -        marbles.human += n
    +        print()
    +        print(f'Okay, taking {marbles_str(n)} ...')
    +        marbles_in_middle -= n
    +        human_marbles += n
             return
     
    -
    -def game_over(marbles: MarbleCounts) -> None:
    +def game_over():
    +    global marbles_in_middle
    +    global human_marbles
    +    global computer_marbles
         print()
    -    print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
    -    print("!! All the marbles are taken: Game Over!")
    -    print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
    +    print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
    +    print('!! All the marbles are taken: Game Over!')
    +    print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
         print()
    -    print_board(marbles)
    -    if marbles.human % 2 == 0:
    -        print("You are the winner! Congratulations!")
    +    print_board()
    +    if human_marbles % 2 == 0:
    +        print('You are the winner! Congratulations!')
         else:
    -        print("The computer wins: all hail mighty silicon!")
    -    print()
    -
    -
    -def computer_turn(marbles: MarbleCounts) -> None:
    -    marbles_to_take = 0
    -
    -    print("It's the computer's turn ...")
    -    r = marbles.middle - 6 * int(marbles.middle / 6)
    -
    -    if int(marbles.human / 2) == marbles.human / 2:
    -        marbles_to_take = 1 if r < 1.5 or r > 5.3 else r - 1
    -    elif marbles.middle < 4.2:
    -        marbles_to_take = marbles.middle
    -    elif r > 3.4:
    -        if r < 4.7 or r > 3.5:
    -            marbles_to_take = 4
    -    else:
    -        marbles_to_take = r + 1
    -
    -    print(f"Computer takes {marbles_str(marbles_to_take)} ...")
    -    marbles.middle -= marbles_to_take
    -    marbles.computer += marbles_to_take
    -
    -
    -def play_game(whose_turn: PlayerType) -> None:
    -    marbles = MarbleCounts(middle=27, human=0, computer=0)
    -    print_board(marbles)
    +        print('The computer wins: all hail mighty silicon!')
    +    print('')
    +
    +def computer_turn():
    +	global marbles_in_middle
    +	global computer_marbles
    +	global human_marbles
    +
    +	marbles_to_take=0
    +
    +	print("It's the computer's turn ...")
    +	r = marbles_in_middle - 6 * int((marbles_in_middle/6)) 	#line 500
    +
    +	if int(human_marbles/2) == human_marbles/2: 			#line 510
    +		if r < 1.5 or r > 5.3: 								#lines 710 and 720	
    +			marbles_to_take = 1
    +		else:
    +			marbles_to_take = r - 1
    +
    +	elif marbles_in_middle < 4.2:							#line 580
    +		marbles_to_take = marbles_in_middle
    +	elif r > 3.4:											#line 530
    +		if r < 4.7 or r > 3.5:
    +			marbles_to_take = 4
    +	else:
    +		marbles_to_take = r + 1
    +	
    +	print(f'Computer takes {marbles_str(marbles_to_take)} ...')
    +	marbles_in_middle -= marbles_to_take
    +	computer_marbles += marbles_to_take
    +
    +def play_game():
    +    global marbles_in_middle
    +    global human_marbles
    +    global computer_marbles
    +
    +    # initialize the game state
    +    marbles_in_middle = 27
    +    human_marbles = 0
    +    computer_marbles = 0
    +    print_board()
     
         while True:
    -        if marbles.middle == 0:
    -            game_over(marbles)
    +        if marbles_in_middle == 0:
    +            game_over()
                 return
    -        elif whose_turn == "human":
    -            human_turn(marbles)
    -            print_board(marbles)
    -            whose_turn = toggle_player(whose_turn)
    -        elif whose_turn == "computer":
    -            computer_turn(marbles)
    -            print_board(marbles)
    -            whose_turn = toggle_player(whose_turn)
    +        elif whose_turn == 'human':
    +            human_turn()
    +            print_board()
    +            next_player()
    +        elif whose_turn == 'computer':
    +            computer_turn()
    +            print_board()
    +            next_player()
             else:
    -            raise Exception(f"whose_turn={whose_turn} is not 'human' or 'computer'")
    +            serious_error(f'play_game: unknown player {whose_turn}')
     
    +def main():
    +    global whose_turn
     
    -def main() -> None:
    -    print_intro()
    +    welcome_screen()
     
         while True:
    -        whose_turn = choose_first_player()
    -        play_game(whose_turn)
    +        choose_first_player()
    +        play_game()
     
    +        # ask if the user if they want to play again
             print()
    -        again = input("Would you like to play again? (y/n) --> ").lower()
    -        if again == "y":
    -            print("\nOk, let's play again ...\n")
    +        again = input('Would you like to play again? (y/n) --> ')
    +        if again == 'y':
    +            print()
    +            print("Ok, let's play again ...")
    +            print()
             else:
    -            print("\nOk, thanks for playing ... goodbye!\n")
    +            print()
    +            print('Ok, thanks for playing ... goodbye!')
    +            print()
                 return
     
    -
    -if __name__ == "__main__":
    +if __name__ == '__main__':
         main()
    diff --git a/35_Even_Wins/rust/Cargo.lock b/35_Even_Wins/rust/Cargo.lock
    deleted file mode 100644
    index b21cc6a2d..000000000
    --- a/35_Even_Wins/rust/Cargo.lock
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    diff --git a/35_Even_Wins/rust/Cargo.toml b/35_Even_Wins/rust/Cargo.toml
    deleted file mode 100644
    index 1ec696335..000000000
    --- a/35_Even_Wins/rust/Cargo.toml
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -[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]
    diff --git a/35_Even_Wins/rust/src/main.rs b/35_Even_Wins/rust/src/main.rs
    deleted file mode 100644
    index 18a08a3a2..000000000
    --- a/35_Even_Wins/rust/src/main.rs
    +++ /dev/null
    @@ -1,229 +0,0 @@
    -use std::io;
    -
    -fn print_intro() {
    -    println!(
    -        "Welcome to Even Wins!
    -Based on evenwins.bas from Creative Computing
    -
    -Even Wins is a two-person game. You start with
    -27 marbles in the middle of the table.
    -
    -Players alternate taking marbles from the middle.
    -A player can take 1 to 4 marbles on their turn, and
    -turns cannot be skipped. The game ends when there are
    -no marbles left, and the winner is the one with an even
    -number of marbles.
    -"
    -    );
    -}
    -
    -#[derive(Debug)]
    -enum PlayerType {
    -    Human,
    -    Computer,
    -}
    -
    -#[derive(Debug)]
    -struct Game {
    -    turn: PlayerType,
    -    middle: u32,
    -    human: u32,
    -    computer: u32,
    -    min_take: u32,
    -    max_take: u32,
    -}
    -
    -impl Game {
    -    fn get_max_take(&mut self) -> u32 {
    -        if self.max_take > self.middle {
    -            return self.middle;
    -        }
    -        return self.max_take;
    -    }
    -
    -    fn take(&mut self, num: u32) -> bool {
    -        let max_take = self.get_max_take();
    -        if num > max_take {
    -            println!("You can take at most {} marbles", max_take);
    -            return false;
    -        }
    -        if num < self.min_take {
    -            println!("You must take at least {} marble!", self.min_take);
    -            return false;
    -        }
    -
    -        self.middle -= num;
    -        match self.turn {
    -            PlayerType::Computer => self.computer += num,
    -            PlayerType::Human => self.human += num,
    -        }
    -        return true;
    -    }
    -
    -    fn next(&mut self) {
    -        self.turn = match self.turn {
    -            PlayerType::Computer => PlayerType::Human,
    -            PlayerType::Human => PlayerType::Computer,
    -        }
    -    }
    -
    -    fn info(&mut self) {
    -        println!("");
    -        println!(
    -            "marbles in the middle: {} **************************",
    -            self.middle
    -        );
    -        println!("# marbles you have: {}", self.human);
    -        println!("# marbles computer has: {}", self.computer);
    -        println!("");
    -    }
    -
    -    fn wininfo(&mut self) {
    -        if self.middle != 0 {
    -            return;
    -        }
    -        println!("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n!! All the marbles are taken: Game Over!\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
    -        self.info();
    -
    -        if self.human % 2 == 0 {
    -            println!("You are the winner! Congratulations!");
    -        } else {
    -            println!("The computer wins: all hail mighty silicon!");
    -        }
    -
    -        println!("");
    -    }
    -}
    -
    -fn human_play(game: &mut Game) {
    -    println!("It's your turn!");
    -    loop {
    -        let max_take = game.get_max_take();
    -        println!("Marbles to take? ({} - {}) --> ", game.min_take, max_take);
    -
    -        let mut num = String::new();
    -        io::stdin()
    -            .read_line(&mut num)
    -            .expect("Failed to read line");
    -
    -        let _: u32 = match num.trim().to_uppercase().parse() {
    -            Ok(num) => {
    -                if game.take(num) {
    -                    println!("Okay, taking {} marble ...", num);
    -                    break;
    -                };
    -                println!("");
    -                continue;
    -            }
    -            _ => {
    -                println!("Please enter a whole number from 1 to 4");
    -                println!("");
    -                continue;
    -            }
    -        };
    -    }
    -}
    -
    -fn compute_play(game: &mut Game) {
    -    println!("It's the computer's turn ...");
    -
    -    let marbles_to_take: u32;
    -
    -    // the magic 6 and 1.5, 5.3 3.4 4.7 3.5 was copy from python implement
    -    let r: f32 = (game.middle % 6) as f32;
    -    if game.human % 2 == 0 {
    -        if r < 1.5 || r > 5.3 {
    -            marbles_to_take = 1;
    -        } else {
    -            marbles_to_take = (r - 1.0) as u32;
    -        }
    -    } else if game.middle <= 4 {
    -        marbles_to_take = game.middle
    -    } else if r > 3.4 {
    -        if r < 4.7 || r > 3.5 {
    -            marbles_to_take = 4;
    -        } else {
    -            marbles_to_take = 1;
    -        }
    -    } else {
    -        marbles_to_take = (r + 1.0) as u32;
    -    }
    -
    -    game.take(marbles_to_take);
    -    println!("Computer takes {} marble ...", marbles_to_take);
    -}
    -
    -fn run_game(turn: PlayerType) {
    -    let mut game = Game {
    -        turn: turn,
    -        middle: 27,
    -        computer: 0,
    -        human: 0,
    -        min_take: 1,
    -        max_take: 4,
    -    };
    -
    -    while game.middle > 0 {
    -        match game.turn {
    -            PlayerType::Computer => {
    -                compute_play(&mut game);
    -            }
    -            PlayerType::Human => {
    -                human_play(&mut game);
    -            }
    -        }
    -        game.info();
    -        game.next();
    -    }
    -    game.wininfo();
    -}
    -
    -fn choose_first_player() -> PlayerType {
    -    loop {
    -        println!("Do you want to play first? (y/n) -->");
    -
    -        let mut flag = String::new();
    -        io::stdin()
    -            .read_line(&mut flag)
    -            .expect("Failed to read line");
    -
    -        match flag.trim().to_uppercase().as_str() {
    -            "Y" => return PlayerType::Human,
    -            "N" => return PlayerType::Computer,
    -            _ => {
    -                println!("Please enter \"y\" if you want to play first,\nor \"n\" if you want to play second.\n");
    -            }
    -        };
    -    }
    -}
    -
    -fn choose_play_again() -> bool {
    -    println!("Would you like to play again? (y/n) --> ");
    -    let mut flag = String::new();
    -    io::stdin()
    -        .read_line(&mut flag)
    -        .expect("Failed to read line");
    -
    -    match flag.trim().to_uppercase().as_str() {
    -        "Y" => {
    -            println!("\nOk, let's play again ...\n");
    -            return true;
    -        }
    -        _ => {
    -            println!("\nOk, thanks for playing ... goodbye!\n");
    -            return false;
    -        }
    -    }
    -}
    -
    -fn main() {
    -    print_intro();
    -    loop {
    -        let first = choose_first_player();
    -        run_game(first);
    -
    -        if !choose_play_again() {
    -            return;
    -        }
    -    }
    -}
    diff --git a/35_Even_Wins/vbnet/EvenWins.sln b/35_Even_Wins/vbnet/EvenWins.sln
    deleted file mode 100644
    index 0714f2044..000000000
    --- a/35_Even_Wins/vbnet/EvenWins.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 7ca1146f1..000000000
    --- a/35_Even_Wins/vbnet/EvenWins.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    EvenWins
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/36_Flip_Flop/README.md b/36_Flip_Flop/README.md
    index d51a4436f..5f32111d6 100644
    --- a/36_Flip_Flop/README.md
    +++ b/36_Flip_Flop/README.md
    @@ -26,7 +26,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/36_Flip_Flop/csharp/FlipFlop.cs b/36_Flip_Flop/csharp/FlipFlop.cs
    index a6cc5bb12..53c613e82 100644
    --- a/36_Flip_Flop/csharp/FlipFlop.cs
    +++ b/36_Flip_Flop/csharp/FlipFlop.cs
    @@ -59,7 +59,7 @@
                 startNewGame = true;
             }
     
    -
    +        
             if (moveIndex == 0)
             {
                 // To reset the line to all X, same game
    @@ -83,8 +83,8 @@
     
                 do
                 {
    -                moveIndex = equalToLastMove
    -                    ? GetMoveIndexWhenEqualeLastMove(moveIndex, gameEntropyRate)
    +                moveIndex = equalToLastMove 
    +                    ? GetMoveIndexWhenEqualeLastMove(moveIndex, gameEntropyRate) 
                         : GetMoveIndex(moveIndex, gameEntropyRate);
     
                     board[moveIndex] = board[moveIndex] == "O" ? "X" : "O";
    @@ -194,4 +194,4 @@ void PrintGameInfo()
         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/java/FlipFlop.java b/36_Flip_Flop/java/FlipFlop.java
    index fe8309d5d..afca236f8 100644
    --- a/36_Flip_Flop/java/FlipFlop.java
    +++ b/36_Flip_Flop/java/FlipFlop.java
    @@ -9,55 +9,55 @@
      * 

    * Note: The idea was to create a version of the 1970's BASIC game in Java, without introducing * new features - no additional text, error checking, etc has been added. - * + * * Converted from BASIC to Java by Darren Cardenas. */ - -public class FlipFlop { - - private final Scanner scan; // For user input - + +public class FlipFlop { + + private final Scanner scan; // For user input + private enum Step { - RANDOMIZE, INIT_BOARD, GET_NUMBER, ILLEGAL_ENTRY, FLIP_POSITION, SET_X_FIRST, SET_X_SECOND, + RANDOMIZE, INIT_BOARD, GET_NUMBER, ILLEGAL_ENTRY, FLIP_POSITION, SET_X_FIRST, SET_X_SECOND, GENERATE_R_FIRST, GENERATE_R_SECOND, PRINT_BOARD, QUERY_RETRY - } - + } + public FlipFlop() { - + scan = new Scanner(System.in); - - } // End of constructor FlipFlop + + } // End of constructor FlipFlop public void play() { - + showIntro(); startGame(); - - } // End of method play - + + } // End of method play + private static void showIntro() { - + System.out.println(" ".repeat(31) + "FLIPFLOP"); System.out.println(" ".repeat(14) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); System.out.println(""); - } // End of method showIntro - + } // End of method showIntro + private void startGame() { double mathVal = 0; - double randVal = 0; + double randVal = 0; double tmpVal = 0; - + int index = 0; int match = 0; int numFlip = 0; - int numGuesses = 0; - + int numGuesses = 0; + Step nextStep = Step.RANDOMIZE; - + String userResponse = ""; - + String[] board = new String[21]; System.out.println("THE OBJECT OF THIS PUZZLE IS TO CHANGE THIS:"); @@ -73,59 +73,59 @@ private void startGame() { System.out.println("OTHERS, TWO WILL CHANGE. TO RESET LINE TO ALL X'S, TYPE 0"); System.out.println("(ZERO) AND TO START OVER IN THE MIDDLE OF A GAME, TYPE "); System.out.println("11 (ELEVEN)."); - System.out.println(""); + System.out.println(""); // Begin outer while loop while (true) { - + // Begin switch switch (nextStep) { - - case RANDOMIZE: - + + case RANDOMIZE: + randVal = Math.random(); System.out.println("HERE IS THE STARTING LINE OF X'S."); System.out.println(""); - - numGuesses = 0; - nextStep = Step.INIT_BOARD; + + numGuesses = 0; + nextStep = Step.INIT_BOARD; break; - + case INIT_BOARD: - + System.out.println("1 2 3 4 5 6 7 8 9 10"); System.out.println("X X X X X X X X X X"); System.out.println(""); - + // Avoid out of bounds error by starting at zero for (index = 0; index <= 10; index++) { - board[index] = "X"; - } + board[index] = "X"; + } - nextStep = Step.GET_NUMBER; + nextStep = Step.GET_NUMBER; break; - + case GET_NUMBER: - + System.out.print("INPUT THE NUMBER? "); - userResponse = scan.nextLine(); - + userResponse = scan.nextLine(); + try { - numFlip = Integer.parseInt(userResponse); - } - catch (NumberFormatException ex) { + numFlip = Integer.parseInt(userResponse); + } + catch (NumberFormatException ex) { nextStep = Step.ILLEGAL_ENTRY; break; - } - + } + // Command to start a new game if (numFlip == 11) { nextStep = Step.RANDOMIZE; - break; - } - - if (numFlip > 11) { + break; + } + + if (numFlip > 11) { nextStep = Step.ILLEGAL_ENTRY; break; } @@ -135,153 +135,153 @@ private void startGame() { nextStep = Step.INIT_BOARD; break; } - + if (match == numFlip) { nextStep = Step.FLIP_POSITION; break; } - + match = numFlip; - - if (board[numFlip].equals("O")) { + + if (board[numFlip].equals("O")) { nextStep = Step.SET_X_FIRST; break; } - + board[numFlip] = "O"; nextStep = Step.GENERATE_R_FIRST; - break; - + break; + case ILLEGAL_ENTRY: System.out.println("ILLEGAL ENTRY--TRY AGAIN."); nextStep = Step.GET_NUMBER; break; - + case GENERATE_R_FIRST: - - mathVal = Math.tan(randVal + numFlip / randVal - numFlip) - Math.sin(randVal / numFlip) + 336 + + mathVal = Math.tan(randVal + numFlip / randVal - numFlip) - Math.sin(randVal / numFlip) + 336 * Math.sin(8 * numFlip); - - tmpVal = mathVal - (int)Math.floor(mathVal); - - numFlip = (int)(10 * tmpVal); - + + tmpVal = mathVal - (int)Math.floor(mathVal); + + numFlip = (int)(10 * tmpVal); + if (board[numFlip].equals("O")) { nextStep = Step.SET_X_FIRST; - break; + break; } - + board[numFlip] = "O"; - nextStep = Step.PRINT_BOARD; - break; - - case SET_X_FIRST: + nextStep = Step.PRINT_BOARD; + break; + + case SET_X_FIRST: board[numFlip] = "X"; - + if (match == numFlip) { - nextStep = Step.GENERATE_R_FIRST; + nextStep = Step.GENERATE_R_FIRST; } else { - nextStep = Step.PRINT_BOARD; + nextStep = Step.PRINT_BOARD; } - break; - + break; + case FLIP_POSITION: - - if (board[numFlip].equals("O")) { + + if (board[numFlip].equals("O")) { nextStep = Step.SET_X_SECOND; break; - } - + } + board[numFlip] = "O"; nextStep = Step.GENERATE_R_SECOND; break; case GENERATE_R_SECOND: - - mathVal = 0.592 * (1 / Math.tan(randVal / numFlip + randVal)) / Math.sin(numFlip * 2 + randVal) + + mathVal = 0.592 * (1 / Math.tan(randVal / numFlip + randVal)) / Math.sin(numFlip * 2 + randVal) - Math.cos(numFlip); - + tmpVal = mathVal - (int)mathVal; numFlip = (int)(10 * tmpVal); - + if (board[numFlip].equals("O")) { nextStep = Step.SET_X_SECOND; break; } - + board[numFlip] = "O"; - nextStep = Step.PRINT_BOARD; + nextStep = Step.PRINT_BOARD; break; - + case SET_X_SECOND: - + board[numFlip] = "X"; if (match == numFlip) { nextStep = Step.GENERATE_R_SECOND; - break; + break; } - - nextStep = Step.PRINT_BOARD; + + nextStep = Step.PRINT_BOARD; break; - + case PRINT_BOARD: System.out.println("1 2 3 4 5 6 7 8 9 10"); - + for (index = 1; index <= 10; index++) { - System.out.print(board[index] + " "); + System.out.print(board[index] + " "); } - + numGuesses++; - + System.out.println(""); - + for (index = 1; index <= 10; index++) { if (!board[index].equals("O")) { - nextStep = Step.GET_NUMBER; + nextStep = Step.GET_NUMBER; break; } - } - + } + if (nextStep == Step.GET_NUMBER) { - break; + break; } - - if (numGuesses > 12) { - System.out.println("TRY HARDER NEXT TIME. IT TOOK YOU " + numGuesses + " GUESSES."); - } else { - System.out.println("VERY GOOD. YOU GUESSED IT IN ONLY " + numGuesses + " GUESSES."); + + if (numGuesses > 12) { + System.out.println("TRY HARDER NEXT TIME. IT TOOK YOU " + numGuesses + " GUESSES."); + } else { + System.out.println("VERY GOOD. YOU GUESSED IT IN ONLY " + numGuesses + " GUESSES."); } - nextStep = Step.QUERY_RETRY; - break; - - case QUERY_RETRY: - - System.out.print("DO YOU WANT TO TRY ANOTHER PUZZLE? "); + nextStep = Step.QUERY_RETRY; + break; + + case QUERY_RETRY: + + System.out.print("DO YOU WANT TO TRY ANOTHER PUZZLE? "); userResponse = scan.nextLine(); - - if (userResponse.toUpperCase().charAt(0) == 'N') { + + if (userResponse.toUpperCase().charAt(0) == 'N') { return; - } + } System.out.println(""); - nextStep = Step.RANDOMIZE; + nextStep = Step.RANDOMIZE; break; - + default: System.out.println("INVALID STEP"); nextStep = Step.QUERY_RETRY; - break; + break; } // End of switch - - } // End outer while loop - - } // End of method startGame + + } // End outer while loop + + } // End of method startGame public static void main(String[] args) { - + FlipFlop game = new FlipFlop(); game.play(); - + } // End of method main - + } // End of class FlipFlop diff --git a/36_Flip_Flop/javascript/flipflop.html b/36_Flip_Flop/javascript/flipflop.html index 924338459..2de8e1980 100644 --- a/36_Flip_Flop/javascript/flipflop.html +++ b/36_Flip_Flop/javascript/flipflop.html @@ -1,10 +1,9 @@ FLIPFLOP - -

    
    +
    
     
     
     
    diff --git a/36_Flip_Flop/javascript/flipflop.js b/36_Flip_Flop/javascript/flipflop.js
    index c74c61cae..fad83d64d 100644
    --- a/36_Flip_Flop/javascript/flipflop.js
    +++ b/36_Flip_Flop/javascript/flipflop.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/36_Flip_Flop/kotlin/README.md b/36_Flip_Flop/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/36_Flip_Flop/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/36_Flip_Flop/lua/README.md b/36_Flip_Flop/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/36_Flip_Flop/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/36_Flip_Flop/lua/flipflop-game.lua b/36_Flip_Flop/lua/flipflop-game.lua
    deleted file mode 100644
    index d529d1017..000000000
    --- a/36_Flip_Flop/lua/flipflop-game.lua
    +++ /dev/null
    @@ -1,183 +0,0 @@
    ---[[
    -Game of FlipFlop
    -===============
    -
    -Based on the original BASIC game of FlipFlop from the 1970s.
    -
    -This is a faithful recreation of the classic game, maintaining the original gameplay
    -while modernizing the implementation for Lua. For example, the original's complex
    -trigonometric random number generation has been replaced with Lua's math.random,
    -as modern random number generators are more sophisticated than those available
    -in 1970s BASIC.
    -
    -How to Play:
    ------------
    -The game presents a row of 10 X's. Your goal is to flip all X's to O's.
    -Enter a number from 1-10 to flip that position. The computer will also make
    -random moves in response. Special commands:
    -- Enter 0 to see the current board again
    -- Enter 11 to quit the game
    -Try to complete the puzzle in 12 moves or fewer for the best score!
    -
    -Strategy Tips:
    -------------
    -- When you make a move, watch how the computer responds. It will often
    -  make a predictable counter-move.
    -- If you enter the same position twice, the computer will use a different
    -  random pattern for its response.
    -- Try to work systematically from one end of the board to the other,
    -  rather than making random moves.
    -- If you get stuck, sometimes starting over (11) is better than continuing
    -  with a poor position.
    -
    -Technical Notes:
    ---------------
    -- Written for Lua 5.1 compatibility
    -- Uses tables for game state management
    -- Implements original game logic without goto statements
    -- Preserves the original game's move counting and win conditions
    -- Maintains the classic text-based interface style
    -
    -Original BASIC Version:
    ---------------------
    -The original game used complex trigonometric functions for random number
    -generation, likely due to limitations in BASIC's random number capabilities:
    -    R=TAN(Q+N/Q-N)-SIN(Q/N)+336*SIN(8*N)
    -    N=R-INT(R)
    -    N=INT(10*N)
    -
    -This has been simplified to use Lua's built-in random number generator
    -while maintaining the same gameplay experience.
    -
    -Converted from BASIC to Lua by Brian Wilkins
    -March 2025
    -]]--
    -
    -local function showInstructions()
    -    print("                    FLIP FLOP")
    -    print("              CREATIVE COMPUTING")
    -    print("            MORRISTOWN, NEW JERSEY")
    -    print("\n\n")
    -    print("THE OBJECT OF THIS GAME IS TO FLIP ALL THE X'S TO O'S.")
    -    print("WHEN YOU INPUT A NUMBER, THAT NUMBER AND ALL ADJACENT")
    -    print("NUMBERS WILL BE FLIPPED.")
    -    print("\n")
    -    print("INPUT A NUMBER FROM 1 TO 10 TO START THE GAME. TO QUIT")
    -    print("THE GAME AT ANY TIME, TYPE A 0 (ZERO). TO START OVER WITH")
    -    print("A NEW PUZZLE IN THE MIDDLE OF A GAME, TYPE A 11 (ELEVEN).")
    -    print("\n\n")
    -end
    -
    -local function printUpdatedBoard(board)
    -    print("1 2 3 4 5 6 7 8 9 10")
    -    print(table.concat(board, " "))
    -    print("\n\n")
    -end
    -
    -local function processMove(gameState, position)
    -    -- Check if current position is O
    -    if gameState.board[position] == "O" then
    -        gameState.board[position] = "X"
    -        if position == gameState["lastMove"] then
    -            -- Generate random position using simplified random logic
    -            local R = math.random()  -- between 0 and 1
    -            local N = math.floor(R * 10) + 1
    -            if gameState.board[N] == "O" then
    -                gameState.board[N] = "X"
    -            else
    -                gameState.board[N] = "O"
    -            end
    -        end
    -    else
    -        gameState.board[position] = "O"
    -        -- Generate another random position
    -        local R = math.random()
    -        local N = math.floor(R * 10) + 1
    -        if gameState.board[N] == "O" then
    -            gameState.board[N] = "X"
    -        else
    -            gameState.board[N] = "O"
    -        end
    -    end
    -end
    -
    -local function checkWin(gameState)
    -    -- Check if all positions are O's
    -    for i = 1, 10 do
    -        if gameState.board[i] ~= "O" then
    -            return false
    -        end
    -    end
    -    return true
    -end
    -
    -local function initializeGame()
    -    local gameState = {
    -        board = {},
    -        lastMove = nil,
    -        moves = 0
    -    }
    -    
    -    -- Initialize board
    -    for i = 1, 10 do
    -        gameState.board[i] = "X"
    -    end
    -    return gameState
    -end
    -
    -local function playGame()
    -    showInstructions()
    -    
    -    local gameState = initializeGame()
    -    local playing = true
    -    
    -    print("HERE IS THE STARTING LINE OF X'S.")
    -    print("\n\n")
    -    printUpdatedBoard(gameState.board)
    -    
    -    while playing do
    -        print("INPUT THE NUMBER")
    -        local N = tonumber(io.read())
    -        
    -        -- Check if input is valid
    -        if not N or N ~= math.floor(N) then
    -            print("ILLEGAL ENTRY--TRY AGAIN.")
    -        elseif N == 11 then
    -            playing = false
    -        elseif N > 11 then
    -            print("ILLEGAL ENTRY--TRY AGAIN.")
    -        elseif N == 0 then
    -            printUpdatedBoard(gameState.board)
    -        else
    -            -- Process the move
    -            processMove(gameState, N)
    -            gameState["lastMove"] = N
    -            gameState.moves = gameState.moves + 1
    -            
    -            -- Show the updated board
    -            printUpdatedBoard(gameState.board)
    -            
    -            -- Check for win
    -            if checkWin(gameState) then
    -                if gameState.moves <= 12 then
    -                    print(string.format("VERY GOOD. YOU GUESSED IT IN ONLY %d GUESSES.", gameState.moves))
    -                else
    -                    print(string.format("TRY HARDER NEXT TIME. IT TOOK YOU %d GUESSES.", gameState.moves))
    -                end
    -                
    -                print("DO YOU WANT TO TRY ANOTHER PUZZLE? (Y/N)")
    -                local answer = io.read():upper()
    -                if answer:sub(1,1) == "Y" then
    -                    gameState = initializeGame()
    -                    print("HERE IS THE STARTING LINE OF X'S.")
    -                    print("\n\n")
    -                    printUpdatedBoard(gameState.board)
    -                else
    -                    playing = false
    -                end
    -            end
    -        end
    -    end
    -end
    -
    -playGame()
    diff --git a/36_Flip_Flop/pascal/README.md b/36_Flip_Flop/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/36_Flip_Flop/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/36_Flip_Flop/perl/flipflop.pl b/36_Flip_Flop/perl/flipflop.pl
    deleted file mode 100755
    index 63e3f84e7..000000000
    --- a/36_Flip_Flop/perl/flipflop.pl
    +++ /dev/null
    @@ -1,124 +0,0 @@
    -#!/usr/bin/perl
    -
    -# Flip Flop program in Perl
    -# Translated by Kevin Brannen (kbrannen)
    -
    -use strict;
    -use warnings;
    -use Math::Trig;
    -
    -print "\n";
    -print " " x 32, "FLIPFLOP";
    -print " " x 15, "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n";
    -# *** CREATED BY MICHAEL CASS
    -
    -print "THE OBJECT OF THIS PUZZLE IS TO CHANGE THIS:\n\n";
    -print "X X X X X X X X X X\n\n";
    -print "TO THIS:\n\n";
    -print "O O O O O O O O O O\n\n";
    -print "BY TYPING THE NUMBER CORRESPONDING TO THE POSITION OF THE\n";
    -print "LETTER ON SOME NUMBERS, ONE POSITION WILL CHANGE, ON\n";
    -print "OTHERS, TWO WILL CHANGE.  TO RESET LINE TO ALL X'S, TYPE 0\n";
    -print "(ZERO) AND TO START OVER IN THE MIDDLE OF A GAME, TYPE \n";
    -print "11 (ELEVEN).\n\n";
    -
    -sub initialize
    -{
    -    my @a;
    -    print "1 2 3 4 5 6 7 8 9 10\n";
    -    print "X X X X X X X X X X\n";
    -    for my $i (0 .. 10) { $a[$i] = "X"; } # make sure [0] has a value just in case
    -    return @a;
    -}
    -
    -while (1)
    -{
    -    my $Q = rand(1);
    -    my $C = 0;
    -    print "HERE IS THE STARTING LINE OF X'S.\n\n";
    -    my @A = initialize();
    -
    -    while (1)
    -    {
    -        my $M = 0;
    -        my $N;
    -        while (1)
    -        {
    -            print "\nINPUT THE NUMBER: ";
    -            chomp($N = <>);
    -            if ($N != int($N) || $N < 0 ||  $N > 11)
    -            {
    -                print "ILLEGAL ENTRY--TRY AGAIN.\n";
    -                next;
    -            }
    -            last;
    -        }
    -        if ($N == 11) # start a new game
    -        {
    -            print "\n\n";
    -            last;
    -        }
    -        if ($N == 0) # reset line
    -        {
    -            @A = initialize();
    -            next;
    -        }
    -
    -        if ($M != $N)
    -        {
    -            $M = $N;
    -            $A[$N] = ($A[$N] eq "O") ? "X" : "O";
    -            while ($M == $N)
    -            {
    -                my $R = tan($Q + $N / $Q - $N) - sin($Q / $N) + 336 * sin(8 * $N);
    -                $N = $R - int($R);
    -                $N = int(10 * $N);
    -                if ($A[$N] eq "O")
    -                {
    -                    $A[$N] = "X";
    -                    next;
    -                }
    -                $A[$N] = "O";
    -                last; # GOTO 610
    -
    -                $A[$N] = "X";
    -            }
    -        }
    -        else
    -        {
    -            if ($A[$N] ne "O") { $A[$N] = "O"; }
    -            while ($M == $N)
    -            {
    -                my $R = .592 * (1 / tan($Q / $N + $Q)) / sin( $N * 2 + $Q) - cos($N);
    -                $N = $R - int($R);
    -                $N = int(10 * $N);
    -                if ($A[$N] eq "O")
    -                {
    -                    $A[$N] = "X";
    -                    next;
    -                }
    -                $A[$N] = "O";
    -                last;
    -            }
    -        }
    -
    -        print "1 2 3 4 5 6 7 8 9 10\n";
    -        for my $i (1 .. 10) { print "$A[$i] "; }
    -        print "\n";
    -        $C++;
    -        my $i;
    -        for ($i=1 ; $i <= 10 ; $i++) {
    -            last if ($A[$i] ne "O");
    -        }
    -        if ($i == 11)
    -        {
    -            if ($C <= 12) { print "VERY GOOD.  YOU GUESSED IT IN ONLY $C GUESSES.\n"; }
    -            else          { print "TRY HARDER NEXT TIME.  IT TOOK YOU $C GUESSES.\n"; }
    -            last;
    -        }
    -    }
    -    print "DO YOU WANT TO TRY ANOTHER PUZZLE (Y/N): ";
    -    $_ = <>;
    -    print "\n";
    -    last if (m/^n/i);
    -}
    diff --git a/36_Flip_Flop/python/flipflop.py b/36_Flip_Flop/python/flipflop.py
    index 8ea7e5b1f..9b6e2323f 100644
    --- a/36_Flip_Flop/python/flipflop.py
    +++ b/36_Flip_Flop/python/flipflop.py
    @@ -21,8 +21,8 @@
     # The original author of this game was
     # Michael Kass of New Hyde Park, New
     # York.
    -import math
     import random
    +import math
     from typing import Callable, List, Tuple
     
     flip_dict = {"X": "O", "O": "X"}
    @@ -36,8 +36,8 @@ def flip_bits(
         """
         while m == n:
             r = r_function(n)
    -        n_tmp = r - int(math.floor(r))
    -        n = int(10 * n_tmp)
    +        n = r - int(math.floor(r))
    +        n = int(10 * n)
             if row[n] == "X":
                 row[n] = "O"
                 break
    @@ -46,7 +46,7 @@ def flip_bits(
         return row, n
     
     
    -def print_instructions() -> None:
    +def print_instructions():
         print(" " * 32 + "FLIPFLOP")
         print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
         print("\n" * 2)
    @@ -61,7 +61,7 @@ def print_instructions() -> None:
         print("11 (ELEVEN).\n")
     
     
    -def main() -> None:
    +def main():
         q = random.random()
     
         print("HERE IS THE STARTING LINE OF X'S.\n")
    @@ -75,9 +75,9 @@ def main() -> None:
             if legal_move:
                 print(" ".join([str(i) for i in range(1, 11)]))
                 print(" ".join(row[1:]) + "\n")
    -        m_str = input("INPUT THE NUMBER\n")
    +        m = input("INPUT THE NUMBER\n")
             try:
    -            m = int(m_str)
    +            m = int(m)
                 if m > 11 or m < 0:
                     raise ValueError()
             except ValueError:
    diff --git a/36_Flip_Flop/ruby/flipflop.rb b/36_Flip_Flop/ruby/flipflop.rb
    index 74ceadeec..3a65a4c29 100644
    --- a/36_Flip_Flop/ruby/flipflop.rb
    +++ b/36_Flip_Flop/ruby/flipflop.rb
    @@ -49,7 +49,7 @@ def print_starting_message
     
       1 2 3 4 5 6 7 8 9 10
       X X X X X X X X X X
    -
    +  
       EOS
     end
     
    @@ -75,7 +75,7 @@ def shuffle_board(game, index, shuffle_function)
     end
     
     #Shuffle logic copied from original BASIC code
    -def shuffle_function1(game, index)
    +def shuffle_function1(game, index) 
       r = Math.tan(game.seed + index / game.seed - index) - Math.sin(game.seed / index) + 336 * Math.sin(8 * index)
       n = r - r.floor
       (10 * n).floor
    @@ -132,9 +132,9 @@ def play_game
         game.guesses += 1
         puts '1 2 3 4 5 6 7 8 9 10'
         puts game.state.join(' ')
    -
    +    
         if game.state.all? { |x| x == 'O' }
    -      if game.guesses > 12
    +      if game.guesses > 12 
             puts "TRY HARDER NEXT TIME. IT TOOK YOU #{game.guesses} GUESSES."
           else
             puts "VERY GOOD.  YOU GUESSED IT IN ONLY #{game.guesses} GUESSES."
    diff --git a/36_Flip_Flop/rust/Cargo.lock b/36_Flip_Flop/rust/Cargo.lock
    deleted file mode 100644
    index 81365033b..000000000
    --- a/36_Flip_Flop/rust/Cargo.lock
    +++ /dev/null
    @@ -1,82 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.10"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.147"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
    -
    -[[package]]
    -name = "morristown"
    -version = "0.1.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "f83b191fd96370b91c2925125774011a7a0f69b4db9e2045815e4fd20af725f6"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    -dependencies = [
    - "morristown",
    - "rand",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/36_Flip_Flop/rust/Cargo.toml b/36_Flip_Flop/rust/Cargo.toml
    deleted file mode 100644
    index 6989f4b29..000000000
    --- a/36_Flip_Flop/rust/Cargo.toml
    +++ /dev/null
    @@ -1,10 +0,0 @@
    -[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"
    -morristown = "0.1.3"
    diff --git a/36_Flip_Flop/rust/src/game.rs b/36_Flip_Flop/rust/src/game.rs
    deleted file mode 100644
    index b0eab60a2..000000000
    --- a/36_Flip_Flop/rust/src/game.rs
    +++ /dev/null
    @@ -1,125 +0,0 @@
    -pub struct Game {
    -    board: [char; 10],
    -    last_move: u8,
    -    entropy: f32,
    -    tries: u8,
    -}
    -
    -impl Game {
    -    pub fn new() -> Self {
    -        Game {
    -            board: ['X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'],
    -            last_move: 0,
    -            entropy: 0.,
    -            tries: 0,
    -        }
    -    }
    -
    -    pub fn play(&mut self) -> bool {
    -        self.reset_game();
    -
    -        println!("\nHERE IS THE STARTING LINE OF X'S.\n");
    -        println!("1 2 3 4 5 6 7 8 9 10");
    -        println!("X X X X X X X X X X\n");
    -
    -        let mut reset = false;
    -
    -        loop {
    -            self.tries += 1;
    -
    -            match Game::get_number() {
    -                0 => self.reset_board(),
    -                11 => {
    -                    reset = true;
    -                    break;
    -                }
    -                n => {
    -                    self.flip(n);
    -
    -                    let other = self.get_other(n, n == self.last_move);
    -                    if other != n {
    -                        self.flip(other);
    -                    }
    -
    -                    println!("other: {}", other);
    -                    self.last_move = n;
    -                }
    -            }
    -            self.draw();
    -
    -            if !self.board.iter().any(|c| *c == 'X') {
    -                break;
    -            }
    -        }
    -
    -        if !reset {
    -            let t = self.tries;
    -
    -            if t > 12 {
    -                println!("TRY HARDER NEXT TIME. IT TOOK YOU {t} GUESSES.");
    -            } else {
    -                println!("VERY GOOD. IT TOOK YOU ONLY {t} GUESSES.");
    -            }
    -
    -            return morristown::prompt_bool("DO YOU WANT TO TRY ANOTHER PUZZLE?", false);
    -        }
    -
    -        true
    -    }
    -
    -    fn flip(&mut self, i: u8) {
    -        if (1..=10).contains(&i) {
    -            let i = (i - 1) as usize;
    -            let char = &mut self.board[i];
    -
    -            match char {
    -                'X' => *char = '0',
    -                '0' => *char = 'X',
    -                _ => println!("INVALID BOARD CHARACTER!"),
    -            }
    -        }
    -    }
    -
    -    fn get_other(&self, m: u8, equals_last_move: bool) -> u8 {
    -        let e = self.entropy;
    -        let m = m as f32;
    -
    -        let rate = if equals_last_move {
    -            0.592 * (1. / (e / m + e).tan()) / (m * 2. + e).sin() - m.cos()
    -        } else {
    -            (e + m / e - m).tan() - (e / m).sin() + 336. * (8. * m).sin()
    -        };
    -
    -        (10. * (rate - rate.floor())).floor() as u8
    -    }
    -
    -    fn draw(&self) {
    -        println!("1 2 3 4 5 6 7 8 9 10");
    -        for c in self.board {
    -            print!("{c} ");
    -        }
    -        println!();
    -    }
    -
    -    fn get_number() -> u8 {
    -        loop {
    -            let n = morristown::prompt_number::("INPUT THE NUMBER?");
    -            if n > 11 {
    -                println!("ILLEGAL ENTRY--TRY AGAIN.");
    -            } else {
    -                return n;
    -            }
    -        }
    -    }
    -
    -    fn reset_board(&mut self) {
    -        self.board = ['X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'];
    -    }
    -
    -    fn reset_game(&mut self) {
    -        self.reset_board();
    -        self.last_move = 0;
    -        self.entropy = rand::random();
    -        self.tries = 0;
    -    }
    -}
    diff --git a/36_Flip_Flop/rust/src/main.rs b/36_Flip_Flop/rust/src/main.rs
    deleted file mode 100644
    index f7c72c865..000000000
    --- a/36_Flip_Flop/rust/src/main.rs
    +++ /dev/null
    @@ -1,24 +0,0 @@
    -mod game;
    -use crate::game::Game;
    -
    -fn main() {
    -    morristown::print_intro("FLIPFLOP");
    -
    -    println!("THE OBJECT OF THIS PUZZLE IS TO CHANGE THIS:\n");
    -    println!("X X X X X X X X X X\n");
    -    println!("TO THIS:\n");
    -    println!("O O O O O O O O O O\n");
    -    println!("BY TYPING THE NUMBER CORRESPONDING TO THE POSITION OF THE");
    -    println!("LETTER ON SOME NUMBERS, ONE POSITION WILL CHANGE, ON");
    -    println!("OTHERS, TWO WILL CHANGE.  TO RESET LINE TO ALL X'S, TYPE 0");
    -    println!("(ZERO) AND TO START OVER IN THE MIDDLE OF A GAME, TYPE ");
    -    println!("11 (ELEVEN).");
    -
    -    let mut game = Game::new();
    -
    -    loop {
    -        if !game.play() {
    -            break;
    -        }
    -    }
    -}
    diff --git a/36_Flip_Flop/vbnet/FlipFlop.sln b/36_Flip_Flop/vbnet/FlipFlop.sln
    deleted file mode 100644
    index 8301941bc..000000000
    --- a/36_Flip_Flop/vbnet/FlipFlop.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 388b75c10..000000000
    --- a/36_Flip_Flop/vbnet/FlipFlop.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    FlipFlop
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/37_Football/README.md b/37_Football/README.md
    index 2f6b68a6d..7f7918617 100644
    --- a/37_Football/README.md
    +++ b/37_Football/README.md
    @@ -16,7 +16,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/37_Football/csharp/Football.csproj b/37_Football/csharp/Football.csproj
    deleted file mode 100644
    index d3fe4757c..000000000
    --- a/37_Football/csharp/Football.csproj
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    diff --git a/37_Football/csharp/Football.sln b/37_Football/csharp/Football.sln
    deleted file mode 100644
    index b0d85b419..000000000
    --- a/37_Football/csharp/Football.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/football.bas b/37_Football/football.bas
    index 9ee2192f3..07e416a32 100644
    --- a/37_Football/football.bas
    +++ b/37_Football/football.bas
    @@ -58,7 +58,7 @@
     790 P=P-Y(T)*K
     794 IF W(T)*P
     
     FOOTBALL
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/37_Football/javascript/football.js b/37_Football/javascript/football.js
    index 4ed0ae02f..ca990f922 100644
    --- a/37_Football/javascript/football.js
    +++ b/37_Football/javascript/football.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    @@ -440,7 +440,7 @@ async function main()
             p = p - wa[t] * y;
             print("\n");
             print("NET YARDS GAINED ON DOWN " + d + " ARE " + y + "\n");
    -
    +        
             g = Math.random();
             if (g <= 0.025) {
                 loss_posession();
    diff --git a/37_Football/javascript/ftball.html b/37_Football/javascript/ftball.html
    index a11b5b988..92862bdec 100644
    --- a/37_Football/javascript/ftball.html
    +++ b/37_Football/javascript/ftball.html
    @@ -1,10 +1,9 @@
     
     
     FTBALL
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/37_Football/javascript/ftball.js b/37_Football/javascript/ftball.js
    index 256a4bfca..16374bd0c 100644
    --- a/37_Football/javascript/ftball.js
    +++ b/37_Football/javascript/ftball.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    @@ -365,7 +365,7 @@ async function main()
                         start = 3;
                         continue;
                     }
    -
    +                
             }
             // Gain or loss
             if (routine <= 1) {
    diff --git a/37_Football/kotlin/README.md b/37_Football/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/37_Football/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/37_Football/lua/README.md b/37_Football/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/37_Football/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/37_Football/pascal/README.md b/37_Football/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/37_Football/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/37_Football/python/README.md b/37_Football/python/README.md
    index 1f375dd88..781945ec4 100644
    --- a/37_Football/python/README.md
    +++ b/37_Football/python/README.md
    @@ -1,30 +1,3 @@
     Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
     
     Conversion to [Python](https://www.python.org/about/)
    -
    -
    -## Porting notes
    -
    -Variables:
    -
    -* E: score_limit
    -* H(2): Scores
    -* T(2): Team toggle
    -* T: team who currently possesses the ball
    -* L: Offset
    -* P: Who has the ball
    -* K: yards
    -* R: Runback current team in yards
    -* P$(20): Actions (see data.json)
    -
    -Functions:
    -
    -* `P$(I)`: Access index `I` of the `P` array
    -* ABS: abs (absolute value)
    -* RND(1): random()
    -* GOSUB: Execute a function - will jump back to this
    -* GOTO: Just jump
    -
    -Patterns:
    -
    -* `T=T(T)`: Toggle the team who currently has the ball
    diff --git a/37_Football/python/data.json b/37_Football/python/data.json
    deleted file mode 100644
    index c387bc674..000000000
    --- a/37_Football/python/data.json
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -{
    -    "players": [17,8,4,14,19,3,10,1,7,11,15,9,5,20,13,18,16,2,12,6,
    -        20,2,17,5,8,18,12,11,1,4,19,14,10,7,9,15,6,13,16,3],
    -    "actions": ["PITCHOUT","TRIPLE REVERSE","DRAW","QB SNEAK","END AROUND",
    -        "DOUBLE REVERSE","LEFT SWEEP","RIGHT SWEEP","OFF TACKLE",
    -        "WISHBONE OPTION","FLARE PASS","SCREEN PASS",
    -        "ROLL OUT OPTION","RIGHT CURL","LEFT CURL","WISHBONE OPTION",
    -        "SIDELINE PASS","HALF-BACK OPTION","RAZZLE-DAZZLE","BOMB!!!!"]
    -}
    diff --git a/37_Football/python/football.py b/37_Football/python/football.py
    deleted file mode 100644
    index c84c8df61..000000000
    --- a/37_Football/python/football.py
    +++ /dev/null
    @@ -1,452 +0,0 @@
    -"""
    -FOOTBALL
    -
    -A game.
    -
    -Ported to Python by Martin Thoma in 2022.
    -The JavaScript version by Oscar Toledo G. (nanochess) was used
    -"""
    -# NOTE: The newlines might be wrong
    -
    -import json
    -from math import floor
    -from pathlib import Path
    -from random import randint, random
    -from typing import List, Tuple
    -
    -with open(Path(__file__).parent / "data.json") as f:
    -    data = json.load(f)
    -
    -player_data = [num - 1 for num in data["players"]]
    -actions = data["actions"]
    -
    -
    -aa: List[int] = [-100 for _ in range(20)]
    -ba: List[int] = [-100 for _ in range(20)]
    -ca: List[int] = [-100 for _ in range(40)]
    -score: List[int] = [0, 0]
    -ta: Tuple[int, int] = (1, 0)
    -wa: Tuple[int, int] = (-1, 1)
    -xa: Tuple[int, int] = (100, 0)
    -ya: Tuple[int, int] = (1, -1)
    -za: Tuple[int, int] = (0, 100)
    -marker: Tuple[str, str] = ("--->", "<---")
    -t: int = 0
    -p: int = 0
    -winning_score: int
    -
    -
    -def ask_bool(prompt: str) -> bool:
    -    while True:
    -        answer = input(prompt).lower()
    -        if answer in ["yes", "y"]:
    -            return True
    -        elif answer in ["no", "n"]:
    -            return False
    -
    -
    -def ask_int(prompt: str) -> int:
    -    while True:
    -        answer = input(prompt)
    -        try:
    -            return int(answer)
    -        except Exception:
    -            pass
    -
    -
    -def get_offense_defense() -> Tuple[int, int]:
    -    while True:
    -        input_str = input("INPUT OFFENSIVE PLAY, DEFENSIVE PLAY: ")
    -        try:
    -            p1, p2 = (int(n) for n in input_str.split(","))
    -            return p1, p2
    -        except Exception:
    -            pass
    -
    -
    -def field_headers() -> None:
    -    print("TEAM 1 [0   10   20   30   40   50   60   70   80   90   100] TEAM 2")
    -    print("\n\n")
    -
    -
    -def separator() -> None:
    -    print("+" * 72 + "\n")
    -
    -
    -def show_ball() -> None:
    -    da: Tuple[int, int] = (0, 3)
    -    print(" " * (da[t] + 5 + int(p / 2)) + marker[t] + "\n")
    -    field_headers()
    -
    -
    -def show_scores() -> bool:
    -    print()
    -    print(f"TEAM 1 SCORE IS {score[0]}")
    -    print(f"TEAM 2 SCORE IS {score[1]}")
    -    print()
    -    if score[t] >= winning_score:
    -        print(f"TEAM {t+1} WINS*******************")
    -        return True
    -    return False
    -
    -
    -def loss_posession() -> None:
    -    global t
    -    print()
    -    print(f"** LOSS OF POSSESSION FROM TEAM {t+1} TO TEAM {ta[t]+1}")
    -    print()
    -    separator()
    -    print()
    -    t = ta[t]
    -
    -
    -def touchdown() -> None:
    -    print()
    -    print(f"TOUCHDOWN BY TEAM {t+1} *********************YEA TEAM")
    -    q = 7
    -    g = random()
    -    if g <= 0.1:
    -        q = 6
    -        print("EXTRA POINT NO GOOD")
    -    else:
    -        print("EXTRA POINT GOOD")
    -    score[t] = score[t] + q
    -
    -
    -def print_header() -> None:
    -    print(" " * 32 + "FOOTBALL")
    -    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n")
    -    print("PRESENTING N.F.U. FOOTBALL (NO FORTRAN USED)\n\n")
    -
    -
    -def print_instructions() -> None:
    -    print(
    -        """THIS IS A FOOTBALL GAME FOR TWO TEAMS IN WHICH PLAYERS MUST
    -PREPARE A TAPE WITH A DATA STATEMENT (1770 FOR TEAM 1,
    -1780 FOR TEAM 2) IN WHICH EACH TEAM SCRAMBLES NOS. 1-20
    -THESE NUMBERS ARE THEN ASSIGNED TO TWENTY GIVEN PLAYS.
    -A LIST OF NOS. AND THEIR PLAYS IS PROVIDED WITH
    -BOTH TEAMS HAVING THE SAME PLAYS. THE MORE SIMILAR THE
    -PLAYS THE LESS YARDAGE GAINED.  SCORES ARE GIVEN
    -WHENEVER SCORES ARE MADE. SCORES MAY ALSO BE OBTAINED
    -BY INPUTTING 99,99 FOR PLAY NOS. TO PUNT OR ATTEMPT A
    -FIELD GOAL, INPUT 77,77 FOR PLAY NUMBERS. QUESTIONS WILL BE
    -ASKED THEN. ON 4TH DOWN, YOU WILL ALSO BE ASKED WHETHER
    -YOU WANT TO PUNT OR ATTEMPT A FIELD GOAL. IF THE ANSWER TO
    -BOTH QUESTIONS IS NO IT WILL BE ASSUMED YOU WANT TO
    -TRY AND GAIN YARDAGE. ANSWER ALL QUESTIONS YES OR NO.
    -THE GAME IS PLAYED UNTIL PLAYERS TERMINATE (CONTROL-C).
    -PLEASE PREPARE A TAPE AND RUN.
    -"""
    -    )
    -
    -
    -def main() -> None:
    -    global winning_score
    -    print_header()
    -    want_instructions = ask_bool("DO YOU WANT INSTRUCTIONS? ")
    -    if want_instructions:
    -        print_instructions()
    -    print()
    -    winning_score = ask_int("PLEASE INPUT SCORE LIMIT ON GAME: ")
    -    for i in range(40):
    -        index = player_data[i - 1]
    -        if i < 20:
    -            aa[index] = i
    -        else:
    -            ba[index] = i - 20
    -        ca[i] = index
    -    offset = 0
    -    for t in [0, 1]:
    -        print(f"TEAM {t+1} PLAY CHART")
    -        print("NO.      PLAY")
    -        for i in range(20):
    -            input_str = f"{ca[i + offset]}"
    -            while len(input_str) < 6:
    -                input_str += " "
    -            input_str += actions[i]
    -            print(input_str)
    -        offset += 20
    -        t = 1
    -        print()
    -        print("TEAR OFF HERE----------------------------------------------")
    -        print("\n" * 10)
    -
    -    field_headers()
    -    print("TEAM 1 DEFEND 0 YD GOAL -- TEAM 2 DEFENDS 100 YD GOAL.")
    -    t = randint(0, 1)
    -    print()
    -    print("THE COIN IS FLIPPED")
    -    routine = 1
    -    while True:
    -        if routine <= 1:
    -            p = xa[t] - ya[t] * 40
    -            separator()
    -            print(f"TEAM {t+1} RECEIVES KICK-OFF")
    -            k = floor(26 * random() + 40)
    -        if routine <= 2:
    -            p = p - ya[t] * k
    -        if routine <= 3:
    -            if wa[t] * p >= za[t] + 10:
    -                print("BALL WENT OUT OF ENDZONE --AUTOMATIC TOUCHBACK--")
    -                p = za[t] - wa[t] * 20
    -                if routine <= 4:
    -                    routine = 5
    -            else:
    -                print(f"BALL WENT {k} YARDS.  NOW ON {p}")
    -                show_ball()
    -
    -        if routine <= 4:
    -            want_runback = ask_bool(f"TEAM {t+1} DO YOU WANT TO RUNBACK? ")
    -
    -            if want_runback:
    -                k = floor(9 * random() + 1)
    -                r = floor(((xa[t] - ya[t] * p + 25) * random() - 15) / k)
    -                p = p - wa[t] * r
    -                print(f"RUNBACK TEAM {t+1} {r} YARDS")
    -                g = random()
    -                if g < 0.25:
    -                    loss_posession()
    -                    routine = 4
    -                    continue
    -                elif ya[t] * p >= xa[t]:
    -                    touchdown()
    -                    if show_scores():
    -                        return
    -                    t = ta[t]
    -                    routine = 1
    -                    continue
    -                elif wa[t] * p >= za[t]:
    -                    print(f"SAFETY AGAINST TEAM {t+1} **********************OH-OH")
    -                    score[ta[t]] = score[ta[t]] + 2
    -                    if show_scores():
    -                        return
    -
    -                    p = za[t] - wa[t] * 20
    -                    want_punt = ask_bool(
    -                        f"TEAM {t+1} DO YOU WANT TO PUNT INSTEAD OF A KICKOFF? "
    -                    )
    -                    if want_punt:
    -                        print(f"TEAM {t+1} WILL PUNT")
    -                        g = random()
    -                        if g < 0.25:
    -                            loss_posession()
    -                            routine = 4
    -                            continue
    -
    -                        print()
    -                        separator()
    -                        k = floor(25 * random() + 35)
    -                        t = ta[t]
    -                        routine = 2
    -                        continue
    -
    -                    touchdown()
    -                    if show_scores():
    -                        return
    -                    t = ta[t]
    -                    routine = 1
    -                    continue
    -                else:
    -                    routine = 5
    -                    continue
    -
    -            else:
    -                if wa[t] * p >= za[t]:
    -                    p = za[t] - wa[t] * 20
    -
    -        if routine <= 5:
    -            d = 1
    -            s = p
    -
    -        if routine <= 6:
    -            print("=" * 72 + "\n")
    -            print(f"TEAM {t+1} DOWN {d} ON {p}")
    -            if d == 1:
    -                if ya[t] * (p + ya[t] * 10) >= xa[t]:
    -                    c = 8
    -                else:
    -                    c = 4
    -
    -            if c != 8:
    -                yards = 10 - (ya[t] * p - ya[t] * s)
    -                print(" " * 27 + f"{yards} YARDS TO 1ST DOWN")
    -            else:
    -                yards = xa[t] - ya[t] * p
    -                print(" " * 27 + f"{yards} YARDS")
    -
    -            show_ball()
    -            if d == 4:
    -                routine = 8
    -
    -        if routine <= 7:
    -            u = floor(3 * random() - 1)
    -            while True:
    -                p1, p2 = get_offense_defense()
    -                if t != 1:
    -                    p2, p1 = p1, p2
    -
    -                if p1 == 99:
    -                    if show_scores():
    -                        return
    -                    if p1 == 99:
    -                        continue
    -
    -                if p1 < 1 or p1 > 20 or p2 < 1 or p2 > 20:
    -                    print("ILLEGAL PLAY NUMBER, CHECK AND ", end="")
    -                    continue
    -
    -                break
    -            p1 -= 1
    -            p2 -= 1
    -
    -        if d == 4 or p1 == 77:
    -            want_punt = ask_bool(f"DOES TEAM {t+1} WANT TO PUNT? ")
    -
    -            if want_punt:
    -                print()
    -                print(f"TEAM {t+1} WILL PUNT")
    -                g = random()
    -                if g < 0.25:
    -                    loss_posession()
    -                    routine = 4
    -                    continue
    -
    -                print()
    -                separator()
    -                k = floor(25 * random() + 35)
    -                t = ta[t]
    -                routine = 2
    -                continue
    -
    -            attempt_field_goal = ask_bool(
    -                f"DOES TEAM {t+1} WANT TO ATTEMPT A FIELD GOAL? "
    -            )
    -
    -            if attempt_field_goal:
    -                print()
    -                print(f"TEAM {t+1} WILL ATTEMPT A FIELD GOAL")
    -                g = random()
    -                if g < 0.025:
    -                    loss_posession()
    -                    routine = 4
    -                    continue
    -                else:
    -                    f = floor(35 * random() + 20)
    -                    print()
    -                    print(f"KICK IS {f} YARDS LONG")
    -                    p = p - wa[t] * f
    -                    g = random()
    -                    if g < 0.35:
    -                        print("BALL WENT WIDE")
    -                    elif ya[t] * p >= xa[t]:
    -                        print(
    -                            f"FIELD GOLD GOOD FOR TEAM {t+1} *********************YEA"
    -                        )
    -                        q = 3
    -                        score[t] = score[t] + q
    -                        if show_scores():
    -                            return
    -                        t = ta[t]
    -                        routine = 1
    -                        continue
    -
    -                    print(f"FIELD GOAL UNSUCCESFUL TEAM {t+1}-----------------TOO BAD")
    -                    print()
    -                    separator()
    -                    if ya[t] * p < xa[t] + 10:
    -                        print()
    -                        print(f"BALL NOW ON {p}")
    -                        t = ta[t]
    -                        show_ball()
    -                        routine = 4
    -                        continue
    -                    else:
    -                        t = ta[t]
    -                        routine = 3
    -                        continue
    -
    -            else:
    -                routine = 7
    -                continue
    -
    -        y = floor(
    -            abs(aa[p1] - ba[p2]) / 19 * ((xa[t] - ya[t] * p + 25) * random() - 15)
    -        )
    -        print()
    -        if t == 1 and aa[p1] < 11 or t == 2 and ba[p2] < 11:
    -            print("THE BALL WAS RUN")
    -        elif u == 0:
    -            print(f"PASS INCOMPLETE TEAM {t+1}")
    -            y = 0
    -        else:
    -            g = random()
    -            if g <= 0.025 and y > 2:
    -                print("PASS COMPLETED")
    -            else:
    -                print("QUARTERBACK SCRAMBLED")
    -
    -        p = p - wa[t] * y
    -        print()
    -        print(f"NET YARDS GAINED ON DOWN {d} ARE {y}")
    -
    -        g = random()
    -        if g <= 0.025:
    -            loss_posession()
    -            routine = 4
    -            continue
    -        elif ya[t] * p >= xa[t]:
    -            touchdown()
    -            if show_scores():
    -                return
    -            t = ta[t]
    -            routine = 1
    -            continue
    -        elif wa[t] * p >= za[t]:
    -            print()
    -            print(f"SAFETY AGAINST TEAM {t+1} **********************OH-OH")
    -            score[ta[t]] = score[ta[t]] + 2
    -            if show_scores():
    -                return
    -            p = za[t] - wa[t] * 20
    -            want_punt = ask_bool(
    -                f"TEAM {t+1} DO YOU WANT TO PUNT INSTEAD OF A KICKOFF? "
    -            )
    -            if want_punt:
    -                print()
    -                print(f"TEAM {t+1} WILL PUNT")
    -                g = random()
    -                if g < 0.25:
    -                    loss_posession()
    -                    routine = 4
    -                    continue
    -
    -                print()
    -                separator()
    -                k = floor(25 * random() + 35)
    -                t = ta[t]
    -                routine = 2
    -                continue
    -
    -            touchdown()
    -            if show_scores():
    -                return
    -            t = ta[t]
    -            routine = 1
    -        elif ya[t] * p - ya[t] * s >= 10:
    -            routine = 5
    -        else:
    -            d += 1
    -            if d != 5:
    -                routine = 6
    -            else:
    -                print()
    -                print(f"CONVERSION UNSUCCESSFUL TEAM {t+1}")
    -                t = ta[t]
    -                print()
    -                separator()
    -                routine = 5
    -
    -
    -if __name__ == "__main__":
    -    main()
    diff --git a/37_Football/vbnet/Football.sln b/37_Football/vbnet/Football.sln
    deleted file mode 100644
    index 2e1777187..000000000
    --- a/37_Football/vbnet/Football.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index ce4046400..000000000
    --- a/37_Football/vbnet/Football.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Football
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/38_Fur_Trader/README.md b/38_Fur_Trader/README.md
    index 6b08911ae..676b605bf 100644
    --- a/38_Fur_Trader/README.md
    +++ b/38_Fur_Trader/README.md
    @@ -14,11 +14,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Known Bugs
    -
    -- The value of some furs are not changed from the previous fort when you select fort 2 or 3.  As a result, you will get a different value for your firs depending on whether you have previously visited a different fort.  (All fur values are set when you visit Fort 1.)
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/38_Fur_Trader/c/README.md b/38_Fur_Trader/c/README.md
    index cb9833d5a..a5b55dd8e 100644
    --- a/38_Fur_Trader/c/README.md
    +++ b/38_Fur_Trader/c/README.md
    @@ -5,18 +5,19 @@ Conversion to [ANSI-C](https://en.wikipedia.org/wiki/ANSI_C)
     ##### Translator Notes:
     I tried to preserve as much of the original layout and flow of the code
     as possible.  However I did use enumerated types for the Fort numbers
    -and Fur types.  I think this was certainly a change for the better, and
    +and Fur types.  I think this was certainly a change for the better, and 
     makes the code much easier to read.
     
    -I also tried to minimise the use of pointers, and stuck with old-school
    +I also tried to minimise the use of pointers, and stuck with old-school 
     C formatting, because you never know how old the compiler is.
     
     Interestingly the code seems to have a bug around the prices of Fox Furs.
     The commodity-rate for these is stored in the variable `D1`, however some
    -paths through the code do not set this price.  So there was a chance of
    -using this uninitialised, or whatever the previous loop set.  I don't
    +paths through the code do not set this price.  So there was a chance of 
    +using this uninitialised, or whatever the previous loop set.  I don't 
     think this was the original authors intent.  So I preserved the original flow
    -of the code (using the previous `D1` value), but also catching the
    +of the code (using the previous `D1` value), but also catching the 
     uninitialised path, and assigning a "best guess" value.
     
     krt@krt.com.au 2020-10-10
    +
    diff --git a/38_Fur_Trader/c/furtrader.c b/38_Fur_Trader/c/furtrader.c
    old mode 100644
    new mode 100755
    index 8735e08f0..80ffbcef7
    --- a/38_Fur_Trader/c/furtrader.c
    +++ b/38_Fur_Trader/c/furtrader.c
    @@ -110,10 +110,10 @@ char getYesOrNo()
     
     
     
    -/*
    +/* 
      * Show the player the choices of Fort, get their input, if the
      * input is a valid choice (1,2,3) return it, otherwise keep
    - * prompting the user.
    + * prompting the user. 
      */
     int getFortChoice()
     {
    @@ -140,7 +140,7 @@ int getFortChoice()
     
     
     /*
    - * Print the description for the fort
    + * Print the description for the fort 
      */
     void showFortComment( int which_fort )
     {
    @@ -172,10 +172,10 @@ void showFortComment( int which_fort )
             exit( 1 );  /* you have a bug */
         }
         print( "" );
    -}
    +}        
     
     
    -/*
    +/*    
      * Prompt the player for how many of each fur type they want.
      * Accept numeric inputs, re-prompting on incorrect input values
      */
    @@ -193,7 +193,7 @@ void getFursPurchase( int *furs )
             furs[i] = getNumericInput();
         }
     }
    -
    +        
     
     /*
      * (Re)Set the player's inventory to zero
    @@ -209,7 +209,7 @@ void zeroInventory( int *player_fur_count )
     
     
     /*
    - * Tally the player's inventory
    + * Tally the player's inventory 
      */
     int sumInventory( int *player_fur_count )
     {
    @@ -225,7 +225,7 @@ int sumInventory( int *player_fur_count )
     
     
     /*
    - * Return a random number between a & b
    + * Return a random number between a & b 
      * Ref: https://stackoverflow.com/a/686376/1730895
      */
     float randomAB(float a, float b)
    @@ -255,7 +255,7 @@ int main( void )
         char  yes_or_no;
         int   event_picker;
         int   which_fort;
    -
    +    
         /* what part of the game is in play */
         int   game_state = STATE_STARTING;
     
    @@ -294,12 +294,12 @@ int main( void )
                     exit( 0 );                 /* STOP */
                 game_state = STATE_TRADING;
             }
    -
    +        
             else if ( game_state == STATE_TRADING )
             {
                 print( "" );
                 printf( "YOU HAVE $ %1.2f IN SAVINGS\n", player_funds );
    -            printf( "AND %d FURS TO BEGIN THE EXPEDITION\n", MAX_FURS );
    +            printf( "AND %d FURS TO BEGIN THE EXPEDITION\n", MAX_FURS ); 
                 getFursPurchase( player_furs );
     
                 if ( sumInventory( player_furs ) > MAX_FURS )
    @@ -392,7 +392,7 @@ int main( void )
                     beaver_price = ( ( 0.25 * randFloat() + 1.00 ) * 100 + 0.5 ) / 100;
                     if ( fox_price < 0 )
                     {
    -                    /* Original Bug?  There is no Fox price generated for New York,
    +                    /* Original Bug?  There is no Fox price generated for New York, 
                            it will use any previous "D1" price.
                            So if there was no previous value, make one up */
                         fox_price = ( ( 0.25 * randFloat() + 1.05 ) * 100 + 0.5 ) / 100; /* not in orginal code */
    @@ -447,7 +447,7 @@ int main( void )
                 fox_value    = fox_price    * player_furs[ FUR_FOX ];
                 ermine_value = ermine_price * player_furs[ FUR_ERMINE ];
                 mink_value   = mink_price   * player_furs[ FUR_MINK ];
    -
    +         
                 print( "" );
                 printf( "YOUR BEAVER SOLD FOR $%6.2f\n", beaver_value );
                 printf( "YOUR FOX SOLD FOR    $%6.2f\n", fox_value );
    @@ -472,3 +472,4 @@ int main( void )
     
         return 0; /* exit OK */
     }
    +
    diff --git a/38_Fur_Trader/csharp/Game.cs b/38_Fur_Trader/csharp/Game.cs
    index 461f8b8a7..fc1aae259 100644
    --- a/38_Fur_Trader/csharp/Game.cs
    +++ b/38_Fur_Trader/csharp/Game.cs
    @@ -116,7 +116,7 @@ private bool ContinueGame()
             private void PlayTurn(GameState state)
             {
                 state.UnasignedFurCount = 190;      /// start with 190 furs each turn
    -
    +            
                 // provide current status to user
                 Console.WriteLine(new string('_', 70));
                 Console.WriteLine("");
    @@ -134,7 +134,7 @@ private void PlayTurn(GameState state)
                 state.UnasignedFurCount -= state.MinkPelts;
                 Console.WriteLine("");
                 Console.ForegroundColor = ConsoleColor.White;
    -            Console.WriteLine($"You have {state.UnasignedFurCount} furs remaining for distribution");
    +            Console.WriteLine($"You have {state.UnasignedFurCount} furs remaining for distribution");            
                 Console.Write("How many Beaver pelts do you have? ");
                 state.BeaverPelts = GetPelts(state.UnasignedFurCount);
                 state.UnasignedFurCount -= state.BeaverPelts;
    @@ -149,7 +149,7 @@ private void PlayTurn(GameState state)
                 Console.WriteLine($"You have {state.UnasignedFurCount} furs remaining for distribution");
                 Console.Write("How many Fox pelts do you have? ");
                 state.FoxPelts = GetPelts(state.UnasignedFurCount);
    -            state.UnasignedFurCount -= state.FoxPelts;
    +            state.UnasignedFurCount -= state.FoxPelts;            
     
                 // get input on which fort to trade with; user gets an opportunity to evaluate and re-select fort after selection until user confirms selection
                 do
    @@ -273,7 +273,7 @@ private void ProcessExpeditionOutcome(GameState state)
                         beaverPrice = RandomPriceGenerator(0.2d , 1.00d);
                         foxPrice =    RandomPriceGenerator(0.25d, 1.10d);
                         erminePrice = RandomPriceGenerator(0.2d , 0.95d);
    -                    minkPrice =   RandomPriceGenerator(0.15d, 1.05d);
    +                    minkPrice =   RandomPriceGenerator(0.15d, 1.05d); 
                         fortname = "Fort New York";
                         suppliesCost = 80.0d;
                         travelExpenses = 25.0d;
    @@ -418,7 +418,7 @@ private bool TradeAtAnotherFort()
             private int GetPelts(int furCount)
             {
                 int peltCount;
    -
    +            
                 // loop until the user enters a valid value
                 do
                 {
    @@ -432,7 +432,7 @@ private int GetPelts(int furCount)
                         // invalid entry; message back to user
                         Console.ForegroundColor = ConsoleColor.Red;
                         Console.WriteLine("Sorry, I didn't understand. Please enter the number of pelts.");
    -
    +                    
                         // continue looping
                         continue;
                     }
    @@ -443,7 +443,7 @@ private int GetPelts(int furCount)
                         // too many pelts selected
                         Console.ForegroundColor = ConsoleColor.Red;
                         Console.WriteLine($"You may not have that many furs. Do not try to cheat. I can add.");
    -
    +                    
                         // continue looping
                         continue;
                     }
    @@ -479,7 +479,7 @@ private int GetSelectedFort()
                         // no, invalid data
                         Console.ForegroundColor = ConsoleColor.Red;
                         Console.WriteLine("Sorry, I didn't understand. Please answer 1, 2, or 3.");
    -
    +                    
                         // continue looping
                         continue;
                     }
    @@ -490,7 +490,7 @@ private int GetSelectedFort()
                         // no, invalid for selected
                         Console.ForegroundColor = ConsoleColor.Red;
                         Console.WriteLine($"Please answer 1, 2, or 3.");
    -
    +                    
                         // continue looping
                         continue;
                     }
    diff --git a/38_Fur_Trader/csharp/GameState.cs b/38_Fur_Trader/csharp/GameState.cs
    index 92330ffe9..41c9d1cac 100644
    --- a/38_Fur_Trader/csharp/GameState.cs
    +++ b/38_Fur_Trader/csharp/GameState.cs
    @@ -8,11 +8,11 @@ internal class GameState
         {
             internal bool GameOver { get; set; }
     
    -        internal double Savings { get; set; }
    +        internal double Savings { get; set; }        
     
    -        internal int ExpeditionCount { get; set; }
    +        internal int ExpeditionCount { get; set; }        
     
    -        internal int UnasignedFurCount { get; set; }
    +        internal int UnasignedFurCount { get; set; }        
     
             internal int[] Pelts { get; private set; }
     
    diff --git a/38_Fur_Trader/furtrader.bas b/38_Fur_Trader/furtrader.bas
    index 9a379b2c1..ce3bedd22 100644
    --- a/38_Fur_Trader/furtrader.bas
    +++ b/38_Fur_Trader/furtrader.bas
    @@ -1,11 +1,11 @@
    -1 DIM F(4)
    +1 DIM F(4) 
     2 PRINT TAB(31);"FUR TRADER"
     4 PRINT TAB(15);"CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY"
     6 PRINT: PRINT: PRINT
    -15 GOSUB 1091
    +15 GOSUB 1091 
     16 LET I=600
     17 PRINT "DO YOU WISH TO TRADE FURS?"
    -18 GOSUB 1402
    +18 GOSUB 1402 
     19 IF B$="YES" THEN 100
     20 IF B$="YES " THEN 100
     21 STOP
    @@ -17,66 +17,66 @@
     300 PRINT
     301 PRINT "YOUR 190 FURS ARE DISTRIBUTED AMONG THE FOLLOWING"
     302 PRINT "KINDS OF PELTS: MINK, BEAVER, ERMINE AND FOX."
    -310 GOSUB 1430
    +310 GOSUB 1430 
     315 RESTORE
    -330 FOR J=1 TO 4
    +330 FOR J=1 TO 4 
     332 READ B$
    -333 PRINT
    -335 PRINT "HOW MANY ";B$;" PELTS DO YOU HAVE";
    -338 INPUT F(J)
    -340 LET F(0)=F(1)+F(2)+F(3)+F(4)
    +333 PRINT  
    +335 PRINT "HOW MANY ";B$;" PELTS DO YOU HAVE"; 
    +338 INPUT F(J) 
    +340 LET F(0)=F(1)+F(2)+F(3)+F(4) 
     342 IF F(0)=190 THEN 1100
    -344 IF F(0)>190 THEN 500
    -348 NEXT J
    -350 GOTO 1100
    +344 IF F(0)>190 THEN 500 
    +348 NEXT J 
    +350 GOTO 1100 
     500 PRINT
    -501 PRINT "YOU MAY NOT HAVE THAT MANY FURS."
    -502 PRINT "DO NOT TRY TO CHEAT.  I CAN ADD."
    +501 PRINT "YOU MAY NOT HAVE THAT MANY FURS."   
    +502 PRINT "DO NOT TRY TO CHEAT.  I CAN ADD." 
     503 PRINT "YOU MUST START AGAIN."
    -504 GOTO 15
    +504 GOTO 15 
     508 PRINT
     511 PRINT "DO YOU WANT TO TRADE FURS NEXT YEAR?"
    -513 GOTO 18
    +513 GOTO 18 
     1091 PRINT "YOU ARE THE LEADER OF A FRENCH FUR TRADING EXPEDITION IN "
    -1092 PRINT "1776 LEAVING THE LAKE ONTARIO AREA TO SELL FURS AND GET"
    +1092 PRINT "1776 LEAVING THE LAKE ONTARIO AREA TO SELL FURS AND GET"  
     1093 PRINT "SUPPLIES FOR THE NEXT YEAR.  YOU HAVE A CHOICE OF THREE"
     1094 PRINT "FORTS AT WHICH YOU MAY TRADE.  THE COST OF SUPPLIES"
    -1095 PRINT "AND THE AMOUNT YOU RECEIVE FOR YOUR FURS WILL DEPEND"
    -1096 PRINT "ON THE FORT THAT YOU CHOOSE."
    -1099 RETURN
    +1095 PRINT "AND THE AMOUNT YOU RECEIVE FOR YOUR FURS WILL DEPEND" 
    +1096 PRINT "ON THE FORT THAT YOU CHOOSE." 
    +1099 RETURN 
     1100 PRINT "YOU MAY TRADE YOUR FURS AT FORT 1, FORT 2,"
     1102 PRINT "OR FORT 3.  FORT 1 IS FORT HOCHELAGA (MONTREAL)"
    -1103 PRINT "AND IS UNDER THE PROTECTION OF THE FRENCH ARMY."
    -1104 PRINT "FORT 2 IS FORT STADACONA (QUEBEC) AND IS UNDER THE"
    +1103 PRINT "AND IS UNDER THE PROTECTION OF THE FRENCH ARMY."  
    +1104 PRINT "FORT 2 IS FORT STADACONA (QUEBEC) AND IS UNDER THE" 
     1105 PRINT "PROTECTION OF THE FRENCH ARMY.  HOWEVER, YOU MUST"
    -1106 PRINT "MAKE A PORTAGE AND CROSS THE LACHINE RAPIDS."
    -1108 PRINT "FORT 3 IS FORT NEW YORK AND IS UNDER DUTCH CONTROL."
    +1106 PRINT "MAKE A PORTAGE AND CROSS THE LACHINE RAPIDS." 
    +1108 PRINT "FORT 3 IS FORT NEW YORK AND IS UNDER DUTCH CONTROL."  
     1109 PRINT "YOU MUST CROSS THROUGH IROQUOIS LAND."
     1110 PRINT "ANSWER 1, 2, OR 3."
     1111 INPUT B
    -1112 IF B=1 THEN 1120
    -1113 IF B=2 THEN 1135
    -1115 IF B=3 THEN 1147
    -1116 GOTO 1110
    -1120 PRINT "YOU HAVE CHOSEN THE EASIEST ROUTE.  HOWEVER, THE FORT"
    -1121 PRINT "IS FAR FROM ANY SEAPORT.  THE VALUE"
    -1122 PRINT "YOU RECEIVE FOR YOUR FURS WILL BE LOW AND THE COST"
    +1112 IF B=1 THEN 1120 
    +1113 IF B=2 THEN 1135 
    +1115 IF B=3 THEN 1147 
    +1116 GOTO 1110 
    +1120 PRINT "YOU HAVE CHOSEN THE EASIEST ROUTE.  HOWEVER, THE FORT"  
    +1121 PRINT "IS FAR FROM ANY SEAPORT.  THE VALUE"  
    +1122 PRINT "YOU RECEIVE FOR YOUR FURS WILL BE LOW AND THE COST"   
     1123 PRINT "OF SUPPLIES HIGHER THAN AT FORTS STADACONA OR NEW YORK."
    -1125 GOSUB 1400
    +1125 GOSUB 1400 
     1129 IF B$="YES" THEN 1110
     1130 GOTO 1160
    -1135 PRINT "YOU HAVE CHOSEN A HARD ROUTE.  IT IS, IN COMPARSION,"
    -1136 PRINT "HARDER THAN THE ROUTE TO HOCHELAGA BUT EASIER THAN"
    +1135 PRINT "YOU HAVE CHOSEN A HARD ROUTE.  IT IS, IN COMPARSION," 
    +1136 PRINT "HARDER THAN THE ROUTE TO HOCHELAGA BUT EASIER THAN"   
     1137 PRINT "THE ROUTE TO NEW YORK.  YOU WILL RECEIVE AN AVERAGE VALUE"
     1138 PRINT "FOR YOUR FURS AND THE COST OF YOUR SUPPLIES WILL BE AVERAGE."
    -1141 GOSUB 1400
    +1141 GOSUB 1400 
     1144 IF B$="YES" THEN 1110
     1145 GOTO 1198
     1147 PRINT "YOU HAVE CHOSEN THE MOST DIFFICULT ROUTE.  AT"
    -1148 PRINT "FORT NEW YORK YOU WILL RECEIVE THE HIGHEST VALUE"
    +1148 PRINT "FORT NEW YORK YOU WILL RECEIVE THE HIGHEST VALUE" 
     1149 PRINT "FOR YOUR FURS.  THE COST OF YOUR SUPPLIES"
    -1150 PRINT "WILL BE LOWER THAN AT ALL THE OTHER FORTS."
    -1152 GOSUB 1400
    +1150 PRINT "WILL BE LOWER THAN AT ALL THE OTHER FORTS."   
    +1152 GOSUB 1400 
     1155 IF B$="YES" THEN 1110
     1156 GOTO 1250
     1160 LET I=I-160
    @@ -87,7 +87,7 @@
     1177 LET D1=INT((.2*RND(1)+.8)*10^2+.5)/10^2
     1180 PRINT "SUPPLIES AT FORT HOCHELAGA COST $150.00."
     1181 PRINT "YOUR TRAVEL EXPENSES TO HOCHELAGA WERE $10.00."
    -1190 GOTO 1410
    +1190 GOTO 1410 
     1198 LET I=I-140
     1201 PRINT
     1205 LET M1=INT((.3*RND(1)+.85)*10^2+.5)/10^2
    @@ -99,26 +99,26 @@
     1213 IF P<=8 THEN 1226
     1215 IF P<=10 THEN 1235
     1216 LET F(2)=0
    -1218 PRINT "YOUR BEAVER WERE TOO HEAVY TO CARRY ACROSS"
    -1219 PRINT "THE PORTAGE.  YOU HAD TO LEAVE THE PELTS, BUT FOUND"
    +1218 PRINT "YOUR BEAVER WERE TOO HEAVY TO CARRY ACROSS" 
    +1219 PRINT "THE PORTAGE.  YOU HAD TO LEAVE THE PELTS, BUT FOUND" 
     1220 PRINT "THEM STOLEN WHEN YOU RETURNED."
    -1221 GOSUB 1244
    -1222 GOTO 1414
    -1224 PRINT "YOU ARRIVED SAFELY AT FORT STADACONA."
    -1225 GOTO 1239
    -1226 GOSUB 1430
    -1230 PRINT "YOUR CANOE UPSET IN THE LACHINE RAPIDS.  YOU"
    -1231 PRINT "LOST ALL YOUR FURS."
    -1232 GOSUB 1244
    -1233 GOTO 1418
    -1235 LET F(4)=0
    +1221 GOSUB 1244 
    +1222 GOTO 1414 
    +1224 PRINT "YOU ARRIVED SAFELY AT FORT STADACONA." 
    +1225 GOTO 1239 
    +1226 GOSUB 1430 
    +1230 PRINT "YOUR CANOE UPSET IN THE LACHINE RAPIDS.  YOU"   
    +1231 PRINT "LOST ALL YOUR FURS." 
    +1232 GOSUB 1244 
    +1233 GOTO 1418 
    +1235 LET F(4)=0 
     1237 PRINT "YOUR FOX PELTS WERE NOT CURED PROPERLY."
     1238 PRINT "NO ONE WILL BUY THEM."
    -1239 GOSUB 1244
    -1240 GOTO 1410
    +1239 GOSUB 1244 
    +1240 GOTO 1410 
     1244 PRINT "SUPPLIES AT FORT STADACONA COST $125.00."
     1246 PRINT "YOUR TRAVEL EXPENSES TO STADACONA WERE $15.00."
    -1248 RETURN
    +1248 RETURN 
     1250 LET I=I-105
     1254 PRINT
     1260 LET M1=INT((.15*RND(1)+1.05)*10^2+.5)/10^2
    @@ -129,30 +129,30 @@
     1273 IF P<=8 THEN 1295
     1274 IF P<=10 THEN 1306
     1281 PRINT "YOU WERE ATTACKED BY A PARTY OF IROQUOIS."
    -1282 PRINT "ALL PEOPLE IN YOUR TRADING GROUP WERE"
    -1283 PRINT "KILLED.  THIS ENDS THE GAME."
    -1284 STOP
    +1282 PRINT "ALL PEOPLE IN YOUR TRADING GROUP WERE"    
    +1283 PRINT "KILLED.  THIS ENDS THE GAME." 
    +1284 STOP 
     1291 PRINT "YOU WERE LUCKY.  YOU ARRIVED SAFELY"
     1292 PRINT "AT FORT NEW YORK."
    -1293 GOTO 1311
    -1295 GOSUB 1430
    +1293 GOTO 1311 
    +1295 GOSUB 1430 
     1300 PRINT "YOU NARROWLY ESCAPED AN IROQUOIS RAIDING PARTY."
     1301 PRINT "HOWEVER, YOU HAD TO LEAVE ALL YOUR FURS BEHIND."
    -1303 GOSUB 1320
    -1304 GOTO 1418
    +1303 GOSUB 1320 
    +1304 GOTO 1418 
     1306 LET B1=B1/2
     1307 LET M1=M1/2
     1308 PRINT "YOUR MINK AND BEAVER WERE DAMAGED ON YOUR TRIP."
     1309 PRINT "YOU RECEIVE ONLY HALF THE CURRENT PRICE FOR THESE FURS."
     1311 GOSUB 1320
    -1312 GOTO 1410
    -1320 PRINT "SUPPLIES AT NEW YORK COST $80.00."
    +1312 GOTO 1410 
    +1320 PRINT "SUPPLIES AT NEW YORK COST $80.00." 
     1321 PRINT "YOUR TRAVEL EXPENSES TO NEW YORK WERE $25.00."
    -1322 RETURN
    +1322 RETURN 
     1400 PRINT "DO YOU WANT TO TRADE AT ANOTHER FORT?"
     1402 PRINT "ANSWER YES OR NO",
     1403 INPUT B$
    -1404 RETURN
    +1404 RETURN 
     1410 PRINT
     1412 PRINT "YOUR BEAVER SOLD FOR $";B1*F(2);
     1414 PRINT "YOUR FOX SOLD FOR $";D1*F(4)
    @@ -162,9 +162,9 @@
     1420 PRINT
     1422 PRINT "YOU NOW HAVE $";I;" INCLUDING YOUR PREVIOUS SAVINGS"
     1425 GOTO 508
    -1430 FOR J=1 TO 4
    -1432 LET F(J)=0
    -1434 NEXT J
    -1436 RETURN
    +1430 FOR J=1 TO 4 
    +1432 LET F(J)=0 
    +1434 NEXT J 
    +1436 RETURN 
     2000 DATA "MINK","BEAVER","ERMINE","FOX"
     2046 END
    diff --git a/38_Fur_Trader/javascript/furtrader.html b/38_Fur_Trader/javascript/furtrader.html
    index 9089b9a85..c7695a092 100644
    --- a/38_Fur_Trader/javascript/furtrader.html
    +++ b/38_Fur_Trader/javascript/furtrader.html
    @@ -1,10 +1,9 @@
     
     
     FUR TRADER
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/38_Fur_Trader/javascript/furtrader.js b/38_Fur_Trader/javascript/furtrader.js
    index 206facd4c..c27ab0494 100644
    --- a/38_Fur_Trader/javascript/furtrader.js
    +++ b/38_Fur_Trader/javascript/furtrader.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    @@ -178,7 +178,7 @@ async function main()
                 }
                 print("SUPPLIES AT FORT STADACONA COST $125.00.\n");
                 print("YOUR TRAVEL EXPENSES TO STADACONA WERE $15.00.\n");
    -
    +            
                 d1 = Math.floor((0.2 * Math.random() + 0.8) * Math.pow(10, 2) + 0.5) / Math.pow(10, 2);
             } else if (b == 3) {
                 i -= 105;
    diff --git a/38_Fur_Trader/kotlin/README.md b/38_Fur_Trader/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/38_Fur_Trader/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/38_Fur_Trader/lua/README.md b/38_Fur_Trader/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/38_Fur_Trader/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/38_Fur_Trader/pascal/README.md b/38_Fur_Trader/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/38_Fur_Trader/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/38_Fur_Trader/perl/README.md b/38_Fur_Trader/perl/README.md
    index c7001be76..e69c8b819 100644
    --- a/38_Fur_Trader/perl/README.md
    +++ b/38_Fur_Trader/perl/README.md
    @@ -1,5 +1,3 @@
     Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
     
     Conversion to [Perl](https://www.perl.org/)
    -
    -You can answer yes/no questions in lower case if desired.
    diff --git a/38_Fur_Trader/perl/furtrader.pl b/38_Fur_Trader/perl/furtrader.pl
    deleted file mode 100755
    index f1e6b01ad..000000000
    --- a/38_Fur_Trader/perl/furtrader.pl
    +++ /dev/null
    @@ -1,265 +0,0 @@
    -#!/usr/bin/perl
    -
    -# Fur Trader program in Perl
    -# Translated by Kevin Brannen (kbrannen)
    -
    -use strict;
    -use warnings;
    -
    -# globals
    -my @Pelts = (qw(0 MINK BEAVER ERMINE FOX ));
    -my $Num_pelts = 4;
    -my @Quantity; # how many of each fur
    -my $Money;
    -my $Max_pelts = 190;
    -my $Ermine_price;  # like we have @Pelts and @Quantity we could have @Prices
    -my $Beaver_price;  # then have 4 constants as index into the arrays to avoid
    -my $Fox_price;     # the magic numbers 1-4, or better have a array of objects (really a hash)
    -my $Mink_price;    # with the 3 keys (name, number, price), but well keep it
    -                   # with 4 vars like the basic program did
    -
    -print "\n";
    -print " " x 31, "FUR TRADER\n";
    -print " " x 15, "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n";
    -
    -init();
    -while (1)
    -{
    -    my $ans = get_yesno();
    -    last if ($ans ne "YES");
    -
    -    $Ermine_price = new_price(.15, 0.95);
    -    $Beaver_price = new_price(.25, 1.00);
    -
    -    print "\nYOU HAVE \$$Money SAVINGS.\n";
    -    print "AND $Max_pelts FURS TO BEGIN THE EXPEDITION.\n";
    -    print "\nYOUR $Max_pelts FURS ARE DISTRIBUTED AMONG THE FOLLOWING\n";
    -    print "KINDS OF PELTS: MINK, BEAVER, ERMINE AND FOX.\n";
    -    reset_furs();
    -
    -    my $total = 0;
    -    for my $j ( 1 .. $Num_pelts)
    -    {
    -        print "\nHOW MANY $Pelts[$j] PELTS DO YOU HAVE? ";
    -        chomp(my $ans = <>);
    -        $Quantity[$j] = int($ans);
    -        $total += $Quantity[$j];
    -    }
    -    if ($total > $Max_pelts)
    -    {
    -        print "\nYOU MAY NOT HAVE THAT MANY FURS.\n";
    -        print "DO NOT TRY TO CHEAT.  I CAN ADD.\n";
    -        print "YOU MUST START AGAIN.\n";
    -        init();
    -        next;
    -    }
    -
    -    print "\nYOU MAY TRADE YOUR FURS AT FORT 1, FORT 2,\n";
    -    print "OR FORT 3.  FORT 1 IS FORT HOCHELAGA (MONTREAL)\n";
    -    print "AND IS UNDER THE PROTECTION OF THE FRENCH ARMY.\n";
    -    print "FORT 2 IS FORT STADACONA (QUEBEC) AND IS UNDER THE\n";
    -    print "PROTECTION OF THE FRENCH ARMY.  HOWEVER, YOU MUST\n";
    -    print "MAKE A PORTAGE AND CROSS THE LACHINE RAPIDS.\n";
    -    print "FORT 3 IS FORT NEW YORK AND IS UNDER DUTCH CONTROL.\n";
    -    print "YOU MUST CROSS THROUGH IROQUOIS LAND.\n";
    -    my $done = 0;
    -    while (!$done)
    -    {
    -        $ans = 0;
    -        while ($ans < 1 || $ans > 3)
    -        {
    -            no warnings; # in case user enters alpha chars, then int() will return 0 with no warnings
    -            print "ANSWER 1, 2, OR 3: ";
    -            $ans = int(<>);
    -        }
    -        # returns 0 if they want to go somewhere else;
    -        # or returns the old basic line number to show what to do
    -        if ($ans == 1)    { $done = fort1(); }
    -        elsif ($ans == 2) { $done = fort2(); }
    -        elsif ($ans == 3) { $done = fort3(); }
    -    }
    -
    -    if ($done == 1410)
    -    {
    -        print "YOUR BEAVER SOLD FOR \$", $Beaver_price * $Quantity[2], "\t";
    -    }
    -
    -    if ($done <= 1414)
    -    {
    -        print "YOUR FOX SOLD FOR \$", $Fox_price * $Quantity[4], "\n";
    -        print "YOUR ERMINE SOLD FOR \$", $Ermine_price * $Quantity[3], "\t";
    -        print "YOUR MINK SOLD FOR \$", $Mink_price * $Quantity[1], "\n";
    -    }
    -
    -    # 1418 is always done
    -    $Money += $Mink_price * $Quantity[1] + $Beaver_price * $Quantity[2] + $Ermine_price * $Quantity[3] + $Fox_price * $Quantity[4];
    -    print "\nYOU NOW HAVE \$$Money INCLUDING YOUR PREVIOUS SAVINGS\n";
    -    print "\nDO YOU WANT TO TRADE FURS NEXT YEAR? ";
    -}
    -exit(0);
    -
    -###############################################################
    -
    -sub init
    -{
    -    print "YOU ARE THE LEADER OF A FRENCH FUR TRADING EXPEDITION IN\n";
    -    print "1776 LEAVING THE LAKE ONTARIO AREA TO SELL FURS AND GET\n";
    -    print "SUPPLIES FOR THE NEXT YEAR.  YOU HAVE A CHOICE OF THREE\n";
    -    print "FORTS AT WHICH YOU MAY TRADE.  THE COST OF SUPPLIES\n";
    -    print "AND THE AMOUNT YOU RECEIVE FOR YOUR FURS WILL DEPEND\n";
    -    print "ON THE FORT THAT YOU CHOOSE.\n";
    -
    -    $Money = 600;
    -    print "DO YOU WISH TO TRADE FURS?\n";
    -}
    -
    -sub new_price
    -{
    -    my ($base, $factor) = @_;
    -    return int(($base * rand(1) + $factor) * 100 + .5) / 100;
    -}
    -
    -sub supplies_fs
    -{
    -    print "SUPPLIES AT FORT STADACONA COST \$125.00.\n";
    -    print "YOUR TRAVEL EXPENSES TO STADACONA WERE \$15.00.\n";
    -}
    -
    -sub supplies_ny
    -{
    -    print "SUPPLIES AT NEW YORK COST \$80.00.\n";
    -    print "YOUR TRAVEL EXPENSES TO NEW YORK WERE \$25.00.\n";
    -}
    -
    -sub reset_furs
    -{
    -    for my $j (1 .. $Num_pelts) { $Quantity[$j] = 0; }
    -}
    -
    -sub get_yesno
    -{
    -    my $ans;
    -    print "ANSWER YES OR NO: ";
    -    chomp($ans = uc(<>));
    -    return $ans;
    -}
    -
    -sub trade_elsewhere
    -{
    -    print "DO YOU WANT TO TRADE AT ANOTHER FORT? ";
    -    my $ans = get_yesno();
    -    return $ans;
    -}
    -
    -sub fort1
    -{
    -    print "\nYOU HAVE CHOSEN THE EASIEST ROUTE.  HOWEVER, THE FORT\n";
    -    print "IS FAR FROM ANY SEAPORT.  THE VALUE\n";
    -    print "YOU RECEIVE FOR YOUR FURS WILL BE LOW AND THE COST\n";
    -    print "OF SUPPLIES HIGHER THAN AT FORTS STADACONA OR NEW YORK.\n";
    -    my $ans = trade_elsewhere();
    -    if ($ans eq "YES") { return 0; }
    -    
    -    $Money -= 160;
    -    $Mink_price = new_price(.2, .7 );
    -    $Ermine_price = new_price(.2, .65);
    -    $Beaver_price = new_price(.2, .75);
    -    $Fox_price = new_price(.2, .8 );
    -    print "\nSUPPLIES AT FORT HOCHELAGA COST \$150.00.\n";
    -    print "YOUR TRAVEL EXPENSES TO HOCHELAGA WERE \$10.00.\n";
    -    return 1410;
    -}
    -
    -sub fort2
    -{
    -    print "\nYOU HAVE CHOSEN A HARD ROUTE.  IT IS, IN COMPARSION,\n";
    -    print "HARDER THAN THE ROUTE TO HOCHELAGA BUT EASIER THAN\n";
    -    print "THE ROUTE TO NEW YORK.  YOU WILL RECEIVE AN AVERAGE VALUE\n";
    -    print "FOR YOUR FURS AND THE COST OF YOUR SUPPLIES WILL BE AVERAGE.\n";
    -    my $ans = trade_elsewhere();
    -    if ($ans eq "YES") { return 0; }
    -
    -    $Money -= 140;
    -    print "\n";
    -    $Mink_price = new_price(.3,  .85);
    -    $Ermine_price = new_price(.15, .8);
    -    $Beaver_price = new_price(.2,  .9);
    -    my $P = int(10 * rand(1)) + 1;
    -    if ($P <= 2)
    -    {
    -        $Quantity[2] = 0;
    -        print "YOUR BEAVER WERE TOO HEAVY TO CARRY ACROSS\n";
    -        print "THE PORTAGE.  YOU HAD TO LEAVE THE PELTS, BUT FOUND\n";
    -        print "THEM STOLEN WHEN YOU RETURNED.\n";
    -        supplies_fs();
    -        return 1414;
    -    }
    -    elsif ($P <= 6)
    -    {
    -        print "YOU ARRIVED SAFELY AT FORT STADACONA.\n";
    -        supplies_fs();
    -    }
    -    elsif ($P <= 8)
    -    {
    -        reset_furs();
    -        print "YOUR CANOE UPSET IN THE LACHINE RAPIDS.  YOU\n";
    -        print "LOST ALL YOUR FURS.\n";
    -        supplies_fs();
    -        return 1418;
    -    }
    -    elsif ($P <= 10)
    -    {
    -        $Quantity[4] = 0;
    -        print "YOUR FOX PELTS WERE NOT CURED PROPERLY.\n";
    -        print "NO ONE WILL BUY THEM.\n";
    -        supplies_fs();
    -    }
    -    return 1410;
    -}
    -
    -sub fort3
    -{
    -    print "\nYOU HAVE CHOSEN THE MOST DIFFICULT ROUTE.  AT\n";
    -    print "FORT NEW YORK YOU WILL RECEIVE THE HIGHEST VALUE\n";
    -    print "FOR YOUR FURS.  THE COST OF YOUR SUPPLIES\n";
    -    print "WILL BE LOWER THAN AT ALL THE OTHER FORTS.\n";
    -    my $ans = trade_elsewhere();
    -    if ($ans eq "YES") { return 0; }
    -
    -    $Money -= 105;
    -    print "\n";
    -    $Mink_price = new_price(.15, 1.05);
    -    $Fox_price = new_price(.25, 1.1);
    -    $Fox_price = new_price(.25, 1.1);
    -    my $P = int(10 * rand(1)) + 1;
    -    if ($P <= 2)
    -    {
    -        print "YOU WERE ATTACKED BY A PARTY OF IROQUOIS.\n";
    -        print "ALL PEOPLE IN YOUR TRADING GROUP WERE\n";
    -        print "KILLED.  THIS ENDS THE GAME.\n";
    -        exit(0);
    -    }
    -    elsif ($P <= 6)
    -    {
    -        print "YOU WERE LUCKY.  YOU ARRIVED SAFELY\n";
    -        print "AT FORT NEW YORK.\n";
    -        supplies_ny();
    -    }
    -    elsif ($P <= 8)
    -    {
    -        reset_furs();
    -        print "YOU NARROWLY ESCAPED AN IROQUOIS RAIDING PARTY.\n";
    -        print "HOWEVER, YOU HAD TO LEAVE ALL YOUR FURS BEHIND.\n";
    -        supplies_ny();
    -        return 1418;
    -    }
    -    elsif ($P <= 10)
    -    {
    -        $Beaver_price /= 2;
    -        $Mink_price /= 2;
    -        print "YOUR MINK AND BEAVER WERE DAMAGED ON YOUR TRIP.\n";
    -        print "YOU RECEIVE ONLY HALF THE CURRENT PRICE FOR THESE FURS.\n";
    -        supplies_ny();
    -    }
    -    return 1410;
    -}
    diff --git a/38_Fur_Trader/python/README.md b/38_Fur_Trader/python/README.md
    index cda8ed790..d90f8449d 100644
    --- a/38_Fur_Trader/python/README.md
    +++ b/38_Fur_Trader/python/README.md
    @@ -5,20 +5,21 @@ Conversion to [Python](https://www.python.org/about/)
     ##### Translator Notes:
     I tried to preserve as much of the original layout and flow of the code
     as possible.  However I did use quasi enumerated types for the Fort numbers
    -and Fur types.  I think this was certainly a change for the better, and
    +and Fur types.  I think this was certainly a change for the better, and 
     makes the code much easier to read.
     
     I program in many different languages on a daily basis.  Most languages
    -require brackets around expressions, so I just cannot bring myself to
    -write an expression without brackets.  IMHO it makes the code easier to study,
    +require brackets around expressions, so I just cannot bring myself to 
    +write an expression without brackets.  IMHO it makes the code easier to study, 
     but it does contravene the Python PEP-8 Style guide.
     
     Interestingly the code seems to have a bug around the prices of Fox Furs.
     The commodity-rate for these is stored in the variable `D1`, however some
    -paths through the code do not set this price.  So there was a chance of
    -using this uninitialised, or whatever the previous loop set.  I don't
    +paths through the code do not set this price.  So there was a chance of 
    +using this uninitialised, or whatever the previous loop set.  I don't 
     think this was the original authors intent.  So I preserved the original flow
    -of the code (using the previous `D1` value), but also catching the
    +of the code (using the previous `D1` value), but also catching the 
     uninitialised path, and assigning a "best guess" value.
     
     krt@krt.com.au 2020-10-10
    +
    diff --git a/38_Fur_Trader/python/furtrader.py b/38_Fur_Trader/python/furtrader.py
    index 0755c4100..b26b2f1ae 100755
    --- a/38_Fur_Trader/python/furtrader.py
    +++ b/38_Fur_Trader/python/furtrader.py
    @@ -1,309 +1,297 @@
    -#!/usr/bin/env python3
    +#! /usr/bin/env python3
     
    -import random  # for generating random numbers
    -import sys  # for system function, like exit()
    -from typing import List
    +import sys             # for system function, like exit()
    +import random          # for generating random numbers
     
    -# global variables for storing player's status
    -player_funds: float = 0  # no money
    -player_furs = [0, 0, 0, 0]  # no furs
     
    +### global variables for storing player's status
    +player_funds = 0               # no money
    +player_furs  = [ 0, 0, 0, 0 ]  # no furs
     
    -# Constants
    -FUR_MINK = 0
    +
    +### Constants
    +FUR_MINK   = 0
     FUR_BEAVER = 1
     FUR_ERMINE = 2
    -FUR_FOX = 3
    -MAX_FURS = 190
    -FUR_NAMES = ["MINK", "BEAVER", "ERMINE", "FOX"]
    +FUR_FOX    = 3
    +MAX_FURS   = 190
    +FUR_NAMES  = [ "MINK", "BEAVER", "ERMINE", "FOX" ]
     
     FORT_MONTREAL = 1
    -FORT_QUEBEC = 2
    -FORT_NEWYORK = 3
    -FORT_NAMES = ["HOCHELAGA (MONTREAL)", "STADACONA (QUEBEC)", "NEW YORK"]
    -
    -
    -def show_introduction() -> None:
    -    """Show the player the introductory message"""
    -    print("YOU ARE THE LEADER OF A FRENCH FUR TRADING EXPEDITION IN ")
    -    print("1776 LEAVING THE LAKE ONTARIO AREA TO SELL FURS AND GET")
    -    print("SUPPLIES FOR THE NEXT YEAR.  YOU HAVE A CHOICE OF THREE")
    -    print("FORTS AT WHICH YOU MAY TRADE.  THE COST OF SUPPLIES")
    -    print("AND THE AMOUNT YOU RECEIVE FOR YOUR FURS WILL DEPEND")
    -    print("ON THE FORT THAT YOU CHOOSE.")
    -    print()
    -
    -
    -def get_fort_choice() -> int:
    -    """Show the player the choices of Fort, get their input, if the
    -    input is a valid choice (1,2,3) return it, otherwise keep
    -    prompting the user."""
    +FORT_QUEBEC   = 2
    +FORT_NEWYORK  = 3
    +FORT_NAMES  = [ "HOCHELAGA (MONTREAL)", "STADACONA (QUEBEC)", "NEW YORK" ]
    +
    +
    +
    +def printAtColumn( column:int, words:str ):
    +    """ Print the words at the specified column """
    +    spaces = ' ' * column    # make a fat string of spaces
    +    print( spaces + words )
    +
    +
    +def showIntroduction():
    +    """ Show the player the introductory message """
    +    print( "YOU ARE THE LEADER OF A FRENCH FUR TRADING EXPEDITION IN " )
    +    print( "1776 LEAVING THE LAKE ONTARIO AREA TO SELL FURS AND GET" )
    +    print( "SUPPLIES FOR THE NEXT YEAR.  YOU HAVE A CHOICE OF THREE" )
    +    print( "FORTS AT WHICH YOU MAY TRADE.  THE COST OF SUPPLIES" )
    +    print( "AND THE AMOUNT YOU RECEIVE FOR YOUR FURS WILL DEPEND" )
    +    print( "ON THE FORT THAT YOU CHOOSE." )
    +    print( "" )
    +
    +
    +def getFortChoice():
    +    """ Show the player the choices of Fort, get their input, if the
    +        input is a valid choice (1,2,3) return it, otherwise keep
    +        prompting the user. """
         result = 0
    -    while result == 0:
    -        print()
    -        print("YOU MAY TRADE YOUR FURS AT FORT 1, FORT 2,")
    -        print("OR FORT 3.  FORT 1 IS FORT HOCHELAGA (MONTREAL)")
    -        print("AND IS UNDER THE PROTECTION OF THE FRENCH ARMY.")
    -        print("FORT 2 IS FORT STADACONA (QUEBEC) AND IS UNDER THE")
    -        print("PROTECTION OF THE FRENCH ARMY.  HOWEVER, YOU MUST")
    -        print("MAKE A PORTAGE AND CROSS THE LACHINE RAPIDS.")
    -        print("FORT 3 IS FORT NEW YORK AND IS UNDER DUTCH CONTROL.")
    -        print("YOU MUST CROSS THROUGH IROQUOIS LAND.")
    -        print("ANSWER 1, 2, OR 3.")
    -
    -        player_choice = input(">> ")  # get input from the player
    +    while ( result == 0 ):
    +        print( "" )
    +        print( "YOU MAY TRADE YOUR FURS AT FORT 1, FORT 2," )
    +        print( "OR FORT 3.  FORT 1 IS FORT HOCHELAGA (MONTREAL)" )
    +        print( "AND IS UNDER THE PROTECTION OF THE FRENCH ARMY." )
    +        print( "FORT 2 IS FORT STADACONA (QUEBEC) AND IS UNDER THE" )
    +        print( "PROTECTION OF THE FRENCH ARMY.  HOWEVER, YOU MUST" )
    +        print( "MAKE A PORTAGE AND CROSS THE LACHINE RAPIDS." )
    +        print( "FORT 3 IS FORT NEW YORK AND IS UNDER DUTCH CONTROL." )
    +        print( "YOU MUST CROSS THROUGH IROQUOIS LAND." )
    +        print( "ANSWER 1, 2, OR 3." )
    +
    +        player_choice = input( ">> " )   # get input from the player
     
             # try to convert the player's string input into an integer
             try:
    -            result = int(player_choice)  # string to integer
    -        except Exception:
    +            result = int( player_choice )   # string to integer
    +        except:
                 # Whatever the player typed, it could not be interpreted as a number
                 pass
     
         return result
     
     
    -def show_fort_comment(which_fort) -> None:
    -    """Print the description for the fort"""
    -    print()
    -    if which_fort == FORT_MONTREAL:
    -        print("YOU HAVE CHOSEN THE EASIEST ROUTE.  HOWEVER, THE FORT")
    -        print("IS FAR FROM ANY SEAPORT.  THE VALUE")
    -        print("YOU RECEIVE FOR YOUR FURS WILL BE LOW AND THE COST")
    -        print("OF SUPPLIES HIGHER THAN AT FORTS STADACONA OR NEW YORK.")
    -    elif which_fort == FORT_QUEBEC:
    -        print("YOU HAVE CHOSEN A HARD ROUTE.  IT IS, IN COMPARSION,")
    -        print("HARDER THAN THE ROUTE TO HOCHELAGA BUT EASIER THAN")
    -        print("THE ROUTE TO NEW YORK.  YOU WILL RECEIVE AN AVERAGE VALUE")
    -        print("FOR YOUR FURS AND THE COST OF YOUR SUPPLIES WILL BE AVERAGE.")
    -    elif which_fort == FORT_NEWYORK:
    -        print("YOU HAVE CHOSEN THE MOST DIFFICULT ROUTE.  AT")
    -        print("FORT NEW YORK YOU WILL RECEIVE THE HIGHEST VALUE")
    -        print("FOR YOUR FURS.  THE COST OF YOUR SUPPLIES")
    -        print("WILL BE LOWER THAN AT ALL THE OTHER FORTS.")
    +def showFortComment( which_fort ):
    +    """ Print the description for the fort """
    +    print( "" )
    +    if ( which_fort == FORT_MONTREAL ):
    +        print( "YOU HAVE CHOSEN THE EASIEST ROUTE.  HOWEVER, THE FORT" )
    +        print( "IS FAR FROM ANY SEAPORT.  THE VALUE" )
    +        print( "YOU RECEIVE FOR YOUR FURS WILL BE LOW AND THE COST" )
    +        print( "OF SUPPLIES HIGHER THAN AT FORTS STADACONA OR NEW YORK." )
    +    elif ( which_fort == FORT_QUEBEC ):
    +        print( "YOU HAVE CHOSEN A HARD ROUTE.  IT IS, IN COMPARSION," )
    +        print( "HARDER THAN THE ROUTE TO HOCHELAGA BUT EASIER THAN" )
    +        print( "THE ROUTE TO NEW YORK.  YOU WILL RECEIVE AN AVERAGE VALUE" )
    +        print( "FOR YOUR FURS AND THE COST OF YOUR SUPPLIES WILL BE AVERAGE." )
    +    elif ( which_fort == FORT_NEWYORK ):
    +        print( "YOU HAVE CHOSEN THE MOST DIFFICULT ROUTE.  AT" )
    +        print( "FORT NEW YORK YOU WILL RECEIVE THE HIGHEST VALUE" )
    +        print( "FOR YOUR FURS.  THE COST OF YOUR SUPPLIES" )
    +        print( "WILL BE LOWER THAN AT ALL THE OTHER FORTS." )
         else:
    -        print(f"Internal error #1, fort {str(which_fort)} does not exist")
    -        sys.exit(1)  # you have a bug
    -    print()
    -
    -
    -def get_yes_or_no() -> str:
    -    """Prompt the player to enter 'YES' or 'NO'. Keep prompting until
    -    valid input is entered.  Accept various spellings by only
    -    checking the first letter of input.
    -    Return a single letter 'Y' or 'N'"""
    -    result = ""
    -    while result not in ("Y", "N"):
    -        print("ANSWER YES OR NO")
    -        player_choice = input(">> ")
    +        print( "Internal error #1, fort " + str( which_fort ) + " does not exist" )
    +        sys.exit( 1 )  # you have a bug
    +    print( "" )
    +        
    +
    +def getYesOrNo():
    +    """ Prompt the player to enter 'YES' or 'NO'. Keep prompting until
    +        valid input is entered.  Accept various spellings by only 
    +        checking the first letter of input.
    +        Return a single letter 'Y' or 'N' """
    +    result = 0
    +    while ( result not in ( 'Y', 'N' ) ):
    +        print( "ANSWER YES OR NO" )
    +        player_choice = input( ">> " )
             player_choice = player_choice.strip().upper()  # trim spaces, make upper-case
    -        if player_choice.startswith("Y"):
    -            result = "Y"
    -        elif player_choice.startswith("N"):
    -            result = "N"
    +        if ( player_choice.startswith( 'Y' ) ):
    +            result = 'Y'
    +        elif ( player_choice.startswith( 'N' ) ):
    +            result = 'N'
         return result
     
    +    
    +def getFursPurchase():
    +    """ Prompt the player for how many of each fur type they want.
    +        Accept numeric inputs, re-prompting on incorrect input values """
    +    results = []
     
    -def get_furs_purchase() -> List[int]:
    -    """Prompt the player for how many of each fur type they want.
    -    Accept numeric inputs, re-prompting on incorrect input values"""
    -    results: List[int] = []
    -
    -    print(f"YOUR {str(MAX_FURS)} FURS ARE DISTRIBUTED AMONG THE FOLLOWING")
    -    print("KINDS OF PELTS: MINK, BEAVER, ERMINE AND FOX.")
    -    print()
    +    print( "YOUR " + str( MAX_FURS ) + " FURS ARE DISTRIBUTED AMONG THE FOLLOWING" )
    +    print( "KINDS OF PELTS: MINK, BEAVER, ERMINE AND FOX." )
    +    print( "" )
     
    -    while len(results) < len(FUR_NAMES):
    -        print(f"HOW MANY {FUR_NAMES[len(results)]} DO YOU HAVE")
    -        count_str = input(">> ")
    +    for i in ( range( len( FUR_NAMES ) ) ):
    +        print( "HOW MANY " + FUR_NAMES[i] + " DO YOU HAVE" )
    +        count_str = input( ">> " )
             try:
    -            count = int(count_str)
    -            results.append(count)
    -        except Exception:  # invalid input, prompt again by re-looping
    -            pass
    +            count = int( count_str )
    +            results.append( count )
    +        except:
    +            # invalid input, prompt again by re-looping
    +            i -= 1
         return results
    +        
    +
    +
    +###
    +### MAIN
    +###
     
    +if ( __name__ == '__main__' ):
     
    -def main() -> None:
    -    print(" " * 31 + "FUR TRADER")
    -    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
    -    print(" " * 15 + "(Ported to Python Oct 2012 krt@krt.com.au)")
    -    print("\n\n\n")
    +    printAtColumn( 31, "FUR TRADER" )
    +    printAtColumn( 15, "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY" )
    +    printAtColumn( 15, "(Ported to Python Oct 2012 krt@krt.com.au)" )
    +    print( "\n\n\n" )
     
    +    game_state = 'starting'
         fox_price = None  # sometimes this takes the "last" price (probably this was a bug)
     
    -    game_state = "starting"
    -    while True:
    -
    -        if game_state == "starting":
    -            show_introduction()
    -
    -            player_funds: float = 600  # Initial player start money
    -            player_furs = [0, 0, 0, 0]  # Player fur inventory
    -
    -            print("DO YOU WISH TO TRADE FURS?")
    -            should_trade = get_yes_or_no()
    -            if should_trade == "N":
    -                sys.exit(0)  # STOP
    -            game_state = "trading"
    -
    -        elif game_state == "trading":
    -            print()
    -            print("YOU HAVE $ %1.2f IN SAVINGS" % (player_funds))
    -            print(f"AND {str(MAX_FURS)} FURS TO BEGIN THE EXPEDITION")
    -            player_furs = get_furs_purchase()
    -
    -            if sum(player_furs) > MAX_FURS:
    -                print()
    -                print("YOU MAY NOT HAVE THAT MANY FURS.")
    -                print("DO NOT TRY TO CHEAT.  I CAN ADD.")
    -                print("YOU MUST START AGAIN.")
    -                game_state = "starting"  # T/N: Wow, harsh.
    +    while ( True ):
    +
    +        if ( game_state == 'starting' ):
    +            showIntroduction()
    +
    +            player_funds = 600             # Initial player start money
    +            player_furs  = [ 0, 0, 0, 0 ]  # Player fur inventory
    +
    +            print( "DO YOU WISH TO TRADE FURS?" )
    +            should_trade = getYesOrNo()
    +            if ( should_trade == 'N' ):
    +                sys.exit( 0 )             # STOP
    +            game_state = 'trading'
    +
    +        elif ( game_state == 'trading' ):
    +            print( "" )
    +            print( "YOU HAVE $ %1.2f IN SAVINGS" % ( player_funds ) )
    +            print( "AND " + str( MAX_FURS ) + " FURS TO BEGIN THE EXPEDITION" )
    +            player_furs = getFursPurchase()
    +
    +            if ( sum( player_furs ) > MAX_FURS ):
    +                print( "" )
    +                print( "YOU MAY NOT HAVE THAT MANY FURS." )
    +                print( "DO NOT TRY TO CHEAT.  I CAN ADD." )
    +                print( "YOU MUST START AGAIN." )
    +                game_state = 'starting'   # T/N: Wow, harsh.
                 else:
    -                game_state = "choosing fort"
    -
    -        elif game_state == "choosing fort":
    -            which_fort = get_fort_choice()
    -            show_fort_comment(which_fort)
    -            print("DO YOU WANT TO TRADE AT ANOTHER FORT?")
    -            change_fort = get_yes_or_no()
    -            if change_fort == "N":
    -                game_state = "travelling"
    -
    -        elif game_state == "travelling":
    -            print()
    -            if which_fort == FORT_MONTREAL:
    -                mink_price = (
    -                    int((0.2 * random.random() + 0.70) * 100 + 0.5) / 100
    -                )  # INT((.2*RND(1)+.7)*10^2+.5)/10^2
    -                ermine_price = (
    -                    int((0.2 * random.random() + 0.65) * 100 + 0.5) / 100
    -                )  # INT((.2*RND(1)+.65)*10^2+.5)/10^2
    -                beaver_price = (
    -                    int((0.2 * random.random() + 0.75) * 100 + 0.5) / 100
    -                )  # INT((.2*RND(1)+.75)*10^2+.5)/10^2
    -                fox_price = (
    -                    int((0.2 * random.random() + 0.80) * 100 + 0.5) / 100
    -                )  # INT((.2*RND(1)+.8)*10^2+.5)/10^2
    -
    -                print("SUPPLIES AT FORT HOCHELAGA COST $150.00.")
    -                print("YOUR TRAVEL EXPENSES TO HOCHELAGA WERE $10.00.")
    +                game_state = 'choosing fort'
    +
    +        elif ( game_state == 'choosing fort' ):
    +            which_fort = getFortChoice()
    +            showFortComment( which_fort )
    +            print( "DO YOU WANT TO TRADE AT ANOTHER FORT?" )
    +            change_fort = getYesOrNo()
    +            if ( change_fort == 'N' ):
    +                game_state = 'travelling'
    +
    +        elif ( game_state == 'travelling' ):
    +            print( "" )
    +            if ( which_fort == FORT_MONTREAL ):
    +                mink_price   = int( ( 0.2 * random.random() + 0.70 ) * 100 + 0.5 ) / 100 #INT((.2*RND(1)+.7)*10^2+.5)/10^2
    +                ermine_price = int( ( 0.2 * random.random() + 0.65 ) * 100 + 0.5 ) / 100 #INT((.2*RND(1)+.65)*10^2+.5)/10^2
    +                beaver_price = int( ( 0.2 * random.random() + 0.75 ) * 100 + 0.5 ) / 100 #INT((.2*RND(1)+.75)*10^2+.5)/10^2
    +                fox_price    = int( ( 0.2 * random.random() + 0.80 ) * 100 + 0.5 ) / 100 #INT((.2*RND(1)+.8)*10^2+.5)/10^2
    +
    +                print( "SUPPLIES AT FORT HOCHELAGA COST $150.00." )
    +                print( "YOUR TRAVEL EXPENSES TO HOCHELAGA WERE $10.00." )
                     player_funds -= 160
     
    -            elif which_fort == FORT_QUEBEC:
    -                mink_price = (
    -                    int((0.30 * random.random() + 0.85) * 100 + 0.5) / 100
    -                )  # INT((.3*RND(1)+.85)*10^2+.5)/10^2
    -                ermine_price = (
    -                    int((0.15 * random.random() + 0.80) * 100 + 0.5) / 100
    -                )  # INT((.15*RND(1)+.8)*10^2+.5)/10^2
    -                beaver_price = (
    -                    int((0.20 * random.random() + 0.90) * 100 + 0.5) / 100
    -                )  # INT((.2*RND(1)+.9)*10^2+.5)/10^2
    -                fox_price = (
    -                    int((0.25 * random.random() + 1.10) * 100 + 0.5) / 100
    -                )  # INT((.25*RND(1)+1.1)*10^2+.5)/10^2
    -                event_picker = int(10 * random.random()) + 1
    -
    -                if event_picker <= 2:
    -                    print("YOUR BEAVER WERE TOO HEAVY TO CARRY ACROSS")
    -                    print("THE PORTAGE.  YOU HAD TO LEAVE THE PELTS, BUT FOUND")
    -                    print("THEM STOLEN WHEN YOU RETURNED.")
    -                    player_furs[FUR_BEAVER] = 0
    -                elif event_picker <= 6:
    -                    print("YOU ARRIVED SAFELY AT FORT STADACONA.")
    -                elif event_picker <= 8:
    -                    print("YOUR CANOE UPSET IN THE LACHINE RAPIDS.  YOU")
    -                    print("LOST ALL YOUR FURS.")
    -                    player_furs = [0, 0, 0, 0]
    -                elif event_picker <= 10:
    -                    print("YOUR FOX PELTS WERE NOT CURED PROPERLY.")
    -                    print("NO ONE WILL BUY THEM.")
    -                    player_furs[FUR_FOX] = 0
    +            elif ( which_fort == FORT_QUEBEC ):
    +                mink_price   = int( ( 0.30 * random.random() + 0.85 ) * 100 + 0.5 ) / 100 #INT((.3*RND(1)+.85)*10^2+.5)/10^2
    +                ermine_price = int( ( 0.15 * random.random() + 0.80 ) * 100 + 0.5 ) / 100 #INT((.15*RND(1)+.8)*10^2+.5)/10^2
    +                beaver_price = int( ( 0.20 * random.random() + 0.90 ) * 100 + 0.5 ) / 100 #INT((.2*RND(1)+.9)*10^2+.5)/10^2
    +                fox_price    = int( ( 0.25 * random.random() + 1.10 ) * 100 + 0.5 ) / 100 #INT((.25*RND(1)+1.1)*10^2+.5)/10^2
    +                event_picker = int( 10 * random.random() ) + 1
    +
    +                if ( event_picker <= 2 ):
    +                    print( "YOUR BEAVER WERE TOO HEAVY TO CARRY ACROSS" )
    +                    print( "THE PORTAGE.  YOU HAD TO LEAVE THE PELTS, BUT FOUND" )
    +                    print( "THEM STOLEN WHEN YOU RETURNED." )
    +                    player_furs[ FUR_BEAVER ] = 0
    +                elif ( event_picker <= 6 ):
    +                    print( "YOU ARRIVED SAFELY AT FORT STADACONA." )
    +                elif ( event_picker <= 8 ):
    +                    print( "YOUR CANOE UPSET IN THE LACHINE RAPIDS.  YOU" )
    +                    print( "LOST ALL YOUR FURS." )
    +                    player_furs = [ 0, 0, 0, 0 ]  
    +                elif ( event_picker <= 10 ):
    +                    print( "YOUR FOX PELTS WERE NOT CURED PROPERLY." )
    +                    print( "NO ONE WILL BUY THEM." )
    +                    player_furs[ FUR_FOX ] = 0
                     else:
    -                    print(f"Internal Error #3, Out-of-bounds event_picker{str(event_picker)}")
    -                    sys.exit(1)  # you have a bug
    +                    print( "Internal Error #3, Out-of-bounds event_picker" + str( event_picker ) )
    +                    sys.exit( 1 )  # you have a bug
     
    -                print()
    -                print("SUPPLIES AT FORT STADACONA COST $125.00.")
    -                print("YOUR TRAVEL EXPENSES TO STADACONA WERE $15.00.")
    +                print( "" )
    +                print( "SUPPLIES AT FORT STADACONA COST $125.00." )
    +                print( "YOUR TRAVEL EXPENSES TO STADACONA WERE $15.00." )
                     player_funds -= 140
     
    -            elif which_fort == FORT_NEWYORK:
    -                mink_price = (
    -                    int((0.15 * random.random() + 1.05) * 100 + 0.5) / 100
    -                )  # INT((.15*RND(1)+1.05)*10^2+.5)/10^2
    -                ermine_price = (
    -                    int((0.15 * random.random() + 0.95) * 100 + 0.5) / 100
    -                )  # INT((.15*RND(1)+.95)*10^2+.5)/10^2
    -                beaver_price = (
    -                    int((0.25 * random.random() + 1.00) * 100 + 0.5) / 100
    -                )  # INT((.25*RND(1)+1.00)*10^2+.5)/10^2
    -                if fox_price is None:
    +            elif ( which_fort == FORT_NEWYORK ):
    +                mink_price   = int( ( 0.15 * random.random() + 1.05 ) * 100 + 0.5 ) / 100 #INT((.15*RND(1)+1.05)*10^2+.5)/10^2
    +                ermine_price = int( ( 0.15 * random.random() + 0.95 ) * 100 + 0.5 ) / 100 #INT((.15*RND(1)+.95)*10^2+.5)/10^2
    +                beaver_price = int( ( 0.25 * random.random() + 1.00 ) * 100 + 0.5 ) / 100 #INT((.25*RND(1)+1.00)*10^2+.5)/10^2
    +                if ( fox_price == None ):
                         # Original Bug?  There is no Fox price generated for New York, it will use any previous "D1" price
                         # So if there was no previous value, make one up
    -                    fox_price = (
    -                        int((0.25 * random.random() + 1.05) * 100 + 0.5) / 100
    -                    )  # not in orginal code
    -                event_picker = int(10 * random.random()) + 1
    -
    -                if event_picker <= 2:
    -                    print("YOU WERE ATTACKED BY A PARTY OF IROQUOIS.")
    -                    print("ALL PEOPLE IN YOUR TRADING GROUP WERE")
    -                    print("KILLED.  THIS ENDS THE GAME.")
    -                    sys.exit(0)
    -                elif event_picker <= 6:
    -                    print("YOU WERE LUCKY.  YOU ARRIVED SAFELY")
    -                    print("AT FORT NEW YORK.")
    -                elif event_picker <= 8:
    -                    print("YOU NARROWLY ESCAPED AN IROQUOIS RAIDING PARTY.")
    -                    print("HOWEVER, YOU HAD TO LEAVE ALL YOUR FURS BEHIND.")
    -                    player_furs = [0, 0, 0, 0]
    -                elif event_picker <= 10:
    +                    fox_price    = int( ( 0.25 * random.random() + 1.05 ) * 100 + 0.5 ) / 100 # not in orginal code
    +                event_picker = int( 10 * random.random() ) + 1
    +
    +                if ( event_picker <= 2 ):
    +                    print( "YOU WERE ATTACKED BY A PARTY OF IROQUOIS." )
    +                    print( "ALL PEOPLE IN YOUR TRADING GROUP WERE" )
    +                    print( "KILLED.  THIS ENDS THE GAME." )
    +                    sys.exit( 0 )
    +                elif ( event_picker <= 6 ):
    +                    print( "YOU WERE LUCKY.  YOU ARRIVED SAFELY" )
    +                    print( "AT FORT NEW YORK." )
    +                elif ( event_picker <= 8 ):
    +                    print( "YOU NARROWLY ESCAPED AN IROQUOIS RAIDING PARTY." )
    +                    print( "HOWEVER, YOU HAD TO LEAVE ALL YOUR FURS BEHIND." )
    +                    player_furs = [ 0, 0, 0, 0 ]  
    +                elif ( event_picker <= 10 ):
                         mink_price /= 2
    -                    fox_price /= 2
    -                    print("YOUR MINK AND BEAVER WERE DAMAGED ON YOUR TRIP.")
    -                    print("YOU RECEIVE ONLY HALF THE CURRENT PRICE FOR THESE FURS.")
    +                    fox_price  /= 2
    +                    print( "YOUR MINK AND BEAVER WERE DAMAGED ON YOUR TRIP." )
    +                    print( "YOU RECEIVE ONLY HALF THE CURRENT PRICE FOR THESE FURS." )
                     else:
    -                    print(f"Internal Error #4, Out-of-bounds event_picker{str(event_picker)}")
    -                    sys.exit(1)  # you have a bug
    +                    print( "Internal Error #4, Out-of-bounds event_picker" + str( event_picker ) )
    +                    sys.exit( 1 )  # you have a bug
     
    -                print()
    -                print("SUPPLIES AT NEW YORK COST $85.00.")
    -                print("YOUR TRAVEL EXPENSES TO NEW YORK WERE $25.00.")
    +                print( "" )
    +                print( "SUPPLIES AT NEW YORK COST $85.00." )
    +                print( "YOUR TRAVEL EXPENSES TO NEW YORK WERE $25.00." )
                     player_funds -= 105
    +                
     
                 else:
    -                print(f"Internal error #2, fort {str(which_fort)} does not exist")
    -                sys.exit(1)  # you have a bug
    +                print( "Internal error #2, fort " + str( which_fort ) + " does not exist" )
    +                sys.exit( 1 )  # you have a bug
     
                 # Calculate sales
    -            beaver_value = beaver_price * player_furs[FUR_BEAVER]
    -            fox_value = fox_price * player_furs[FUR_FOX]
    -            ermine_value = ermine_price * player_furs[FUR_ERMINE]
    -            mink_value = mink_price * player_furs[FUR_MINK]
    -
    -            print()
    -            print("YOUR BEAVER SOLD FOR $%6.2f" % (beaver_value))
    -            print("YOUR FOX SOLD FOR    $%6.2f" % (fox_value))
    -            print("YOUR ERMINE SOLD FOR $%6.2f" % (ermine_value))
    -            print("YOUR MINK SOLD FOR   $%6.2f" % (mink_value))
    +            beaver_value = beaver_price * player_furs[ FUR_BEAVER ]
    +            fox_value    = fox_price    * player_furs[ FUR_FOX ]
    +            ermine_value = ermine_price * player_furs[ FUR_ERMINE ]
    +            mink_value   = mink_price   * player_furs[ FUR_MINK ]
    +         
    +            print( "" )
    +            print( "YOUR BEAVER SOLD FOR $%6.2f" % ( beaver_value ) )
    +            print( "YOUR FOX SOLD FOR    $%6.2f" % ( fox_value ) ) 
    +            print( "YOUR ERMINE SOLD FOR $%6.2f" % ( ermine_value ) )
    +            print( "YOUR MINK SOLD FOR   $%6.2f" % ( mink_value ) )
     
                 player_funds += beaver_value + fox_value + ermine_value + mink_value
     
    -            print()
    -            print(
    -                "YOU NOW HAVE $ %1.2f INCLUDING YOUR PREVIOUS SAVINGS" % (player_funds)
    -            )
    +            print( "" )
    +            print( "YOU NOW HAVE $ %1.2f INCLUDING YOUR PREVIOUS SAVINGS" % ( player_funds ) )
     
    -            print()
    -            print("DO YOU WANT TO TRADE FURS NEXT YEAR?")
    -            should_trade = get_yes_or_no()
    -            if should_trade == "N":
    -                sys.exit(0)  # STOP
    +            print( "" )
    +            print( "DO YOU WANT TO TRADE FURS NEXT YEAR?" )
    +            should_trade = getYesOrNo()
    +            if ( should_trade == 'N' ):
    +                sys.exit( 0 )             # STOP
                 else:
    -                game_state = "trading"
    +                game_state = 'trading'
     
    +            
     
    -if __name__ == "__main__":
    -    main()
    diff --git a/38_Fur_Trader/vbnet/FurTrader.sln b/38_Fur_Trader/vbnet/FurTrader.sln
    deleted file mode 100644
    index cb1297189..000000000
    --- a/38_Fur_Trader/vbnet/FurTrader.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 61ab6d990..000000000
    --- a/38_Fur_Trader/vbnet/FurTrader.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    FurTrader
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/39_Golf/README.md b/39_Golf/README.md
    index f8769f99b..28da35942 100644
    --- a/39_Golf/README.md
    +++ b/39_Golf/README.md
    @@ -13,11 +13,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Known Bugs
    -
    -- The weakness numbers printed in the original BASIC program are wrong.  It says 4=TRAP SHOTS, 5=PUTTING, but in the code, trap shots and putting are 3 and 4, respectively.
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/39_Golf/csharp/Golf.csproj b/39_Golf/csharp/Golf.csproj
    deleted file mode 100644
    index d3fe4757c..000000000
    --- a/39_Golf/csharp/Golf.csproj
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    diff --git a/39_Golf/csharp/Golf.sln b/39_Golf/csharp/Golf.sln
    deleted file mode 100644
    index 07c90dde0..000000000
    --- a/39_Golf/csharp/Golf.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/csharp/Program.cs b/39_Golf/csharp/Program.cs
    index 623409cde..abbbaf6b8 100644
    --- a/39_Golf/csharp/Program.cs
    +++ b/39_Golf/csharp/Program.cs
    @@ -1,10 +1,10 @@
     //
    -//          8""""8 8"""88 8     8""""
    -//          8    " 8    8 8     8
    -//          8e     8    8 8e    8eeee
    -//          88  ee 8    8 88    88
    -//          88   8 8    8 88    88
    -//          88eee8 8eeee8 88eee 88
    +//          8""""8 8"""88 8     8"""" 
    +//          8    " 8    8 8     8     
    +//          8e     8    8 8e    8eeee 
    +//          88  ee 8    8 88    88    
    +//          88   8 8    8 88    88    
    +//          88eee8 8eeee8 88eee 88    
     //
     // GOLF
     //
    @@ -20,7 +20,7 @@
     //
     // Windows compile:
     // dotnet publish -r win-x64 -c Release /p:PublishSingleFile=true
    -//
    +// 
     //
     // INDEX
     // ----------------- methods
    @@ -62,79 +62,79 @@
     // ToDegrees360
     // Odds
     //
    -//  Despite being a text based game, the code uses simple geometry to simulate a course.
    +//  Despite being a text based game, the code uses simple geometry to simulate a course. 
     //  Fairways are 40 yard wide rectangles, surrounded by 5 yards of rough around the perimeter.
    -//  The green is a circle of 10 yards radius around the cup.
    -//  The cup is always at point (0,0).
    +//  The green is a circle of 10 yards radius around the cup. 
    +//  The cup is always at point (0,0). 
     //
     //  Using basic trigonometry we can plot the ball's location using the distance of the stroke and
    -//  and the angle of deviation (hook/slice).
    +//  and the angle of deviation (hook/slice). 
     //
    -//  The stroke distances are based on real world averages of different club types.
    +//  The stroke distances are based on real world averages of different club types. 
     //  Lots of randomization, "business rules", and luck influence the game play.
    -//  Probabilities are commented in the code.
    +//  Probabilities are commented in the code. 
     //
     //  note: 'courseInfo', 'clubs', & 'scoreCard' arrays each include an empty object so indexing
     //  can begin at 1. Like all good programmers we count from zero, but in this context,
     //  it's more natural when hole number one is at index one
     //
    -//
    -//     |-----------------------------|
    +//            
    +//     |-----------------------------|   
     //     |            rough            |
    -//     |   ----------------------    |
    -//     |   |                     |   |
    -//     | r |        =  =         | r |
    -//     | o |     =        =      | o |
    -//     | u |    =    .     =     | u |
    -//     | g |    =   green  =     | g |
    -//     | h |     =        =      | h |
    -//     |   |        =  =         |   |
    -//     |   |                     |   |
    -//     |   |                     |   |
    -//     |   |      Fairway        |   |
    -//     |   |                     |   |
    +//     |   ----------------------    | 
    +//     |   |                     |   | 
    +//     | r |        =  =         | r | 
    +//     | o |     =        =      | o | 
    +//     | u |    =    .     =     | u | 
    +//     | g |    =   green  =     | g |  
    +//     | h |     =        =      | h | 
    +//     |   |        =  =         |   | 
    +//     |   |                     |   | 
    +//     |   |                     |   | 
    +//     |   |      Fairway        |   | 
    +//     |   |                     |   | 
     //     |   |               ------    |
     //     |   |            --        -- |
     //     |   |           --  hazard  --|
     //     |   |            --        -- |
     //     |   |               ------    |
    -//     |   |                     |   |
    +//     |   |                     |   | 
     //     |   |                     |   |   out
     //     |   |                     |   |   of
     //     |   |                     |   |   bounds
     //     |   |                     |   |
    -//     |   |                     |   |
    -//     |            tee              |
    -//
    +//     |   |                     |   |     
    +//     |            tee              |  
    +//                  
     //
     //  Typical green size: 20-30 yards
    -//  Typical golf course fairways are 35 to 45 yards wide
    +//  Typical golf course fairways are 35 to 45 yards wide          
     //  Our fairway extends 5 yards past green
     //  Our rough is a 5 yard perimeter around fairway
    -//
    +//  
     //  We calculate the new position of the ball given the ball's point, the distance
     //  of the stroke, and degrees off line (hook or slice).
     //
     //  Degrees off (for a right handed golfer):
    -//  Slice: positive degrees = ball goes right
    +//  Slice: positive degrees = ball goes right 
     //  Hook: negative degrees = left goes left
    -//
    +//  
     //  The cup is always at point: 0,0.
     //  We use atan2 to compute the angle between the cup and the ball.
    -//  Setting the cup's vector to 0,-1 on a 360 circle is equivalent to:
    +//  Setting the cup's vector to 0,-1 on a 360 circle is equivalent to: 
     //  0 deg = 12 o'clock;  90 deg = 3 o'clock;  180 deg = 6 o'clock;  270 = 9 o'clock
     //  The reverse angle between the cup and the ball is a difference of PI (using radians).
     //
     //  Given the angle and stroke distance (hypotenuse), we use cosine to compute
     //  the opposite and adjacent sides of the triangle, which, is the ball's new position.
    -//
    +//    
     //           0
     //           |
     //    270 - cup - 90
     //           |
     //          180
    -//
    -//
    +//    
    +//    
     //          cup
     //           |
     //           |
    @@ -147,19 +147,19 @@
     //           |/
     //          tee
     //
    -//    <- hook    slice ->
    +//    <- hook    slice ->  
     //
     //
     //  Given the large number of combinations needed to describe a particular stroke / ball location,
    -//  we use the technique of "bitwise masking" to describe stroke results.
    +//  we use the technique of "bitwise masking" to describe stroke results. 
     //  With bit masking, multiple flags (bits) are combined into a single binary number that can be
     //  tested by applying a mask. A mask is another binary number that isolates a particular bit that
     //  you are interested in. You can then apply your language's bitwise opeartors to test or
    -//  set a flag.
    +//  set a flag. 
     //
     //  Game design by Jason Bonthron, 2021
     //  www.bonthron.com
    -//  for my father, Raymond Bonthron, an avid golfer
    +//  for my father, Raymond Bonthron, an avid golfer 
     //
     //  Inspired by the 1978 "Golf" from "Basic Computer Games"
     //  by Steve North, who modified an existing golf game by an unknown author
    @@ -176,7 +176,7 @@ namespace Golf
     {
         using Ball = Golf.CircleGameObj;
         using Hazard = Golf.CircleGameObj;
    -
    +    
         // --------------------------------------------------------------------------- Program
         class Program
         {
    @@ -186,7 +186,7 @@ static void Main(string[] args)
             }
         }
     
    -
    +    
         // --------------------------------------------------------------------------- Golf
         public class Golf
         {
    @@ -209,7 +209,7 @@ public class Golf
     
             List> ScoreCard = new List> { new List() };
     
    -        static void w(string s) { Console.WriteLine(s); } // WRITE
    +        static void w(string s) { Console.WriteLine(s); } // WRITE        
             Random RANDOM = new Random();
     
     
    @@ -238,7 +238,7 @@ public Golf()
                 Wait((z) =>
                 {
                     w(" ");
    -                w("              YOUR BAG");
    +                w("              YOUR BAG");                
                     ReviewBag();
                     w("Type BAG at any time to review the clubs in your bag.");
                     w(" ");
    @@ -246,7 +246,7 @@ public Golf()
                     Wait((zz) =>
                     {
                         w(" ");
    -
    +                    
                         Ask("PGA handicaps range from 0 to 30.\nWhat is your handicap?", 0, 30, (i) =>
                         {
                             Handicap = i;
    @@ -342,7 +342,7 @@ void TeeUp()
                 };
             }
     
    -
    +        
             // -------------------------------------------------------- bitwise Flags
             int dub         = 0b00000000000001;
             int hook        = 0b00000000000010;
    @@ -412,24 +412,24 @@ void Stroke(double clubAmt, int clubIndex)
                 };
     
                 // beginner's luck !
    -            // If handicap is greater than 15, there's a 10% chance of avoiding all errors
    +            // If handicap is greater than 15, there's a 10% chance of avoiding all errors 
                 if ((Handicap > 15) && (Odds(10))) { flags |= luck; };
     
                 // ace
    -            // there's a 10% chance of an Ace on a par 3
    +            // there's a 10% chance of an Ace on a par 3           
                 if (CourseInfo[HOLE_NUM].Par == 3 && Odds(10) && STROKE_NUM == 1) { flags |= ace; };
     
                 // distance:
                 // If handicap is < 15, there a 50% chance of reaching club average,
    -            // a 25% of exceeding it, and a 25% of falling short
    +            // a 25% of exceeding it, and a 25% of falling short 
                 // If handicap is > 15, there's a 25% chance of reaching club average,
                 // and 75% chance of falling short
                 // The greater the handicap, the more the ball falls short
    -            // If poor distance is a known playerDifficulty, then reduce distance by 10%
    +            // If poor distance is a known playerDifficulty, then reduce distance by 10% 
     
                 double distance;
                 int rnd = RANDOM.Next(1, 101);
    -
    +             
                 if (Handicap < 15)
                 {
                     if (rnd <= 25)
    @@ -465,7 +465,7 @@ void Stroke(double clubAmt, int clubIndex)
                 if ((flags & luck) == luck) { distance = clubAmt; }
     
                 // angle
    -            // For all strokes, there's a possible "drift" of 4 degrees
    +            // For all strokes, there's a possible "drift" of 4 degrees 
                 // a hooks or slice increases the angle between 5-10 degrees, hook uses negative degrees
                 int angle = RANDOM.Next(0, 5);
                 if ((flags & slice) == slice) { angle = RANDOM.Next(5, 11); };
    @@ -614,7 +614,7 @@ void InterpretResults(Plot plot, int flags)
                 TeeUp();
             }
     
    -
    +        
             // --------------------------------------------------------------- ReportCurrentScore
             void ReportCurrentScore()
             {
    @@ -624,18 +624,18 @@ void ReportCurrentScore()
                 if (ScoreCard[HOLE_NUM].Count == (par - 1)) { w("A birdie! One below par."); };
                 if (ScoreCard[HOLE_NUM].Count == (par - 2)) { w("An Eagle! Two below par."); };
                 if (ScoreCard[HOLE_NUM].Count == (par - 3)) { w("Double Eagle! Unbelievable."); };
    -
    +            
                 int totalPar = 0;
                 for (var i = 1; i <= HOLE_NUM; i++) { totalPar += CourseInfo[i].Par; };
     
                 w(" ");
    -            w("-----------------------------------------------------");
    +            w("-----------------------------------------------------");            
                 Console.WriteLine(" Total par for {0} hole{1} is: {2}. Your total is: {3}.",
                                   HOLE_NUM,
    -                              ((HOLE_NUM > 1) ? "s" : ""), //plural
    +                              ((HOLE_NUM > 1) ? "s" : ""), //plural    
                                   totalPar,
                                   ScoreCardGetTotal());
    -            w("-----------------------------------------------------");
    +            w("-----------------------------------------------------");            
                 w(" ");
     
                 if (HOLE_NUM == 18)
    @@ -649,7 +649,7 @@ void ReportCurrentScore()
                 };
             }
     
    -
    +        
             // --------------------------------------------------------------- FindBall
             int FindBall(Ball ball, int flags)
             {
    @@ -660,7 +660,7 @@ int FindBall(Ball ball, int flags)
                 if (IsInHazard(ball, GameObjType.WATER)) { flags |= inWater; }
                 if (IsInHazard(ball, GameObjType.TREES)) { flags |= inTrees; }
                 if (IsInHazard(ball, GameObjType.SAND))  { flags |= inSand;  }
    -
    +            
                 if (ball.Y < 0) { flags |= passedCup; }
     
                 // less than 2, it's in the cup
    @@ -671,14 +671,14 @@ int FindBall(Ball ball, int flags)
                 return flags;
             }
     
    -
    +        
             // --------------------------------------------------------------- IsOnFairway
             bool IsOnFairway(Ball ball)
             {
                 return IsInRectangle(ball, holeGeometry.Fairway);
             }
     
    -
    +        
             // --------------------------------------------------------------- IsOngreen
             bool IsOnGreen(Ball ball)
             {
    @@ -687,7 +687,7 @@ bool IsOnGreen(Ball ball)
                 return d < holeGeometry.Green.Radius;
             }
     
    -
    +        
             // --------------------------------------------------------------- IsInHazard
             bool IsInHazard(Ball ball, GameObjType hazard)
             {
    @@ -700,7 +700,7 @@ bool IsInHazard(Ball ball, GameObjType hazard)
                 return result;
             }
     
    -
    +        
             // --------------------------------------------------------------- IsInRough
             bool IsInRough(Ball ball)
             {
    @@ -708,7 +708,7 @@ bool IsInRough(Ball ball)
                     (IsInRectangle(ball, holeGeometry.Fairway) == false);
             }
     
    -
    +        
             // --------------------------------------------------------------- IsOutOfBounds
             bool IsOutOfBounds(Ball ball)
             {
    @@ -723,7 +723,7 @@ void ScoreCardStartNewHole()
             }
     
     
    -        // --------------------------------------------------------------- ScoreCardRecordStroke
    +        // --------------------------------------------------------------- ScoreCardRecordStroke 
             void ScoreCardRecordStroke(Ball ball)
             {
                 var clone = new Ball(ball.X, ball.Y, 0, GameObjType.BALL);
    @@ -783,7 +783,7 @@ void Ask(string question, int min, int max, Action callback)
             void Wait(Action callback)
             {
                 w("Press any key to continue.");
    -
    +            
                 ConsoleKeyInfo keyinfo;
                 do { keyinfo = Console.ReadKey(true); }
                 while (keyinfo.KeyChar < 0);
    @@ -828,10 +828,10 @@ void GameOver()
             {
                 var net = ScoreCardGetTotal() - Handicap;
                 w("Good game!");
    -            w("Your net score is: " + net);
    +            w("Your net score is: " + net);            
                 w("Let's visit the pro shop...");
                 w(" ");
    -            Wait((z) => { });
    +            Wait((z) => { });            
                 return;
             }
     
    @@ -840,8 +840,8 @@ void GameOver()
             // ======================================================== Clubs
             (string, int)[] Clubs = new (string, int)[] {
                 ("",0),
    -
    -                // name, average yardage
    +                
    +                // name, average yardage                
                     ("Driver", 250),
                     ("3 Wood", 225),
                     ("5 Wood", 200),
    @@ -861,7 +861,7 @@ void GameOver()
             HoleInfo[] CourseInfo = new HoleInfo[]{
                 new HoleInfo(0, 0, 0, new Hazard[]{}, ""), // include a blank so index 1 == hole 1
     
    -
    +            
                 // -------------------------------------------------------- front 9
                 // hole, yards, par, hazards, (description)
     
    @@ -927,8 +927,8 @@ void GameOver()
                                  new Hazard(-30, 180, 20, GameObjType.TREES),
                                  new Hazard( 14,  -8,  5, GameObjType.SAND)
                              },
    -                         ""),
    -
    +                         ""), 
    +            
                 // -------------------------------------------------------- back 9
                 // hole, yards, par, hazards, (description)
     
    @@ -999,7 +999,7 @@ void GameOver()
                              "There is a water hazard near the green.")
             };
     
    -
    +        
             // -------------------------------------------------------- HoleInfo
             class HoleInfo
             {
    @@ -1114,7 +1114,7 @@ bool IsInRectangle(CircleGameObj pt, RectGameObj rect)
                         (pt.Y < rect.Y + rect.Length));
             }
     
    -
    +        
             // -------------------------------------------------------- ToRadians
             double ToRadians(double angle) { return angle * (Math.PI / 180.0); }
     
    diff --git a/39_Golf/csharp/README.md b/39_Golf/csharp/README.md
    index c632babb7..126658a1b 100644
    --- a/39_Golf/csharp/README.md
    +++ b/39_Golf/csharp/README.md
    @@ -2,9 +2,14 @@ Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/gam
     
     Conversion to [Microsoft C#](https://docs.microsoft.com/en-us/dotnet/csharp/)
     
    -There are 2 compiled executables in the compiled/ directory (windows and linux) that you can play right away!
    +There are 2 compiled executables in the compiled/ directory (windows and linux) that you can play right away! 
     
    -Program.cs contains the C# source code.
    +Program.cs contains the C# source code. 
     It has been written for .NET Core 3.1
     
     The source code is well documented.
    +
    +
    +
    +
    +
    diff --git a/39_Golf/javascript/golf.html b/39_Golf/javascript/golf.html
    index 13803915f..bf43de8e0 100644
    --- a/39_Golf/javascript/golf.html
    +++ b/39_Golf/javascript/golf.html
    @@ -1,10 +1,9 @@
     
     
     GOLF
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/39_Golf/javascript/golf.js b/39_Golf/javascript/golf.js
    index 660c95ba4..814d589e3 100644
    --- a/39_Golf/javascript/golf.js
    +++ b/39_Golf/javascript/golf.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    @@ -198,7 +198,7 @@ async function main()
                     show_obstacle();
                 }
             }
    -
    +        
             while (1) {
                 if (a != 1) {
                     print("SELECTION OF CLUBS\n");
    diff --git a/39_Golf/kotlin/README.md b/39_Golf/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/39_Golf/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/39_Golf/lua/README.md b/39_Golf/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/39_Golf/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/39_Golf/pascal/README.md b/39_Golf/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/39_Golf/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/39_Golf/python/golf.py b/39_Golf/python/golf.py
    deleted file mode 100644
    index d60bb60bb..000000000
    --- a/39_Golf/python/golf.py
    +++ /dev/null
    @@ -1,969 +0,0 @@
    -'''
    -        8""""8 8"""88 8     8""""
    -        8    " 8    8 8     8
    -        8e     8    8 8e    8eeee
    -        88  ee 8    8 88    88
    -        88   8 8    8 88    88
    -        88eee8 8eeee8 88eee 88
    -
    -GOLF
    -
    -
    -Despite being a text based game, the code uses simple geometry to simulate a course.
    -Fairways are 40 yard wide rectangles, surrounded by 5 yards of rough around the perimeter.
    -The green is a circle of 10 yards radius around the cup.
    -The cup is always at point (0,0).
    -
    -Using basic trigonometry we can plot the ball's location using the distance of the stroke and
    -and the angle of deviation (hook/slice).
    -
    -The stroke distances are based on real world averages of different club types.
    -Lots of randomization, "business rules", and luck influence the game play.
    -Probabilities are commented in the code.
    -
    -note: 'courseInfo', 'clubs', & 'scoreCard' arrays each include an empty object so indexing
    -can begin at 1. Like all good programmers we count from zero, but in this context,
    -it's more natural when hole number one is at index one
    -
    -
    -    |-----------------------------|
    -    |            rough            |
    -    |   ----------------------    |
    -    |   |                     |   |
    -    | r |        =  =         | r |
    -    | o |     =        =      | o |
    -    | u |    =    .     =     | u |
    -    | g |    =   green  =     | g |
    -    | h |     =        =      | h |
    -    |   |        =  =         |   |
    -    |   |                     |   |
    -    |   |                     |   |
    -    |   |      Fairway        |   |
    -    |   |                     |   |
    -    |   |               ------    |
    -    |   |            --        -- |
    -    |   |           --  hazard  --|
    -    |   |            --        -- |
    -    |   |               ------    |
    -    |   |                     |   |
    -    |   |                     |   |   out
    -    |   |                     |   |   of
    -    |   |                     |   |   bounds
    -    |   |                     |   |
    -    |   |                     |   |
    -    |            tee              |
    -
    -
    -Typical green size: 20-30 yards
    -Typical golf course fairways are 35 to 45 yards wide
    -Our fairway extends 5 yards past green
    -Our rough is a 5 yard perimeter around fairway
    -
    -We calculate the new position of the ball given the ball's point, the distance
    -of the stroke, and degrees off line (hook or slice).
    -
    -Degrees off (for a right handed golfer):
    -Slice: positive degrees = ball goes right
    -Hook: negative degrees = left goes left
    -
    -The cup is always at point: 0,0.
    -We use atan2 to compute the angle between the cup and the ball.
    -Setting the cup's vector to 0,-1 on a 360 circle is equivalent to:
    -0 deg = 12 o'clock;  90 deg = 3 o'clock;  180 deg = 6 o'clock;  270 = 9 o'clock
    -The reverse angle between the cup and the ball is a difference of PI (using radians).
    -
    -Given the angle and stroke distance (hypotenuse), we use cosine to compute
    -the opposite and adjacent sides of the triangle, which, is the ball's new position.
    -
    -        0
    -        |
    -270 - cup - 90
    -        |
    -        180
    -
    -
    -        cup
    -        |
    -        |
    -        | opp
    -        |-----* new position
    -        |    /
    -        |   /
    -    adj  |  /
    -        | /  hyp
    -        |/
    -        tee
    -
    -<- hook    slice ->
    -
    -
    -Given the large number of combinations needed to describe a particular stroke / ball location,
    -we use the technique of "bitwise masking" to describe stroke results.
    -With bit masking, multiple flags (bits) are combined into a single binary number that can be
    -tested by applying a mask. A mask is another binary number that isolates a particular bit that
    -you are interested in. You can then apply your language's bitwise opeartors to test or
    -set a flag.
    -
    -Game design by Jason Bonthron, 2021
    -www.bonthron.com
    -for my father, Raymond Bonthron, an avid golfer
    -
    -Inspired by the 1978 "Golf" from "Basic Computer Games"
    -by Steve North, who modified an existing golf game by an unknown author
    -
    -Ported in 2022 to Python by Martin Thoma
    -'''
    -
    -
    -import enum
    -import math
    -import random
    -import time
    -from dataclasses import dataclass
    -from functools import partial
    -from typing import Any, Callable, List, NamedTuple, Tuple
    -
    -
    -def clear_console() -> None:
    -    print("\033[H\033[J", end="")
    -
    -
    -class Point(NamedTuple):
    -    x: int
    -    y: int
    -
    -
    -class GameObjType(enum.Enum):
    -    BALL = enum.auto()
    -    CUP = enum.auto()
    -    GREEN = enum.auto()
    -    FAIRWAY = enum.auto()
    -    ROUGH = enum.auto()
    -    TREES = enum.auto()
    -    WATER = enum.auto()
    -    SAND = enum.auto()
    -
    -
    -class CircleGameObj(NamedTuple):
    -    # center point
    -    X: int
    -    Y: int
    -    Radius: int
    -    Type: GameObjType
    -
    -
    -class RectGameObj(NamedTuple):
    -    # Upper left corner
    -    X: int
    -    Y: int
    -    Width: int
    -    Length: int
    -    Type: GameObjType
    -
    -
    -Ball = CircleGameObj
    -Hazard = CircleGameObj
    -
    -
    -class HoleInfo(NamedTuple):
    -    hole: int
    -    yards: int
    -    par: int
    -    hazards: List[Hazard]
    -    description: str
    -
    -
    -class HoleGeometry(NamedTuple):
    -    cup: CircleGameObj
    -    green: CircleGameObj
    -    fairway: RectGameObj
    -    rough: RectGameObj
    -    hazards: List[Hazard]
    -
    -
    -@dataclass
    -class Plot:
    -    x: int
    -    y: int
    -    offline: int
    -
    -
    -def get_distance(pt1: Point, pt2: Point) -> float:
    -    """distance between 2 points"""
    -    return math.sqrt(math.pow((pt2.x - pt1.x), 2) + math.pow((pt2.y - pt1.y), 2))
    -
    -
    -def is_in_rectangle(pt: CircleGameObj, rect: RectGameObj) -> bool:
    -    # only true if its completely inside
    -    return (
    -        (pt.X > rect.X)
    -        and (pt.X < rect.X + rect.Width)
    -        and (pt.Y > rect.Y)
    -        and (pt.Y < rect.Y + rect.Length)
    -    )
    -
    -
    -def to_radians(angle: float) -> float:
    -    return angle * (math.pi / 180.0)
    -
    -
    -def to_degrees_360(angle: float) -> float:
    -    """radians to 360 degrees"""
    -    deg = angle * (180.0 / math.pi)
    -    if deg < 0.0:
    -        deg += 360.0
    -    return deg
    -
    -
    -def odds(x: int) -> bool:
    -    # chance an integer is <= the given argument
    -    # between 1-100
    -    return random.randint(1, 101) <= x
    -
    -
    -# THE COURSE
    -CourseInfo = [
    -    HoleInfo(0, 0, 0, [], ""),  # include a blank so index 1 == hole 1
    -    # -------------------------------------------------------- front 9
    -    HoleInfo(
    -        1,
    -        361,
    -        4,
    -        [
    -            Hazard(20, 100, 10, GameObjType.TREES),
    -            Hazard(-20, 80, 10, GameObjType.TREES),
    -            Hazard(-20, 100, 10, GameObjType.TREES),
    -        ],
    -        "There are a couple of trees on the left and right.",
    -    ),
    -    HoleInfo(
    -        2,
    -        389,
    -        4,
    -        [Hazard(0, 160, 20, GameObjType.WATER)],
    -        "There is a large water hazard across the fairway about 150 yards.",
    -    ),
    -    HoleInfo(
    -        3,
    -        206,
    -        3,
    -        [
    -            Hazard(20, 20, 5, GameObjType.WATER),
    -            Hazard(-20, 160, 10, GameObjType.WATER),
    -            Hazard(10, 12, 5, GameObjType.SAND),
    -        ],
    -        "There is some sand and water near the green.",
    -    ),
    -    HoleInfo(
    -        4,
    -        500,
    -        5,
    -        [Hazard(-14, 12, 12, GameObjType.SAND)],
    -        "There's a bunker to the left of the green.",
    -    ),
    -    HoleInfo(
    -        5,
    -        408,
    -        4,
    -        [
    -            Hazard(20, 120, 20, GameObjType.TREES),
    -            Hazard(20, 160, 20, GameObjType.TREES),
    -            Hazard(10, 20, 5, GameObjType.SAND),
    -        ],
    -        "There are some trees to your right.",
    -    ),
    -    HoleInfo(
    -        6,
    -        359,
    -        4,
    -        [Hazard(14, 0, 4, GameObjType.SAND), Hazard(-14, 0, 4, GameObjType.SAND)],
    -        "",
    -    ),
    -    HoleInfo(
    -        7,
    -        424,
    -        5,
    -        [
    -            Hazard(20, 200, 10, GameObjType.SAND),
    -            Hazard(10, 180, 10, GameObjType.SAND),
    -            Hazard(20, 160, 10, GameObjType.SAND),
    -        ],
    -        "There are several sand traps along your right.",
    -    ),
    -    HoleInfo(8, 388, 4, [Hazard(-20, 340, 10, GameObjType.TREES)], ""),
    -    HoleInfo(
    -        9,
    -        196,
    -        3,
    -        [Hazard(-30, 180, 20, GameObjType.TREES), Hazard(14, -8, 5, GameObjType.SAND)],
    -        "",
    -    ),
    -    # -------------------------------------------------------- back 9
    -    HoleInfo(
    -        hole=10,
    -        yards=400,
    -        par=4,
    -        hazards=[
    -            Hazard(-14, -8, 5, GameObjType.SAND),
    -            Hazard(14, -8, 5, GameObjType.SAND),
    -        ],
    -        description="",
    -    ),
    -    HoleInfo(
    -        11,
    -        560,
    -        5,
    -        [
    -            Hazard(-20, 400, 10, GameObjType.TREES),
    -            Hazard(-10, 380, 10, GameObjType.TREES),
    -            Hazard(-20, 260, 10, GameObjType.TREES),
    -            Hazard(-20, 200, 10, GameObjType.TREES),
    -            Hazard(-10, 180, 10, GameObjType.TREES),
    -            Hazard(-20, 160, 10, GameObjType.TREES),
    -        ],
    -        "Lots of trees along the left of the fairway.",
    -    ),
    -    HoleInfo(
    -        12,
    -        132,
    -        3,
    -        [
    -            Hazard(-10, 120, 10, GameObjType.WATER),
    -            Hazard(-5, 100, 10, GameObjType.SAND),
    -        ],
    -        "There is water and sand directly in front of you. A good drive should clear both.",
    -    ),
    -    HoleInfo(
    -        13,
    -        357,
    -        4,
    -        [
    -            Hazard(-20, 200, 10, GameObjType.TREES),
    -            Hazard(-10, 180, 10, GameObjType.TREES),
    -            Hazard(-20, 160, 10, GameObjType.TREES),
    -            Hazard(14, 12, 8, GameObjType.SAND),
    -        ],
    -        "",
    -    ),
    -    HoleInfo(14, 294, 4, [Hazard(0, 20, 10, GameObjType.SAND)], ""),
    -    HoleInfo(
    -        15,
    -        475,
    -        5,
    -        [Hazard(-20, 20, 10, GameObjType.WATER), Hazard(10, 20, 10, GameObjType.SAND)],
    -        "Some sand and water near the green.",
    -    ),
    -    HoleInfo(16, 375, 4, [Hazard(-14, -8, 5, GameObjType.SAND)], ""),
    -    HoleInfo(
    -        17,
    -        180,
    -        3,
    -        [
    -            Hazard(20, 100, 10, GameObjType.TREES),
    -            Hazard(-20, 80, 10, GameObjType.TREES),
    -        ],
    -        "",
    -    ),
    -    HoleInfo(
    -        18,
    -        550,
    -        5,
    -        [Hazard(20, 30, 15, GameObjType.WATER)],
    -        "There is a water hazard near the green.",
    -    ),
    -]
    -
    -
    -# -------------------------------------------------------- bitwise Flags
    -dub = 0b00000000000001
    -hook = 0b00000000000010
    -slice_ = 0b00000000000100
    -passed_cup = 0b00000000001000
    -in_cup = 0b00000000010000
    -on_fairway = 0b00000000100000
    -on_green = 0b00000001000000
    -in_rough = 0b00000010000000
    -in_sand = 0b00000100000000
    -in_trees = 0b00001000000000
    -in_water = 0b00010000000000
    -out_of_bounds = 0b00100000000000
    -luck = 0b01000000000000
    -ace = 0b10000000000000
    -
    -
    -class Golf:
    -    ball: Ball
    -    hole_num: int = 0
    -    stroke_num: int = 0
    -    handicap: int = 0
    -    player_difficulty: int = 0
    -    hole_geometry: HoleGeometry
    -
    -    # all fairways are 40 yards wide, extend 5 yards beyond the cup, and
    -    # have 5 yards of rough around the perimeter
    -    fairway_width: int = 40
    -    fairway_extension: int = 5
    -    rough_amt: int = 5
    -
    -    # ScoreCard records the ball position after each stroke
    -    # a new list for each hole
    -    # include a blank list so index 1 == hole 1
    -    score_card: List[List[Ball]] = [[]]
    -
    -    # YOUR BAG
    -    clubs: List[Tuple[str, int]] = [
    -        ("", 0),
    -        # name, average yardage
    -        ("Driver", 250),
    -        ("3 Wood", 225),
    -        ("5 Wood", 200),
    -        ("Hybrid", 190),
    -        ("4 Iron", 170),
    -        ("7 Iron", 150),
    -        ("9 Iron", 125),
    -        ("Pitching wedge", 110),
    -        ("Sand wedge", 75),
    -        ("Putter", 10),
    -    ]
    -
    -    def __init__(self) -> None:
    -        print(" ")
    -        print('          8""""8 8"""88 8     8"""" ')
    -        print('          8    " 8    8 8     8     ')
    -        print("          8e     8    8 8e    8eeee ")
    -        print("          88  ee 8    8 88    88    ")
    -        print("          88   8 8    8 88    88    ")
    -        print("          88eee8 8eeee8 88eee 88    ")
    -        print(" ")
    -        print("Welcome to the Creative Computing Country Club,")
    -        print("an eighteen hole championship layout located a short")
    -        print("distance from scenic downtown Lambertville, New Jersey.")
    -        print("The game will be explained as you play.")
    -        print("Enjoy your game! See you at the 19th hole...")
    -        print(" ")
    -        print("Type QUIT at any time to leave the game.")
    -        print("Type BAG at any time to review the clubs in your bag.")
    -        print(" ")
    -
    -        input("Press any key to continue.")
    -        clear_console()
    -        self.start_game()
    -
    -    def start_game(self) -> None:
    -        print(" ")
    -        print("              YOUR BAG")
    -        self.review_bag()
    -        print("Type BAG at any time to review the clubs in your bag.")
    -        print(" ")
    -
    -        input("Press any key to continue.")
    -        clear_console()
    -        self.ask_handicap()
    -
    -    def ask_handicap(self) -> None:
    -        print(" ")
    -
    -        self.ask(
    -            "PGA handicaps range from 0 to 30.\nWhat is your handicap?",
    -            0,
    -            30,
    -            self.set_handicap_ask_difficulty,
    -        )
    -
    -    def set_handicap_ask_difficulty(self, i: int) -> None:
    -        self.handicap = i
    -        print(" ")
    -
    -        self.ask(
    -            (
    -                "Common difficulties at golf include:\n"
    -                "1=Hook, 2=Slice, 3=Poor Distance, 4=Trap Shots, 5=Putting\n"
    -                "Which one is your worst?"
    -            ),
    -            1,
    -            5,
    -            self.set_difficulty_and_hole,
    -        )
    -
    -    def set_difficulty_and_hole(self, j: int) -> None:
    -        self.player_difficulty = j
    -        clear_console()
    -        self.new_hole()
    -
    -    def new_hole(self) -> None:
    -        self.hole_num += 1
    -        self.stroke_num = 0
    -
    -        info: HoleInfo = CourseInfo[self.hole_num]
    -
    -        yards: int = info.yards
    -        # from tee to cup
    -        cup = CircleGameObj(0, 0, 0, GameObjType.CUP)
    -        green = CircleGameObj(0, 0, 10, GameObjType.GREEN)
    -
    -        fairway = RectGameObj(
    -            0 - int(self.fairway_width / 2),
    -            0 - (green.Radius + self.fairway_extension),
    -            self.fairway_width,
    -            yards + (green.Radius + self.fairway_extension) + 1,
    -            GameObjType.FAIRWAY,
    -        )
    -
    -        rough = RectGameObj(
    -            fairway.X - self.rough_amt,
    -            fairway.Y - self.rough_amt,
    -            fairway.Width + (2 * self.rough_amt),
    -            fairway.Length + (2 * self.rough_amt),
    -            GameObjType.ROUGH,
    -        )
    -
    -        self.ball = Ball(0, yards, 0, GameObjType.BALL)
    -
    -        self.score_card_start_new_hole()
    -
    -        self.hole_geometry = HoleGeometry(cup, green, fairway, rough, info.hazards)
    -
    -        print(f"                |> {self.hole_num}")
    -        print("                |        ")
    -        print("                |        ")
    -        print("          ^^^^^^^^^^^^^^^")
    -
    -        print(
    -            f"Hole #{self.hole_num}. You are at the tee. Distance {info.yards} yards, par {info.par}."
    -        )
    -        print(info.description)
    -
    -        self.tee_up()
    -
    -    def set_putter_and_stroke(self, strength: float) -> None:
    -        putter = self.clubs[self.putt]
    -        self.stroke((putter[1] * (strength / 10.0)), self.putt)
    -
    -    def ask_gauge(self, c: int) -> None:
    -        self.club = self.clubs[c]
    -
    -        print(" ")
    -        print(f"[{self.club[0].upper()}: average {self.club[1]} yards]")
    -
    -        foo = partial(self.make_stroke, c=c)
    -
    -        self.ask(
    -            "Now gauge your distance by a percentage of a full swing. (1-10)",
    -            1,
    -            10,
    -            foo,
    -        )
    -
    -    def make_stroke(self, strength: float, c: int) -> None:
    -        self.stroke((self.club[1] * (strength / 10.0)), c)
    -
    -    def tee_up(self) -> None:
    -        # on the green? automatically select putter
    -        # otherwise Ask club and swing strength
    -        if self.is_on_green(self.ball) and not self.is_in_hazard(
    -            self.ball, GameObjType.SAND
    -        ):
    -            self.putt = 10
    -            print("[PUTTER: average 10 yards]")
    -            msg = "Keep your head down.\n" if odds(20) else ""
    -            self.ask(
    -                f"{msg}Choose your putt potency. (1-10)",
    -                1,
    -                10,
    -                self.set_putter_and_stroke,
    -            )
    -        else:
    -            self.ask("What club do you choose? (1-10)", 1, 10, self.ask_gauge)
    -
    -    def stroke(self, club_amt: float, club_index: int) -> None:
    -        self.stroke_num += 1
    -
    -        flags = 0b000000000000
    -
    -        # fore! only when driving
    -        if (self.stroke_num == 1) and (club_amt > 210) and odds(30):
    -            print('"...Fore !"')
    -
    -        # dub
    -        if odds(5):
    -            # there's always a 5% chance of dubbing it
    -            flags |= dub
    -
    -        # if you're in the rough, or sand, you really should be using a wedge
    -        if (
    -            (
    -                self.is_in_rough(self.ball)
    -                or self.is_in_hazard(self.ball, GameObjType.SAND)
    -            )
    -            and club_index not in {8, 9}
    -            and odds(40)
    -        ):
    -            flags |= dub
    -
    -        # trap difficulty
    -        if (
    -            self.is_in_hazard(self.ball, GameObjType.SAND)
    -            and self.player_difficulty == 4
    -        ) and odds(20):
    -            flags |= dub
    -
    -        # hook/slice
    -        # There's 10% chance of a hook or slice
    -        # if it's a known player_difficulty then increase chance to 30%
    -        # if it's a putt & putting is a player_difficulty increase to 30%
    -
    -        rand_hook_slice: bool
    -        if (
    -            self.player_difficulty == 1
    -            or self.player_difficulty == 2
    -            or (self.player_difficulty == 5 and self.is_on_green(self.ball))
    -        ):
    -            rand_hook_slice = odds(30)
    -        else:
    -            rand_hook_slice = odds(10)
    -
    -        if rand_hook_slice:
    -            if self.player_difficulty == 1:
    -                if odds(80):
    -                    flags |= hook
    -                else:
    -                    flags |= slice_
    -            elif self.player_difficulty == 2:
    -                if odds(80):
    -                    flags |= slice_
    -                else:
    -                    flags |= hook
    -            elif odds(50):
    -                flags |= hook
    -            else:
    -                flags |= slice_
    -
    -        # beginner's luck !
    -        # If handicap is greater than 15, there's a 10% chance of avoiding all errors
    -        if (self.handicap > 15) and (odds(10)):
    -            flags |= luck
    -
    -        # ace
    -        # there's a 10% chance of an Ace on a par 3
    -        if CourseInfo[self.hole_num].par == 3 and odds(10) and self.stroke_num == 1:
    -            flags |= ace
    -
    -        # distance:
    -        # If handicap is < 15, there a 50% chance of reaching club average,
    -        # a 25% of exceeding it, and a 25% of falling short
    -        # If handicap is > 15, there's a 25% chance of reaching club average,
    -        # and 75% chance of falling short
    -        # The greater the handicap, the more the ball falls short
    -        # If poor distance is a known player_difficulty, then reduce distance by 10%
    -
    -        distance: float
    -        rnd = random.randint(1, 101)
    -
    -        if self.handicap < 15 and rnd <= 25 or self.handicap >= 15 and rnd <= 75:
    -            distance = club_amt - (club_amt * (self.handicap / 100.0))
    -        elif self.handicap < 15 and rnd <= 75 or self.handicap >= 15:
    -            distance = club_amt
    -        else:
    -            distance = club_amt + (club_amt * 0.10)
    -        if self.player_difficulty == 3 and odds(80):  # poor distance
    -            distance *= 0.80
    -
    -        if (flags & luck) == luck:
    -            distance = club_amt
    -
    -        # angle
    -        # For all strokes, there's a possible "drift" of 4 degrees
    -        # a hooks or slice increases the angle between 5-10 degrees,
    -        # hook uses negative degrees
    -        angle = random.randint(0, 5)
    -        if (flags & slice_) == slice_:
    -            angle = random.randint(5, 11)
    -        if (flags & hook) == hook:
    -            angle = 0 - random.randint(5, 11)
    -        if (flags & luck) == luck:
    -            angle = 0
    -
    -        plot = self.plot_ball(self.ball, distance, angle)
    -        # calculate a new location
    -        if (flags & luck) == luck and plot.y > 0:
    -            plot.y = 2
    -
    -        flags = self.find_ball(
    -            Ball(plot.x, plot.y, plot.offline, GameObjType.BALL), flags
    -        )
    -
    -        self.interpret_results(plot, flags)
    -
    -    def plot_ball(self, ball: Ball, stroke_distance: float, degrees_off: float) -> Plot:
    -        cup_vector = Point(0, -1)
    -        rad_from_cup = math.atan2(ball.Y, ball.X) - math.atan2(
    -            cup_vector.y, cup_vector.x
    -        )
    -        rad_from_ball = rad_from_cup - math.pi
    -
    -        hypotenuse = stroke_distance
    -        adjacent = math.cos(rad_from_ball + to_radians(degrees_off)) * hypotenuse
    -        opposite = math.sqrt(math.pow(hypotenuse, 2) - math.pow(adjacent, 2))
    -
    -        new_pos: Point
    -        if to_degrees_360(rad_from_ball + to_radians(degrees_off)) > 180:
    -            new_pos = Point(int(ball.X - opposite), int(ball.Y - adjacent))
    -        else:
    -            new_pos = Point(int(ball.X + opposite), int(ball.Y - adjacent))
    -
    -        return Plot(new_pos.x, new_pos.y, int(opposite))
    -
    -    def interpret_results(self, plot: Plot, flags: int) -> None:
    -        cup_distance: int = int(
    -            get_distance(
    -                Point(plot.x, plot.y),
    -                Point(self.hole_geometry.cup.X, self.hole_geometry.cup.Y),
    -            )
    -        )
    -        travel_distance: int = int(
    -            get_distance(Point(plot.x, plot.y), Point(self.ball.X, self.ball.Y))
    -        )
    -
    -        print(" ")
    -
    -        if (flags & ace) == ace:
    -            print("Hole in One! You aced it.")
    -            self.score_card_record_stroke(Ball(0, 0, 0, GameObjType.BALL))
    -            self.report_current_score()
    -            return
    -
    -        if (flags & in_trees) == in_trees:
    -            print("Your ball is lost in the trees. Take a penalty stroke.")
    -            self.score_card_record_stroke(self.ball)
    -            self.tee_up()
    -            return
    -
    -        if (flags & in_water) == in_water:
    -            if odds(50):
    -                msg = "Your ball has gone to a watery grave."
    -            else:
    -                msg = "Your ball is lost in the water."
    -            print(f"{msg} Take a penalty stroke.")
    -            self.score_card_record_stroke(self.ball)
    -            self.tee_up()
    -            return
    -
    -        if (flags & out_of_bounds) == out_of_bounds:
    -            print("Out of bounds. Take a penalty stroke.")
    -            self.score_card_record_stroke(self.ball)
    -            self.tee_up()
    -            return
    -
    -        if (flags & dub) == dub:
    -            print("You dubbed it.")
    -            self.score_card_record_stroke(self.ball)
    -            self.tee_up()
    -            return
    -
    -        if (flags & in_cup) == in_cup:
    -            msg = "You holed it." if odds(50) else "It's in!"
    -            print(msg)
    -            self.score_card_record_stroke(Ball(plot.x, plot.y, 0, GameObjType.BALL))
    -            self.report_current_score()
    -            return
    -
    -        if (flags & slice_) == slice_ and flags & on_green != on_green:
    -            bad = "badly" if (flags & out_of_bounds) == out_of_bounds else ""
    -            print(f"You sliced{bad}: {plot.offline} yards offline.")
    -
    -        if (flags & hook) == hook and flags & on_green != on_green:
    -            bad = "badly" if (flags & out_of_bounds) == out_of_bounds else ""
    -            print(f"You hooked{bad}: {plot.offline} yards offline.")
    -
    -        if self.stroke_num > 1:
    -            prev_ball = self.score_card_get_previous_stroke()
    -            d1 = get_distance(
    -                Point(prev_ball.X, prev_ball.Y),
    -                Point(self.hole_geometry.cup.X, self.hole_geometry.cup.Y),
    -            )
    -            d2 = cup_distance
    -            if d2 > d1:
    -                print("Too much club.")
    -
    -        if (flags & in_rough) == in_rough:
    -            print("You're in the rough.")
    -
    -        if (flags & in_sand) == in_sand:
    -            print("You're in a sand trap.")
    -
    -        if (flags & on_green) == on_green:
    -            if cup_distance < 4:
    -                pd = f"{str(cup_distance * 3)} feet"
    -            else:
    -                pd = f"{cup_distance} yards"
    -            print(f"You're on the green. It's {pd} from the pin.")
    -
    -        if ((flags & on_fairway) == on_fairway) or ((flags & in_rough) == in_rough):
    -            print(
    -                f"Shot went {travel_distance} yards. "
    -                f"It's {cup_distance} yards from the cup."
    -            )
    -
    -        self.score_card_record_stroke(Ball(plot.x, plot.y, 0, GameObjType.BALL))
    -
    -        self.ball = Ball(plot.x, plot.y, 0, GameObjType.BALL)
    -
    -        self.tee_up()
    -
    -    def report_current_score(self) -> None:
    -        par = CourseInfo[self.hole_num].par
    -        if len(self.score_card[self.hole_num]) == par + 1:
    -            print("A bogey. One above par.")
    -        if len(self.score_card[self.hole_num]) == par:
    -            print("Par. Nice.")
    -        if len(self.score_card[self.hole_num]) == (par - 1):
    -            print("A birdie! One below par.")
    -        if len(self.score_card[self.hole_num]) == (par - 2):
    -            print("An Eagle! Two below par.")
    -        if len(self.score_card[self.hole_num]) == (par - 3):
    -            print("Double Eagle! Unbelievable.")
    -
    -        total_par: int = sum(CourseInfo[i].par for i in range(1, self.hole_num + 1))
    -        print(" ")
    -        print("-----------------------------------------------------")
    -        hole_str = "holes" if self.hole_num > 1 else "hole"
    -        print(
    -            f" Total par for {self.hole_num} {hole_str} is: {total_par}. "
    -            f"Your total is: {self.score_card_get_total()}."
    -        )
    -        print("-----------------------------------------------------")
    -        print(" ")
    -
    -        if self.hole_num == 18:
    -            self.game_over()
    -        else:
    -            time.sleep(2)
    -            self.new_hole()
    -
    -    def find_ball(self, ball: Ball, flags: int) -> int:
    -        if self.is_on_fairway(ball) and not self.is_on_green(ball):
    -            flags |= on_fairway
    -        if self.is_on_green(ball):
    -            flags |= on_green
    -        if self.is_in_rough(ball):
    -            flags |= in_rough
    -        if self.is_out_of_bounds(ball):
    -            flags |= out_of_bounds
    -        if self.is_in_hazard(ball, GameObjType.WATER):
    -            flags |= in_water
    -        if self.is_in_hazard(ball, GameObjType.TREES):
    -            flags |= in_trees
    -        if self.is_in_hazard(ball, GameObjType.SAND):
    -            flags |= in_sand
    -
    -        if ball.Y < 0:
    -            flags |= passed_cup
    -
    -        # less than 2, it's in the cup
    -        d = get_distance(
    -            Point(ball.X, ball.Y),
    -            Point(self.hole_geometry.cup.X, self.hole_geometry.cup.Y),
    -        )
    -        if d < 2:
    -            flags |= in_cup
    -
    -        return flags
    -
    -    def is_on_fairway(self, ball: Ball) -> bool:
    -        return is_in_rectangle(ball, self.hole_geometry.fairway)
    -
    -    def is_on_green(self, ball: Ball) -> bool:
    -        d = get_distance(
    -            Point(ball.X, ball.Y),
    -            Point(self.hole_geometry.cup.X, self.hole_geometry.cup.Y),
    -        )
    -        return d < self.hole_geometry.green.Radius
    -
    -    def hazard_hit(self, h: Hazard, ball: Ball, hazard: GameObjType) -> bool:
    -        d = get_distance(Point(ball.X, ball.Y), Point(h.X, h.Y))
    -        return d < h.Radius and h.Type == hazard
    -
    -    def is_in_hazard(self, ball: Ball, hazard: GameObjType) -> bool:
    -        result: bool = False
    -        for h in self.hole_geometry.hazards:
    -            result = result and self.hazard_hit(h, ball, hazard)
    -        return result
    -
    -    def is_in_rough(self, ball: Ball) -> bool:
    -        return is_in_rectangle(ball, self.hole_geometry.rough) and (
    -            not is_in_rectangle(ball, self.hole_geometry.fairway)
    -        )
    -
    -    def is_out_of_bounds(self, ball: Ball) -> bool:
    -        return (not self.is_on_fairway(ball)) and (not self.is_in_rough(ball))
    -
    -    def score_card_start_new_hole(self) -> None:
    -        self.score_card.append([])
    -
    -    def score_card_record_stroke(self, ball: Ball) -> None:
    -        clone = Ball(ball.X, ball.Y, 0, GameObjType.BALL)
    -        self.score_card[self.hole_num].append(clone)
    -
    -    def score_card_get_previous_stroke(self) -> Ball:
    -        return self.score_card[self.hole_num][len(self.score_card[self.hole_num]) - 1]
    -
    -    def score_card_get_total(self) -> int:
    -        total: int = sum(len(h) for h in self.score_card)
    -        return total
    -
    -    def ask(
    -        self, question: str, min_: int, max_: int, callback: Callable[[int], Any]
    -    ) -> None:
    -        # input from console is always an integer passed to a callback
    -        # or "quit" to end game
    -        print(question)
    -        i = input().strip().lower()
    -        if i == "quit":
    -            self.quit_game()
    -            return
    -        if i == "bag":
    -            self.review_bag()
    -
    -        try:
    -            n = int(i)
    -            success = True
    -        except Exception:
    -            success = False
    -            n = 0
    -
    -        if success and n >= min_ and n <= max_:
    -            callback(n)
    -        else:
    -            self.ask(question, min_, max_, callback)
    -
    -    def review_bag(self) -> None:
    -        print(" ")
    -        print("  #     Club      Average Yardage")
    -        print("-----------------------------------")
    -        print("  1    Driver           250")
    -        print("  2    3 Wood           225")
    -        print("  3    5 Wood           200")
    -        print("  4    Hybrid           190")
    -        print("  5    4 Iron           170")
    -        print("  6    7 Iron           150")
    -        print("  7    9 Iron           125")
    -        print("  8    Pitching wedge   110")
    -        print("  9    Sand wedge        75")
    -        print(" 10    Putter            10")
    -        print(" ")
    -
    -    def quit_game(self) -> None:
    -        print("\nLooks like rain. Goodbye!\n")
    -        return
    -
    -    def game_over(self) -> None:
    -        net = self.score_card_get_total() - self.handicap
    -        print("Good game!")
    -        print(f"Your net score is: {net}")
    -        print("Let's visit the pro shop...")
    -        print(" ")
    -        return
    -
    -
    -if __name__ == "__main__":
    -    Golf()
    diff --git a/39_Golf/vbnet/Golf.sln b/39_Golf/vbnet/Golf.sln
    deleted file mode 100644
    index 6698c79f3..000000000
    --- a/39_Golf/vbnet/Golf.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 1a20f8314..000000000
    --- a/39_Golf/vbnet/Golf.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Golf
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/40_Gomoko/README.md b/40_Gomoko/README.md
    index 9276ede2d..9b6ad6b6c 100644
    --- a/40_Gomoko/README.md
    +++ b/40_Gomoko/README.md
    @@ -14,7 +14,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/40_Gomoko/csharp/Gomoko.csproj b/40_Gomoko/csharp/Gomoko.csproj
    deleted file mode 100644
    index d3fe4757c..000000000
    --- a/40_Gomoko/csharp/Gomoko.csproj
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    diff --git a/40_Gomoko/csharp/Gomoko.sln b/40_Gomoko/csharp/Gomoko.sln
    deleted file mode 100644
    index 84182037e..000000000
    --- a/40_Gomoko/csharp/Gomoko.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/gomoko.bas b/40_Gomoko/gomoko.bas
    index d57c10a1b..662cca132 100644
    --- a/40_Gomoko/gomoko.bas
    +++ b/40_Gomoko/gomoko.bas
    @@ -28,7 +28,7 @@
     440 A(I,J)=1
     500 REM *** COMPUTER TRIES AN INTELLIGENT MOVE ***
     510 FOR E=-1 TO 1: FOR F=-1 TO 1: IF E+F-E*F=0 THEN 590
    -540 X=I+E: Y=J+F: GOSUB 910
    +540 X=I+F: Y=J+F: GOSUB 910
     570 IF L=0 THEN 590
     580 IF A(X,Y)=1 THEN 710
     590 NEXT F: NEXT E
    diff --git a/40_Gomoko/java/Gomoko.java b/40_Gomoko/java/Gomoko.java
    index 75600b2a5..64ad7c748 100644
    --- a/40_Gomoko/java/Gomoko.java
    +++ b/40_Gomoko/java/Gomoko.java
    @@ -208,3 +208,4 @@ public String toString() {
     	}
     
     }
    +
    diff --git a/40_Gomoko/javascript/gomoko.html b/40_Gomoko/javascript/gomoko.html
    index e316ff9b0..adbfd6918 100644
    --- a/40_Gomoko/javascript/gomoko.html
    +++ b/40_Gomoko/javascript/gomoko.html
    @@ -1,10 +1,9 @@
     
     
     GOMOKO
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/40_Gomoko/javascript/gomoko.js b/40_Gomoko/javascript/gomoko.js
    index 7d57c64ef..662feabbf 100644
    --- a/40_Gomoko/javascript/gomoko.js
    +++ b/40_Gomoko/javascript/gomoko.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/40_Gomoko/kotlin/README.md b/40_Gomoko/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/40_Gomoko/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/40_Gomoko/lua/README.md b/40_Gomoko/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/40_Gomoko/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/40_Gomoko/pascal/README.md b/40_Gomoko/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/40_Gomoko/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/40_Gomoko/perl/gomoko.pl b/40_Gomoko/perl/gomoko.pl
    index 891e4e186..9bd2f3db3 100644
    --- a/40_Gomoko/perl/gomoko.pl
    +++ b/40_Gomoko/perl/gomoko.pl
    @@ -112,8 +112,10 @@ sub ValidMove {
     	if ($Board[$X][$Y]!=0) {
     		if ($Val==1) { print "SQUARE OCCUPIED. TRY AGAIN...\n"; }
     		return 0;
    -		}
    +		}	
     
     	#$Board[$X][$Y]= $Val;
     	return 1;
     	}
    +
    +
    diff --git a/40_Gomoko/python/Gomoko.py b/40_Gomoko/python/Gomoko.py
    deleted file mode 100644
    index cc4930a3e..000000000
    --- a/40_Gomoko/python/Gomoko.py
    +++ /dev/null
    @@ -1,136 +0,0 @@
    -import random
    -from typing import Any, List, Tuple
    -
    -
    -def print_board(A: List[List[Any]], n: int) -> None:
    -    """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
    -    return _I >= 1 and _I <= _N and _J >= 1 and _J <= _N
    -
    -
    -def print_banner() -> None:
    -    print(" " * 33 + "GOMOKU")
    -    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n")
    -    print("WELCOME TO THE ORIENTAL GAME OF GOMOKO.\n")
    -    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'.\n")
    -    print("THE COMPUTER DOES NOT KEEP TRACK OF WHO HAS WON.")
    -    print("TO END THE GAME, TYPE -1,-1 FOR YOUR MOVE.\n")
    -
    -
    -def get_board_dimensions() -> int:
    -    n = 0
    -    while True:
    -        n = int(input("WHAT IS YOUR BOARD SIZE (MIN 7/ MAX 19)? "))
    -        if n >= 7 and n <= 19:
    -            break
    -        print("I SAID, THE MINIMUM IS 7, THE MAXIMUM IS 19.")
    -        print()
    -    return n
    -
    -
    -def get_move() -> Tuple[int, int]:
    -    while True:
    -        xy = input("YOUR PLAY (I,J)? ")
    -        print()
    -        x_str, y_str = xy.split(",")
    -        try:
    -            x = int(x_str)
    -            y = int(y_str)
    -        except Exception:
    -            print("ILLEGAL MOVE.  TRY AGAIN...")
    -            continue
    -        return x, y
    -
    -
    -def initialize_board(n: int) -> List[List[int]]:
    -    # Initialize the board
    -    board = []
    -    for _x in range(n):
    -        sub_a = [0 for _y in range(n)]
    -        board.append(sub_a)
    -    return board
    -
    -
    -def main() -> None:
    -    print_banner()
    -
    -    while True:
    -        n = get_board_dimensions()
    -        board = initialize_board(n)
    -
    -        print()
    -        print()
    -        print("WE ALTERNATE MOVES. YOU GO FIRST...")
    -        print()
    -
    -        while True:
    -            x, y = get_move()
    -            if x == -1:
    -                break
    -            elif not check_move(x, y, n):
    -                print("ILLEGAL MOVE.  TRY AGAIN...")
    -            elif board[x - 1][y - 1] == 0:
    -                board[x - 1][y - 1] = 1
    -                # COMPUTER TRIES AN INTELLIGENT MOVE
    -                skip_ef_loop = False
    -                for E in range(-1, 2):
    -                    for F in range(-1, 2):
    -                        if E + F - E * F == 0 or skip_ef_loop:
    -                            continue
    -                        X = x + F
    -                        Y = y + F
    -                        if not check_move(X, Y, n):
    -                            continue
    -                        if board[X - 1][Y - 1] == 1:
    -                            skip_ef_loop = True
    -                            X = x - E
    -                            Y = y - F
    -                            if not check_move(X, Y, n):  # 750
    -                                while True:  # 610
    -                                    X = random.randint(1, n)
    -                                    Y = random.randint(1, n)
    -                                    if (
    -                                        check_move(X, Y, n)
    -                                        and board[X - 1][Y - 1] == 0
    -                                    ):
    -                                        board[X - 1][Y - 1] = 2
    -                                        print_board(board, n)
    -                                        break
    -                            elif board[X - 1][Y - 1] == 0:
    -                                board[X - 1][Y - 1] = 2
    -                                print_board(board, n)
    -                            else:
    -                                while True:
    -                                    X = random.randint(1, n)
    -                                    Y = random.randint(1, n)
    -                                    if (
    -                                        check_move(X, Y, n)
    -                                        and board[X - 1][Y - 1] == 0
    -                                    ):
    -                                        board[X - 1][Y - 1] = 2
    -                                        print_board(board, n)
    -                                        break
    -            else:
    -                print("SQUARE OCCUPIED.  TRY AGAIN...")
    -        print()
    -        print("THANKS FOR THE GAME!!")
    -        repeat = int(input("PLAY AGAIN (1 FOR YES, 0 FOR NO)? "))
    -        if repeat == 0:
    -            break
    -
    -
    -if __name__ == "__main__":
    -    main()
    diff --git a/40_Gomoko/rust/Cargo.lock b/40_Gomoko/rust/Cargo.lock
    deleted file mode 100644
    index 7ef3861c9..000000000
    --- a/40_Gomoko/rust/Cargo.lock
    +++ /dev/null
    @@ -1,411 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 4
    -
    -[[package]]
    -name = "anyhow"
    -version = "1.0.102"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
    -
    -[[package]]
    -name = "bitflags"
    -version = "2.11.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af"
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
    -
    -[[package]]
    -name = "chacha20"
    -version = "0.10.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601"
    -dependencies = [
    - "cfg-if",
    - "cpufeatures",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "cpufeatures"
    -version = "0.3.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201"
    -dependencies = [
    - "libc",
    -]
    -
    -[[package]]
    -name = "equivalent"
    -version = "1.0.2"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
    -
    -[[package]]
    -name = "foldhash"
    -version = "0.1.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.4.2"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "r-efi",
    - "rand_core",
    - "wasip2",
    - "wasip3",
    -]
    -
    -[[package]]
    -name = "gomoku"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "hashbrown"
    -version = "0.15.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
    -dependencies = [
    - "foldhash",
    -]
    -
    -[[package]]
    -name = "hashbrown"
    -version = "0.16.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
    -
    -[[package]]
    -name = "heck"
    -version = "0.5.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
    -
    -[[package]]
    -name = "id-arena"
    -version = "2.3.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
    -
    -[[package]]
    -name = "indexmap"
    -version = "2.13.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017"
    -dependencies = [
    - "equivalent",
    - "hashbrown 0.16.1",
    - "serde",
    - "serde_core",
    -]
    -
    -[[package]]
    -name = "itoa"
    -version = "1.0.18"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
    -
    -[[package]]
    -name = "leb128fmt"
    -version = "0.1.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.183"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d"
    -
    -[[package]]
    -name = "log"
    -version = "0.4.29"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
    -
    -[[package]]
    -name = "memchr"
    -version = "2.8.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
    -
    -[[package]]
    -name = "prettyplease"
    -version = "0.2.37"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
    -dependencies = [
    - "proc-macro2",
    - "syn",
    -]
    -
    -[[package]]
    -name = "proc-macro2"
    -version = "1.0.106"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
    -dependencies = [
    - "unicode-ident",
    -]
    -
    -[[package]]
    -name = "quote"
    -version = "1.0.45"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
    -dependencies = [
    - "proc-macro2",
    -]
    -
    -[[package]]
    -name = "r-efi"
    -version = "6.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
    -
    -[[package]]
    -name = "rand"
    -version = "0.10.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "bc266eb313df6c5c09c1c7b1fbe2510961e5bcd3add930c1e31f7ed9da0feff8"
    -dependencies = [
    - "chacha20",
    - "getrandom",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.10.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba"
    -
    -[[package]]
    -name = "semver"
    -version = "1.0.27"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
    -
    -[[package]]
    -name = "serde"
    -version = "1.0.228"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
    -dependencies = [
    - "serde_core",
    -]
    -
    -[[package]]
    -name = "serde_core"
    -version = "1.0.228"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
    -dependencies = [
    - "serde_derive",
    -]
    -
    -[[package]]
    -name = "serde_derive"
    -version = "1.0.228"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
    -dependencies = [
    - "proc-macro2",
    - "quote",
    - "syn",
    -]
    -
    -[[package]]
    -name = "serde_json"
    -version = "1.0.149"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
    -dependencies = [
    - "itoa",
    - "memchr",
    - "serde",
    - "serde_core",
    - "zmij",
    -]
    -
    -[[package]]
    -name = "syn"
    -version = "2.0.117"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
    -dependencies = [
    - "proc-macro2",
    - "quote",
    - "unicode-ident",
    -]
    -
    -[[package]]
    -name = "unicode-ident"
    -version = "1.0.24"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
    -
    -[[package]]
    -name = "unicode-xid"
    -version = "0.2.6"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
    -
    -[[package]]
    -name = "wasip2"
    -version = "1.0.2+wasi-0.2.9"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5"
    -dependencies = [
    - "wit-bindgen",
    -]
    -
    -[[package]]
    -name = "wasip3"
    -version = "0.4.0+wasi-0.3.0-rc-2026-01-06"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5"
    -dependencies = [
    - "wit-bindgen",
    -]
    -
    -[[package]]
    -name = "wasm-encoder"
    -version = "0.244.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319"
    -dependencies = [
    - "leb128fmt",
    - "wasmparser",
    -]
    -
    -[[package]]
    -name = "wasm-metadata"
    -version = "0.244.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909"
    -dependencies = [
    - "anyhow",
    - "indexmap",
    - "wasm-encoder",
    - "wasmparser",
    -]
    -
    -[[package]]
    -name = "wasmparser"
    -version = "0.244.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe"
    -dependencies = [
    - "bitflags",
    - "hashbrown 0.15.5",
    - "indexmap",
    - "semver",
    -]
    -
    -[[package]]
    -name = "wit-bindgen"
    -version = "0.51.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
    -dependencies = [
    - "wit-bindgen-rust-macro",
    -]
    -
    -[[package]]
    -name = "wit-bindgen-core"
    -version = "0.51.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc"
    -dependencies = [
    - "anyhow",
    - "heck",
    - "wit-parser",
    -]
    -
    -[[package]]
    -name = "wit-bindgen-rust"
    -version = "0.51.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21"
    -dependencies = [
    - "anyhow",
    - "heck",
    - "indexmap",
    - "prettyplease",
    - "syn",
    - "wasm-metadata",
    - "wit-bindgen-core",
    - "wit-component",
    -]
    -
    -[[package]]
    -name = "wit-bindgen-rust-macro"
    -version = "0.51.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a"
    -dependencies = [
    - "anyhow",
    - "prettyplease",
    - "proc-macro2",
    - "quote",
    - "syn",
    - "wit-bindgen-core",
    - "wit-bindgen-rust",
    -]
    -
    -[[package]]
    -name = "wit-component"
    -version = "0.244.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2"
    -dependencies = [
    - "anyhow",
    - "bitflags",
    - "indexmap",
    - "log",
    - "serde",
    - "serde_derive",
    - "serde_json",
    - "wasm-encoder",
    - "wasm-metadata",
    - "wasmparser",
    - "wit-parser",
    -]
    -
    -[[package]]
    -name = "wit-parser"
    -version = "0.244.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736"
    -dependencies = [
    - "anyhow",
    - "id-arena",
    - "indexmap",
    - "log",
    - "semver",
    - "serde",
    - "serde_derive",
    - "serde_json",
    - "unicode-xid",
    - "wasmparser",
    -]
    -
    -[[package]]
    -name = "zmij"
    -version = "1.0.21"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
    diff --git a/40_Gomoko/rust/Cargo.toml b/40_Gomoko/rust/Cargo.toml
    deleted file mode 100644
    index 6874f0e90..000000000
    --- a/40_Gomoko/rust/Cargo.toml
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -[package]
    -name = "gomoku"
    -version = "0.1.0"
    -edition = "2024"
    -
    -[dependencies]
    -rand = "0.10.0"
    diff --git a/40_Gomoko/rust/src/main.rs b/40_Gomoko/rust/src/main.rs
    deleted file mode 100644
    index 53ec70ae9..000000000
    --- a/40_Gomoko/rust/src/main.rs
    +++ /dev/null
    @@ -1,209 +0,0 @@
    -use std::{
    -    fmt::Display,
    -    io::{BufRead, Write},
    -};
    -
    -use rand::prelude::*;
    -
    -fn main() {
    -    println!("{:>33}GOMOKU", "");
    -    println!("{:>15}CREATIVE COMPUTING  MORISSTOWN, NEW JERSEY\n\n\n", "");
    -
    -    println!("Welcome to the oriental game of Gomoku.");
    -    println!("\nThe game is played on an N by N grid of a size");
    -    println!("that you specify. During your play, you may cover one grid");
    -    println!("intersection with a marker. The object of the game is to get");
    -    println!("5 adjacent markers in a row -- horizontally, vertically, or");
    -    println!("diagonally. On the board diagram, your moves are marked");
    -    println!("with a '1' and the computer moves with a '2'.");
    -    println!("\nThe computer does not keep track of who has won.");
    -    println!("To end the game, type -1,-1 for your move.\n");
    -
    -    loop {
    -        let size = get_board_size();
    -
    -        // Line 210: initialize the game board
    -        let mut game = Gomoku::new(size);
    -
    -        if !game.play() {
    -            break;
    -        }
    -    }
    -}
    -
    -struct Gomoku {
    -    board: Vec>,
    -    size: isize,
    -}
    -
    -impl Gomoku {
    -    fn new(size: usize) -> Self {
    -        Self {
    -            board: vec![vec![Piece::Empty; size]; size],
    -            size: size as isize,
    -        }
    -    }
    -
    -    fn get_player_move(&self) -> (isize, isize) {
    -        let mut first_attempt = true;
    -        loop {
    -            if !first_attempt {
    -                println!("Illegal move. Try again...");
    -            }
    -            first_attempt = false;
    -            let response = prompt_for_input("Your play (I,J)");
    -            let Some((i, j)) = response.split_once(',') else {
    -                continue;
    -            };
    -            let Ok(i) = i.trim().parse::() else {
    -                continue;
    -            };
    -            let Ok(j) = j.trim().parse::() else {
    -                continue;
    -            };
    -            if i == -1 {
    -                return (-1, -1);
    -            }
    -            if i < 1 || i > self.size || j < 1 || j > self.size {
    -                continue;
    -            }
    -            return (i, j);
    -        }
    -    }
    -
    -    fn play(&mut self) -> bool {
    -        let mut rng = rand::rng();
    -
    -        // Line 300
    -        println!("\nWe alternate moves. You go first...\n");
    -
    -        'next_move: loop {
    -            println!("{self}");
    -
    -            // Line 310
    -            let (i, j) = self.get_player_move();
    -
    -            // Line 320
    -            if i == -1 {
    -                break;
    -            }
    -
    -            let pos = self.get(i, j);
    -
    -            match *pos {
    -                Piece::Empty => *pos = Piece::Human,
    -                Piece::Computer | Piece::Human => {
    -                    println!("Square occupied. Try again...");
    -                    continue;
    -                }
    -            }
    -
    -            // Lines 500-590: The computer tries an intelligent move
    -            for e in -1..=1 {
    -                for f in -1..=1 {
    -                    // Line 510:
    -                    if e == 0 && f == 0 {
    -                        continue;
    -                    }
    -
    -                    // Line 540:
    -                    let x = i + e;
    -                    let y = j + f;
    -                    if x < 1 || x > self.size || y < 1 || y > self.size {
    -                        continue;
    -                    }
    -
    -                    let pos = self.get(x, y);
    -                    if *pos == Piece::Human {
    -                        let x = i - e;
    -                        let y = j - f;
    -                        if x < 1 || x > self.size || y < 1 || y > self.size {
    -                            continue;
    -                        }
    -                        let pos = self.get(x, y);
    -                        if *pos == Piece::Empty {
    -                            *pos = Piece::Computer;
    -                            continue 'next_move;
    -                        }
    -                    }
    -                }
    -            }
    -
    -            // Lines 600-660: The computer tries a random move
    -            loop {
    -                let x = rng.random_range(1..=self.size as usize) as isize;
    -                let y = rng.random_range(1..=self.size as usize) as isize;
    -                let pos = self.get(x, y);
    -                if *pos == Piece::Empty {
    -                    *pos = Piece::Computer;
    -                    continue 'next_move;
    -                }
    -            }
    -        }
    -
    -        // Lines 980-999
    -        println!("\nThanks for the game!!");
    -        prompt_for_input("Play again (1 for yes, 0 for no)") == "1"
    -    }
    -
    -    fn get(&mut self, i: isize, j: isize) -> &mut Piece {
    -        &mut self.board[i as usize - 1][j as usize - 1]
    -    }
    -}
    -
    -impl Display for Gomoku {
    -    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    -        for row in &self.board {
    -            for col in row {
    -                write!(f, "{col}")?;
    -            }
    -            writeln!(f)?;
    -        }
    -        Ok(())
    -    }
    -}
    -
    -#[derive(Clone, Copy, PartialEq)]
    -enum Piece {
    -    Empty,
    -    Computer,
    -    Human,
    -}
    -
    -impl Display for Piece {
    -    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    -        write!(
    -            f,
    -            " {}",
    -            match self {
    -                Piece::Empty => '0',
    -                Piece::Computer => '2',
    -                Piece::Human => '1',
    -            }
    -        )
    -    }
    -}
    -
    -fn prompt_for_input>(prompt: S) -> String {
    -    print!("{}? ", prompt.as_ref());
    -    let mut lock = std::io::stdout().lock();
    -    let _ = lock.flush();
    -
    -    let mut buffer = String::new();
    -    let stdin = std::io::stdin();
    -    let mut handle = stdin.lock();
    -    let _ = handle.read_line(&mut buffer);
    -    buffer.trim().to_string()
    -}
    -
    -fn get_board_size() -> usize {
    -    loop {
    -        let buffer = prompt_for_input("What is your board size (min 7/ max 19)");
    -        if let Ok(val) = buffer.trim().parse::()
    -            && (7..=19).contains(&val)
    -        {
    -            return val;
    -        }
    -        println!("I said, the minimum is 7, the maximum is 19.");
    -    }
    -}
    diff --git a/40_Gomoko/vbnet/Gomoko.sln b/40_Gomoko/vbnet/Gomoko.sln
    deleted file mode 100644
    index fb1c4673e..000000000
    --- a/40_Gomoko/vbnet/Gomoko.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 5350e7616..000000000
    --- a/40_Gomoko/vbnet/Gomoko.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Gomoko
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/41_Guess/README.md b/41_Guess/README.md
    index e43da0da6..cb041db70 100644
    --- a/41_Guess/README.md
    +++ b/41_Guess/README.md
    @@ -14,7 +14,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/41_Guess/csharp/Game.cs b/41_Guess/csharp/Game.cs
    deleted file mode 100644
    index 57ae071a8..000000000
    --- a/41_Guess/csharp/Game.cs
    +++ /dev/null
    @@ -1,78 +0,0 @@
    -namespace Guess;
    -
    -internal class Game
    -{
    -    private readonly IReadWrite _io;
    -    private readonly IRandom _random;
    -
    -    public Game(IReadWrite io, IRandom random)
    -    {
    -        _io = io;
    -        _random = random;
    -    }
    -
    -    public void Play()
    -    {
    -        while (true)
    -        {
    -            _io.Write(Streams.Introduction);
    -
    -            var limit = _io.ReadNumber(Prompts.Limit);
    -            _io.WriteLine();
    -
    -            // There's a bug here that exists in the original code. 
    -            // If the limit entered is <= 0 then the program will crash.
    -            var targetGuessCount = checked((int)Math.Log2(limit) + 1);
    -
    -            PlayGuessingRounds(limit, targetGuessCount);
    -
    -            _io.Write(Streams.BlankLines);
    -        }
    -    }
    -
    -    private void PlayGuessingRounds(float limit, int targetGuessCount)
    -    {
    -        while (true)
    -        {
    -            _io.WriteLine(Formats.Thinking, limit);
    -
    -            // There's a bug here that exists in the original code. If a non-integer is entered as the limit
    -            // then it's possible for the secret number to be the next integer greater than the limit.
    -            var secretNumber = (int)_random.NextFloat(limit) + 1;
    -
    -            var guessCount = 0;
    -
    -            while (true)
    -            {
    -                var guess = _io.ReadNumber("");
    -                if (guess <= 0) { return; }
    -                guessCount++;
    -                if (IsGuessCorrect(guess, secretNumber)) { break; }
    -            }
    -
    -            ReportResult(guessCount, targetGuessCount);
    -
    -            _io.Write(Streams.BlankLines);
    -        }
    -    }
    -
    -    private bool IsGuessCorrect(float guess, int secretNumber)
    -    {
    -        if (guess < secretNumber) { _io.Write(Streams.TooLow); }
    -        if (guess > secretNumber) { _io.Write(Streams.TooHigh); }
    -
    -        return guess == secretNumber;
    -    }
    -
    -    private void ReportResult(int guessCount, int targetGuessCount)
    -    {
    -        _io.WriteLine(Formats.ThatsIt, guessCount);
    -        _io.WriteLine(
    -            (guessCount - targetGuessCount) switch
    -            {
    -                < 0 => Strings.VeryGood,
    -                0 => Strings.Good,
    -                > 0 => string.Format(Formats.ShouldHave, targetGuessCount)
    -            });
    -    }
    -}
    \ No newline at end of file
    diff --git a/41_Guess/csharp/Guess.csproj b/41_Guess/csharp/Guess.csproj
    deleted file mode 100644
    index 3870320c9..000000000
    --- a/41_Guess/csharp/Guess.csproj
    +++ /dev/null
    @@ -1,17 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    -  
    -    
    -  
    -
    -  
    -    
    -  
    -
    diff --git a/41_Guess/csharp/Guess.sln b/41_Guess/csharp/Guess.sln
    deleted file mode 100644
    index c66492560..000000000
    --- a/41_Guess/csharp/Guess.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/csharp/Program.cs b/41_Guess/csharp/Program.cs
    deleted file mode 100644
    index 73ab09dd0..000000000
    --- a/41_Guess/csharp/Program.cs
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -global using Games.Common.IO;
    -global using Games.Common.Randomness;
    -global using static Guess.Resources.Resource;  
    -
    -using Guess;
    -
    -new Game(new ConsoleIO(), new RandomNumberGenerator()).Play();
    diff --git a/41_Guess/csharp/Resources/BlankLines.txt b/41_Guess/csharp/Resources/BlankLines.txt
    deleted file mode 100644
    index 3f2ff2d6c..000000000
    --- a/41_Guess/csharp/Resources/BlankLines.txt
    +++ /dev/null
    @@ -1,5 +0,0 @@
    -
    -
    -
    -
    -
    diff --git a/41_Guess/csharp/Resources/Good.txt b/41_Guess/csharp/Resources/Good.txt
    deleted file mode 100644
    index 989dfa38a..000000000
    --- a/41_Guess/csharp/Resources/Good.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Good.
    \ No newline at end of file
    diff --git a/41_Guess/csharp/Resources/Introduction.txt b/41_Guess/csharp/Resources/Introduction.txt
    deleted file mode 100644
    index ed6794920..000000000
    --- a/41_Guess/csharp/Resources/Introduction.txt
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -                                 Guess
    -               Creative Computing  Morristown, New Jersey
    -
    -
    -
    -This is a number guessing game. I'll think
    -of a number between 1 and any limit you want.
    -The you have to guess what it is.
    -
    diff --git a/41_Guess/csharp/Resources/Limit.txt b/41_Guess/csharp/Resources/Limit.txt
    deleted file mode 100644
    index 62e698a60..000000000
    --- a/41_Guess/csharp/Resources/Limit.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -What limit do you want
    \ No newline at end of file
    diff --git a/41_Guess/csharp/Resources/Resource.cs b/41_Guess/csharp/Resources/Resource.cs
    deleted file mode 100644
    index d42477e2e..000000000
    --- a/41_Guess/csharp/Resources/Resource.cs
    +++ /dev/null
    @@ -1,44 +0,0 @@
    -using System.Reflection;
    -using System.Runtime.CompilerServices;
    -
    -namespace Guess.Resources;
    -
    -internal static class Resource
    -{
    -    internal static class Streams
    -    {
    -        public static Stream Introduction => GetStream();
    -        public static Stream TooLow => GetStream();
    -        public static Stream TooHigh => GetStream();
    -        public static Stream BlankLines => GetStream();
    -    }
    -
    -    internal static class Formats
    -    {
    -        public static string Thinking => GetString();
    -        public static string ThatsIt => GetString();
    -        public static string ShouldHave => GetString();
    -    }
    -
    -    internal static class Prompts
    -    {
    -        public static string Limit => GetString();
    -    }
    -
    -    internal static class Strings
    -    {
    -        public static string Good => GetString();
    -        public static string VeryGood => GetString();
    -    }
    -
    -    private static string GetString([CallerMemberName] string? name = null)
    -    {
    -        using var stream = GetStream(name);
    -        using var reader = new StreamReader(stream);
    -        return reader.ReadToEnd();
    -    }
    -
    -    private static Stream GetStream([CallerMemberName] string? name = null) =>
    -        Assembly.GetExecutingAssembly().GetManifestResourceStream($"{typeof(Resource).Namespace}.{name}.txt")
    -            ?? throw new Exception($"Could not find embedded resource stream '{name}'.");
    -}
    \ No newline at end of file
    diff --git a/41_Guess/csharp/Resources/ShouldHave.txt b/41_Guess/csharp/Resources/ShouldHave.txt
    deleted file mode 100644
    index 848035889..000000000
    --- a/41_Guess/csharp/Resources/ShouldHave.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -You should have been able to get it in only {0}
    \ No newline at end of file
    diff --git a/41_Guess/csharp/Resources/ThatsIt.txt b/41_Guess/csharp/Resources/ThatsIt.txt
    deleted file mode 100644
    index 61f78c436..000000000
    --- a/41_Guess/csharp/Resources/ThatsIt.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -That's it! You got it in {0} tries.
    \ No newline at end of file
    diff --git a/41_Guess/csharp/Resources/Thinking.txt b/41_Guess/csharp/Resources/Thinking.txt
    deleted file mode 100644
    index 8f1bbac7c..000000000
    --- a/41_Guess/csharp/Resources/Thinking.txt
    +++ /dev/null
    @@ -1,2 +0,0 @@
    -I'm thinking of a number between 1 and {0}
    -Now you try to guess what it is.
    \ No newline at end of file
    diff --git a/41_Guess/csharp/Resources/TooHigh.txt b/41_Guess/csharp/Resources/TooHigh.txt
    deleted file mode 100644
    index bb4ee4edc..000000000
    --- a/41_Guess/csharp/Resources/TooHigh.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Too high. Try a smaller answer.
    \ No newline at end of file
    diff --git a/41_Guess/csharp/Resources/TooLow.txt b/41_Guess/csharp/Resources/TooLow.txt
    deleted file mode 100644
    index 4bc1776f3..000000000
    --- a/41_Guess/csharp/Resources/TooLow.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Too low. Try a bigger answer.
    \ No newline at end of file
    diff --git a/41_Guess/csharp/Resources/VeryGood.txt b/41_Guess/csharp/Resources/VeryGood.txt
    deleted file mode 100644
    index 606150c7e..000000000
    --- a/41_Guess/csharp/Resources/VeryGood.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Very good.
    \ No newline at end of file
    diff --git a/41_Guess/javascript/guess.html b/41_Guess/javascript/guess.html
    index 54a5510b5..22a1bee00 100644
    --- a/41_Guess/javascript/guess.html
    +++ b/41_Guess/javascript/guess.html
    @@ -1,10 +1,9 @@
     
     
     GUESS
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/41_Guess/javascript/guess.js b/41_Guess/javascript/guess.js
    index a9e25edbf..e313169cd 100644
    --- a/41_Guess/javascript/guess.js
    +++ b/41_Guess/javascript/guess.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    @@ -61,7 +61,7 @@ async function main()
             print("OF A NUMBER BETWEEN 1 AND ANY LIMIT YOU WANT.\n");
             print("THEN YOU HAVE TO GUESS WHAT IT IS.\n");
             print("\n");
    -
    +        
             print("WHAT LIMIT DO YOU WANT");
             l = parseInt(await input());
             print("\n");
    diff --git a/41_Guess/kotlin/README.md b/41_Guess/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/41_Guess/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/41_Guess/lua/README.md b/41_Guess/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/41_Guess/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/41_Guess/pascal/README.md b/41_Guess/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/41_Guess/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/41_Guess/perl/guess.pl b/41_Guess/perl/guess.pl
    index 0aac6c523..f16a3e843 100755
    --- a/41_Guess/perl/guess.pl
    +++ b/41_Guess/perl/guess.pl
    @@ -48,3 +48,5 @@ sub ENTERS { #GOSUB 70
     		}
     	return;
     	}
    +
    +
    diff --git a/41_Guess/python/guess.py b/41_Guess/python/guess.py
    index 8c1775f44..98cde9b7d 100644
    --- a/41_Guess/python/guess.py
    +++ b/41_Guess/python/guess.py
    @@ -1,22 +1,24 @@
    -"""
    -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.
    -"""
    +########################################################
    +#
    +# 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.
    +#
    +########################################################
     
     # Altough the introduction says that the computer chooses
     # a number between 0 and any limit, it actually chooses
    @@ -26,14 +28,13 @@
     
     from math import log
     from random import random
    -from typing import Tuple
     
     
    -def insert_whitespaces() -> None:
    +def insert_whitespaces():
         print("\n\n\n\n\n")
     
     
    -def limit_set() -> Tuple[int, int]:
    +def limit_set():
         print("                   Guess")
         print("Creative Computing  Morristown, New Jersey")
         print("\n\n\n")
    @@ -54,47 +55,42 @@ def limit_set() -> Tuple[int, int]:
         return limit, limit_goal
     
     
    -def main() -> None:
    -    limit, limit_goal = limit_set()
    -    while True:
    -        guess_count = 1
    -        still_guessing = True
    -        won = False
    -        my_guess = int(limit * random() + 1)
    -
    -        print(f"I'm thinking of a number between 1 and {limit}")
    -        print("Now you try to guess what it is.")
    -
    -        while still_guessing:
    -            n = int(input())
    -
    -            if n < 0:
    -                break
    -
    -            insert_whitespaces()
    -            if n < my_guess:
    -                print("Too low. Try a bigger answer")
    -                guess_count += 1
    -            elif n > my_guess:
    -                print("Too high. Try a smaller answer")
    -                guess_count += 1
    -            else:
    -                print(f"That's it! You got it in {guess_count} tries")
    -                won = True
    -                still_guessing = False
    -
    -        if won:
    -            if guess_count < limit_goal:
    -                print("Very good.")
    -            elif guess_count == limit_goal:
    -                print("Good.")
    -            else:
    -                print(f"You should have been able to get it in only {limit_goal}")
    -            insert_whitespaces()
    -        else:
    -            insert_whitespaces()
    -            limit, limit_goal = limit_set()
    +limit, limit_goal = limit_set()
    +while True:
    +    guess_count = 1
    +    still_guessing = True
    +    won = False
    +    my_guess = int(limit * random() + 1)
    +
    +    print("I'm thinking of a number between 1 and {}".format(limit))
    +    print("Now you try to guess what it is.")
    +
    +    while still_guessing:
    +        n = int(input())
     
    +        if n < 0:
    +            break
     
    -if __name__ == "__main__":
    -    main()
    +        insert_whitespaces()
    +        if n < my_guess:
    +            print("Too low. Try a bigger answer")
    +            guess_count += 1
    +        elif n > my_guess:
    +            print("Too high. Try a smaller answer")
    +            guess_count += 1
    +        else:
    +            print("That's it! You got it in {} tries".format(guess_count))
    +            won = True
    +            still_guessing = False
    +
    +    if won:
    +        if guess_count < limit_goal:
    +            print("Very good.")
    +        elif guess_count == limit_goal:
    +            print("Good.")
    +        else:
    +            print("You should have been able to get it in only {}".format(limit_goal))
    +        insert_whitespaces()
    +    else:
    +        insert_whitespaces()
    +        limit, limit_goal = limit_set()
    diff --git a/41_Guess/ruby/guess.rb b/41_Guess/ruby/guess.rb
    deleted file mode 100644
    index cf2deea23..000000000
    --- a/41_Guess/ruby/guess.rb
    +++ /dev/null
    @@ -1,48 +0,0 @@
    -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
    diff --git a/41_Guess/rust/Cargo.lock b/41_Guess/rust/Cargo.lock
    deleted file mode 100644
    index 5329dedd1..000000000
    --- a/41_Guess/rust/Cargo.lock
    +++ /dev/null
    @@ -1,75 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.10"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "guess"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.147"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/41_Guess/rust/Cargo.toml b/41_Guess/rust/Cargo.toml
    deleted file mode 100644
    index ecedf3b63..000000000
    --- a/41_Guess/rust/Cargo.toml
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -[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"
    diff --git a/41_Guess/rust/README.md b/41_Guess/rust/README.md
    deleted file mode 100644
    index fc6468b9f..000000000
    --- a/41_Guess/rust/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Rust](https://www.rust-lang.org/)
    diff --git a/41_Guess/rust/src/main.rs b/41_Guess/rust/src/main.rs
    deleted file mode 100644
    index ad0681cb3..000000000
    --- a/41_Guess/rust/src/main.rs
    +++ /dev/null
    @@ -1,109 +0,0 @@
    -//#######################################################
    -//
    -// 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;
    -// 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
    -}
    diff --git a/41_Guess/vbnet/Guess.sln b/41_Guess/vbnet/Guess.sln
    deleted file mode 100644
    index 2238b0bea..000000000
    --- a/41_Guess/vbnet/Guess.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 8a5fe396c..000000000
    --- a/41_Guess/vbnet/Guess.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Guess
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/42_Gunner/README.md b/42_Gunner/README.md
    index 6f4f6a9af..0621ec54c 100644
    --- a/42_Gunner/README.md
    +++ b/42_Gunner/README.md
    @@ -14,7 +14,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/42_Gunner/csharp/Gunner.csproj b/42_Gunner/csharp/Gunner.csproj
    deleted file mode 100644
    index 74abf5c97..000000000
    --- a/42_Gunner/csharp/Gunner.csproj
    +++ /dev/null
    @@ -1,10 +0,0 @@
    -
    -
    -  
    -    Exe
    -    net6.0
    -    enable
    -    enable
    -  
    -
    -
    diff --git a/42_Gunner/csharp/Gunner.sln b/42_Gunner/csharp/Gunner.sln
    deleted file mode 100644
    index 5fadb3597..000000000
    --- a/42_Gunner/csharp/Gunner.sln
    +++ /dev/null
    @@ -1,25 +0,0 @@
    -
    -Microsoft Visual Studio Solution File, Format Version 12.00
    -# Visual Studio Version 16
    -VisualStudioVersion = 16.0.30114.105
    -MinimumVisualStudioVersion = 10.0.40219.1
    -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(ExtensibilityGlobals) = postSolution
    -		SolutionGuid = {09C668DA-38D4-4EF4-9FCA-EB1FF9EF6067}
    -	EndGlobalSection
    -EndGlobal
    diff --git a/42_Gunner/csharp/Program.cs b/42_Gunner/csharp/Program.cs
    index c9e458829..f93c57d5b 100644
    --- a/42_Gunner/csharp/Program.cs
    +++ b/42_Gunner/csharp/Program.cs
    @@ -5,7 +5,7 @@ class Program
             static void Main(string[] args)
             {
                 PrintIntro();
    -
    +        
                 string keepPlaying = "Y";
     
                 while (keepPlaying == "Y") {
    @@ -43,7 +43,7 @@ static void PlayGame()
                         Console.WriteLine($"TOTAL ROUNDS EXPENDED WERE:{totalAttempts}");
     
                         if (amountOfGames < 4) {
    -                        Console.WriteLine("THE FORWARD OBSERVER HAS SIGHTED MORE ENEMY ACTIVITY...");
    +                        Console.WriteLine("THE FORWARD OBSERVER HAS SIGHTED MORE ENEMY ACTIVITY...");                    
                         } else {
                             if (totalAttempts > 18) {
                                 PrintReturnToBase();
    @@ -111,7 +111,7 @@ static int GetElevation()
                 return elevation;
             }
     
    -        static void PrintIntro()
    +        static void PrintIntro() 
             {
                 Console.WriteLine(new String(' ', 30) + "GUNNER");
                 Console.WriteLine(new String(' ', 15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY" + Environment.NewLine + Environment.NewLine + Environment.NewLine);
    diff --git a/93_23_Matches/csharp/csharp.csproj b/42_Gunner/csharp/csharp.csproj
    similarity index 100%
    rename from 93_23_Matches/csharp/csharp.csproj
    rename to 42_Gunner/csharp/csharp.csproj
    diff --git a/42_Gunner/javascript/gunner.html b/42_Gunner/javascript/gunner.html
    index 47c70fc39..431c9064e 100644
    --- a/42_Gunner/javascript/gunner.html
    +++ b/42_Gunner/javascript/gunner.html
    @@ -1,10 +1,9 @@
     
     
     GUNNER
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/42_Gunner/javascript/gunner.js b/42_Gunner/javascript/gunner.js
    index 892617dea..64a427a15 100644
    --- a/42_Gunner/javascript/gunner.js
    +++ b/42_Gunner/javascript/gunner.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    @@ -67,7 +67,7 @@ async function main()
                 s = 0;
                 print("DISTANCE TO THE TARGET IS " + t + " YARDS.\n");
                 print("\n");
    -
    +            
                 while (1) {
                     print("\n");
                     print("ELEVATION");
    diff --git a/42_Gunner/kotlin/README.md b/42_Gunner/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/42_Gunner/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/42_Gunner/lua/README.md b/42_Gunner/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/42_Gunner/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/42_Gunner/pascal/README.md b/42_Gunner/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/42_Gunner/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/42_Gunner/perl/gunner.pl b/42_Gunner/perl/gunner.pl
    deleted file mode 100755
    index 9df20deb4..000000000
    --- a/42_Gunner/perl/gunner.pl
    +++ /dev/null
    @@ -1,81 +0,0 @@
    -#!/usr/bin/perl
    -
    -# Gunner program in Perl
    -#   Required extensive restructuring to remove all of the GOTO's.
    -# Translated by Kevin Brannen (kbrannen)
    -
    -use strict;
    -use warnings;
    -
    -# globals
    -my $Max_range = int(40000*rand(1)+20000);
    -my $Total_shots = 0;
    -my $Games = 0;
    -
    -print "\n";
    -print " " x 30, "GUNNER\n";
    -print " " x 15, "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n";
    -
    -print "YOU ARE THE OFFICER-IN-CHARGE, GIVING ORDERS TO A GUN\n";
    -print "CREW, TELLING THEM THE DEGREES OF ELEVATION YOU ESTIMATE\n";
    -print "WILL PLACE A PROJECTILE ON TARGET.  A HIT WITHIN 100 YARDS\n";
    -print "OF THE TARGET WILL DESTROY IT.\n\n";
    -print "MAXIMUM RANGE OF YOUR GUN IS $Max_range YARDS.\n\n";
    -
    -GAME: while (1)
    -{
    -    my $target_dist = int($Max_range * (.1 + .8 * rand(1)));
    -    my $shots = 0;
    -    print "DISTANCE TO THE TARGET IS $target_dist YARDS.\n\n";
    -    while (1)
    -    {
    -        my $elevation = get_elevation(); # in degrees
    -        $shots++;
    -        my $dist = int($target_dist - ($Max_range * sin(2 * $elevation / 57.3)));
    -        if (abs($dist) < 100)
    -        {
    -            print "*** TARGET DESTROYED ***  $shots ROUNDS OF AMMUNITION EXPENDED.\n";
    -            $Total_shots += $shots;
    -            if ($Games++ == 4)
    -            {
    -                print "\n\nTOTAL ROUNDS EXPENDED WERE: $Total_shots\n";
    -                if ($Total_shots > 18) { print "BETTER GO BACK TO FORT SILL FOR REFRESHER TRAINING!\n"; }
    -                else                   { print "NICE SHOOTING !!\n"; }
    -                last;
    -            }
    -            print "\nTHE FORWARD OBSERVER HAS SIGHTED MORE ENEMY ACTIVITY...\n";
    -            next GAME;
    -        }
    -        if ($dist > 100) { print "SHORT OF TARGET BY ", abs($dist)," YARDS.\n"; }
    -        else             { print "OVER TARGET BY ", abs($dist), " YARDS.\n"; }
    -
    -        if ($shots >= 5)
    -        {
    -            print "\nBOOM !!!!   YOU HAVE JUST BEEN DESTROYED BY THE ENEMY.\n\n\n\n"; 
    -            print "BETTER GO BACK TO FORT SILL FOR REFRESHER TRAINING!\n";
    -            last;
    -        }
    -    }
    -
    -    print "\nTRY AGAIN (Y OR N): ";
    -    chomp(my $ans=uc(<>));
    -    if ($ans ne "Y") { last; }
    -    else             { $Games = 0; $Total_shots = 0; }
    -}
    -
    -print "\nOK.  RETURN TO BASE CAMP.\n";
    -
    -####################################
    -
    -sub get_elevation
    -{
    -    my $elevation;
    -    while (1)
    -    {
    -        print "\nELEVATION: ";
    -        chomp($elevation = <>);
    -        if    ($elevation > 89) { print "MAXIMUM ELEVATION IS 89 DEGREES.\n"; }
    -        elsif ($elevation < 1)  { print "MINIMUM ELEVATION IS ONE DEGREE.\n"; }
    -        else                    { return $elevation; }
    -    }
    -}
    diff --git a/42_Gunner/python/gunner.py b/42_Gunner/python/gunner.py
    index 6c6d19c72..e12c0e56d 100644
    --- a/42_Gunner/python/gunner.py
    +++ b/42_Gunner/python/gunner.py
    @@ -6,73 +6,71 @@
     from random import random
     
     
    -def gunner() -> None:
    -    gun_range = int(40000 * random() + 20000)
    +def gunner():
    +    R = int(40000 * random() + 20000)
     
    -    print("\nMAXIMUM RANGE OF YOUR GUN IS", gun_range, "YARDS.")
    +    print("\nMAXIMUM RANGE OF YOUR GUN IS", R, "YARDS.")
     
    -    killed_enemies = 0
    +    Z = 0
         S1 = 0
     
         while True:
    -        target_distance = int(gun_range * (0.1 + 0.8 * random()))
    -        shots = 0
    +        T = int(R * (.1 + .8 * random()))
    +        S = 0
     
    -        print("\nDISTANCE TO THE TARGET IS", target_distance, "YARDS.")
    +        print("\nDISTANCE TO THE TARGET IS", T, "YARDS.")
     
             while True:
    -            elevation = float(input("\n\nELEVATION? "))
    +            B = float(input("\n\nELEVATION? "))
     
    -            if elevation > 89:
    +            if B > 89:
                     print("MAXIMUM ELEVATION IS 89 DEGREES.")
                     continue
     
    -            if elevation < 1:
    +            if B < 1:
                     print("MINIMUM ELEVATION IS ONE DEGREE.")
                     continue
     
    -            shots += 1
    -
    -            if shots < 6:
    -                B2 = 2 * elevation / 57.3
    -                shot_impact = gun_range * sin(B2)
    -                shot_proximity = target_distance - shot_impact
    -                shot_proximity_int = int(shot_proximity)
    -
    -                if abs(shot_proximity_int) < 100:
    -                    print(
    -                        "*** TARGET DESTROYED *** ",
    -                        shots,
    -                        "ROUNDS OF AMMUNITION EXPENDED.",
    -                    )
    -                    S1 += shots
    -                    if killed_enemies == 4:
    +            S += 1
    +
    +            if S < 6:
    +                B2 = 2 * B / 57.3
    +                I = R * sin(B2)
    +                X = T - I
    +                E = int(X)
    +
    +                if (abs(E) < 100):
    +                    print("*** TARGET DESTROYED *** ", S, "ROUNDS OF AMMUNITION EXPENDED.")
    +                    S1 += S
    +                    if Z == 4:
                             print("\n\nTOTAL ROUNDS EXPENDED WERE: ", S1)
                             if S1 > 18:
                                 print("BETTER GO BACK TO FORT SILL FOR REFRESHER TRAINING!")
    +                            return
                             else:
                                 print("NICE SHOOTING !!")
    -                        return
    +                            return
                         else:
    -                        killed_enemies += 1
    -                        print(
    -                            "\nTHE FORWARD OBSERVER HAS SIGHTED MORE ENEMY ACTIVITY..."
    -                        )
    +                        Z += 1
    +                        print("\nTHE FORWARD OBSERVER HAS SIGHTED MORE ENEMY ACTIVITY...")
                             break
    -                elif shot_proximity_int > 100:
    -                    print("SHORT OF TARGET BY", abs(shot_proximity_int), "YARDS.")
                     else:
    -                    print("OVER TARGET BY", abs(shot_proximity_int), "YARDS.")
    +                    if E > 100:
    +                        print("SHORT OF TARGET BY", abs(E), "YARDS.")
    +                    else:
    +                        print("OVER TARGET BY", abs(E), "YARDS.")
                 else:
                     print("\nBOOM !!!!   YOU HAVE JUST BEEN DESTROYED BY THE ENEMY.\n\n\n")
                     print("BETTER GO BACK TO FORT SILL FOR REFRESHER TRAINING!")
                     return
     
     
    -def main() -> None:
    +if __name__ == "__main__":
         print(" " * 33 + "GUNNER")
         print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
    +
         print("\n\n\n")
    +
         print("YOU ARE THE OFFICER-IN-CHARGE, GIVING ORDERS TO A GUN")
         print("CREW, TELLING THEM THE DEGREES OF ELEVATION YOU ESTIMATE")
         print("WILL PLACE A PROJECTILE ON TARGET.  A HIT WITHIN 100 YARDS")
    @@ -81,11 +79,7 @@ def main() -> None:
         while True:
             gunner()
     
    -        not_again = input("TRY AGAIN (Y OR N)? ").upper() != "Y"
    -        if not_again:
    +        Y = input("TRY AGAIN (Y OR N)? ")
    +        if (Y != "Y"):
                 print("\nOK.  RETURN TO BASE CAMP.")
                 break
    -
    -
    -if __name__ == "__main__":
    -    main()
    diff --git a/42_Gunner/rust/Cargo.lock b/42_Gunner/rust/Cargo.lock
    deleted file mode 100644
    index 1bc05f192..000000000
    --- a/42_Gunner/rust/Cargo.lock
    +++ /dev/null
    @@ -1,411 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 4
    -
    -[[package]]
    -name = "anyhow"
    -version = "1.0.101"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5f0e0fee31ef5ed1ba1316088939cea399010ed7731dba877ed44aeb407a75ea"
    -
    -[[package]]
    -name = "bitflags"
    -version = "2.10.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
    -
    -[[package]]
    -name = "chacha20"
    -version = "0.10.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601"
    -dependencies = [
    - "cfg-if",
    - "cpufeatures",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "cpufeatures"
    -version = "0.3.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201"
    -dependencies = [
    - "libc",
    -]
    -
    -[[package]]
    -name = "equivalent"
    -version = "1.0.2"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
    -
    -[[package]]
    -name = "foldhash"
    -version = "0.1.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.4.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "r-efi",
    - "rand_core",
    - "wasip2",
    - "wasip3",
    -]
    -
    -[[package]]
    -name = "gunner"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "hashbrown"
    -version = "0.15.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
    -dependencies = [
    - "foldhash",
    -]
    -
    -[[package]]
    -name = "hashbrown"
    -version = "0.16.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
    -
    -[[package]]
    -name = "heck"
    -version = "0.5.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
    -
    -[[package]]
    -name = "id-arena"
    -version = "2.3.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
    -
    -[[package]]
    -name = "indexmap"
    -version = "2.13.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017"
    -dependencies = [
    - "equivalent",
    - "hashbrown 0.16.1",
    - "serde",
    - "serde_core",
    -]
    -
    -[[package]]
    -name = "itoa"
    -version = "1.0.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
    -
    -[[package]]
    -name = "leb128fmt"
    -version = "0.1.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.182"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112"
    -
    -[[package]]
    -name = "log"
    -version = "0.4.29"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
    -
    -[[package]]
    -name = "memchr"
    -version = "2.8.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
    -
    -[[package]]
    -name = "prettyplease"
    -version = "0.2.37"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
    -dependencies = [
    - "proc-macro2",
    - "syn",
    -]
    -
    -[[package]]
    -name = "proc-macro2"
    -version = "1.0.106"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
    -dependencies = [
    - "unicode-ident",
    -]
    -
    -[[package]]
    -name = "quote"
    -version = "1.0.44"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4"
    -dependencies = [
    - "proc-macro2",
    -]
    -
    -[[package]]
    -name = "r-efi"
    -version = "5.3.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
    -
    -[[package]]
    -name = "rand"
    -version = "0.10.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "bc266eb313df6c5c09c1c7b1fbe2510961e5bcd3add930c1e31f7ed9da0feff8"
    -dependencies = [
    - "chacha20",
    - "getrandom",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.10.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba"
    -
    -[[package]]
    -name = "semver"
    -version = "1.0.27"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
    -
    -[[package]]
    -name = "serde"
    -version = "1.0.228"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
    -dependencies = [
    - "serde_core",
    -]
    -
    -[[package]]
    -name = "serde_core"
    -version = "1.0.228"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
    -dependencies = [
    - "serde_derive",
    -]
    -
    -[[package]]
    -name = "serde_derive"
    -version = "1.0.228"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
    -dependencies = [
    - "proc-macro2",
    - "quote",
    - "syn",
    -]
    -
    -[[package]]
    -name = "serde_json"
    -version = "1.0.149"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
    -dependencies = [
    - "itoa",
    - "memchr",
    - "serde",
    - "serde_core",
    - "zmij",
    -]
    -
    -[[package]]
    -name = "syn"
    -version = "2.0.115"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "6e614ed320ac28113fa64972c4262d5dbc89deacdfd00c34a3e4cea073243c12"
    -dependencies = [
    - "proc-macro2",
    - "quote",
    - "unicode-ident",
    -]
    -
    -[[package]]
    -name = "unicode-ident"
    -version = "1.0.23"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "537dd038a89878be9b64dd4bd1b260315c1bb94f4d784956b81e27a088d9a09e"
    -
    -[[package]]
    -name = "unicode-xid"
    -version = "0.2.6"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
    -
    -[[package]]
    -name = "wasip2"
    -version = "1.0.2+wasi-0.2.9"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5"
    -dependencies = [
    - "wit-bindgen",
    -]
    -
    -[[package]]
    -name = "wasip3"
    -version = "0.4.0+wasi-0.3.0-rc-2026-01-06"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5"
    -dependencies = [
    - "wit-bindgen",
    -]
    -
    -[[package]]
    -name = "wasm-encoder"
    -version = "0.244.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319"
    -dependencies = [
    - "leb128fmt",
    - "wasmparser",
    -]
    -
    -[[package]]
    -name = "wasm-metadata"
    -version = "0.244.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909"
    -dependencies = [
    - "anyhow",
    - "indexmap",
    - "wasm-encoder",
    - "wasmparser",
    -]
    -
    -[[package]]
    -name = "wasmparser"
    -version = "0.244.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe"
    -dependencies = [
    - "bitflags",
    - "hashbrown 0.15.5",
    - "indexmap",
    - "semver",
    -]
    -
    -[[package]]
    -name = "wit-bindgen"
    -version = "0.51.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
    -dependencies = [
    - "wit-bindgen-rust-macro",
    -]
    -
    -[[package]]
    -name = "wit-bindgen-core"
    -version = "0.51.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc"
    -dependencies = [
    - "anyhow",
    - "heck",
    - "wit-parser",
    -]
    -
    -[[package]]
    -name = "wit-bindgen-rust"
    -version = "0.51.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21"
    -dependencies = [
    - "anyhow",
    - "heck",
    - "indexmap",
    - "prettyplease",
    - "syn",
    - "wasm-metadata",
    - "wit-bindgen-core",
    - "wit-component",
    -]
    -
    -[[package]]
    -name = "wit-bindgen-rust-macro"
    -version = "0.51.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a"
    -dependencies = [
    - "anyhow",
    - "prettyplease",
    - "proc-macro2",
    - "quote",
    - "syn",
    - "wit-bindgen-core",
    - "wit-bindgen-rust",
    -]
    -
    -[[package]]
    -name = "wit-component"
    -version = "0.244.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2"
    -dependencies = [
    - "anyhow",
    - "bitflags",
    - "indexmap",
    - "log",
    - "serde",
    - "serde_derive",
    - "serde_json",
    - "wasm-encoder",
    - "wasm-metadata",
    - "wasmparser",
    - "wit-parser",
    -]
    -
    -[[package]]
    -name = "wit-parser"
    -version = "0.244.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736"
    -dependencies = [
    - "anyhow",
    - "id-arena",
    - "indexmap",
    - "log",
    - "semver",
    - "serde",
    - "serde_derive",
    - "serde_json",
    - "unicode-xid",
    - "wasmparser",
    -]
    -
    -[[package]]
    -name = "zmij"
    -version = "1.0.21"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
    diff --git a/42_Gunner/rust/Cargo.toml b/42_Gunner/rust/Cargo.toml
    deleted file mode 100644
    index cfc8f092c..000000000
    --- a/42_Gunner/rust/Cargo.toml
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -[package]
    -name = "gunner"
    -version = "0.1.0"
    -edition = "2024"
    -
    -[dependencies]
    -rand = "0.10.0"
    diff --git a/42_Gunner/rust/src/main.rs b/42_Gunner/rust/src/main.rs
    deleted file mode 100644
    index 1f4547d53..000000000
    --- a/42_Gunner/rust/src/main.rs
    +++ /dev/null
    @@ -1,161 +0,0 @@
    -use rand::{RngExt, rngs::ThreadRng};
    -use std::{
    -    convert::Infallible,
    -    io::{self, BufRead, Write},
    -    str::FromStr,
    -};
    -
    -fn main() {
    -    println!("{:>30}GUNNER", "");
    -    println!("{:>15}CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY", "");
    -    println!("\n\n");
    -
    -    println!("You are the officer-in-charge, giving orders to a gun");
    -    println!("crew, telling them the degrees of elevation you estimate");
    -    println!("will place a projectile on target.  A hit wihtin 100 yards");
    -    println!("of the target will destroy it.\n");
    -
    -    let mut game = GunnerGame::new();
    -    while game.run() == PlayAgain::Yes {
    -        // do nothing -- just loop around and call game.run() again
    -    }
    -}
    -
    -struct GunnerGame {
    -    gun_range: usize, // each game has different range for the gun. "R" in the basic code
    -    targets_destroyed: isize, // the "Z" counter in basic
    -    total_rounds: isize, // how many rounds were fired across all targets. "S1" in basic
    -    rng: ThreadRng,   // our PRNG
    -}
    -
    -impl GunnerGame {
    -    fn new() -> Self {
    -        let mut rng = rand::rng();
    -        let gun_range = rng.random_range(20_000..=60_000);
    -
    -        Self {
    -            gun_range,
    -            rng,
    -            targets_destroyed: 0,
    -            total_rounds: 0,
    -        }
    -    }
    -
    -    fn run(&mut self) -> PlayAgain {
    -        println!("Maximum range of your gun is {} yards.\n", self.gun_range);
    -
    -        for targets in 0..4 {
    -            if targets > 0 {
    -                // After the first round, we want to let the user know that there's
    -                // another target in sight
    -                println!("\nThe forward observer has sighted more enemy activity...");
    -            }
    -
    -            // let the player try to destroy it
    -            let target_destroyed = self.handle_target();
    -
    -            if !target_destroyed {
    -                println!("\nBoom !!!!   You have just been destroyed by the enemy.\n\n\n");
    -                println!("Better go back to Fort Sill for refresher training!");
    -
    -                println!();
    -                break;
    -            } else {
    -                self.targets_destroyed += 1;
    -            }
    -        }
    -
    -        // only display success message if all targets were destroyed
    -        if self.targets_destroyed == 4 {
    -            println!("\n\nTotal rounds expended were: {}", self.total_rounds);
    -            if self.total_rounds <= 18 {
    -                println!("Nice shooting !!");
    -            }
    -        }
    -
    -        println!("\n");
    -        get_input("Try again (Y or N)")
    -    }
    -
    -    fn handle_target(&mut self) -> bool {
    -        let target_distance =
    -            ((self.gun_range as f32) * (0.1 + 0.8 * self.rng.random::())) as isize;
    -
    -        println!("Distance to the target is {target_distance} yards.\n\n");
    -
    -        // The player gets 5 shots. On the 6th shot we still ask for an elevation,
    -        // but then report that they've been destroyed.
    -        for shots_fired in 1..=6 {
    -            let elevation = loop {
    -                let elevation: f32 = get_input("Elevation");
    -
    -                // Let the player know how well they did.
    -                if elevation < 1.0 {
    -                    println!("Miniumum elevation is one degree.");
    -                } else if elevation > 89.0 {
    -                    println!("Maximum elevation is 89 degrees.");
    -                } else {
    -                    break elevation;
    -                }
    -            };
    -
    -            // Only allow the player to destroy the target with the first 5 shots. The
    -            // sixth is ignored.
    -            if shots_fired < 6 {
    -                let angle = 2.0 * elevation / 57.3;
    -                let intersection = self.gun_range as f32 * angle.sin();
    -                let delta = target_distance - (intersection as isize);
    -
    -                if delta.abs() < 100 {
    -                    println!(
    -                        "*** Target Destroyed ***  {shots_fired} rounds of ammunition expended."
    -                    );
    -                    self.total_rounds += shots_fired;
    -                    return true;
    -                } else if delta > 100 {
    -                    println!("Short of target by {delta} yards.");
    -                } else {
    -                    println!("Over target by {} yards.", delta.abs());
    -                }
    -            }
    -        }
    -
    -        false
    -    }
    -}
    -
    -#[derive(PartialEq, Eq)]
    -enum PlayAgain {
    -    Yes,
    -    No,
    -}
    -
    -impl FromStr for PlayAgain {
    -    type Err = Infallible;
    -
    -    fn from_str(line: &str) -> Result {
    -        if line.to_uppercase() == "Y" {
    -            Ok(Self::Yes)
    -        } else {
    -            Ok(Self::No)
    -        }
    -    }
    -}
    -
    -fn get_input>(prompt: S) -> R {
    -    loop {
    -        print!("{}? ", prompt.as_ref());
    -        let mut stdout = io::stdout().lock();
    -        let _ = stdout.flush();
    -
    -        let mut buffer = String::new();
    -        let stdin = std::io::stdin();
    -        let mut handle = stdin.lock();
    -        let _ = handle.read_line(&mut buffer);
    -
    -        if let Ok(result) = buffer.trim().to_string().parse::() {
    -            return result;
    -        }
    -        println!("?Re-enter");
    -    }
    -}
    diff --git a/42_Gunner/vbnet/Gunner.sln b/42_Gunner/vbnet/Gunner.sln
    deleted file mode 100644
    index 33d681264..000000000
    --- a/42_Gunner/vbnet/Gunner.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 19918a805..000000000
    --- a/42_Gunner/vbnet/Gunner.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Gunner
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/43_Hammurabi/README.md b/43_Hammurabi/README.md
    index 937044c86..c02219b17 100644
    --- a/43_Hammurabi/README.md
    +++ b/43_Hammurabi/README.md
    @@ -21,10 +21,6 @@ As published in Basic Computer Games (1978):
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
     
    -#### Porting Notes
    -
    -- Though the file name and README both spell "Hammurabi" with two M's, the program itself consistently uses only one M.
    -
     #### External Links
      - C: https://github.com/beyonddream/hamurabi
      - Rust: https://github.com/beyonddream/hamurabi.rs
    diff --git a/21_Calendar/csharp/Calendar.csproj b/43_Hammurabi/csharp/Game.csproj
    similarity index 100%
    rename from 21_Calendar/csharp/Calendar.csproj
    rename to 43_Hammurabi/csharp/Game.csproj
    diff --git a/43_Hammurabi/csharp/Hammurabi.sln b/43_Hammurabi/csharp/Hammurabi.sln
    index 7475f8fd4..feeae2122 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 17
    -VisualStudioVersion = 17.0.32014.148
    +# Visual Studio Version 16
    +VisualStudioVersion = 16.0.31129.286
     MinimumVisualStudioVersion = 10.0.40219.1
    -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hammurabi", "Hammurabi.csproj", "{2C4407AF-5ED6-4C9F-833E-35461DF7DBBB}"
    +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Game", "Game.csproj", "{20599300-7C6E-48A2-AB24-EC7CCF224A5C}"
     EndProject
     Global
     	GlobalSection(SolutionConfigurationPlatforms) = preSolution
    @@ -11,10 +11,10 @@ Global
     		Release|Any CPU = Release|Any CPU
     	EndGlobalSection
     	GlobalSection(ProjectConfigurationPlatforms) = postSolution
    -		{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
    +		{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
     	EndGlobalSection
     	GlobalSection(SolutionProperties) = preSolution
     		HideSolutionNode = FALSE
    diff --git a/43_Hammurabi/csharp/ActionResult.cs b/43_Hammurabi/csharp/src/ActionResult.cs
    similarity index 100%
    rename from 43_Hammurabi/csharp/ActionResult.cs
    rename to 43_Hammurabi/csharp/src/ActionResult.cs
    diff --git a/43_Hammurabi/csharp/Controller.cs b/43_Hammurabi/csharp/src/Controller.cs
    similarity index 100%
    rename from 43_Hammurabi/csharp/Controller.cs
    rename to 43_Hammurabi/csharp/src/Controller.cs
    diff --git a/43_Hammurabi/csharp/GameResult.cs b/43_Hammurabi/csharp/src/GameResult.cs
    similarity index 100%
    rename from 43_Hammurabi/csharp/GameResult.cs
    rename to 43_Hammurabi/csharp/src/GameResult.cs
    diff --git a/43_Hammurabi/csharp/GameState.cs b/43_Hammurabi/csharp/src/GameState.cs
    similarity index 100%
    rename from 43_Hammurabi/csharp/GameState.cs
    rename to 43_Hammurabi/csharp/src/GameState.cs
    diff --git a/43_Hammurabi/csharp/GreatOffence.cs b/43_Hammurabi/csharp/src/GreatOffence.cs
    similarity index 100%
    rename from 43_Hammurabi/csharp/GreatOffence.cs
    rename to 43_Hammurabi/csharp/src/GreatOffence.cs
    diff --git a/43_Hammurabi/csharp/PerformanceRating.cs b/43_Hammurabi/csharp/src/PerformanceRating.cs
    similarity index 100%
    rename from 43_Hammurabi/csharp/PerformanceRating.cs
    rename to 43_Hammurabi/csharp/src/PerformanceRating.cs
    diff --git a/43_Hammurabi/csharp/Program.cs b/43_Hammurabi/csharp/src/Program.cs
    similarity index 100%
    rename from 43_Hammurabi/csharp/Program.cs
    rename to 43_Hammurabi/csharp/src/Program.cs
    diff --git a/43_Hammurabi/csharp/Rules.cs b/43_Hammurabi/csharp/src/Rules.cs
    similarity index 100%
    rename from 43_Hammurabi/csharp/Rules.cs
    rename to 43_Hammurabi/csharp/src/Rules.cs
    diff --git a/43_Hammurabi/csharp/View.cs b/43_Hammurabi/csharp/src/View.cs
    similarity index 99%
    rename from 43_Hammurabi/csharp/View.cs
    rename to 43_Hammurabi/csharp/src/View.cs
    index e0c5b0545..fcfb4cd5c 100644
    --- a/43_Hammurabi/csharp/View.cs
    +++ b/43_Hammurabi/csharp/src/View.cs
    @@ -133,7 +133,7 @@ public static void ShowGameResult(GameResult result)
                         break;
                     case PerformanceRating.Bad:
                         Console.WriteLine("YOUR HEAVY-HANDED PERFORMANCE SMACKS OF NERO AND IVAN IV.");
    -                    Console.WriteLine("THE PEOPLE (REMAINING) FIND YOU AN UNPLEASANT RULER, AND,");
    +                    Console.WriteLine("THE PEOPLE (REMIANING) FIND YOU AN UNPLEASANT RULER, AND,");
                         Console.WriteLine("FRANKLY, HATE YOUR GUTS!!");
                         break;
                     case PerformanceRating.Ok:
    diff --git a/43_Hammurabi/hammurabi.bas b/43_Hammurabi/hammurabi.bas
    index e41fe4fbd..8f0998f05 100644
    --- a/43_Hammurabi/hammurabi.bas
    +++ b/43_Hammurabi/hammurabi.bas
    @@ -108,7 +108,7 @@
     900 PRINT "A FANTASTIC PERFORMANCE!!!  CHARLEMANGE, DISRAELI, AND"
     905 PRINT "JEFFERSON COMBINED COULD NOT HAVE DONE BETTER!":GOTO 990
     940 PRINT "YOUR HEAVY-HANDED PERFORMANCE SMACKS OF NERO AND IVAN IV."
    -945 PRINT "THE PEOPLE (REMAINING) FIND YOU AN UNPLEASANT RULER, AND,"
    +945 PRINT "THE PEOPLE (REMIANING) FIND YOU AN UNPLEASANT RULER, AND,"
     950 PRINT "FRANKLY, HATE YOUR GUTS!!":GOTO 990
     960 PRINT "YOUR PERFORMANCE COULD HAVE BEEN SOMEWHAT BETTER, BUT"
     965 PRINT "REALLY WASN'T TOO BAD AT ALL. ";INT(P*.8*RND(1));"PEOPLE"
    diff --git a/43_Hammurabi/javascript/hammurabi.html b/43_Hammurabi/javascript/hammurabi.html
    index cff8f00a3..2facdcb48 100644
    --- a/43_Hammurabi/javascript/hammurabi.html
    +++ b/43_Hammurabi/javascript/hammurabi.html
    @@ -1,10 +1,9 @@
     
     
     HAMMURABI
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/43_Hammurabi/javascript/hammurabi.js b/43_Hammurabi/javascript/hammurabi.js
    index ca4d471d6..285753c75 100644
    --- a/43_Hammurabi/javascript/hammurabi.js
    +++ b/43_Hammurabi/javascript/hammurabi.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    @@ -49,7 +49,7 @@ function exceeded_grain()
     {
         print("HAMURABI: THINK AGAIN.  YOU HAVE ONLY\n");
         print(s + " BUSHELS OF GRAIN.  NOW THEN,\n");
    -
    +    
     }
     
     function exceeded_acres()
    @@ -68,7 +68,7 @@ async function main()
         print("TRY YOUR HAND AT GOVERNING ANCIENT SUMERIA\n");
         print("FOR A TEN-YEAR TERM OF OFFICE.\n");
         print("\n");
    -
    +    
         d1 = 0;
         p1 = 0;
         z = 0;
    @@ -233,7 +233,7 @@ async function main()
                 print("ALSO BEEN DECLARED NATIONAL FINK!!!!\n");
             } else if (p1 > 10 || l < 9) {
                 print("YOUR HEAVY-HANDED PERFORMANCE SMACKS OF NERO AND IVAN IV.\n");
    -            print("THE PEOPLE (REMAINING) FIND YOU AN UNPLEASANT RULER, AND,\n");
    +            print("THE PEOPLE (REMIANING) FIND YOU AN UNPLEASANT RULER, AND,\n");
                 print("FRANKLY, HATE YOUR GUTS!!\n");
             } else if (p1 > 3 || l < 10) {
                 print("YOUR PERFORMANCE COULD HAVE BEEN SOMEWHAT BETTER, BUT\n");
    diff --git a/43_Hammurabi/kotlin/README.md b/43_Hammurabi/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/43_Hammurabi/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/43_Hammurabi/lua/README.md b/43_Hammurabi/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/43_Hammurabi/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/43_Hammurabi/pascal/README.md b/43_Hammurabi/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/43_Hammurabi/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/43_Hammurabi/perl/lib/BasicComputerGames/Hammurabi.pm b/43_Hammurabi/perl/lib/BasicComputerGames/Hammurabi.pm
    deleted file mode 100644
    index cfcffb343..000000000
    --- a/43_Hammurabi/perl/lib/BasicComputerGames/Hammurabi.pm
    +++ /dev/null
    @@ -1,472 +0,0 @@
    -#!/usr/bin/env perl
    -package BasicComputerGames::Hammurabi;
    -
    -use v5.24;
    -use warnings;
    -use experimental 'signatures';
    -
    -{
    -   # Quick and dirty accessors
    -   no strict 'refs';
    -   for my $feature (
    -      qw< year population store rats_toll had_plague planted
    -      production_per_acre acres new_arrivals starved status max_year fed
    -      percent_starved total_starved cost_per_acre >
    -     )
    -   {
    -      *{__PACKAGE__ . '::' . $feature} = sub ($self, @new) {
    -         $self->{$feature} = $new[0] if @new;
    -         return $self->{$feature};
    -      };
    -   } ## end for my $feature (...)
    -}
    -
    -sub new ($package, %args) {
    -   my $self = bless {
    -
    -      # These defaults can be overridden by %args
    -      population          => 100,
    -      store               => 2800,
    -      rats_toll           => 200,
    -      production_per_acre => 3,
    -      acres               => 1000,
    -      new_arrivals        => 5,
    -      fed                 => 0,
    -      max_year            => 10,
    -
    -      %args,
    -
    -      # These starting values cannot be overridden by %args
    -      status          => 'start',
    -      year            => 1,
    -      starved         => 0,
    -      total_starved   => 0,
    -      percent_starved => 0,
    -      had_plague      => 0,
    -      planted         => 0,
    -      cost_per_acre   => 0,
    -   }, $package;
    -
    -   return $self;
    -} ## end sub new
    -
    -sub step ($self, $input) {
    -   my $method = $self->can('_handle_' . $self->status);
    -   $self->$method($input);
    -}
    -
    -########################################################################
    -#
    -# All _handle_* methods below represents handlers for different states
    -# of the game, e.g. state `start` is managed by _handle_start(). Each
    -# handler receives two input arguments: an instance to the game object and
    -# the input that was collected by the UI for that particular state (if
    -# any).
    -
    -# start of the game
    -sub _handle_start ($self, $input) {
    -   $self->status('start_of_year');
    -}
    -
    -# start of each year
    -sub _handle_start_of_year ($self, $input) {
    -   $self->cost_per_acre(int(rand(10)) + 17);
    -   $self->status('advertise_cost_per_acre');
    -}
    -
    -# intermediate state to allow for printing the cost per acre, moves
    -# directly to following state
    -sub _handle_advertise_cost_per_acre ($self, $input) {
    -   $self->status('buy_acres');
    -}
    -
    -# buy acres of land, making sure to be able to cover for the cost
    -sub _handle_buy_acres ($self, $input) {
    -   return $self->status('bail_out')   if $input < 0;
    -   return $self->status('sell_acres') if $input == 0;
    -   my $cpa  = $self->cost_per_acre;
    -   my $cost = $cpa * $input;
    -   return $self->status('buy_acres_again')
    -     if $cost > $self->store;
    -   $self->acres($self->acres + $input);
    -   $self->store($self->store - $cost);
    -   return $self->status('feeding');
    -} ## end sub _handle_buy_acres
    -
    -# intermediate state to allow for notifying that the request for new
    -# acres of land could not be covered, moves directly to the following
    -# state
    -sub _handle_buy_acres_again ($self, $input) {
    -   $self->status('buy_acres');
    -}
    -
    -# sell acres of land, making sure to sell only what can be sold.
    -sub _handle_sell_acres ($self, $input) {
    -   return $self->status('bail_out')         if $input < 0;
    -   return $self->status('sell_acres_again') if $input >= $self->acres;
    -   $self->acres($self->acres - $input);
    -   $self->store($self->store + $self->cost_per_acre * $input);
    -   return $self->status('feeding');
    -} ## end sub _handle_sell_acres
    -
    -# intermediate state to allow for notifying that the request to sell
    -# acres of land could not be covered, moves directly to the following
    -# state
    -sub _handle_sell_acres_again ($self, $input) {
    -   $self->status('sell_acres');
    -}
    -
    -# feed people, making sure we have the necessary resources
    -sub _handle_feeding ($self, $input) {
    -   return $self->status('bail_out')      if $input < 0;
    -   return $self->status('feeding_again') if $input >= $self->store;
    -   $self->store($self->store - $input);
    -   $self->fed($input);
    -   $self->status('planting');
    -} ## end sub _handle_feeding
    -
    -# intermediate state to allow for notifying that the request to use
    -# bushels of grain could not be covered, moves directly to the following
    -# state
    -sub _handle_feeding_again ($self, $input) {
    -   $self->status('feeding');
    -}
    -
    -# plant crops, making sure we have the land, the seeds and the workers.
    -sub _handle_planting ($self, $input) {
    -   return $self->status('bail_out') if $input < 0;
    -
    -   return $self->status('planting_fail_acres') if $input > $self->acres;
    -
    -   my $store = $self->store;
    -   return $self->status('planting_fail_seeds')
    -     if $store < int($input / 2);
    -
    -   return $self->status('planting_fail_people')
    -     if $input >= $self->population * 10;
    -
    -   $self->planted($input);
    -   $self->store($store - int($input / 2));
    -   $self->status('simulate_year');
    -} ## end sub _handle_planting
    -
    -# complain about lack of land to cover the planting request
    -sub _handle_planting_fail_acres ($self, $input) {
    -   $self->status('planting');
    -}
    -
    -# complain about lack of seeds to cover the planting request
    -sub _handle_planting_fail_seeds ($self, $input) {
    -   $self->status('planting');
    -}
    -
    -# complain about lack of workers to cover the planting request
    -sub _handle_planting_fail_people ($self, $input) {
    -   $self->status('planting');
    -}
    -
    -# simulate the rest of the year after all inputs, i.e. rats, crops, etc.
    -sub _handle_simulate_year ($self, $input) {
    -   my $store = $self->store;
    -
    -   # rats might take a toll during the year
    -   my $c         = 1 + int(rand(5));
    -   my $rats_toll = $c % 2 ? 0 : int($store / $c);
    -   $self->rats_toll($rats_toll);
    -
    -   # planting also gains us grain after the harvest
    -   my $ppa     = $self->production_per_acre(1 + int(rand(5)));
    -   my $harvest = $ppa * $self->planted;
    -
    -   # let's update the stored seeds finally
    -   $self->store($store += $harvest - $rats_toll);
    -
    -   # let's see how population evolved
    -   my $population = $self->population;
    -
    -   # how many people had full tummies
    -   my $fed_people = int($self->fed / 20);
    -   my $starved    = $population - $fed_people;
    -   $starved = 0 if $starved < 0;    # cannot create people from seeds
    -   $self->starved($starved);
    -
    -   # check preliminary exit condition for a very bad year
    -   return $self->status('impeach_year')
    -     if $starved > $population * 0.45;
    -
    -   # update statistics
    -   $self->total_starved($self->total_starved + $starved);
    -   my $perc = $self->percent_starved;
    -   my $year = $self->year;
    -   $perc = (($year - 1) * $perc + $starved * 100 / $population) / $year;
    -   $self->percent_starved($perc);
    -
    -   # babies
    -   my $acres    = $self->acres;
    -   my $rand     = 1 + int(rand(5));
    -   my $arrivals = $self->new_arrivals(
    -      int(1 + $rand * (20 * $acres + $store) / $population / 100));
    -
    -   $population += $arrivals - $starved;
    -
    -   # HORROS, A 15% CHANCE OF PLAGUE
    -   my $had_plague = $self->had_plague(rand(1) < 0.15);
    -   $population = int($population / 2) if $had_plague;
    -
    -   # save population for next round
    -   $self->population($population);
    -
    -   # advance to next year
    -   $self->year(++$year);
    -   if ($year > $self->max_year) {
    -      $self->status('summary');
    -   }
    -   else {
    -      $self->status('start_of_year');
    -   }
    -} ## end sub _handle_simulate_year
    -
    -# this is a transition after the impeachment message
    -sub _handle_impeach_year ($self, $input) {
    -   $self->status('goodbye');
    -}
    -
    -# this is a transition after printing the summary
    -sub _handle_summary ($self, $input) {
    -   $self->status('goodbye');
    -}
    -
    -# this is a transition after printing the final salutation message
    -sub _handle_goodbye ($self, $input) {
    -   $self->status('game_over');
    -}
    -
    -# this is a transition after asking the king to hire someone else!
    -sub _handle_bail_out ($self, $input) {
    -   $self->status('game_over');
    -}
    -
    -# The following package implements all the User Interface, using the
    -# game state (as exposed by $game->status) to figure out what to print
    -# and if an input is needed from the user. It all happens on the
    -# standard input and output.
    -package BasicComputerGames::Hammurabi::DefaultIO;
    -
    -# All __io_* functions take a $game object as input, in case of need for
    -# some specific data (e.g. population amount or amassed grain bushels).
    -# They usually print something out and collect input from standard
    -# input for states that require a user input. All functions are named
    -# after the available states in BasicComputerGames::Hammurabi.
    -
    -sub __io_start ($game) {
    -   say ' ' x 32, 'HAMURABI';
    -   say ' ' x 15, 'CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY';
    -   print "\n\n\n";
    -   say 'TRY YOUR HAND AT GOVERNING ANCIENT SUMERIA';
    -   say 'FOR A TEN-YEAR TERM OF OFFICE';
    -   print "\n";
    -   return;
    -} ## end sub __io_start
    -
    -sub __io_start_of_year ($game) {
    -   print "\n\n";
    -   say "HAMURABI:  I BEG TO REPORT TO YOU,";
    -   printf "IN YEAR %d , %d PEOPLE STARVED, %d CAME TO THE CITY,\n",
    -     $game->year, $game->starved, $game->new_arrivals;
    -   say 'A HORRIBLE PLAGUE STRUCK!  HALF THE PEOPLE DIED.'
    -     if $game->had_plague;
    -   say 'POPULATION IS NOW ', $game->population;
    -   say 'THE CITY NOW OWNS ', $game->acres,           ' ACRES.';
    -   say 'YOU HARVESTED ', $game->production_per_acre, ' BUSHELS PER ACRE.';
    -   say 'THE RATS ATE ',  $game->rats_toll,           ' BUSHELS.';
    -   say 'YOU NOW HAVE ',  $game->store,               ' BUSHELS IN STORE.';
    -   print "\n";
    -   return;
    -} ## end sub __io_start_of_year
    -
    -sub get_input ($game = undef) {
    -   while () {
    -      chomp(my $input = $_);
    -      return 0 unless $input;
    -      return $input if $input =~ m{\A -? \d+ \z}mxs;
    -      print "REENTER?\n?? ";
    -   } ## end while ()
    -   die "\n";
    -} ## end sub get_input
    -
    -sub __io_bail_out ($game) {
    -   say "\nHAMURABI:  I CANNOT DO WHAT YOU WISH.";
    -   say 'GET YOURSELF ANOTHER STEWARD!!!!!';
    -   return;
    -}
    -
    -sub __not_enough_bushels ($game) {
    -   say 'HAMURABI:  THINK AGAIN.  YOU HAVE ONLY';
    -   say $game->store, ' BUSHELS OF GRAIN. NOW, THEN,';
    -}
    -
    -sub __not_enough_acres ($game) {
    -   say 'HAMURABI:  THINK AGAIN.  YOU OWN ONLY ',
    -     $game->acres, ' ACRES.  NOW, THEN,';
    -}
    -
    -sub __io_buy_acres ($game) {
    -   print 'HOW MANY ACRES DO YOU WISH TO BUY?? ';
    -   return get_input();
    -}
    -
    -sub __io_advertise_cost_per_acre ($game) {
    -   say 'LAND IS TRADING AT ', $game->cost_per_acre, ' BUSHELS PER ACRE.';
    -   return;
    -}
    -
    -sub __io_sell_acres ($game) {
    -   print 'HOW MANY ACRES DO YOU WISH TO SELL?? ';
    -   return get_input();
    -}
    -
    -sub __io_feeding ($game) {
    -   print "\nHOW MANY BUSHELS DO YOU WISH TO FEED YOUR PEOPLE?? ";
    -   return get_input();
    -}
    -
    -sub __io_planting ($game) {
    -   print "\nHOW MANY ACRES DO YOU WISH TO PLANT WITH SEED?? ";
    -   return get_input();
    -}
    -
    -sub __io_buy_acres_again ($game) { __not_enough_bushels($game) }
    -
    -sub __io_sell_acres_again ($game) { __not_enough_acres($game) }
    -
    -sub __io_feeding_again ($game) { __not_enough_bushels($game) }
    -
    -sub __io_planting_fail_acres ($game) { __not_enough_acres($game) }
    -
    -sub __io_planting_fail_seeds ($game) { __not_enough_bushels($game) }
    -
    -sub __io_planting_fail_people ($game) {
    -   say 'BUT YOU HAVE ONLY ', $game->population,
    -     ' PEOPLE TO TEND THE FIELDS!  NOW, THEN,';
    -}
    -
    -sub __impeachment {
    -   say 'DUE TO THIS EXTREME MISMANAGEMENT YOU HAVE NOT ONLY';
    -   say 'BEEN IMPEACHED AND THROWN OUT OF OFFICE BUT YOU HAVE';
    -   say 'ALSO BEEN DECLARED NATIONAL FINK!!!!';
    -}
    -
    -sub __io_impeach_year ($game) {
    -   printf "\nYOU STARVED %d PEOPLE IN ONE YEAR!!!\n", $game->starved;
    -   return __impeachment();
    -}
    -
    -sub __io_goodbye ($game) {
    -   say "\nSO LONG FOR NOW.\n";
    -   return;
    -}
    -
    -# Final summary for the game, print statistics and evaluation
    -sub __io_summary ($game) {
    -   my $starved = $game->total_starved;
    -   my $years   = $game->max_years;
    -   my $p1      = 100 * $starved / $years;
    -   my $l       = $game->acres / $game->population;
    -   printf "IN YOUR %d-YEAR TERM OF OFFICE, %d PERCENT OF THE\n",
    -     $years, $p1;
    -   say 'POPULATION STARVED PER YEAR ON THE AVERAGE, I.E. A TOTAL OF';
    -   printf "%d PEOPLE DIED!!\n", $starved;
    -   say 'YOU STARTED WITH 10 ACRES PER PERSON AND ENDED WITH';
    -   printf "%.2f ACRES PER PERSON.\n\n", $l;
    -
    -   if ($p1 > 33 || $l < 7) {
    -      __impeachment();
    -   }
    -   elsif ($p1 > 10 || $l < 9) {
    -      say 'YOUR HEAVY-HANDED PERFORMANCE SMACKS OF NERO AND IVAN IV.';
    -      say 'THE PEOPLE (REMAINING) FIND YOU AN UNPLEASANT RULER, AND,';
    -      say 'FRANKLY, HATE YOUR GUTS!!';
    -   }
    -   elsif ($p1 > 3 || $l < 10) {
    -      my $haters = int($game->population * rand(0.8));
    -      say 'YOUR PERFORMANCE COULD HAVE BEEN SOMEWHAT BETTER, BUT';
    -      say "REALLY WASN'T TOO BAD AT ALL.  $haters PEOPLE";
    -      say 'WOULD DEARLY LIKE TO SEE YOU ASSASSINATED BUT WE ALL HAVE OUR';
    -      say 'TRIVIAL PROBLEMS.';
    -   } ## end elsif ($p1 > 3 || $l < 10)
    -   else {
    -      say 'A FANTASTIC PERFORMANCE!!!  CHARLEMANGE, DISRAELI, AND';
    -      say 'JEFFERSON COMBINED COULD NOT HAVE DONE BETTER!';
    -   }
    -
    -   return;
    -} ## end sub __io_summary
    -
    -# this class method allows using this module... easily. Call with
    -# arguments to be fed to the BasicComputerGames::Hammurabi constructor.
    -sub run ($package, @args) {
    -   my $game = BasicComputerGames::Hammurabi->new(@args);
    -   while ((my $status = $game->status) ne 'game_over') {
    -      eval {
    -         my $retval;
    -         if (my $cb = $package->can('__io_' . $status)) {
    -            $retval = $cb->($game);
    -         }
    -         $game->step($retval);
    -         1;
    -      } or last;
    -   } ## end while ((my $status = $game...))
    -   say '';
    -   return 0;
    -} ## end sub run
    -
    -# Modulino (https://gitlab.com/polettix/notechs/-/snippets/1868370)
    -exit __PACKAGE__->run(@ARGV) unless caller;
    -
    -1;
    -__END__
    -
    -=pod
    -
    -=encoding UTF-8
    -
    -=head1 NAME
    -
    -BasicComputerGames::Hammurabi - the Hammurabi game from BASIC
    -
    -=head1 SYNOPSIS
    -
    -   use BasicComputerGames::Hammurabi;
    -
    -   # if you have a way to manage the UI yourself, then you can get the
    -   # game logic handler
    -   my $game_handler = BasicComputerGames::Hammurabi->new;
    -   while ((my $status = $game_handler->status) ne 'game_over') {
    -      # figure out what to print out with $status, this is totally
    -      # up to the interface implementation, which also has to collect
    -      # the inputs
    -      my $retval = manage_ui_for($game_handler);
    -
    -      # now we feed whatever came from the interface back to the handler
    -      $game_handler->step($retval);
    -   }
    -
    -   # Want the plain terminal experience? No problem:
    -   BasicComputerGames::Hammurabi::DefaultIO->run;
    -
    -=head1 IMPLEMENTATION DETAILS
    -
    -The code tries to behave like the original BASIC, including some dubious
    -conditions checks that e.g. do not allow using the full potential of
    -available resources for lack of an equal sign.
    -
    -The calculation of the final average of starved people per year is
    -differnet from the original and avoids what is considered (by me) a bug
    -that kicks in when there are years in which nobody starves.
    -
    -=head1 AUTHOR
    -
    -Adapted by Flavio Poletti from the BASIC version by David Ahl. Game text
    -copied verbatim from the original BASIC implementation, including typos.
    -
    -=cut
    diff --git a/43_Hammurabi/python/hamurabi.py b/43_Hammurabi/python/hamurabi.py
    index 46ef975d6..e7310fc73 100644
    --- a/43_Hammurabi/python/hamurabi.py
    +++ b/43_Hammurabi/python/hamurabi.py
    @@ -1,227 +1,203 @@
    -from random import random, seed
    +from random import random
    +from random import seed
     
     
    -def gen_random() -> int:
    +def gen_random():
         return int(random() * 5) + 1
     
     
    -def bad_input_850() -> None:
    +def bad_input_850():
         print("\nHAMURABI:  I CANNOT DO WHAT YOU WISH.")
         print("GET YOURSELF ANOTHER STEWARD!!!!!")
    +    Z = 99
     
     
    -def bad_input_710(grain_bushels: int) -> None:
    +def bad_input_710(S):
         print("HAMURABI:  THINK AGAIN.  YOU HAVE ONLY")
    -    print(f"{grain_bushels} BUSHELS OF GRAIN.  NOW THEN,")
    +    print(S, "BUSHELS OF GRAIN.  NOW THEN,")
     
     
    -def bad_input_720(acres: float) -> None:
    -    print(f"HAMURABI:  THINK AGAIN.  YOU OWN ONLY {acres} ACRES.  NOW THEN,")
    +def bad_input_720(A):
    +    print("HAMURABI:  THINK AGAIN.  YOU OWN ONLY", A, "ACRES.  NOW THEN,")
     
     
    -def national_fink() -> None:
    +def national_fink():
         print("DUE TO THIS EXTREME MISMANAGEMENT YOU HAVE NOT ONLY")
         print("BEEN IMPEACHED AND THROWN OUT OF OFFICE BUT YOU HAVE")
         print("ALSO BEEN DECLARED NATIONAL FINK!!!!")
     
     
    -def b_input(promptstring: str) -> int:
    -    """emulate BASIC input. It rejects non-numeric values"""
    +def b_input(promptstring):  # emulate BASIC input. It rejects non-numeric values
         x = input(promptstring)
         while x.isalpha():
             x = input("?REDO FROM START\n? ")
         return int(x)
     
     
    -def main() -> None:
    -    seed()
    -    title = "HAMURABI"
    -    title = title.rjust(32, " ")
    -    print(title)
    -    attribution = "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY"
    -    attribution = attribution.rjust(15, " ")
    -    print(attribution)
    -    print("\n\n\n")
    -    print("TRY YOUR HAND AT GOVERNING ANCIENT SUMERIA")
    -    print("FOR A TEN-YEAR TERM OF OFFICE.\n")
    -
    -    D1 = 0
    -    P1: float = 0
    -    year = 0
    -    population = 95
    -    grain_stores = 2800
    -    H = 3000
    -    eaten_rats = H - grain_stores
    -    bushels_per_acre = (
    -        3  # yield (amount of production from land). Reused as price per acre
    -    )
    -    acres = H / bushels_per_acre  # acres of land
    -    immigrants = 5
    -    plague = 1  # boolean for plague, also input for buy/sell land
    -    people = 0
    -
    -    while year < 11:  # line 270. main loop. while the year is less than 11
    -        print("\n\n\nHAMURABI:  I BEG TO REPORT TO YOU")
    -        year += 1
    -        print(
    -            "IN YEAR",
    -            year,
    -            ",",
    -            people,
    -            "PEOPLE STARVED,",
    -            immigrants,
    -            "CAME TO THE CITY,",
    -        )
    -        population = population + immigrants
    -
    -        if plague == 0:
    -            population = int(population / 2)
    -            print("A HORRIBLE PLAGUE STRUCK!  HALF THE PEOPLE DIED.")
    -
    -        print("POPULATION IS NOW", population)
    -        print("THE CITY NOW OWNS", acres, "ACRES.")
    -        print("YOU HARVESTED", bushels_per_acre, "BUSHELS PER ACRE.")
    -        print("THE RATS ATE", eaten_rats, "BUSHELS.")
    -        print("YOU NOW HAVE ", grain_stores, "BUSHELS IN STORE.\n")
    -        C = int(10 * random())  # random number between 1 and 10
    -        bushels_per_acre = C + 17
    -        print("LAND IS TRADING AT", bushels_per_acre, "BUSHELS PER ACRE.")
    -
    -        plague = -99  # dummy value to track status
    -        while plague == -99:  # always run the loop once
    -            plague = b_input("HOW MANY ACRES DO YOU WISH TO BUY? ")
    -            if plague < 0:
    -                plague = -1  # to avoid the corner case of Q=-99
    +seed()
    +title = "HAMURABI"
    +title = title.rjust(32, ' ')
    +print(title)
    +attribution = "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY"
    +attribution = attribution.rjust(15, " ")
    +print(attribution)
    +print('\n\n\n')
    +print("TRY YOUR HAND AT GOVERNING ANCIENT SUMERIA")
    +print("FOR A TEN-YEAR TERM OF OFFICE.\n")
    +
    +D1 = 0
    +P1 = 0
    +Z = 0  # year
    +P = 95  # population
    +S = 2800  # grain stores
    +H = 3000
    +E = H - S  # rats eaten
    +Y = 3  # yield (amount of production from land). Reused as price per acre
    +A = H / Y  # acres of land
    +I = 5  # immigrants
    +Q = 1  # boolean for plague, also input for buy/sell land
    +D = 0  # people
    +
    +while Z < 11:  # line 270. main loop. while the year is less than 11
    +    print("\n\n\nHAMURABI:  I BEG TO REPORT TO YOU")
    +    Z = Z + 1  # year
    +    print("IN YEAR", Z, ",", D, "PEOPLE STARVED,", I, "CAME TO THE CITY,")
    +    P = P + I
    +
    +    if Q == 0:
    +        P = int(P / 2)
    +        print("A HORRIBLE PLAGUE STRUCK!  HALF THE PEOPLE DIED.")
    +
    +    print("POPULATION IS NOW", P)
    +    print("THE CITY NOW OWNS", A, "ACRES.")
    +    print("YOU HARVESTED", Y, "BUSHELS PER ACRE.")
    +    print("THE RATS ATE", E, "BUSHELS.")
    +    print("YOU NOW HAVE ", S, "BUSHELS IN STORE.\n")
    +    C = int(10 * random())  # random number between 1 and 10
    +    Y = C + 17
    +    print("LAND IS TRADING AT", Y, "BUSHELS PER ACRE.")
    +
    +    Q = -99  # dummy value to track status
    +    while Q == -99:  # always run the loop once
    +        Q = b_input("HOW MANY ACRES DO YOU WISH TO BUY? ")
    +        if Q < 0:
    +            Q = -1  # to avoid the corner case of Q=-99
    +            bad_input_850()
    +            Z = 99  # jump out of main loop and exit
    +        elif Y * Q > S:  # can't afford it
    +            bad_input_710(S)
    +            Q = -99  # give'm a second change to get it right
    +        elif Y * Q <= S:  # normal case, can afford it
    +            A = A + Q  # increase the number of acres by Q
    +            S = S - Y * Q  # decrease the amount of grain in store to pay for it
    +            C = 0  # WTF is C for?
    +
    +    if Q == 0 and Z != 99:  # maybe you want to sell some land?
    +        Q = -99
    +        while Q == -99:
    +            Q = b_input("HOW MANY ACRES DO YOU WISH TO SELL? ")
    +            if Q < 0:
                     bad_input_850()
    -                year = 99  # jump out of main loop and exit
    -            elif bushels_per_acre * plague > grain_stores:  # can't afford it
    -                bad_input_710(grain_stores)
    -                plague = -99  # give'm a second change to get it right
    -            else:
    -                acres = acres + plague  # increase the number of acres by Q
    -                grain_stores = (
    -                    grain_stores - bushels_per_acre * plague
    -                )  # decrease the amount of grain in store to pay for it
    -                C = 0  # WTF is C for?
    -
    -        if plague == 0 and year != 99:  # maybe you want to sell some land?
    -            plague = -99
    -            while plague == -99:
    -                plague = b_input("HOW MANY ACRES DO YOU WISH TO SELL? ")
    -                if plague < 0:
    -                    bad_input_850()
    -                    year = 99  # jump out of main loop and exit
    -                elif plague <= acres:  # normal case
    -                    acres = acres - plague  # reduce the acres
    -                    grain_stores = (
    -                        grain_stores + bushels_per_acre * plague
    -                    )  # add to grain stores
    -                    C = 0  # still don't know what C is for
    -                else:  # Q>A error!
    -                    bad_input_720(acres)
    -                    plague = -99  # reloop
    -            print("\n")
    -
    -        plague = -99
    -        while plague == -99 and year != 99:
    -            plague = b_input("HOW MANY BUSHELS DO YOU WISH TO FEED YOUR PEOPLE? ")
    -            if plague < 0:
    -                bad_input_850()
    -                year = 99  # jump out of main loop and exit
    -            # REM *** TRYING TO USE MORE GRAIN THAN IS IN SILOS?
    -            elif plague > grain_stores:
    -                bad_input_710(grain_stores)
    -                plague = -99  # try again!
    -            else:  # we're good. do the transaction
    -                grain_stores = grain_stores - plague  # remove the grain from the stores
    -                C = 1  # set the speed of light to 1. jk
    -
    +                Z = 99  # jump out of main loop and exit
    +            elif Q <= A:  # normal case
    +                A = A - Q  # reduce the acres
    +                S = S + Y * Q  # add to grain stores
    +                C = 0  # still don't know what C is for
    +            else:  # Q>A error!
    +                bad_input_720(A)
    +                Q = -99  # reloop
             print("\n")
    -        people = -99  # dummy value to force at least one loop
    -        while people == -99 and year != 99:
    -            people = b_input("HOW MANY ACRES DO YOU WISH TO PLANT WITH SEED? ")
    -            if people < 0:
    -                bad_input_850()
    -                year = 99  # jump out of main loop and exit
    -            elif people > 0:
    -                if people > acres:
    -                    # REM *** TRYING TO PLANT MORE ACRES THAN YOU OWN?
    -                    bad_input_720(acres)
    -                    people = -99
    -                elif int(people / 2) > grain_stores:
    -                    # REM *** ENOUGH GRAIN FOR SEED?
    -                    bad_input_710(grain_stores)
    -                    people = -99
    -                elif people > 10 * population:
    -                    # REM *** ENOUGH PEOPLE TO TEND THE CROPS?
    -                    print(
    -                        "BUT YOU HAVE ONLY",
    -                        population,
    -                        "PEOPLE TO TEND THE FIELDS!  NOW THEN,",
    -                    )
    -                    people = -99
    -                else:  # we're good. decrement the grain store
    -                    grain_stores = grain_stores - int(people / 2)
    -
    -        C = gen_random()
    -        # REM *** A BOUNTIFUL HARVEST!
    -        bushels_per_acre = C
    -        H = people * bushels_per_acre
    -        C = gen_random()
    -        eaten_rats = int(grain_stores / C) if int(C / 2) == C / 2 else 0
    -        grain_stores = grain_stores - eaten_rats + H  # deduct losses from stores
    -
    -        C = gen_random()
    -        # REM *** LET'S HAVE SOME BABIES
    -        immigrants = int(C * (20 * acres + grain_stores) / population / 100 + 1)
    -        # REM *** HOW MANY PEOPLE HAD FULL TUMMIES?
    -        C = int(plague / 20)
    -        # REM *** HORROS, A 15% CHANCE OF PLAGUE
    -        # yeah, should be HORRORS, but left it
    -        plague = int(10 * (2 * random() - 0.3))
    -        if (
    -            population >= C and year != 99
    -        ):  # if there are some people without full bellies...
    -            # REM *** STARVE ENOUGH FOR IMPEACHMENT?
    -            people = population - C
    -            if people > 0.45 * population:
    -                print("\nYOU STARVED", people, "PEOPLE IN ONE YEAR!!!")
    -                national_fink()
    -                year = 99  # exit the loop
    -            P1 = ((year - 1) * P1 + people * 100 / population) / year
    -            population = C
    -            D1 = D1 + people
    -
    -    if year != 99:
    -        print("IN YOUR 10-YEAR TERM OF OFFICE,", P1, "PERCENT OF THE")
    -        print("POPULATION STARVED PER YEAR ON THE AVERAGE, I.E. A TOTAL OF")
    -        print(D1, "PEOPLE DIED!!")
    -        L = acres / population
    -        print("YOU STARTED WITH 10 ACRES PER PERSON AND ENDED WITH")
    -        print(L, "ACRES PER PERSON.\n")
    -        if P1 > 33 or L < 7:
    +
    +    Q = -99
    +    while Q == -99 and Z != 99:
    +        Q = b_input("HOW MANY BUSHELS DO YOU WISH TO FEED YOUR PEOPLE? ")
    +        if Q < 0:
    +            bad_input_850()
    +        # REM *** TRYING TO USE MORE GRAIN THAN IS IN SILOS?
    +        elif Q > S:
    +            bad_input_710(S)
    +            Q = -99  # try again!
    +        else:  # we're good. do the transaction
    +            S = S - Q  # remove the grain from the stores
    +            C = 1  # set the speed of light to 1. jk
    +
    +    print("\n")
    +    D = -99  # dummy value to force at least one loop
    +    while D == -99 and Z != 99:
    +        D = b_input("HOW MANY ACRES DO YOU WISH TO PLANT WITH SEED? ")
    +        if D < 0:
    +            bad_input_850()
    +            Z = 99
    +        elif D > 0:
    +            if D > A:
    +                # REM *** TRYING TO PLANT MORE ACRES THAN YOU OWN?
    +                bad_input_720(A)
    +                D = -99
    +            elif int(D / 2) > S:
    +                # REM *** ENOUGH GRAIN FOR SEED?
    +                bad_input_710(S)
    +                D = -99
    +            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
    +            else:  # we're good. decrement the grain store
    +                S = S - int(D / 2)
    +
    +    C = gen_random()
    +    # REM *** A BOUNTIFUL HARVEST!
    +    Y = C
    +    H = D * Y
    +    E = 0
    +
    +    C = gen_random()
    +    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
    +
    +    C = gen_random()
    +    # REM *** LET'S HAVE SOME BABIES
    +    I = int(C * (20 * A + S) / P / 100 + 1)
    +    # REM *** HOW MANY PEOPLE HAD FULL TUMMIES?
    +    C = int(Q / 20)
    +    # REM *** HORROS, A 15% CHANCE OF PLAGUE
    +    # yeah, should be HORRORS, but left it
    +    Q = int(10 * (2 * random() - .3))
    +    if P >= C and Z != 99:  # if there are some people without full bellies...
    +        # REM *** STARVE ENOUGH FOR IMPEACHMENT?
    +        D = P - C
    +        if D > .45 * P:
    +            print("\nYOU STARVED", D, "PEOPLE IN ONE YEAR!!!")
                 national_fink()
    -        elif P1 > 10 or L < 9:
    -            print("YOUR HEAVY-HANDED PERFORMANCE SMACKS OF NERO AND IVAN IV.")
    -            print("THE PEOPLE (REMAINING) FIND YOU AN UNPLEASANT RULER, AND,")
    -            print("FRANKLY, HATE YOUR GUTS!!")
    -        elif P1 > 3 or L < 10:
    -            print("YOUR PERFORMANCE COULD HAVE BEEN SOMEWHAT BETTER, BUT")
    -            print(
    -                "REALLY WASN'T TOO BAD AT ALL. ",
    -                int(population * 0.8 * random()),
    -                "PEOPLE",
    -            )
    -            print("WOULD DEARLY LIKE TO SEE YOU ASSASSINATED BUT WE ALL HAVE OUR")
    -            print("TRIVIAL PROBLEMS.")
    -        else:
    -            print("A FANTASTIC PERFORMANCE!!!  CHARLEMANGE, DISRAELI, AND")
    -            print("JEFFERSON COMBINED COULD NOT HAVE DONE BETTER!\n")
    -        for _ in range(1, 10):
    -            print("\a")
    -
    -    print("\nSO LONG FOR NOW.\n")
    -
    -
    -if __name__ == "__main__":
    -    main()
    +            Z = 99  # exit the loop
    +        P1 = ((Z - 1) * P1 + D * 100 / P) / Z
    +        P = C
    +        D1 = D1 + D
    +
    +if Z != 99:
    +    print("IN YOUR 10-YEAR TERM OF OFFICE,", P1, "PERCENT OF THE")
    +    print("POPULATION STARVED PER YEAR ON THE AVERAGE, I.E. A TOTAL OF")
    +    print(D1, "PEOPLE DIED!!")
    +    L = A / P
    +    print("YOU STARTED WITH 10 ACRES PER PERSON AND ENDED WITH")
    +    print(L, "ACRES PER PERSON.\n")
    +    if P1 > 33 or L < 7:
    +        national_fink()
    +    elif P1 > 10 or L < 9:
    +        print("YOUR HEAVY-HANDED PERFORMANCE SMACKS OF NERO AND IVAN IV.")
    +        print("THE PEOPLE (REMIANING) FIND YOU AN UNPLEASANT RULER, AND,")
    +        print("FRANKLY, HATE YOUR GUTS!!")
    +    elif P1 > 3 or L < 10:
    +        print("YOUR PERFORMANCE COULD HAVE BEEN SOMEWHAT BETTER, BUT")
    +        print("REALLY WASN'T TOO BAD AT ALL. ", int(P * .8 * random()), "PEOPLE")
    +        print("WOULD DEARLY LIKE TO SEE YOU ASSASSINATED BUT WE ALL HAVE OUR")
    +        print("TRIVIAL PROBLEMS.")
    +    else:
    +        print("A FANTASTIC PERFORMANCE!!!  CHARLEMANGE, DISRAELI, AND")
    +        print("JEFFERSON COMBINED COULD NOT HAVE DONE BETTER!\n")
    +    for N in range(1, 10):
    +        print('\a')
    +
    +print("\nSO LONG FOR NOW.\n")
    diff --git a/43_Hammurabi/rust/Cargo.lock b/43_Hammurabi/rust/Cargo.lock
    deleted file mode 100644
    index 4fe2abbea..000000000
    --- a/43_Hammurabi/rust/Cargo.lock
    +++ /dev/null
    @@ -1,75 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.10"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.147"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/43_Hammurabi/rust/Cargo.toml b/43_Hammurabi/rust/Cargo.toml
    deleted file mode 100644
    index 3b1d02f52..000000000
    --- a/43_Hammurabi/rust/Cargo.toml
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -[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/43_Hammurabi/rust/README.md b/43_Hammurabi/rust/README.md
    deleted file mode 100644
    index fc6468b9f..000000000
    --- a/43_Hammurabi/rust/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Rust](https://www.rust-lang.org/)
    diff --git a/43_Hammurabi/rust/src/main.rs b/43_Hammurabi/rust/src/main.rs
    deleted file mode 100644
    index 529a61451..000000000
    --- a/43_Hammurabi/rust/src/main.rs
    +++ /dev/null
    @@ -1,262 +0,0 @@
    -use std::io;
    -use rand::Rng;
    -
    -fn run() {
    -    // Set up variables
    -    let mut year = 0;
    -    let mut population = 95;
    -    let mut immigrants = 5;
    -    let mut starved = 0;
    -    let mut total_starved = 0;
    -    let mut plague = false;
    -    let mut grain = 2800;
    -    let mut bushels_fed;
    -    let mut harvest;
    -    let mut planted;
    -    let mut yield_acre = 3;
    -    let mut eaten_rats = 200;
    -    let mut acres = 1000;
    -    let mut land_price;
    -    let mut bought_land;
    -    let mut perc_starved = 0.0;
    -    let mut game_failed = false;
    -
    -    'main: loop {
    -        year += 1;
    -        if year > 11 {
    -            break;
    -        }
    -        println!("\n\n\nHAMURABI: I BEG TO REPORT TO YOU,");
    -        println!("IN YEAR {year}, {starved} PEOPLE STARVED, {immigrants} CAME TO THE CITY,");
    -        population += immigrants;
    -        if plague{
    -            population /= 2;
    -            plague = false;
    -            println!("A HORRIBLE PLAGUE STRUCK! HALF THE PEOPLE DIED.");
    -        }
    -        println!("POPULATION IS NOW {population}");
    -        println!("THE CITY NOW OWNS {acres} ACRES.");
    -        println!("YOU HARVESTED {yield_acre} BUSHELS PER ACRE.");
    -        println!("THE RATS ATE {eaten_rats} BUSHELS.");
    -        println!("YOU NOW HAVE {grain} BUSHELS IN STORE.\n");
    -        let r = rand::thread_rng().gen_range(1..10);
    -        land_price = r + 17;
    -        println!("LAND IS TRADING AT {land_price} BUSHELS PER ACRE.");
    -
    -        loop {  
    -            println!("HOW MANY ACRES DO YOU WISH TO BUY? ");
    -            if let Some(qty) = get_input() {
    -                // Player decides not to buy any land
    -                if qty == 0 {
    -                    bought_land = false;
    -                    break;
    -                }
    -                // Trying to buy more land than you can afford?
    -                if land_price * qty > grain {
    -                    insufficient_grain(grain);
    -                    continue;
    -                }
    -                // Everything checks out OK
    -                if land_price * qty <= grain {
    -                    acres += qty ;
    -                    grain -= land_price * qty ;
    -                    bought_land = true;
    -                    break;
    -                }
    -            } else {
    -                impossible_task();
    -                game_failed = true;
    -                break 'main;
    -            }
    -        }
    -
    -        if !bought_land {
    -            loop {  
    -                println!("HOW MANY ACRES DO YOU WISH TO SELL? ");
    -                if let Some(qty) = get_input() {
    -                    // Everything checks out OK
    -                    if qty <= acres {
    -                        acres -= qty;
    -                        grain += land_price * qty;
    -                        break;
    -                    }
    -                    // Trying to sell more land that you own
    -                    insufficient_land(acres);
    -                } else {
    -                    impossible_task();
    -                    game_failed = true;
    -                    break 'main;
    -                }
    -            }
    -        }
    -
    -        loop {  
    -            println!("HOW MANY BUSHELS DO YOU WISH TO FEED YOUR PEOPLE? ");
    -            if let Some(qty) = get_input() {
    -                // Trying to use more grain than is in silos?
    -                if qty > grain {
    -                    insufficient_grain(grain);
    -                    continue;
    -                }
    -                // Everything checks out OK
    -                bushels_fed = qty;
    -                grain -= bushels_fed;
    -                break;
    -            } else {
    -                impossible_task();
    -                game_failed = true;
    -                break 'main;
    -            }
    -        }
    -
    -        loop {  
    -            println!("HOW MANY ACRES DO YOU WISH TO PLANT WITH SEED? ");
    -            if let Some(qty) = get_input() {
    -                // Trying to plant more acres than you own?
    -                if qty > acres {
    -                    insufficient_land(acres);
    -                    continue;
    -                }
    -                // Enough grain for seed?
    -                if qty / 2 > grain {
    -                    insufficient_grain(grain);
    -                    continue;
    -                }
    -                // Enough people to tend the crops?
    -                if qty > (10 * population) {
    -                    insufficient_people(population);
    -                    continue;
    -                }
    -                // Everything checks out OK
    -                planted = qty;
    -                grain -= planted / 2;
    -                break;
    -            } else {
    -                impossible_task();
    -                game_failed = true;
    -                break 'main;
    -            }
    -        }
    -
    -        // A bountiful harvest!
    -        yield_acre = gen_random();
    -        harvest = planted * yield_acre;
    -        eaten_rats = 0;
    -
    -        // Determine if any grain was eaten by rats
    -        let mut c = gen_random();
    -        if c % 2 == 0 { // If c is even...
    -            // Rats are running wild!
    -            eaten_rats = grain / c;
    -        }
    -        // Update the amount of grain held
    -        grain = grain - eaten_rats + harvest;
    -
    -        // Let's have some babies
    -        c = gen_random();
    -        immigrants = c * (20 * acres + grain) / population / 100 + 1;
    -
    -        // How many people had full tummies?
    -        c = bushels_fed / 20;
    -        // Horrors, a 15% chance of plague
    -        let rf: f32 = rand::thread_rng().gen();
    -        let plague_chance = (10. * ((2. * rf) - 0.3)) as i32;
    -        if plague_chance == 0 {
    -            plague = true;
    -        }
    -        if population >= c {
    -            // Starve enough for impeachment?
    -            starved = population - c;
    -            if starved > (0.45 * population as f32) as u32 {
    -                println!("YOU STARVED {starved} PEOPLE IN ONE YEAR!!!");
    -                national_fink();
    -                game_failed = true;
    -                break;
    -            }
    -            // Calculate percentage of people that starved per year on average
    -            perc_starved = ((year - 1) as f32 * perc_starved + starved as f32 * 100. / population as f32) / year as f32;
    -            population = c;
    -            total_starved += starved;
    -        }
    -    }
    -
    -    if !game_failed {
    -        println!("IN YOUR 10-YEAR TERM OF OFFICE {perc_starved} PERCENT OF THE");
    -        println!("POPULATION STARVED PER YEAR ON THE AVERAGE, I.E. A TOTAL OF");
    -        println!("{total_starved} PEOPLE DIED!!");
    -        let acres_head = acres / population;
    -        println!("YOU STARTED WITH 10 ACRES PER PERSON AND ENDED WITH");
    -        println!("{acres_head} ACRES PER PERSON.\n");
    -        if perc_starved > 33. || acres_head < 7 {
    -            national_fink();
    -        }
    -        else if perc_starved > 10. || acres_head < 9 {
    -            println!("YOUR HEAVY-HANDED PERFORMANCE SMACKS OF NERO AND IVAN IV.");
    -            println!("THE PEOPLE (REMAINING) FIND YOU AND UNPLEASANT RULER, AND,");
    -            println!("FRANKLY, HATE YOUR GUTS!!");
    -        }
    -        else if perc_starved > 3. || acres_head < 10 {
    -            let haters = (population as f32 * 0.8 * gen_random() as f32) as u32;
    -            println!("YOUR PERFORMANCE COULD HAVE BEEN SOMEWHAT BETTER, BUT");
    -            println!("REALLY WASN'T TOO BAD AT ALL. {haters} PEOPLE");
    -            println!("WOULD DEARLY LIKE TO SEE YOU ASSASSINATED BUT WE ALL HAVE OUR");
    -            println!("TRIVIAL PROBLEMS.");
    -        } else {
    -            println!("A FANTASTIC PERFORMANCE!!! CHARLEMANGE, DISRAELI, AND");
    -            println!("JEFFERSON COMBINED COULD NOT HAVE DONE BETTER!\n");
    -        }
    -        for _ in 1..10 {
    -            println!();
    -        }
    -    }
    -            
    -    println!("\nSO LONG FOR NOW.\n");
    -}
    -
    -fn get_input() -> Option {
    -    let mut input = String::new();
    -    io::stdin().read_line(&mut input).expect("Failed read_line");
    -    match input.trim().parse() {
    -        Ok(num) => Some(num),
    -        Err(_) => None,
    -    }
    -}
    -
    -fn gen_random() -> u32 {
    -    let r: f32 = rand::thread_rng().gen();
    -    (r * 5.0 + 1.0) as u32
    -}
    -
    -fn impossible_task() {
    -    println!("HAMURABI:  I CANNOT DO WHAT YOU WISH.");
    -    println!("GET YOURSELF ANOTHER STEWARD!!!!!");
    -}
    -
    -fn insufficient_grain(grain: u32) {
    -    println!("HAMURABI:  THINK AGAIN.  YOU HAVE ONLY");
    -    println!("{grain} BUSHELS OF GRAIN.  NOW THEN,");
    -}
    -
    -fn insufficient_land(acres: u32) {
    -    println!("HAMURABI: THINK AGAIN. YOU OWN ONLY {acres} ACRES.  NOW THEN,");
    -}
    -
    -fn insufficient_people(population: u32) {
    -    println!("BUT YOU HAVE ONLY {population} PEOPLE TO TEND THE FIELDS!  NOW THEN,");
    -}
    -
    -fn national_fink() {
    -    println!("DUE TO THIS EXTREME MISMANAGEMENT YOU HAVE NOT ONLY");
    -    println!("BEEN IMPEACHED AND THROWN OUT OF OFFICE BUT YOU HAVE");
    -    println!("ALSO BEEN DECLARED NATIONAL FINK!!!!");
    -}
    -
    -fn main() {
    -    println!("                 HAMURABI");
    -    println!("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY");
    -    print!("\n\n\n\n");
    -    println!("TRY YOUR HAND AT GOVERNING ANCIENT SUMERIA");
    -    println!("FOR A TEN-YEAR TERM OF OFFICE.\n");
    -
    -    run();
    -}
    diff --git a/43_Hammurabi/vbnet/Hammurabi.sln b/43_Hammurabi/vbnet/Hammurabi.sln
    deleted file mode 100644
    index 41a13843e..000000000
    --- a/43_Hammurabi/vbnet/Hammurabi.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 8f89306c0..000000000
    --- a/43_Hammurabi/vbnet/Hammurabi.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Hammurabi
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/44_Hangman/README.md b/44_Hangman/README.md
    index a8af66e07..ee533251b 100644
    --- a/44_Hangman/README.md
    +++ b/44_Hangman/README.md
    @@ -24,7 +24,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/44_Hangman/csharp/Graphic.cs b/44_Hangman/csharp/Hangman/Graphic.cs
    similarity index 99%
    rename from 44_Hangman/csharp/Graphic.cs
    rename to 44_Hangman/csharp/Hangman/Graphic.cs
    index 62eea111f..ba01fcac7 100644
    --- a/44_Hangman/csharp/Graphic.cs
    +++ b/44_Hangman/csharp/Hangman/Graphic.cs
    @@ -108,22 +108,22 @@ public void AddRightHand()
             {
                 _graphic[2, 2] = '/';
             }
    -
    +        
             public void AddLeftHand()
             {
                 _graphic[2, 10] = '\\';
             }
    -
    +        
             public void AddRightFoot()
             {
                 _graphic[11, 9] = '\\';
                 _graphic[11, 10] = '-';
             }
    -
    +        
             public void AddLeftFoot()
             {
                 _graphic[11, 3] = '/';
                 _graphic[11, 2] = '-';
             }
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/44_Hangman/csharp/Hangman.csproj b/44_Hangman/csharp/Hangman/Hangman.csproj
    similarity index 100%
    rename from 44_Hangman/csharp/Hangman.csproj
    rename to 44_Hangman/csharp/Hangman/Hangman.csproj
    diff --git a/44_Hangman/csharp/Hangman.sln b/44_Hangman/csharp/Hangman/Hangman.sln
    similarity index 100%
    rename from 44_Hangman/csharp/Hangman.sln
    rename to 44_Hangman/csharp/Hangman/Hangman.sln
    diff --git a/44_Hangman/csharp/Hangman/Program.cs b/44_Hangman/csharp/Hangman/Program.cs
    new file mode 100644
    index 000000000..7ecb09df9
    --- /dev/null
    +++ b/44_Hangman/csharp/Hangman/Program.cs
    @@ -0,0 +1,313 @@
    +using System;
    +using System.Collections.Generic;
    +using System.Linq;
    +using System.Text.Json.Serialization;
    +
    +namespace Hangman
    +{
    +    /// 
    +    /// C# version of the game "Hangman" from the book BASIC Computer Games.
    +    /// 
    +    static class Program
    +    {
    +        static void Main()
    +        {
    +            Console.WriteLine(Tab(32) + "HANGMAN");
    +            Console.WriteLine(Tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY");
    +            Console.WriteLine();
    +            Console.WriteLine();
    +            Console.WriteLine();
    +            MainLoop();
    +            Console.WriteLine();
    +            Console.WriteLine("IT'S BEEN FUN!  BYE FOR NOW.");
    +        }
    +
    +        static void MainLoop()
    +        {
    +            var words = GetWords();
    +            var stillPlaying = true;
    +
    +            while (stillPlaying)
    +            {
    +                if (words.Count == 0)
    +                {
    +                    Console.WriteLine("YOU DID ALL THE WORDS!!");
    +                    break;
    +                }
    +
    +                // Get a random number from 0 to the number of words we have minus one (C# arrays are zero-based).
    +                var rnd = new Random();
    +                var randomNumber = rnd.Next(words.Count - 1);
    +
    +                // Pick a random word and remove it from the list.
    +                var word = words[randomNumber];
    +                words.Remove(word);
    +
    +                GameLoop(word);
    +                
    +                // Game finished. Ask if player wants another one.
    +                Console.WriteLine("WANT ANOTHER WORD? ");
    +                var response = Console.ReadLine();
    +                if (response == null || response.ToUpper() != "YES")
    +                {
    +                    stillPlaying = false;   // Exit the loop if the player didn't answer "yes".
    +                }
    +            }
    +        }
    +
    +        static void GameLoop(string word)
    +        {
    +            var graphic = new Graphic();
    +            var wrongGuesses = 0;
    +            var numberOfGuesses = 0;
    +            var usedLetters = new List();
    +
    +            // The word that the user sees. Since we just started, it's just dashes.
    +            var displayedWord = new char[word.Length];
    +            for (var i = 0; i < word.Length; i++)
    +            {
    +                displayedWord[i] = '-';
    +            }
    +
    +            var stillPlaying = true;
    +            while (stillPlaying)
    +            {
    +                var guess = GetLetterFromPlayer(displayedWord, usedLetters);
    +                usedLetters.Add(guess);
    +                numberOfGuesses++;
    +                var correctLetterCount = 0;
    +                // Now we check every letter in the word to see if the player guessed any of them correctly.
    +                for(var i = 0; i < word.Length; i++)
    +                {
    +                    if (word[i] == guess)
    +                    {
    +                        correctLetterCount++;
    +                        displayedWord[i] = guess;
    +                    }
    +                }
    +
    +                if (correctLetterCount == 0)
    +                {
    +                    // Wrong guess.
    +                    Console.WriteLine("SORRY, THAT LETTER ISN'T IN THE WORD.");
    +                    wrongGuesses++;
    +                    DrawBody(graphic, wrongGuesses);
    +                    if (wrongGuesses == 10)
    +                    {
    +                        // Player exhausted all their guesses. Finish the game loop.
    +                        Console.WriteLine($"SORRY, YOU LOSE.  THE WORD WAS {word}");
    +                        Console.Write("YOU MISSED THAT ONE.  DO YOU ");
    +                        stillPlaying = false;
    +                    }
    +                }
    +                else
    +                {
    +                    // Player guessed a correct letter. Let's see if there are any unguessed letters left in the word.
    +                    if (displayedWord.Contains('-'))
    +                    {
    +                        Console.WriteLine(displayedWord);
    +                        
    +                        // Give the player a chance to guess the whole word.
    +                        var wordGuess = GetWordFromPlayer();
    +                        if (word == wordGuess)
    +                        {
    +                            // Player found the word. Mark it found.
    +                            Console.WriteLine("YOU FOUND THE WORD!");
    +                            stillPlaying = false;   // Exit game loop.
    +                        }
    +                        else
    +                        {
    +                            // Player didn't guess the word. Continue the game loop.
    +                            Console.WriteLine("WRONG.  TRY ANOTHER LETTER.");
    +                        }
    +                    }
    +                    else
    +                    {
    +                        // Player guessed all the letters.
    +                        Console.WriteLine("YOU FOUND THE WORD!");
    +                        stillPlaying = false;   // Exit game loop.
    +                    }
    +                }
    +            } // End of game loop.
    +        }
    +
    +        /// 
    +        /// Display the current state of the word and all the already guessed letters, and get a new guess from the player
    +        /// 
    +        /// A char array that represents the current state of the guessed word
    +        /// A list of chars that represents all the letters guessed so far
    +        /// The letter that the player has just entered as a guess
    +        private static char GetLetterFromPlayer(char[] displayedWord, List usedLetters)
    +        {
    +            while (true)    // Infinite loop, unless the player enters an unused letter.
    +            {
    +                Console.WriteLine();
    +                Console.WriteLine(displayedWord);
    +                Console.WriteLine();
    +                Console.WriteLine();
    +                Console.WriteLine("HERE ARE THE LETTERS YOU USED:");
    +                for (var i = 0; i < usedLetters.Count; i++)
    +                {
    +                    Console.Write(usedLetters[i]);
    +
    +                    // If it's not the last letter, print a comma.
    +                    if (i != usedLetters.Count - 1)
    +                    {
    +                        Console.Write(",");
    +                    }
    +                }
    +
    +                Console.WriteLine();
    +                Console.WriteLine("WHAT IS YOUR GUESS?");
    +                var guess = char.ToUpper(Console.ReadKey().KeyChar);
    +                Console.WriteLine();
    +                
    +                if (usedLetters.Contains(guess))
    +                {
    +                    // After this the loop will continue.
    +                    Console.WriteLine("YOU GUESSED THAT LETTER BEFORE!");
    +                }
    +                else
    +                {
    +                    // Break out of the loop by returning guessed letter.
    +                    return guess;
    +                }
    +            }
    +        }
    +
    +        /// 
    +        /// Gets a word guess from the player.
    +        /// 
    +        /// The guessed word.
    +        private static string GetWordFromPlayer()
    +        {
    +            while (true)    // Infinite loop, unless the player enters something.
    +            {
    +                Console.WriteLine("WHAT IS YOUR GUESS FOR THE WORD? ");
    +                var guess = Console.ReadLine();
    +                if (guess != null)
    +                {
    +                    return guess.ToUpper();
    +                }
    +            }
    +        }
    +
    +        /// 
    +        /// Draw body after wrong guess.
    +        /// 
    +        /// The instance of the Graphic class being used.
    +        /// Number of wrong guesses.
    +        private static void DrawBody(Graphic graphic, int wrongGuesses)
    +        {
    +            switch (wrongGuesses)
    +                    {
    +                        case 1:
    +                            Console.WriteLine("FIRST, WE DRAW A HEAD.");
    +                            graphic.AddHead();
    +                            break;
    +                        case 2:
    +                            Console.WriteLine("NOW WE DRAW A BODY.");
    +                            graphic.AddBody();
    +                            break;
    +                        case 3:
    +                            Console.WriteLine("NEXT WE DRAW AN ARM.");
    +                            graphic.AddRightArm();
    +                            break;
    +                        case 4:
    +                            Console.WriteLine("THIS TIME IT'S THE OTHER ARM.");
    +                            graphic.AddLeftArm();
    +                            break;
    +                        case 5:
    +                            Console.WriteLine("NOW, LET'S DRAW THE RIGHT LEG.");
    +                            graphic.AddRightLeg();
    +                            break;
    +                        case 6:
    +                            Console.WriteLine("THIS TIME WE DRAW THE LEFT LEG.");
    +                            graphic.AddLeftLeg();
    +                            break;
    +                        case 7:
    +                            Console.WriteLine("NOW WE PUT UP A HAND.");
    +                            graphic.AddRightHand();
    +                            break;
    +                        case 8:
    +                            Console.WriteLine("NEXT THE OTHER HAND.");
    +                            graphic.AddLeftHand();
    +                            break;
    +                        case 9:
    +                            Console.WriteLine("NOW WE DRAW ONE FOOT.");
    +                            graphic.AddRightFoot();
    +                            break;
    +                        case 10:
    +                            Console.WriteLine("HERE'S THE OTHER FOOT -- YOU'RE HUNG!!");
    +                            graphic.AddLeftFoot();
    +                            break;
    +                    }
    +                    graphic.Print();
    +        }
    +        
    +        /// 
    +        /// Get a list of words to use in the game.
    +        /// 
    +        /// List of strings.
    +        private static List GetWords() => new()
    +        {
    +            "GUM",
    +            "SIN",
    +            "FOR",
    +            "CRY",
    +            "LUG",
    +            "BYE",
    +            "FLY",
    +            "UGLY",
    +            "EACH",
    +            "FROM",
    +            "WORK",
    +            "TALK",
    +            "WITH",
    +            "SELF",
    +            "PIZZA",
    +            "THING",
    +            "FEIGN",
    +            "FIEND",
    +            "ELBOW",
    +            "FAULT",
    +            "DIRTY",
    +            "BUDGET",
    +            "SPIRIT",
    +            "QUAINT",
    +            "MAIDEN",
    +            "ESCORT",
    +            "PICKAX",
    +            "EXAMPLE",
    +            "TENSION",
    +            "QUININE",
    +            "KIDNEY",
    +            "REPLICA",
    +            "SLEEPER",
    +            "TRIANGLE",
    +            "KANGAROO",
    +            "MAHOGANY",
    +            "SERGEANT",
    +            "SEQUENCE",
    +            "MOUSTACHE",
    +            "DANGEROUS",
    +            "SCIENTIST",
    +            "DIFFERENT",
    +            "QUIESCENT",
    +            "MAGISTRATE",
    +            "ERRONEOUSLY",
    +            "LOUDSPEAKER",
    +            "PHYTOTOXIC",
    +            "MATRIMONIAL",
    +            "PARASYMPATHOMIMETIC",
    +            "THIGMOTROPISM"
    +        };
    +
    +        /// 
    +        /// Leave a number of spaces empty.
    +        /// 
    +        /// Number of spaces.
    +        /// The result string.
    +        private static string Tab(int length) => new string(' ', length);
    +    }
    +}
    \ No newline at end of file
    diff --git a/44_Hangman/csharp/Program.cs b/44_Hangman/csharp/Program.cs
    deleted file mode 100644
    index f5658daef..000000000
    --- a/44_Hangman/csharp/Program.cs
    +++ /dev/null
    @@ -1,313 +0,0 @@
    -using System;
    -using System.Collections.Generic;
    -using System.Linq;
    -using System.Text.Json.Serialization;
    -
    -namespace Hangman
    -{
    -    /// 
    -    /// C# version of the game "Hangman" from the book BASIC Computer Games.
    -    /// 
    -    static class Program
    -    {
    -        static void Main()
    -        {
    -            Console.WriteLine(Tab(32) + "HANGMAN");
    -            Console.WriteLine(Tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY");
    -            Console.WriteLine();
    -            Console.WriteLine();
    -            Console.WriteLine();
    -            MainLoop();
    -            Console.WriteLine();
    -            Console.WriteLine("IT'S BEEN FUN!  BYE FOR NOW.");
    -        }
    -
    -        static void MainLoop()
    -        {
    -            var words = GetWords();
    -            var stillPlaying = true;
    -
    -            while (stillPlaying)
    -            {
    -                if (words.Count == 0)
    -                {
    -                    Console.WriteLine("YOU DID ALL THE WORDS!!");
    -                    break;
    -                }
    -
    -                // Get a random number from 0 to the number of words we have minus one (C# arrays are zero-based).
    -                var rnd = new Random();
    -                var randomNumber = rnd.Next(words.Count - 1);
    -
    -                // Pick a random word and remove it from the list.
    -                var word = words[randomNumber];
    -                words.Remove(word);
    -
    -                GameLoop(word);
    -
    -                // Game finished. Ask if player wants another one.
    -                Console.WriteLine("WANT ANOTHER WORD? ");
    -                var response = Console.ReadLine();
    -                if (response == null || response.ToUpper() != "YES")
    -                {
    -                    stillPlaying = false;   // Exit the loop if the player didn't answer "yes".
    -                }
    -            }
    -        }
    -
    -        static void GameLoop(string word)
    -        {
    -            var graphic = new Graphic();
    -            var wrongGuesses = 0;
    -            var numberOfGuesses = 0;
    -            var usedLetters = new List();
    -
    -            // The word that the user sees. Since we just started, it's just dashes.
    -            var displayedWord = new char[word.Length];
    -            for (var i = 0; i < word.Length; i++)
    -            {
    -                displayedWord[i] = '-';
    -            }
    -
    -            var stillPlaying = true;
    -            while (stillPlaying)
    -            {
    -                var guess = GetLetterFromPlayer(displayedWord, usedLetters);
    -                usedLetters.Add(guess);
    -                numberOfGuesses++;
    -                var correctLetterCount = 0;
    -                // Now we check every letter in the word to see if the player guessed any of them correctly.
    -                for(var i = 0; i < word.Length; i++)
    -                {
    -                    if (word[i] == guess)
    -                    {
    -                        correctLetterCount++;
    -                        displayedWord[i] = guess;
    -                    }
    -                }
    -
    -                if (correctLetterCount == 0)
    -                {
    -                    // Wrong guess.
    -                    Console.WriteLine("SORRY, THAT LETTER ISN'T IN THE WORD.");
    -                    wrongGuesses++;
    -                    DrawBody(graphic, wrongGuesses);
    -                    if (wrongGuesses == 10)
    -                    {
    -                        // Player exhausted all their guesses. Finish the game loop.
    -                        Console.WriteLine($"SORRY, YOU LOSE.  THE WORD WAS {word}");
    -                        Console.Write("YOU MISSED THAT ONE.  DO YOU ");
    -                        stillPlaying = false;
    -                    }
    -                }
    -                else
    -                {
    -                    // Player guessed a correct letter. Let's see if there are any unguessed letters left in the word.
    -                    if (displayedWord.Contains('-'))
    -                    {
    -                        Console.WriteLine(displayedWord);
    -
    -                        // Give the player a chance to guess the whole word.
    -                        var wordGuess = GetWordFromPlayer();
    -                        if (word == wordGuess)
    -                        {
    -                            // Player found the word. Mark it found.
    -                            Console.WriteLine("YOU FOUND THE WORD!");
    -                            stillPlaying = false;   // Exit game loop.
    -                        }
    -                        else
    -                        {
    -                            // Player didn't guess the word. Continue the game loop.
    -                            Console.WriteLine("WRONG.  TRY ANOTHER LETTER.");
    -                        }
    -                    }
    -                    else
    -                    {
    -                        // Player guessed all the letters.
    -                        Console.WriteLine("YOU FOUND THE WORD!");
    -                        stillPlaying = false;   // Exit game loop.
    -                    }
    -                }
    -            } // End of game loop.
    -        }
    -
    -        /// 
    -        /// Display the current state of the word and all the already guessed letters, and get a new guess from the player
    -        /// 
    -        /// A char array that represents the current state of the guessed word
    -        /// A list of chars that represents all the letters guessed so far
    -        /// The letter that the player has just entered as a guess
    -        private static char GetLetterFromPlayer(char[] displayedWord, List usedLetters)
    -        {
    -            while (true)    // Infinite loop, unless the player enters an unused letter.
    -            {
    -                Console.WriteLine();
    -                Console.WriteLine(displayedWord);
    -                Console.WriteLine();
    -                Console.WriteLine();
    -                Console.WriteLine("HERE ARE THE LETTERS YOU USED:");
    -                for (var i = 0; i < usedLetters.Count; i++)
    -                {
    -                    Console.Write(usedLetters[i]);
    -
    -                    // If it's not the last letter, print a comma.
    -                    if (i != usedLetters.Count - 1)
    -                    {
    -                        Console.Write(",");
    -                    }
    -                }
    -
    -                Console.WriteLine();
    -                Console.WriteLine("WHAT IS YOUR GUESS?");
    -                var guess = char.ToUpper(Console.ReadKey().KeyChar);
    -                Console.WriteLine();
    -
    -                if (usedLetters.Contains(guess))
    -                {
    -                    // After this the loop will continue.
    -                    Console.WriteLine("YOU GUESSED THAT LETTER BEFORE!");
    -                }
    -                else
    -                {
    -                    // Break out of the loop by returning guessed letter.
    -                    return guess;
    -                }
    -            }
    -        }
    -
    -        /// 
    -        /// Gets a word guess from the player.
    -        /// 
    -        /// The guessed word.
    -        private static string GetWordFromPlayer()
    -        {
    -            while (true)    // Infinite loop, unless the player enters something.
    -            {
    -                Console.WriteLine("WHAT IS YOUR GUESS FOR THE WORD? ");
    -                var guess = Console.ReadLine();
    -                if (guess != null)
    -                {
    -                    return guess.ToUpper();
    -                }
    -            }
    -        }
    -
    -        /// 
    -        /// Draw body after wrong guess.
    -        /// 
    -        /// The instance of the Graphic class being used.
    -        /// Number of wrong guesses.
    -        private static void DrawBody(Graphic graphic, int wrongGuesses)
    -        {
    -            switch (wrongGuesses)
    -                    {
    -                        case 1:
    -                            Console.WriteLine("FIRST, WE DRAW A HEAD.");
    -                            graphic.AddHead();
    -                            break;
    -                        case 2:
    -                            Console.WriteLine("NOW WE DRAW A BODY.");
    -                            graphic.AddBody();
    -                            break;
    -                        case 3:
    -                            Console.WriteLine("NEXT WE DRAW AN ARM.");
    -                            graphic.AddRightArm();
    -                            break;
    -                        case 4:
    -                            Console.WriteLine("THIS TIME IT'S THE OTHER ARM.");
    -                            graphic.AddLeftArm();
    -                            break;
    -                        case 5:
    -                            Console.WriteLine("NOW, LET'S DRAW THE RIGHT LEG.");
    -                            graphic.AddRightLeg();
    -                            break;
    -                        case 6:
    -                            Console.WriteLine("THIS TIME WE DRAW THE LEFT LEG.");
    -                            graphic.AddLeftLeg();
    -                            break;
    -                        case 7:
    -                            Console.WriteLine("NOW WE PUT UP A HAND.");
    -                            graphic.AddRightHand();
    -                            break;
    -                        case 8:
    -                            Console.WriteLine("NEXT THE OTHER HAND.");
    -                            graphic.AddLeftHand();
    -                            break;
    -                        case 9:
    -                            Console.WriteLine("NOW WE DRAW ONE FOOT.");
    -                            graphic.AddRightFoot();
    -                            break;
    -                        case 10:
    -                            Console.WriteLine("HERE'S THE OTHER FOOT -- YOU'RE HUNG!!");
    -                            graphic.AddLeftFoot();
    -                            break;
    -                    }
    -                    graphic.Print();
    -        }
    -
    -        /// 
    -        /// Get a list of words to use in the game.
    -        /// 
    -        /// List of strings.
    -        private static List GetWords() => new()
    -        {
    -            "GUM",
    -            "SIN",
    -            "FOR",
    -            "CRY",
    -            "LUG",
    -            "BYE",
    -            "FLY",
    -            "UGLY",
    -            "EACH",
    -            "FROM",
    -            "WORK",
    -            "TALK",
    -            "WITH",
    -            "SELF",
    -            "PIZZA",
    -            "THING",
    -            "FEIGN",
    -            "FIEND",
    -            "ELBOW",
    -            "FAULT",
    -            "DIRTY",
    -            "BUDGET",
    -            "SPIRIT",
    -            "QUAINT",
    -            "MAIDEN",
    -            "ESCORT",
    -            "PICKAX",
    -            "EXAMPLE",
    -            "TENSION",
    -            "QUININE",
    -            "KIDNEY",
    -            "REPLICA",
    -            "SLEEPER",
    -            "TRIANGLE",
    -            "KANGAROO",
    -            "MAHOGANY",
    -            "SERGEANT",
    -            "SEQUENCE",
    -            "MOUSTACHE",
    -            "DANGEROUS",
    -            "SCIENTIST",
    -            "DIFFERENT",
    -            "QUIESCENT",
    -            "MAGISTRATE",
    -            "ERRONEOUSLY",
    -            "LOUDSPEAKER",
    -            "PHYTOTOXIC",
    -            "MATRIMONIAL",
    -            "PARASYMPATHOMIMETIC",
    -            "THIGMOTROPISM"
    -        };
    -
    -        /// 
    -        /// Leave a number of spaces empty.
    -        /// 
    -        /// Number of spaces.
    -        /// The result string.
    -        private static string Tab(int length) => new string(' ', length);
    -    }
    -}
    diff --git a/44_Hangman/java/Hangman.java b/44_Hangman/java/Hangman.java
    index 994255671..56567bb25 100644
    --- a/44_Hangman/java/Hangman.java
    +++ b/44_Hangman/java/Hangman.java
    @@ -10,7 +10,6 @@
      *
      * Converted from BASIC to Java by Aldrin Misquitta (@aldrinm)
      */
    -
     public class Hangman {
     
     	//50 word list
    @@ -33,7 +32,7 @@ public static void main(String[] args) {
     		int[] usedWords = new int[50];
     		int roundNumber = 1;
     		int totalWords = words.size();
    -		boolean continueGame = false;
    +		boolean continueGame;
     
     		do {
     			if (roundNumber > totalWords) {
    @@ -54,10 +53,7 @@ public static void main(String[] args) {
     				System.out.print("\nWANT ANOTHER WORD? ");
     			}
     			final String anotherWordChoice = scan.next();
    -
    -			if (anotherWordChoice.toUpperCase().equals("YES") || anotherWordChoice.toUpperCase().equals("Y")) {
    -				continueGame = true;
    -			}
    +			continueGame = "YES".equals(anotherWordChoice);
     			roundNumber++;
     		} while (continueGame);
     
    @@ -103,7 +99,7 @@ private static boolean playRound(Scanner scan, String word) {
     
     				System.out.print("WHAT IS YOUR GUESS? ");
     				var tmpRead = scan.next();
    -				guessLetter = Character.toUpperCase(tmpRead.charAt(0));
    +				guessLetter = tmpRead.charAt(0);
     				if (lettersUsed.contains(guessLetter)) {
     					System.out.println("YOU GUESSED THAT LETTER BEFORE!");
     				} else {
    @@ -136,7 +132,7 @@ private static boolean playRound(Scanner scan, String word) {
     				printDiscoveredLetters(discoveredLetters);
     				System.out.print("WHAT IS YOUR GUESS FOR THE WORD? ");
     				final String wordGuess = scan.next();
    -				if (wordGuess.toUpperCase().equals(word)) {
    +				if (wordGuess.equals(word)) {
     					System.out.printf("RIGHT!!  IT TOOK YOU %s GUESSES!", totalWordGuesses);
     					return true;
     				} else {
    @@ -245,3 +241,5 @@ private static void printIntro() {
     	}
     
     }
    +
    +
    diff --git a/44_Hangman/javascript/hangman.html b/44_Hangman/javascript/hangman.html
    index 895297587..7bf3d2509 100644
    --- a/44_Hangman/javascript/hangman.html
    +++ b/44_Hangman/javascript/hangman.html
    @@ -1,10 +1,9 @@
     
     
     HANGMAN
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/44_Hangman/javascript/hangman.js b/44_Hangman/javascript/hangman.js
    index c7f6b8c5c..322fd94f0 100644
    --- a/44_Hangman/javascript/hangman.js
    +++ b/44_Hangman/javascript/hangman.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/44_Hangman/kotlin/README.md b/44_Hangman/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/44_Hangman/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/44_Hangman/lua/README.md b/44_Hangman/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/44_Hangman/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/44_Hangman/pascal/README.md b/44_Hangman/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/44_Hangman/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/44_Hangman/perl/hangman.pl b/44_Hangman/perl/hangman.pl
    index 3fa83ca4c..45a6da9bc 100755
    --- a/44_Hangman/perl/hangman.pl
    +++ b/44_Hangman/perl/hangman.pl
    @@ -175,7 +175,7 @@ sub addchar {
                 }
                 if ($hangCount == 7) {
                     print "Now we put up a hand.\n";
    -                addchar(2,10,"\\");
    +                addchar(2,10,"\\"); 
                 }
                 if ($hangCount == 8) {
                     print "Next the other hand.\n";
    @@ -188,7 +188,7 @@ sub addchar {
                 }
                 if ($hangCount == 10) {
                     print "Here's the other foot -- you're hung!!\n";
    -                addchar(11,2,"-");
    +                addchar(11,2,"-"); 
                     addchar(11,3, "/");
                 }
     
    @@ -208,7 +208,7 @@ sub addchar {
     } # PLAY block
     
     # This block is reached either by the player winning (see the "next PLAY")
    -# statement) or by the user losing (as the PLAY block is complete and
    +# statement) or by the user losing (as the PLAY block is complete and 
     # execution naturally comes to this continue block).
     continue {
         print "Want another word ? ";
    diff --git a/44_Hangman/python/hangman.py b/44_Hangman/python/hangman.py
    index 59d443dbc..e883bf015 100755
    --- a/44_Hangman/python/hangman.py
    +++ b/44_Hangman/python/hangman.py
    @@ -1,42 +1,44 @@
     #!/usr/bin/env python3
    -
    -"""
    -HANGMAN
    -
    -Converted from BASIC to Python by Trevor Hobson and Daniel Piron
    -"""
    +# HANGMAN
    +#
    +# Converted from BASIC to Python by Trevor Hobson and Daniel Piron
     
     import random
    -from typing import List
     
     
     class Canvas:
    -    """For drawing text-based figures"""
    +    """ For drawing text-based figures """
     
    -    def __init__(self, width: int = 12, height: int = 12, fill: str = " ") -> None:
    +    def __init__(self, width=12, height=12, fill=" "):
             self._buffer = []
             for _ in range(height):
    -            line = ["" for _ in range(width)]
    +            line = []
    +            for _ in range(width):
    +                line.append("")
                 self._buffer.append(line)
     
             self.clear()
     
    -    def clear(self, fill: str = " ") -> None:
    +    def clear(self, fill=" "):
             for row in self._buffer:
                 for x in range(len(row)):
                     row[x] = fill
     
    -    def render(self) -> str:
    -        lines = ["".join(line) for line in self._buffer]
    +    def render(self):
    +        lines = []
    +        for line  in self._buffer:
    +            # Joining by the empty string ("") smooshes all of the
    +            # individual characters together as one line.
    +            lines.append("".join(line))
             return "\n".join(lines)
     
    -    def put(self, s: str, x: int, y: int) -> None:
    +    def put(self, s, x, y):
             # In an effort to avoid distorting the drawn image, only write the
             # first character of the given string to the buffer.
             self._buffer[y][x] = s[0]
     
     
    -def init_gallows(canvas: Canvas) -> None:
    +def init_gallows(canvas):
         for i in range(12):
             canvas.put("X", 0, i)
         for i in range(7):
    @@ -44,7 +46,7 @@ def init_gallows(canvas: Canvas) -> None:
         canvas.put("X", 6, 1)
     
     
    -def draw_head(canvas: Canvas) -> None:
    +def draw_head(canvas):
         canvas.put("-", 5, 2)
         canvas.put("-", 6, 2)
         canvas.put("-", 7, 2)
    @@ -57,47 +59,47 @@ def draw_head(canvas: Canvas) -> None:
         canvas.put("-", 7, 4)
     
     
    -def draw_body(canvas: Canvas) -> None:
    +def draw_body(canvas):
         for i in range(5, 9, 1):
             canvas.put("X", 6, i)
     
     
    -def draw_right_arm(canvas: Canvas) -> None:
    +def draw_right_arm(canvas):
         for i in range(3, 7):
             canvas.put("\\", i - 1, i)
     
     
    -def draw_left_arm(canvas: Canvas) -> None:
    +def draw_left_arm(canvas):
         canvas.put("/", 10, 3)
         canvas.put("/", 9, 4)
         canvas.put("/", 8, 5)
         canvas.put("/", 7, 6)
     
     
    -def draw_right_leg(canvas: Canvas) -> None:
    +def draw_right_leg(canvas):
         canvas.put("/", 5, 9)
         canvas.put("/", 4, 10)
     
     
    -def draw_left_leg(canvas: Canvas) -> None:
    +def draw_left_leg(canvas):
         canvas.put("\\", 7, 9)
         canvas.put("\\", 8, 10)
     
     
    -def draw_left_hand(canvas: Canvas) -> None:
    +def draw_left_hand(canvas):
         canvas.put("\\", 10, 2)
     
     
    -def draw_right_hand(canvas: Canvas) -> None:
    +def draw_right_hand(canvas):
         canvas.put("/", 2, 2)
     
     
    -def draw_left_foot(canvas: Canvas) -> None:
    +def draw_left_foot(canvas):
         canvas.put("\\", 9, 11)
         canvas.put("-", 10, 11)
     
     
    -def draw_right_foot(canvas: Canvas) -> None:
    +def draw_right_foot(canvas):
         canvas.put("-", 2, 11)
         canvas.put("/", 3, 11)
     
    @@ -112,69 +114,26 @@ def draw_right_foot(canvas: Canvas) -> None:
         ("Now we put up a hand.", draw_left_hand),
         ("Next the other hand.", draw_right_hand),
         ("Now we draw one foot", draw_left_foot),
    -    ("Here's the other foot -- you're hung!!", draw_right_foot),
    +    ("Here's the other foot -- you're hung!!", draw_right_foot)
     )
     
     
    -words = [
    -    "GUM",
    -    "SIN",
    -    "FOR",
    -    "CRY",
    -    "LUG",
    -    "BYE",
    -    "FLY",
    -    "UGLY",
    -    "EACH",
    -    "FROM",
    -    "WORK",
    -    "TALK",
    -    "WITH",
    -    "SELF",
    -    "PIZZA",
    -    "THING",
    -    "FEIGN",
    -    "FIEND",
    -    "ELBOW",
    -    "FAULT",
    -    "DIRTY",
    -    "BUDGET",
    -    "SPIRIT",
    -    "QUAINT",
    -    "MAIDEN",
    -    "ESCORT",
    -    "PICKAX",
    -    "EXAMPLE",
    -    "TENSION",
    -    "QUININE",
    -    "KIDNEY",
    -    "REPLICA",
    -    "SLEEPER",
    -    "TRIANGLE",
    -    "KANGAROO",
    -    "MAHOGANY",
    -    "SERGEANT",
    -    "SEQUENCE",
    -    "MOUSTACHE",
    -    "DANGEROUS",
    -    "SCIENTIST",
    -    "DIFFERENT",
    -    "QUIESCENT",
    -    "MAGISTRATE",
    -    "ERRONEOUSLY",
    -    "LOUDSPEAKER",
    -    "PHYTOTOXIC",
    -    "MATRIMONIAL",
    -    "PARASYMPATHOMIMETIC",
    -    "THIGMOTROPISM",
    -]
    -
    -
    -def play_game(guess_target: str) -> None:
    +words = ["GUM", "SIN", "FOR", "CRY", "LUG", "BYE", "FLY",
    +         "UGLY", "EACH", "FROM", "WORK", "TALK", "WITH", "SELF",
    +         "PIZZA", "THING", "FEIGN", "FIEND", "ELBOW", "FAULT", "DIRTY",
    +         "BUDGET", "SPIRIT", "QUAINT", "MAIDEN", "ESCORT", "PICKAX",
    +         "EXAMPLE", "TENSION", "QUININE", "KIDNEY", "REPLICA", "SLEEPER",
    +         "TRIANGLE", "KANGAROO", "MAHOGANY", "SERGEANT", "SEQUENCE",
    +         "MOUSTACHE", "DANGEROUS", "SCIENTIST", "DIFFERENT", "QUIESCENT",
    +         "MAGISTRATE", "ERRONEOUSLY", "LOUDSPEAKER", "PHYTOTOXIC",
    +         "MATRIMONIAL", "PARASYMPATHOMIMETIC", "THIGMOTROPISM"]
    +
    +
    +def play_game(guess_target):
         """Play one round of the game"""
         wrong_guesses = 0
         guess_progress = ["-"] * len(guess_target)
    -    guess_list: List[str] = []
    +    guess_list = []
     
         gallows = Canvas()
         init_gallows(gallows)
    @@ -186,7 +145,7 @@ def play_game(guess_target: str) -> None:
             print("".join(guess_progress) + "\n")
             guess_letter = ""
             guess_word = ""
    -        while not guess_letter:
    +        while guess_letter == "":
     
                 guess_letter = input("What is your guess? ").upper()[0]
                 if not guess_letter.isalpha():
    @@ -199,17 +158,15 @@ def play_game(guess_target: str) -> None:
             guess_list.append(guess_letter)
             guess_count += 1
             if guess_letter in guess_target:
    -            indices = [
    -                i for i, letter in enumerate(guess_target) if letter == guess_letter
    -            ]
    +            indices = [i for i, letter in enumerate(guess_target) if letter == guess_letter]
                 for i in indices:
                     guess_progress[i] = guess_letter
    -            if "".join(guess_progress) == guess_target:
    +            if guess_progress == guess_target:
                     print("You found the word!")
                     break
                 else:
                     print("\n" + "".join(guess_progress) + "\n")
    -                while not guess_word:
    +                while guess_word == "":
                         guess_word = input("What is your guess for the word? ").upper()
                         if not guess_word.isalpha():
                             guess_word = ""
    @@ -228,11 +185,11 @@ def play_game(guess_target: str) -> None:
                 print("Sorry, that letter isn't in the word.")
     
                 if wrong_guesses == 10:
    -                print(f"Sorry, you lose. The word was {guess_target}")
    +                print("Sorry, you lose. The word was " + guess_target)
                     break
     
     
    -def main() -> None:
    +def main():
         print(" " * 32 + "HANGMAN")
         print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n")
     
    @@ -250,12 +207,11 @@ def main() -> None:
                 print("You did all the words!!")
                 keep_playing = False
             else:
    -            keep_playing = (
    -                input("Want another word? (yes or no) ").lower().startswith("y")
    -            )
    +            keep_playing = input("Want another word? (yes or no) ").lower().startswith("y")
     
         print("It's been fun! Bye for now.")
     
     
     if __name__ == "__main__":
         main()
    +
    diff --git a/44_Hangman/ruby/hangman.rb b/44_Hangman/ruby/hangman.rb
    deleted file mode 100644
    index b9ad8aa33..000000000
    --- a/44_Hangman/ruby/hangman.rb
    +++ /dev/null
    @@ -1,280 +0,0 @@
    -class Canvas
    -	BUFFER = []
    -	def initialize width = 12, height = 12, fill = " "
    -		for i in (0...height) do
    -			line = []
    -			for i in (0...width) do
    -				line << ""
    -			end
    -			BUFFER << line
    -		end
    -
    -		clear
    -	end
    -
    -	def render
    -		lines = []
    -		for line in BUFFER do
    -			lines << line.join("")
    -		end
    -
    -		return lines.join("\n")
    -	end
    -
    -	def put s, x, y
    -		BUFFER[y][x] = s[0]
    -	end
    -
    -	private
    -		def clear fill = " "
    -			for row in BUFFER do
    -				for x in (0...(row.length)) do
    -					row[x] = fill
    -				end
    -			end
    -		end
    -end
    -
    -def init_gallows canvas
    -	for i in (0...12) do
    -		canvas.put("X", 0, i)
    -	end
    -
    -	for i in (0...7) do
    -		canvas.put("X", i, 0)
    -	end
    -
    -	canvas.put("X", 6, 1)
    -end
    -
    -def draw_head canvas
    -	canvas.put("-", 5, 2)
    -	canvas.put("-", 6, 2)
    -	canvas.put("-", 7, 2)
    -	canvas.put("(", 4, 3)
    -	canvas.put(".", 5, 3)
    -	canvas.put(".", 7, 3)
    -	canvas.put(")", 8, 3)
    -	canvas.put("-", 5, 4)
    -	canvas.put("-", 6, 4)
    -	canvas.put("-", 7, 4)
    -end
    -
    -def draw_body canvas
    -	for i in (5...9) do
    -		canvas.put("X", 6, i)
    -	end
    -end
    -
    -def draw_right_arm canvas
    -	for i in (3...8) do
    -		canvas.put("\\", i - 1, i)
    -	end
    -end
    -
    -def draw_left_arm canvas
    -	canvas.put("/", 10, 3)
    -	canvas.put("/", 9, 4)
    -	canvas.put("/", 8, 5)
    -	canvas.put("/", 7, 6)
    -end
    -
    -def draw_right_leg canvas
    -	canvas.put("/", 5, 9)
    -	canvas.put("/", 4, 10)
    -end
    -
    -def draw_left_leg canvas
    -	canvas.put("\\", 7, 9)
    -	canvas.put("\\", 8, 10)
    -end
    -
    -def draw_left_hand canvas
    -	canvas.put("\\", 10, 2)
    -end
    -
    -def draw_right_hand canvas
    -	canvas.put("/", 2, 2)
    -end
    -
    -def draw_left_foot canvas
    -	canvas.put("\\", 9, 11)
    -	canvas.put("-", 10, 11)
    -end
    -
    -def draw_right_foot canvas
    -	canvas.put("-", 2, 11)
    -	canvas.put("/", 3, 11)
    -end
    -
    -PHASES = [
    -	["First, we draw a head", 'draw_head'],
    -	["Now we draw a body.", 'draw_body'],
    -	["Next we draw an arm.", 'draw_right_arm'],
    -	["this time it's the other arm.", 'draw_left_arm'],
    -	["Now, let's draw the right leg.", 'draw_right_leg'],
    -	["This time we draw the left leg.", 'draw_left_leg'],
    -	["Now we put up a hand.", 'draw_left_hand'],
    -	["Next the other hand.", 'draw_right_hand'],
    -	["Now we draw one foot", 'draw_left_foot'],
    -	["Here's the other foot -- you're hung!!", 'draw_right_foot'],
    -]
    -
    -WORDS = [
    -	"GUM",
    -	"SIN",
    -	"FOR",
    -	"CRY",
    -	"LUG",
    -	"BYE",
    -	"FLY",
    -	"UGLY",
    -	"EACH",
    -	"FROM",
    -	"WORK",
    -	"TALK",
    -	"WITH",
    -	"SELF",
    -	"PIZZA",
    -	"THING",
    -	"FEIGN",
    -	"FIEND",
    -	"ELBOW",
    -	"FAULT",
    -	"DIRTY",
    -	"BUDGET",
    -	"SPIRIT",
    -	"QUAINT",
    -	"MAIDEN",
    -	"ESCORT",
    -	"PICKAX",
    -	"EXAMPLE",
    -	"TENSION",
    -	"QUININE",
    -	"KIDNEY",
    -	"REPLICA",
    -	"SLEEPER",
    -	"TRIANGLE",
    -	"KANGAROO",
    -	"MAHOGANY",
    -	"SERGEANT",
    -	"SEQUENCE",
    -	"MOUSTACHE",
    -	"DANGEROUS",
    -	"SCIENTIST",
    -	"DIFFERENT",
    -	"QUIESCENT",
    -	"MAGISTRATE",
    -	"ERRONEOUSLY",
    -	"LOUDSPEAKER",
    -	"PHYTOTOXIC",
    -	"MATRIMONIAL",
    -	"PARASYMPATHOMIMETIC",
    -	"THIGMOTROPISM",
    -]
    -
    -def play_game guess_target
    -	wrong_guesses = 0
    -	guess_progress = ["-"] * guess_target.length
    -	guess_list = []
    -
    -	gallows = Canvas.new
    -	init_gallows(gallows)
    -
    -	guess_count = 0
    -	while true
    -		puts "Here are the letters you used:"
    -		puts "#{guess_list.join(",")}\n"
    -		puts "#{guess_progress.join("")}\n"
    -
    -		guess_letter = ""
    -		guess_word = ""
    -		while guess_letter == ""
    -			print "What is your guess? "
    -			guess_letter = gets.chomp!.upcase[0]
    -			if !guess_letter.match?(/[[:alpha:]]/)
    -				guess_letter = ""
    -				puts "Only letters are allowed!"
    -			elsif guess_list.include?(guess_letter)
    -				guess_letter = ""
    -				puts "You guessed that letter before!"
    -			end
    -		end
    -
    -		guess_list << guess_letter
    -		guess_count += 1
    -
    -		if guess_target.include?(guess_letter)
    -			indices = (0...guess_target.length).find_all { |i| guess_target[i,1] == guess_letter }
    -
    -			for i in indices do
    -				guess_progress[i] = guess_letter
    -			end
    -
    -			if guess_progress.join("") == guess_target
    -				puts "You found the word!"
    -				break
    -			else
    -				puts "\n#{guess_progress.join("")}\n"
    -
    -				while guess_word == ""
    -					print "What is your guess for the word? "
    -					guess_word = gets.chomp!.upcase
    -					if !guess_word.match?(/[[:alpha:]]/)
    -						guess_word = ""
    -						puts "Only words are allowed!"
    -					end
    -				end
    -
    -				if guess_word == guess_target
    -					puts "Right!! It took you #{guess_count} guesses!"
    -					break
    -				end
    -			end
    -		else
    -			comment, draw_bodypart = PHASES[wrong_guesses]
    -
    -			puts comment
    -			method(draw_bodypart).call(gallows)
    -			puts gallows.render()
    -
    -			wrong_guesses += 1
    -			puts "Sorry, that letter isn't in the word."
    -
    -			if wrong_guesses == 10
    -				puts "Sorry, you lose. The word was #{guess_target}"
    -				break
    -			end
    -		end
    -	end
    -end
    -
    -
    -def main
    -	puts "#{(" " * 32)}HANGMAN"
    -
    -	shuffled = WORDS.shuffle(random: Random.new)
    -	current_word = 0
    -	word_count = shuffled.length
    -
    -	keep_playing = true
    -	while keep_playing
    -
    -		play_game(shuffled[current_word])
    -		current_word += 1
    -
    -		if current_word == word_count
    -			puts "You did all the words!!"
    -			keep_playing = false
    -		else
    -			print "Want another word? (yes or no) "
    -			a = gets.chomp!.upcase
    -			keep_playing = true if a == 'Y' || a == 'y' || a == 'Yes' || a == 'YES' || a == 'yes'
    -		end
    -	end
    -	puts "It's been fun! Bye for now."
    -end
    -
    -if __FILE__ == $0
    -	main
    -end
    \ No newline at end of file
    diff --git a/44_Hangman/vbnet/Hangman.sln b/44_Hangman/vbnet/Hangman.sln
    deleted file mode 100644
    index 355c5093f..000000000
    --- a/44_Hangman/vbnet/Hangman.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 6ad7969c6..000000000
    --- a/44_Hangman/vbnet/Hangman.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Hangman
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/45_Hello/README.md b/45_Hello/README.md
    index 243efa700..117db0ce2 100644
    --- a/45_Hello/README.md
    +++ b/45_Hello/README.md
    @@ -2,7 +2,7 @@
     
     This is a sample of one of the great number of conversational programs. In a sense, it is like a CAI program except that its responses are just good fun. Whenever a computer is exhibited at a convention or conference with people that have not used a computer before, the conversational programs seem to get the first activity.
     
    -In this particular program, the computer dispenses advice on various problems such as sex, health, money, or job.
    +In this particular program, the computer dispenses advice on various problems such as sex. health, money, or job.
     
     David Ahl is the author of HELLO.
     
    @@ -14,7 +14,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/45_Hello/csharp/Hello.csproj b/45_Hello/csharp/Hello.csproj
    deleted file mode 100644
    index d3fe4757c..000000000
    --- a/45_Hello/csharp/Hello.csproj
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    diff --git a/45_Hello/csharp/Hello.sln b/45_Hello/csharp/Hello.sln
    deleted file mode 100644
    index 216c70b6f..000000000
    --- a/45_Hello/csharp/Hello.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/java/Hello.java b/45_Hello/java/Hello.java
    index bb9d701b7..7807a2ddb 100644
    --- a/45_Hello/java/Hello.java
    +++ b/45_Hello/java/Hello.java
    @@ -8,47 +8,47 @@
      * 

    * Note: The idea was to create a version of the 1970's BASIC game in Java, without introducing * new features - no additional text, error checking, etc has been added. - * + * * Converted from BASIC to Java by Darren Cardenas. */ public class Hello { - + private static final int MONEY_WAIT_MS = 3000; - - private final boolean goodEnding = false; - + + private final boolean goodEnding = false; + private final Scanner scan; // For user input public Hello() { - + scan = new Scanner(System.in); - - } // End of constructor Hello - + + } // End of constructor Hello + public void play() { - + showIntro(); startGame(); - - } // End of method play - + + } // End of method play + private static void showIntro() { - + System.out.println(" ".repeat(32) + "HELLO"); System.out.println(" ".repeat(14) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); System.out.println("\n\n"); - - } // End of method showIntro - + + } // End of method showIntro + private void startGame() { - + boolean moreProblems = true; - + String userCategory = ""; String userName = ""; String userResponse = ""; - + // Name question System.out.println("HELLO. MY NAME IS CREATIVE COMPUTER.\n\n"); System.out.print("WHAT'S YOUR NAME? "); @@ -56,49 +56,49 @@ private void startGame() { System.out.println(""); // Enjoyment question - System.out.print("HI THERE, " + userName + ", ARE YOU ENJOYING YOURSELF HERE? "); - + System.out.print("HI THERE, " + userName + ", ARE YOU ENJOYING YOURSELF HERE? "); + while (true) { userResponse = scan.nextLine(); System.out.println(""); - + if (userResponse.toUpperCase().equals("YES")) { System.out.println("I'M GLAD TO HEAR THAT, " + userName + ".\n"); break; - } + } else if (userResponse.toUpperCase().equals("NO")) { System.out.println("OH, I'M SORRY TO HEAR THAT, " + userName + ". MAYBE WE CAN"); - System.out.println("BRIGHTEN UP YOUR VISIT A BIT."); + System.out.println("BRIGHTEN UP YOUR VISIT A BIT."); break; } else { System.out.println(userName + ", I DON'T UNDERSTAND YOUR ANSWER OF '" + userResponse + "'."); - System.out.print("PLEASE ANSWER 'YES' OR 'NO'. DO YOU LIKE IT HERE? "); + System.out.print("PLEASE ANSWER 'YES' OR 'NO'. DO YOU LIKE IT HERE? "); } } // Category question System.out.println(""); - System.out.println("SAY, " + userName + ", I CAN SOLVE ALL KINDS OF PROBLEMS EXCEPT"); + System.out.println("SAY, " + userName + ", I CAN SOLVE ALL KINDS OF PROBLEMS EXCEPT"); System.out.println("THOSE DEALING WITH GREECE. WHAT KIND OF PROBLEMS DO"); - System.out.print("YOU HAVE (ANSWER SEX, HEALTH, MONEY, OR JOB)? "); - + System.out.print("YOU HAVE (ANSWER SEX, HEALTH, MONEY, OR JOB)? "); + while (moreProblems) { userCategory = scan.nextLine(); System.out.println(""); // Sex advice - if (userCategory.toUpperCase().equals("SEX")) { - System.out.print("IS YOUR PROBLEM TOO MUCH OR TOO LITTLE? "); + if (userCategory.toUpperCase().equals("SEX")) { + System.out.print("IS YOUR PROBLEM TOO MUCH OR TOO LITTLE? "); userResponse = scan.nextLine(); System.out.println(""); - - while (true) { + + while (true) { if (userResponse.toUpperCase().equals("TOO MUCH")) { System.out.println("YOU CALL THAT A PROBLEM?!! I SHOULD HAVE SUCH PROBLEMS!"); System.out.println("IF IT BOTHERS YOU, " + userName + ", TAKE A COLD SHOWER."); break; - } + } else if (userResponse.toUpperCase().equals("TOO LITTLE")) { System.out.println("WHY ARE YOU HERE IN SUFFERN, " + userName + "? YOU SHOULD BE"); System.out.println("IN TOKYO OR NEW YORK OR AMSTERDAM OR SOMEPLACE WITH SOME"); @@ -109,29 +109,29 @@ else if (userResponse.toUpperCase().equals("TOO LITTLE")) { System.out.println("DON'T GET ALL SHOOK, " + userName + ", JUST ANSWER THE QUESTION"); System.out.print("WITH 'TOO MUCH' OR 'TOO LITTLE'. WHICH IS IT? "); userResponse = scan.nextLine(); - } - } - } + } + } + } // Health advice else if (userCategory.toUpperCase().equals("HEALTH")) { System.out.println("MY ADVICE TO YOU " + userName + " IS:"); - System.out.println(" 1. TAKE TWO ASPRIN"); + System.out.println(" 1. TAKE TWO ASPRIN"); System.out.println(" 2. DRINK PLENTY OF FLUIDS (ORANGE JUICE, NOT BEER!)"); System.out.println(" 3. GO TO BED (ALONE)"); } // Money advice else if (userCategory.toUpperCase().equals("MONEY")) { System.out.println("SORRY, " + userName + ", I'M BROKE TOO. WHY DON'T YOU SELL"); - System.out.println("ENCYCLOPEADIAS OR MARRY SOMEONE RICH OR STOP EATING"); + System.out.println("ENCYCLOPEADIAS OR MARRY SOMEONE RICH OR STOP EATING"); System.out.println("SO YOU WON'T NEED SO MUCH MONEY?"); - } + } // Job advice else if (userCategory.toUpperCase().equals("JOB")) { System.out.println("I CAN SYMPATHIZE WITH YOU " + userName + ". I HAVE TO WORK"); - System.out.println("VERY LONG HOURS FOR NO PAY -- AND SOME OF MY BOSSES"); + System.out.println("VERY LONG HOURS FOR NO PAY -- AND SOME OF MY BOSSES"); System.out.println("REALLY BEAT ON MY KEYBOARD. MY ADVICE TO YOU, " + userName + ","); System.out.println("IS TO OPEN A RETAIL COMPUTER STORE. IT'S GREAT FUN."); - } + } else { System.out.println("OH, " + userName + ", YOUR ANSWER OF " + userCategory + " IS GREEK TO ME."); } @@ -139,50 +139,50 @@ else if (userCategory.toUpperCase().equals("JOB")) { // More problems question while (true) { System.out.println(""); - System.out.print("ANY MORE PROBLEMS YOU WANT SOLVED, " + userName + "? "); + System.out.print("ANY MORE PROBLEMS YOU WANT SOLVED, " + userName + "? "); userResponse = scan.nextLine(); - System.out.println(""); - + System.out.println(""); + if (userResponse.toUpperCase().equals("YES")) { System.out.print("WHAT KIND (SEX, MONEY, HEALTH, JOB)? "); break; - } + } else if (userResponse.toUpperCase().equals("NO")) { moreProblems = false; break; } else { System.out.println("JUST A SIMPLE 'YES' OR 'NO' PLEASE, " + userName + "."); - } - } - } - + } + } + } + // Payment question System.out.println(""); System.out.println("THAT WILL BE $5.00 FOR THE ADVICE, " + userName + "."); System.out.println("PLEASE LEAVE THE MONEY ON THE TERMINAL."); - // Pause - try { - Thread.sleep(MONEY_WAIT_MS); - } catch (Exception e) { - System.out.println("Caught Exception: " + e.getMessage()); + // Pause + try { + Thread.sleep(MONEY_WAIT_MS); + } catch (Exception e) { + System.out.println("Caught Exception: " + e.getMessage()); } - + System.out.println("\n\n"); - + while (true) { System.out.print("DID YOU LEAVE THE MONEY? "); userResponse = scan.nextLine(); - System.out.println(""); - + System.out.println(""); + if (userResponse.toUpperCase().equals("YES")) { System.out.println("HEY, " + userName + "??? YOU LEFT NO MONEY AT ALL!"); System.out.println("YOU ARE CHEATING ME OUT OF MY HARD-EARNED LIVING."); System.out.println(""); System.out.println("WHAT A RIP OFF, " + userName + "!!!\n"); break; - } + } else if (userResponse.toUpperCase().equals("NO")) { System.out.println("THAT'S HONEST, " + userName + ", BUT HOW DO YOU EXPECT"); System.out.println("ME TO GO ON WITH MY PSYCHOLOGY STUDIES IF MY PATIENTS"); @@ -192,25 +192,25 @@ else if (userResponse.toUpperCase().equals("NO")) { else { System.out.println("YOUR ANSWER OF '" + userResponse + "' CONFUSES ME, " + userName + "."); System.out.println("PLEASE RESPOND WITH 'YES' OR 'NO'."); - } - } - + } + } + // Legacy included unreachable code if (goodEnding) { - System.out.println("NICE MEETING YOU, " + userName + ", HAVE A NICE DAY."); + System.out.println("NICE MEETING YOU, " + userName + ", HAVE A NICE DAY."); } else { System.out.println(""); - System.out.println("TAKE A WALK, " + userName + ".\n"); + System.out.println("TAKE A WALK, " + userName + ".\n"); } - - } // End of method startGame - + + } // End of method startGame + public static void main(String[] args) { - + Hello hello = new Hello(); hello.play(); - + } // End of method main - + } // End of class Hello diff --git a/45_Hello/javascript/hello.html b/45_Hello/javascript/hello.html index 962e67e84..ac6fe180b 100644 --- a/45_Hello/javascript/hello.html +++ b/45_Hello/javascript/hello.html @@ -1,10 +1,9 @@ HELLO - -

    
    +
    
     
     
     
    diff --git a/45_Hello/javascript/hello.js b/45_Hello/javascript/hello.js
    index ff72fd841..d79b15f8e 100644
    --- a/45_Hello/javascript/hello.js
    +++ b/45_Hello/javascript/hello.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/45_Hello/kotlin/README.md b/45_Hello/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/45_Hello/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/45_Hello/lua/README.md b/45_Hello/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/45_Hello/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/45_Hello/lua/hello.lua b/45_Hello/lua/hello.lua
    deleted file mode 100644
    index 5628749bd..000000000
    --- a/45_Hello/lua/hello.lua
    +++ /dev/null
    @@ -1,156 +0,0 @@
    --- HELLO
    ---
    --- Converted from BASIC to Lua by Recanman
    -
    -local function tab(space)
    -    local str = ""
    -
    -    for _ = space, 1, -1 do
    -        str = str .. " "
    -    end
    -
    -    return str
    -end
    -
    --- reused from Bagels.lua
    -function getInput(prompt)
    -    io.write(prompt)
    -    io.flush()
    -    local input = io.read("l")
    -    if not input then  --- test for EOF
    -        print("GOODBYE")
    -        os.exit(0)
    -    end
    -    return input
    -end
    -
    -print(tab(33) .. "HELLO\n")
    -print(tab(15) .. "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n")
    -print("\n")
    -print("\n")
    -print("\n")
    -
    -print("HELLO.  MY NAME IS CREATIVE COMPUTER.\n")
    -print("\n")
    -print("\n")
    -
    -print("WHAT'S YOUR NAME")
    -local ns = getInput("? ")
    -
    -print("\n")
    -print("HI THERE, " .. ns .. ", ARE YOU ENJOYING YOURSELF HERE")
    -
    -while true do
    -    local bs = getInput("? ")
    -    print("\n")
    -    if bs == "YES" then
    -        print("I'M GLAD TO HEAR THAT, " .. ns .. ".\n")
    -        print("\n")
    -        break
    -    elseif bs == "NO" then
    -        print("OH, I'M SORRY TO HEAR THAT, " .. ns .. ". MAYBE WE CAN\n")
    -        print("BRIGHTEN UP YOUR VISIT A BIT.\n")
    -        break
    -    else
    -        print("PLEASE ANSWER 'YES' OR 'NO'.  DO YOU LIKE IT HERE")
    -    end
    -end
    -
    -local function main()
    -    print("\n")
    -    print("SAY, " .. ns .. ", I CAN SOLVED ALL KINDS OF PROBLEMS EXCEPT\n")
    -    print("THOSE DEALING WITH GREECE.  WHAT KIND OF PROBLEMS DO\n")
    -    print("YOU HAVE (ANSWER SEX, HEALTH, MONEY, OR JOB)")
    -
    -    while true do
    -        local cs = getInput("? ")
    -        print("\n")
    -
    -        if cs ~= "SEX" and cs ~= "HEALTH" and cs ~= "MONEY" and cs ~= "JOB" then
    -            print("OH, " .. ns .. ", YOUR ANSWER OF " .. cs .. " IS GREEK TO ME.\n")
    -        elseif cs == "JOB" then
    -            print("I CAN SYMPATHIZE WITH YOU " .. ns .. ".  I HAVE TO WORK\n")
    -            print("VERY LONG HOURS FOR NO PAY -- AND SOME OF MY BOSSES\n")
    -            print("REALLY BEAT ON MY KEYBOARD.  MY ADVICE TO YOU, " .. ns .. ",\n")
    -            print("IS TO OPEN A RETAIL COMPUTER STORE.  IT'S GREAT FUN.\n")
    -        elseif cs == "MONEY" then
    -            print("SORRY, " .. ns .. ", I'M BROKE TOO.  WHY DON'T YOU SELL\n")
    -            print("ENCYCLOPEADIAS OR MARRY SOMEONE RICH OR STOP EATING\n")
    -            print("SO YOU WON'T NEED SO MUCH MONEY?\n")
    -        elseif cs == "HEALTH" then
    -            print("MY ADVICE TO YOU " .. ns .. " IS:\n")
    -            print(tab(5) .. "1.  TAKE TWO ASPRIN\n")
    -            print(tab(5) .. "2.  DRINK PLENTY OF FLUIDS (ORANGE JUICE, NOT BEER!)\n")
    -            print(tab(5) .. "3.  GO TO BED (ALONE)\n")
    -        elseif cs == "SEX" then
    -            print("IS YOUR PROBLEM TOO MUCH OR TOO LITTLE")
    -
    -            while true do
    -                local ds = getInput("? ")
    -                print("\n")
    -
    -                if ds == "TOO MUCH" then
    -                    print("YOU CALL THAT A PROBLEM?!!  I SHOULD HAVE SUCH PROBLEMS!\n")
    -                    print("IF IT BOTHERS YOU, " .. ns .. ", TAKE A COLD SHOWER.\n")
    -                    break
    -                elseif ds == "TOO LITTLE" then
    -                    print("WHY ARE YOU HERE IN SUFFERN, " .. ns .. "?  YOU SHOULD BE\n")
    -                    print("IN TOKYO OR NEW YORK OR AMSTERDAM OR SOMEPLACE WITH SOME\n")
    -                    print("REAL ACTION.\n")
    -                    break
    -                else
    -                    print("DON'T GET ALL SHOOK, " .. ns .. ", JUST ANSWER THE QUESTION\n")
    -                    print("WITH 'TOO MUCH' OR 'TOO LITTLE'.  WHICH IS IT")
    -                end
    -            end
    -        end
    -
    -        print("\n")
    -        print("ANY MORE PROBLEMS YOU WANT SOLVED, " .. ns)
    -
    -        local es = getInput("? ")
    -
    -        if es == "YES" then
    -            print("WHAT KIND (SEX, MONEY, HEALTH, JOB)")
    -        elseif es == "NO" then
    -            print("THAT WILL BE $5.00 FOR THE ADVICE, " .. ns .. ".\n")
    -            print("PLEASE LEAVE THE MONEY ON THE TERMINAL.\n")
    -            print("\n")
    -            print("\n")
    -            print("\n")
    -
    -            while true do
    -                print("DID YOU LEAVE THE MONEY")
    -
    -                local gs = getInput("? ")
    -                print("\n")
    -
    -                if gs == "YES" then
    -                    print("HEY, " .. ns .. "??? YOU LEFT NO MONEY AT ALL!\n")
    -                    print("YOU ARE CHEATING ME OUT OF MY HARD-EARNED LIVING.\n")
    -                    print("\n")
    -                    print("WHAT A RIP OFF, " .. ns .. "!!!\n")
    -                    print("\n")
    -                    break
    -                elseif gs == "NO" then
    -                    print("THAT'S HONEST, " .. ns .. ", BUT HOW DO YOU EXPECT\n")
    -                    print("ME TO GO ON WITH MY PSYCHOLOGY STUDIES IF MY PATIENT\n")
    -                    print("DON'T PAY THEIR BILLS?\n")
    -                    break
    -                else
    -                    print("YOUR ANSWER OF '" .. gs .. "' CONFUSES ME, " .. ns .. ".\n")
    -                    print("PLEASE RESPOND WITH 'YES' OR 'NO'.\n")
    -                end
    -            end
    -
    -            break
    -        end
    -    end
    -
    -    print("\n")
    -    print("TAKE A WALK, " .. ns .. ".\n")
    -    print("\n")
    -    print("\n")
    -end
    -
    -main()
    \ No newline at end of file
    diff --git a/45_Hello/pascal/README.md b/45_Hello/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/45_Hello/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/45_Hello/python/hello.py b/45_Hello/python/hello.py
    index 661ea60a1..35a37c00d 100644
    --- a/45_Hello/python/hello.py
    +++ b/45_Hello/python/hello.py
    @@ -9,10 +9,17 @@
     """
     
     import time
    -from typing import Optional, Tuple
     
     
    -def get_yes_or_no() -> Tuple[bool, Optional[bool], str]:
    +def print_with_tab(space_count, msg):
    +    if space_count > 0:
    +        spaces = " " * space_count
    +    else:
    +        spaces = ""
    +    print(spaces + msg)
    +
    +
    +def get_yes_or_no():
         msg = input()
         if msg.upper() == "YES":
             return True, True, msg
    @@ -22,9 +29,10 @@ def get_yes_or_no() -> Tuple[bool, Optional[bool], str]:
             return False, None, msg
     
     
    -def ask_enjoy_question(user_name: str) -> None:
    +def ask_enjoy_question(user_name):
         print(f"HI THERE, {user_name}, ARE YOU ENJOYING YOURSELF HERE?")
     
    +    has_answer = False
         while True:
             valid, value, msg = get_yes_or_no()
     
    @@ -41,16 +49,17 @@ def ask_enjoy_question(user_name: str) -> None:
                 print("PLEASE ANSWER 'YES' OR 'NO'.  DO YOU LIKE IT HERE?")
     
     
    -def prompt_for_problems(user_name: str) -> str:
    +def prompt_for_problems(user_name):
         print()
         print(f"SAY, {user_name}, I CAN SOLVE ALL KINDS OF PROBLEMS EXCEPT")
         print("THOSE DEALING WITH GREECE.  WHAT KIND OF PROBLEMS DO")
         print("YOU HAVE? (ANSWER SEX, HEALTH, MONEY, OR JOB)")
     
    -    return input().upper()
    +    problem_type = input().upper()
    +    return problem_type
     
     
    -def prompt_too_much_or_too_little() -> Tuple[bool, Optional[bool]]:
    +def prompt_too_much_or_too_little():
         answer = input().upper()
         if answer == "TOO MUCH":
             return True, True
    @@ -59,49 +68,49 @@ def prompt_too_much_or_too_little() -> Tuple[bool, Optional[bool]]:
         return False, None
     
     
    -def solve_sex_problem(user_name: str) -> None:
    +def solve_sex_problem(user_name):
         print("IS YOUR PROBLEM TOO MUCH OR TOO LITTLE?")
         while True:
             valid, too_much = prompt_too_much_or_too_little()
             if valid:
                 if too_much:
    -                print("YOU CALL THAT A PROBLEM?!!  I SHOULD HAVE SUCH PROBLEMS!")
    +                print(f"YOU CALL THAT A PROBLEM?!!  I SHOULD HAVE SUCH PROBLEMS!")
                     print(f"IF IT BOTHERS YOU, {user_name}, TAKE A COLD SHOWER.")
                 else:
                     print(f"WHY ARE YOU HERE IN SUFFERN, {user_name}?  YOU SHOULD BE")
    -                print("IN TOKYO OR NEW YORK OR AMSTERDAM OR SOMEPLACE WITH SOME")
    -                print("REAL ACTION.")
    +                print(f"IN TOKYO OR NEW YORK OR AMSTERDAM OR SOMEPLACE WITH SOME")
    +                print(f"REAL ACTION.")
                 return
             else:
                 print(f"DON'T GET ALL SHOOK, {user_name}, JUST ANSWER THE QUESTION")
    -            print("WITH 'TOO MUCH' OR 'TOO LITTLE'.  WHICH IS IT?")
    +            print(f"WITH 'TOO MUCH' OR 'TOO LITTLE'.  WHICH IS IT?")
     
     
    -def solve_money_problem(user_name: str) -> None:
    +def solve_money_problem(user_name):
         print(f"SORRY, {user_name}, I'M BROKE TOO.  WHY DON'T YOU SELL")
         print("ENCYCLOPEADIAS OR MARRY SOMEONE RICH OR STOP EATING")
         print("SO YOU WON'T NEED SO MUCH MONEY?")
     
     
    -def solve_health_problem(user_name: str) -> None:
    +def solve_health_problem(user_name):
         print(f"MY ADVICE TO YOU {user_name} IS:")
         print("     1.  TAKE TWO ASPRIN")
         print("     2.  DRINK PLENTY OF FLUIDS (ORANGE JUICE, NOT BEER!)")
         print("     3.  GO TO BED (ALONE)")
     
     
    -def solve_job_problem(user_name: str) -> None:
    +def solve_job_problem(user_name):
         print(f"I CAN SYMPATHIZE WITH YOU {user_name}.  I HAVE TO WORK")
         print("VERY LONG HOURS FOR NO PAY -- AND SOME OF MY BOSSES")
         print(f"REALLY BEAT ON MY KEYBOARD.  MY ADVICE TO YOU, {user_name},")
         print("IS TO OPEN A RETAIL COMPUTER STORE.  IT'S GREAT FUN.")
     
     
    -def alert_unknown_problem_type(user_name: str, problem_type: str) -> None:
    +def alert_unknown_problem_type(user_name, problem_type):
         print(f"OH, {user_name}, YOUR ANSWER OF {problem_type} IS GREEK TO ME.")
     
     
    -def ask_question_loop(user_name: str) -> None:
    +def ask_question_loop(user_name):
         while True:
             problem_type = prompt_for_problems(user_name)
             if problem_type == "SEX":
    @@ -121,17 +130,18 @@ def ask_question_loop(user_name: str) -> None:
     
                 valid, value, msg = get_yes_or_no()
                 if valid:
    -                if not value:
    +                if value:
    +                    print("WHAT KIND (SEX, MONEY, HEALTH, JOB)")
    +                    break
    +                else:
                         return
    -                print("WHAT KIND (SEX, MONEY, HEALTH, JOB)")
    -                break
                 print(f"JUST A SIMPLE 'YES' OR 'NO' PLEASE, {user_name}.")
     
     
    -def ask_for_fee(user_name: str) -> None:
    +def ask_for_fee(user_name):
         print()
         print(f"THAT WILL BE $5.00 FOR THE ADVICE, {user_name}.")
    -    print("PLEASE LEAVE THE MONEY ON THE TERMINAL.")
    +    print(f"PLEASE LEAVE THE MONEY ON THE TERMINAL.")
         time.sleep(4)
         print()
         print()
    @@ -157,21 +167,26 @@ def ask_for_fee(user_name: str) -> None:
                 print("PLEASE RESPOND WITH 'YES' or 'NO'.")
     
     
    -def unhappy_goodbye(user_name: str) -> None:
    +def unhappy_goodbye(user_name):
         print()
         print(f"TAKE A WALK, {user_name}.")
         print()
         print()
     
     
    -def happy_goodbye(user_name: str) -> None:
    +def happy_goodbye(user_name):
         print(f"NICE MEETING YOU, {user_name}, HAVE A NICE DAY.")
     
     
    -def main() -> None:
    -    print(" " * 33 + "HELLO")
    -    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n")
    -    print("HELLO.  MY NAME IS CREATIVE COMPUTER.\n\n")
    +def main():
    +    print_with_tab(33, "HELLO")
    +    print_with_tab(15, "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
    +    print()
    +    print()
    +    print()
    +    print("HELLO.  MY NAME IS CREATIVE COMPUTER.")
    +    print()
    +    print()
         print("WHAT'S YOUR NAME?")
         user_name = input()
         print()
    @@ -182,7 +197,10 @@ def main() -> None:
     
         ask_for_fee(user_name)
     
    -    unhappy_goodbye(user_name)
    +    if False:
    +        happy_goodbye(user_name)
    +    else:
    +        unhappy_goodbye(user_name)
     
     
     if __name__ == "__main__":
    diff --git a/45_Hello/ruby/hello.rb b/45_Hello/ruby/hello.rb
    deleted file mode 100644
    index eb24d293d..000000000
    --- a/45_Hello/ruby/hello.rb
    +++ /dev/null
    @@ -1,191 +0,0 @@
    -class Hello
    -  def start
    -    puts  "HELLO.  MY NAME IS CREATIVE COMPUTER.\n\n"
    -    print "WHAT'S YOUR NAME? "
    -    user_name = gets.chomp!
    -
    -    ask_enjoy_question(user_name)
    -
    -    ask_question_loop(user_name)
    -
    -    isHonest = ask_for_fee(user_name)
    -    
    -    if isHonest
    -      happy_goodbye(user_name)
    -    else
    -      unhappy_goodbye(user_name)
    -    end
    -  end
    -  private
    -    def get_yes_or_no
    -      msg = gets.chomp!
    -      if msg.upcase() == "YES"
    -          return true, true, msg
    -      elsif msg.upcase() == "NO"
    -          return true, false, msg
    -      else
    -          return false, false, msg
    -      end
    -    end
    -
    -    def ask_enjoy_question user_name
    -      print "\nHI THERE, #{user_name}, ARE YOU ENJOYING YOURSELF HERE? "
    -
    -      while true
    -        valid, value, msg = get_yes_or_no()
    -
    -        if valid
    -          if value
    -            puts "\nI'M GLAD TO HEAR THAT, #{user_name}."
    -            break
    -          else
    -            puts "\nOH, I'M SORRY TO HEAR THAT, #{user_name}. MAYBE WE CAN"
    -            puts "BRIGHTEN UP YOUR VISIT A BIT."
    -            break
    -          end
    -        else
    -          puts "\n#{user_name}, I DON'T UNDERSTAND YOUR ANSWER OF '#{msg}'."
    -          print "PLEASE ANSWER 'YES' OR 'NO'.  DO YOU LIKE IT HERE? "
    -        end
    -      end
    -    end
    -
    -    def prompt_for_problems user_name
    -      puts "\nSAY, #{user_name}, I CAN SOLVE ALL KINDS OF PROBLEMS EXCEPT" 
    -      puts "THOSE DEALING WITH GREECE.  WHAT KIND OF PROBLEMS DO"
    -      print "YOU HAVE? (ANSWER SEX, HEALTH, MONEY, OR JOB) "
    -  
    -      problem_type = gets.chomp!
    -      return problem_type
    -    end
    -
    -    def prompt_too_much_or_too_little
    -      answer = gets.chomp!
    -      if answer.upcase() == "TOO MUCH"
    -        return true, true
    -      elsif answer.upcase() == "TOO LITTLE"
    -        return true, false
    -      else
    -        return false, false
    -      end
    -    end
    -
    -    def solve_sex_problem user_name
    -      print "\nIS YOUR PROBLEM TOO MUCH OR TOO LITTLE? "
    -      while true
    -        valid, too_much = prompt_too_much_or_too_little()
    -        if valid
    -          if too_much
    -            puts "\nYOU CALL THAT A PROBLEM?!!  I SHOULD HAVE SUCH PROBLEMS!"
    -            puts "IF IT BOTHERS YOU, #{user_name}, TAKE A COLD SHOWER."
    -            break
    -          else
    -            puts "\nWHY ARE YOU HERE IN SUFFERN, #{user_name}?  YOU SHOULD BE"
    -            puts "IN TOKYO OR NEW YORK OR AMSTERDAM OR SOMEPLACE WITH SOME"
    -            puts "REAL ACTION."
    -            break
    -          end
    -        else
    -          puts "\nDON'T GET ALL SHOOK, #{user_name}, JUST ANSWER THE QUESTION"
    -          print "WITH 'TOO MUCH' OR 'TOO LITTLE'.  WHICH IS IT? "
    -        end
    -      end
    -    end
    -
    -    def solve_health_problem user_name
    -      puts "\nMY ADVICE TO YOU #{user_name} IS:"
    -      puts "     1.  TAKE TWO ASPRIN"
    -      puts "     2.  DRINK PLENTY OF FLUIDS (ORANGE JUICE, NOT BEER!)"
    -      puts "     3.  GO TO BED (ALONE)"
    -    end
    -
    -    def solve_money_problem user_name
    -      puts "\nSORRY, #{user_name}, I'M BROKE TOO.  WHY DON'T YOU SELL"
    -      puts "ENCYCLOPEADIAS OR MARRY SOMEONE RICH OR STOP EATING"
    -      puts "SO YOU WON'T NEED SO MUCH MONEY?"
    -    end
    -
    -    def solve_job_problem user_name
    -      puts "\nI CAN SYMPATHIZE WITH YOU #{user_name}.  I HAVE TO WORK"
    -      puts "VERY LONG HOURS FOR NO PAY -- AND SOME OF MY BOSSES"
    -      puts "REALLY BEAT ON MY KEYBOARD.  MY ADVICE TO YOU, #{user_name},"
    -      puts "IS TO OPEN A RETAIL COMPUTER STORE.  IT'S GREAT FUN."
    -    end
    -
    -    def alert_unknown_problem_type user_name, problem_type
    -      puts "\nOH, #{user_name}, YOUR ANSWER OF #{problem_type} IS GREEK TO ME."
    -    end
    -
    -    def ask_question_loop user_name
    -      while true
    -        problem_type = prompt_for_problems(user_name)
    -        if problem_type == "SEX"
    -          solve_sex_problem(user_name)
    -        elsif problem_type == "HEALTH"
    -          solve_health_problem(user_name)
    -        elsif problem_type == "MONEY"
    -          solve_money_problem(user_name)
    -        elsif problem_type == "JOB"
    -          solve_job_problem(user_name)
    -        else
    -          alert_unknown_problem_type(user_name, problem_type)
    -        end
    -
    -        while true
    -          print "\nANY MORE PROBLEMS YOU WANT SOLVED, #{user_name}? "
    -
    -          valid, value, msg = get_yes_or_no()
    -          if valid
    -            if value
    -              puts "\nWHAT KIND (SEX, MONEY, HEALTH, JOB)"
    -              break
    -            else
    -              return
    -            end
    -          else
    -            puts "\nJUST A SIMPLE 'YES' OR 'NO' PLEASE, #{user_name}."
    -          end
    -        end
    -      end
    -    end
    -
    -    def ask_for_fee user_name
    -      puts "\nTHAT WILL BE $5.00 FOR THE ADVICE, #{user_name}."
    -      puts "PLEASE LEAVE THE MONEY ON THE TERMINAL."
    -      sleep(3)
    -      print "\n\nDID YOU LEAVE THE MONEY? "
    -  
    -      while true
    -        valid, value, msg = get_yes_or_no()
    -        if valid
    -            if value
    -              puts "\nHEY, #{user_name}, YOU LEFT NO MONEY AT ALL!"
    -              puts "YOU ARE CHEATING ME OUT OF MY HARD-EARNED LIVING."
    -              puts "\nWHAT A RIP OFF, #{user_name}!!!"
    -              return false
    -            else
    -              puts "\nTHAT'S HONEST, #{user_name}, BUT HOW DO YOU EXPECT"
    -              puts "ME TO GO ON WITH MY PSYCHOLOGY STUDIES IF MY PATIENTS"
    -              puts "DON'T PAY THEIR BILLS?"
    -              return true
    -            end
    -        else
    -          puts "\nYOUR ANSWER OF '#{msg}' CONFUSES ME, #{user_name}."
    -          print "PLEASE RESPOND WITH 'YES' or 'NO'. "
    -        end
    -      end
    -    end
    -
    -    def unhappy_goodbye user_name
    -      puts "\nTAKE A WALK, #{user_name}.\n\n"
    -    end
    -  
    -    def happy_goodbye user_name
    -      puts "\nNICE MEETING YOU, #{user_name}, HAVE A NICE DAY."
    -    end
    -end
    -
    -if __FILE__ == $0
    -  hello = Hello.new
    -  hello.start()
    -end
    \ No newline at end of file
    diff --git a/45_Hello/rust/Cargo.toml b/45_Hello/rust/Cargo.toml
    deleted file mode 100644
    index 7d75412a6..000000000
    --- a/45_Hello/rust/Cargo.toml
    +++ /dev/null
    @@ -1,6 +0,0 @@
    -[package]
    -name = "rust"
    -version = "0.1.0"
    -edition = "2021"
    -
    -[dependencies]
    diff --git a/45_Hello/rust/src/main.rs b/45_Hello/rust/src/main.rs
    deleted file mode 100644
    index 310c5db32..000000000
    --- a/45_Hello/rust/src/main.rs
    +++ /dev/null
    @@ -1,247 +0,0 @@
    -/** HELLO GAME BY DAVID AHL
    - * https://github.com/coding-horror/basic-computer-games/blob/main/45_Hello/hello.bas
    - * Direct conversion from BASIC to Rust by Pablo Marques (marquesrs).
    - * No additional features or improvements were added. As a faithful translation, 
    - * many of the code here are done in an unrecommended way by today's standards.
    - * 17/02/25
    -*/
    -
    -use std::io::Write;
    -
    -fn main() {
    -    // 2 PRINT TAB(33);"HELLO"
    -    // 4 PRINT TAB(15);"CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY"
    -    // 6 PRINT: PRINT: PRINT
    -    print!(
    -        "{}{}\n{}{}\n\n\n\n", 
    -        " ".repeat(33),
    -        "HELLO",
    -        " ".repeat(15),
    -        "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY"
    -    );
    -
    -    let mut input = String::new();
    -    
    -    //10 PRINT "HELLO.  MY NAME IS CREATIVE COMPUTER."
    -    //20 PRINT: PRINT: INPUT "WHAT'S YOUR NAME";N$: PRINT
    -    print!("HELLO. MY NAME IS CREATIVE COMPUTER.\n\nWHAT'S YOUR NAME? ");
    -    let _ = std::io::stdout().flush().unwrap();
    -    input.clear();
    -    std::io::stdin().read_line(&mut input).unwrap();
    -    let n = input.trim().to_uppercase();
    -    
    -    //30 PRINT "HI THERE, ";N$;", ARE YOU ENJOYING YOURSELF HERE";
    -    //40 INPUT B$: PRINT
    -    print!("\nHI THERE, {n}, ARE YOU ENJOYING YOURSELF HERE? ");
    -    loop {
    -        let _ = std::io::stdout().flush().unwrap();
    -        input.clear();
    -        std::io::stdin().read_line(&mut input).unwrap();
    -        let b = input.trim().to_uppercase();
    -
    -        //50 IF B$="YES" THEN 70    
    -        if b == "YES" {
    -            //70 PRINT "I'M GLAD TO HEAR THAT, ";N$;".": PRINT
    -            //75 GOTO 100
    -            println!("\nI'M GLAD TO HEAR THAT, {n}.");
    -            break;
    -        }
    -        //55 IF B$="NO" THEN 80
    -        else if b == "NO" { 
    -            //80 PRINT "OH, I'M SORRY TO HEAR THAT, ";N$;". MAYBE WE CAN"
    -            //85 PRINT "BRIGHTEN UP YOUR VISIT A BIT."
    -            println!("\nOH, I'M SORRY TO HEAR THAT, {n}. MAYBE WE CAN\n{}",
    -                "BRIGHTEN UP YOUR VISIT A BIT."
    -            );
    -            break;
    -        }
    -        else {
    -            //60 PRINT N$;", I DON'T UNDERSTAND YOUR ANSWER OF '";B$;"'."
    -            //65 PRINT "PLEASE ANSWER 'YES' OR 'NO'.  DO YOU LIKE IT HERE";: GOTO 40
    -            print!("\n{n}, I DON'T UNDERSTAND YOUR ANSWER OF '{b}'.\n{}",
    -                "PLEASE ANSWER 'YES' OR 'NO'.  DO YOU LIKE IT HERE? "
    -            );
    -        }
    -    }
    -    
    -    //100 PRINT
    -    //105 PRINT "SAY, ";N$;", I CAN SOLVE ALL KINDS OF PROBLEMS EXCEPT"
    -    //110 PRINT "THOSE DEALING WITH GREECE.  WHAT KIND OF PROBLEMS DO"
    -    //120 PRINT "YOU HAVE (ANSWER SEX, HEALTH, MONEY, OR JOB)";
    -    //125 INPUT C$
    -    //126 PRINT
    -    print!("\nSAY, {n}, I CAN SOLVE ALL KINDS OF PROBLEMS EXCEPT\n{}\n{}",
    -        "THOSE DEALING WITH GREECE.  WHAT KIND OF PROBLEMS DO",
    -        "YOU HAVE (ANSWER SEX, HEALTH, MONEY, OR JOB)? "
    -    );
    -    'outer: loop {
    -        let _ = std::io::stdout().flush().unwrap();
    -        input.clear();
    -        std::io::stdin().read_line(&mut input).unwrap();
    -        let c = input.trim().to_uppercase();
    -
    -        //130 IF C$="SEX" THEN 200
    -        if c == "SEX" {
    -            loop {
    -                //200 INPUT "IS YOUR PROBLEM TOO MUCH OR TOO LITTLE";D$: PRINT
    -                print!("\nIS YOUR PROBLEM TOO MUCH OR TOO LITTLE? ");
    -                let _ = std::io::stdout().flush().unwrap();
    -                input.clear();
    -                std::io::stdin().read_line(&mut input).unwrap();
    -                let d = input.trim().to_uppercase();
    -                
    -                //210 IF D$="TOO MUCH" THEN 220
    -                if d == "TOO MUCH" {
    -                    //220 PRINT "YOU CALL THAT A PROBLEM?!!  I SHOULD HAVE SUCH PROBLEMS!"
    -                    //225 PRINT "IF IT BOTHERS YOU, ";N$;", TAKE A COLD SHOWER."
    -                    //228 GOTO 250
    -                    println!("\nYOU CALL THAT A PROBLEM?!! I SHOULD HAVE SUCH PROBLEMS!\n{}",
    -                        format!("IF IT BOTHERS YOU, {n}, TAKE A COLD SHOWER.")
    -                    );
    -                    break;
    -                }
    -                //212 IF D$="TOO LITTLE" THEN 230
    -                else if d == "TOO LITTLE" {
    -                    //230 PRINT "WHY ARE YOU HERE IN SUFFERN, ";N$;"?  YOU SHOULD BE"
    -                    //235 PRINT "IN TOKYO OR NEW YORK OR AMSTERDAM OR SOMEPLACE WITH SOME"
    -                    //240 PRINT "REAL ACTION."
    -                    //250 PRINT
    -                    println!("\nWHY ARE YOU HERE IN SUFFERN, {n}? YOU SHOULD BE\n{}\n{}",
    -                        "IN TOKYO OR NEW YORK OR AMSTERDAM OR SOMEPLACE WITH",
    -                        "SOME REAL ACTION."
    -                    );
    -                    break;
    -                }
    -                else {
    -                    //215 PRINT "DON'T GET ALL SHOOK, ";N$;", JUST ANSWER THE QUESTION"
    -                    //217 INPUT "WITH 'TOO MUCH' OR 'TOO LITTLE'.  WHICH IS IT";D$:GOTO 210
    -                    println!("\nDON'T GET ALL SHOOK, {n}, JUST ANSWER THE QUESTION\n{}",
    -                        "WITH 'TOO MUCH' OR 'TOO LITTLE'. WHICH IS IT? "
    -                    );
    -                }
    -            }
    -        }
    -        //132 IF C$="HEALTH" THEN 180
    -        else if c == "HEALTH" {
    -            //180 PRINT "MY ADVICE TO YOU ";N$;" IS:"
    -            //185 PRINT "     1.  TAKE TWO ASPRIN"
    -            //188 PRINT "     2.  DRINK PLENTY OF FLUIDS (ORANGE JUICE, NOT BEER!)"
    -            //190 PRINT "     3.  GO TO BED (ALONE)"
    -            //195 GOTO 250
    -            println!("\nMY ADVICE TO YOU {n} IS:\n{}\n{}\n{}",
    -                "     1.  TAKE TWO ASPRIN",
    -                "     2.  DRINK PLENTY OF FLUIDS (ORANGE JUICE, NOT BEER!)",
    -                "     3.  GO TO BED (ALONE)"
    -            );
    -        }
    -        //134 IF C$="MONEY" THEN 160
    -        else if c == "MONEY" {
    -            //160 PRINT "SORRY, ";N$;", I'M BROKE TOO.  WHY DON'T YOU SELL"
    -            //162 PRINT "ENCYCLOPEADIAS OR MARRY SOMEONE RICH OR STOP EATING"
    -            //164 PRINT "SO YOU WON'T NEED SO MUCH MONEY?"
    -            //170 GOTO 250
    -            println!("\nSORRY, {n}, I'M BROKE TOO.  WHY DON'T YOU SELL\n{}\n{}",
    -                "ENCYCLOPEADIAS OR MARRY SOMEONE RICH OR STOP EATING",
    -                "SO YOU WON'T NEED SO MUCH MONEY? "
    -            );
    -        }
    -        //136 IF C$="JOB" THEN 145
    -        else if c == "JOB" {
    -            //145 PRINT "I CAN SYMPATHIZE WITH YOU ";N$;".  I HAVE TO WORK"
    -            //148 PRINT "VERY LONG HOURS FOR NO PAY -- AND SOME OF MY BOSSES"
    -            //150 PRINT "REALLY BEAT ON MY KEYBOARD.  MY ADVICE TO YOU, ";N$;","
    -            //153 PRINT "IS TO OPEN A RETAIL COMPUTER STORE.  IT'S GREAT FUN."
    -            //155 GOTO 250
    -            println!("\nI CAN SYMPATHIZE WITH YOU {n}.  I HAVE TO WORK\n{}\n{}\n{}",
    -                "VERY LONG HOURS FOR NO PAY -- AND SOME OF MY BOSSES",
    -                format!("REALLY BEAT ON MY KEYBOARD.  MY ADVICE TO YOU, {n}"),
    -                "IS TO OPEN A RETAIL COMPUTER STORE.  IT'S GREAT FUN."
    -            );
    -        }
    -        else {
    -            //138 PRINT "OH, ";N$;", YOUR ANSWER OF ";C$;" IS GREEK TO ME."
    -            //140 GOTO 250
    -            println!("\nOH, {n}, YOUR ANSWER OF {c} IS GREEK TO ME.");
    -        }
    -        
    -        loop {
    -            //255 PRINT "ANY MORE PROBLEMS YOU WANT SOLVED, ";N$;
    -            //260 INPUT E$: PRINT
    -            print!("\nANY MORE PROBLEMS YOU WANT SOLVED, {n}? ");
    -            let _ = std::io::stdout().flush().unwrap();
    -            input.clear();
    -            std::io::stdin().read_line(&mut input).unwrap();
    -            let e = input.trim().to_uppercase();
    -            
    -            //270 IF E$="YES" THEN 280
    -            if e == "YES" {
    -                //280 PRINT "WHAT KIND (SEX, MONEY, HEALTH, JOB)";
    -                //282 GOTO 125
    -                print!("\nWHAT KIND (SEX, MONEY, HEALTH, JOB)? ");
    -                continue 'outer;
    -            }
    -            //273 IF E$="NO" THEN 300
    -            else if e == "NO" {
    -                break 'outer;
    -            }
    -            else {
    -                //275 PRINT "JUST A SIMPLE 'YES' OR 'NO' PLEASE, ";N$;"."
    -                //277 GOTO 255
    -                println!("\nJUST A SIMPLE 'YES' OR 'NO' PLEASE, {n}.");
    -            }
    -        }
    -    }
    -    //300 PRINT
    -    //302 PRINT "THAT WILL BE $5.00 FOR THE ADVICE, ";N$;"."
    -    //305 PRINT "PLEASE LEAVE THE MONEY ON THE TERMINAL."
    -    println!("\nTHAT WILL BE $5.00 FOR THE ADVICE, {n}.\n{}",
    -        "PLEASE LEAVE THE MONEY ON THE TERMINAL."
    -    );
    -    //307 FOR I=1 TO 2000: NEXT I
    -    //310 PRINT: PRINT: PRINT
    -    loop {
    -        //315 PRINT "DID YOU LEAVE THE MONEY";
    -        //320 INPUT G$: PRINT
    -        print!("\nDID YOU LEAVE THE MONEY? ");
    -        let _ = std::io::stdout().flush().unwrap();
    -        input.clear();
    -        std::io::stdin().read_line(&mut input).unwrap();
    -        let g = input.trim().to_uppercase();
    -        
    -        //325 IF G$="YES" THEN 350
    -        if g == "YES" {
    -            //350 PRINT "HEY, ";N$;"??? YOU LEFT NO MONEY AT ALL!"
    -            //355 PRINT "YOU ARE CHEATING ME OUT OF MY HARD-EARNED LIVING."
    -            //360 PRINT:PRINT "WHAT A RIP OFF, ";N$;"!!!":PRINT
    -            //365 GOTO 385
    -            println!("\nHEY, {n}??? YOU LEFT NO MONEY AT ALL!\n{}\n{}",
    -                "YOU ARE CHEATING ME OUT OF MY HARD-EARNED LIVING.",
    -                format!("WHAT A RIP OFF, {n}!!!\n\nTAKE A WALK, {n}")
    -            );
    -            break;
    -        }
    -        //330 IF G$="NO" THEN 370
    -        else if g == "NO" {
    -            //370 PRINT "THAT'S HONEST, ";N$;", BUT HOW DO YOU EXPECT"
    -            //375 PRINT "ME TO GO ON WITH MY PSYCHOLOGY STUDIES IF MY PATIENTS"
    -            //380 PRINT "DON'T PAY THEIR BILLS?"
    -            //385 PRINT:PRINT "TAKE A WALK, ";N$;".":PRINT:PRINT:GOTO 999
    -            println!("\nTHAT'S HONEST, {n}, BUT HOW DO YOU EXPECT\n{}\n{}",
    -                "ME TO GO ON WITH MY PSYCHOLOGY STUDIES IF MY PATIENTS",
    -                format!("DON'T PAY THEIR BILLS?\n\nTAKE A WALK, {n}")
    -            );
    -            break;
    -        }
    -        else {
    -            //335 PRINT "YOUR ANSWER OF '";G$;"' CONFUSES ME, ";N$;"."
    -            //340 PRINT "PLEASE RESPOND WITH 'YES' OR 'NO'.": GOTO 315
    -            println!("YOUR ANSWER OF '{g}' CONFUSES ME, {n}.\n{}",
    -                "PLEASE RESPOND WITH 'YES' OR 'NO'."
    -            );
    -        }    
    -    }
    -    
    -    //390 PRINT "NICE MEETING YOU, ";N$;", HAVE A NICE DAY." -> unreachable
    -    //400 REM
    -    //999 END
    -}
    diff --git a/45_Hello/vbnet/Hello.sln b/45_Hello/vbnet/Hello.sln
    deleted file mode 100644
    index 72ecdc64d..000000000
    --- a/45_Hello/vbnet/Hello.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 9b55d8056..000000000
    --- a/45_Hello/vbnet/Hello.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Hello
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/46_Hexapawn/README.md b/46_Hexapawn/README.md
    index 6376c0367..0197fa143 100644
    --- a/46_Hexapawn/README.md
    +++ b/46_Hexapawn/README.md
    @@ -14,11 +14,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Known Bugs
    -
    -- There are valid board positions that will cause the program to print "ILLEGAL BOARD PATTERN" and break.  For example: human 8,5; computer 1,5; human 9,5; computer 3,5; human 7,5.  This is a valid game-over pattern, but it is not detected as such because of incorrect logic in lines 240-320 (intended to detect whether the computer has any legal moves).
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/46_Hexapawn/csharp/Board.cs b/46_Hexapawn/csharp/Board.cs
    deleted file mode 100644
    index dbca8681b..000000000
    --- a/46_Hexapawn/csharp/Board.cs
    +++ /dev/null
    @@ -1,72 +0,0 @@
    -using System;
    -using System.Collections;
    -using System.Collections.Generic;
    -using System.Linq;
    -using System.Text;
    -
    -using static Hexapawn.Pawn;
    -
    -namespace Hexapawn;
    -
    -internal class Board : IEnumerable, IEquatable
    -{
    -    private readonly Pawn[] _cells;
    -
    -    public Board()
    -    {
    -        _cells = new[]
    -        {
    -            Black, Black, Black,
    -            None,  None,  None,
    -            White, White, White
    -        };
    -    }
    -
    -    public Board(params Pawn[] cells)
    -    {
    -        _cells = cells;
    -    }
    -
    -    public Pawn this[int index]
    -    {
    -        get => _cells[index - 1];
    -        set => _cells[index - 1] = value;
    -    }
    -
    -    public Board Reflected => new(Cell.AllCells.Select(c => this[c.Reflected]).ToArray());
    -
    -    public IEnumerator GetEnumerator() => _cells.OfType().GetEnumerator();
    -
    -    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
    -
    -    public override string ToString()
    -    {
    -        var builder = new StringBuilder().AppendLine();
    -        for (int row = 0; row < 3; row++)
    -        {
    -            builder.Append("          ");
    -            for (int col = 0; col < 3; col++)
    -            {
    -                builder.Append(_cells[row * 3 + col]);
    -            }
    -            builder.AppendLine();
    -        }
    -        return builder.ToString();
    -    }
    -
    -    public bool Equals(Board other) => other?.Zip(this).All(x => x.First == x.Second) ?? false;
    -
    -    public override bool Equals(object obj) => Equals(obj as Board);
    -
    -    public override int GetHashCode()
    -    {
    -        var hash = 19;
    -
    -        for (int i = 0; i < 9; i++)
    -        {
    -            hash = hash * 53 + _cells[i].GetHashCode();
    -        }
    -
    -        return hash;
    -    }
    -}
    diff --git a/46_Hexapawn/csharp/Cell.cs b/46_Hexapawn/csharp/Cell.cs
    deleted file mode 100644
    index ac244ed58..000000000
    --- a/46_Hexapawn/csharp/Cell.cs
    +++ /dev/null
    @@ -1,41 +0,0 @@
    -using System;
    -using System.Collections.Generic;
    -
    -namespace Hexapawn;
    -
    -// Represents a cell on the board, numbered 1 to 9, with support for finding the reflection of the reference around
    -// the middle column of the board.
    -internal class Cell
    -{
    -    private static readonly Cell[] _cells = new Cell[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    -    private static readonly Cell[] _reflected = new Cell[] { 3, 2, 1, 6, 5, 4, 9, 8, 7 };
    -    private readonly int _number;
    -    private Cell(int number)
    -    {
    -        if (number < 1 || number > 9)
    -        {
    -            throw new ArgumentOutOfRangeException(nameof(number), number, "Must be from 1 to 9");
    -        }
    -        _number = number;
    -    }
    -    // Facilitates enumerating all the cells.
    -    public static IEnumerable AllCells => _cells;
    -    // Takes a value input by the user and attempts to create a Cell reference
    -    public static bool TryCreate(float input, out Cell cell)
    -    {
    -        if (IsInteger(input) && input >= 1 && input <= 9)
    -        {
    -            cell = (int)input;
    -            return true;
    -        }
    -        cell = default;
    -        return false;
    -        static bool IsInteger(float value) => value - (int)value == 0;
    -    }
    -    // Returns the reflection of the cell reference about the middle column of the board.
    -    public Cell Reflected => _reflected[_number - 1];
    -    // Allows the cell reference to be used where an int is expected, such as the indexer in Board.
    -    public static implicit operator int(Cell c) => c._number;
    -    public static implicit operator Cell(int number) => new(number);
    -    public override string ToString() => _number.ToString();
    -}
    diff --git a/46_Hexapawn/csharp/Computer.cs b/46_Hexapawn/csharp/Computer.cs
    deleted file mode 100644
    index 9411a4a8a..000000000
    --- a/46_Hexapawn/csharp/Computer.cs
    +++ /dev/null
    @@ -1,138 +0,0 @@
    -using System;
    -using System.Collections.Generic;
    -using System.Linq;
    -using Games.Common.IO;
    -using Games.Common.Randomness;
    -using static Hexapawn.Pawn;
    -
    -namespace Hexapawn;
    -
    -/// 
    -/// Encapsulates the logic of the computer player.
    -/// 
    -internal class Computer
    -{
    -    private readonly TextIO _io;
    -    private readonly IRandom _random;
    -    private readonly Dictionary> _potentialMoves;
    -    private (List, Move) _lastMove;
    -    public Computer(TextIO io, IRandom random)
    -    {
    -        _io = io;
    -        _random = random;
    -
    -        // This dictionary implements the data in the original code, which encodes board positions for which the
    -        // computer has a legal move, and the list of possible moves for each position:
    -        //   900 DATA -1,-1,-1,1,0,0,0,1,1,-1,-1,-1,0,1,0,1,0,1
    -        //   905 DATA -1,0,-1,-1,1,0,0,0,1,0,-1,-1,1,-1,0,0,0,1
    -        //   910 DATA -1,0,-1,1,1,0,0,1,0,-1,-1,0,1,0,1,0,0,1
    -        //   915 DATA 0,-1,-1,0,-1,1,1,0,0,0,-1,-1,-1,1,1,1,0,0
    -        //   920 DATA -1,0,-1,-1,0,1,0,1,0,0,-1,-1,0,1,0,0,0,1
    -        //   925 DATA 0,-1,-1,0,1,0,1,0,0,-1,0,-1,1,0,0,0,0,1
    -        //   930 DATA 0,0,-1,-1,-1,1,0,0,0,-1,0,0,1,1,1,0,0,0
    -        //   935 DATA 0,-1,0,-1,1,1,0,0,0,-1,0,0,-1,-1,1,0,0,0
    -        //   940 DATA 0,0,-1,-1,1,0,0,0,0,0,-1,0,1,-1,0,0,0,0
    -        //   945 DATA -1,0,0,-1,1,0,0,0,0
    -        //   950 DATA 24,25,36,0,14,15,36,0,15,35,36,47,36,58,59,0
    -        //   955 DATA 15,35,36,0,24,25,26,0,26,57,58,0
    -        //   960 DATA 26,35,0,0,47,48,0,0,35,36,0,0,35,36,0,0
    -        //   965 DATA 36,0,0,0,47,58,0,0,15,0,0,0
    -        //   970 DATA 26,47,0,0,47,58,0,0,35,36,47,0,28,58,0,0,15,47,0,0
    -        //
    -        // The original code loaded this data into two arrays.
    -        //   40 FOR I=1 TO 19: FOR J=1 TO 9: READ B(I,J): NEXT J: NEXT I
    -        //   45 FOR I=1 TO 19: FOR J=1 TO 4: READ M(I,J): NEXT J: NEXT I
    -        //
    -        // When finding moves for the computer the first array was searched for the current board position, or the
    -        // reflection of it, and the resulting index was used in the second array to get the possible moves.
    -        // With this dictionary we can just use the current board as the index, and retrieve a list of moves for
    -        // consideration by the computer.
    -        _potentialMoves = new()
    -        {
    -            [new(Black, Black, Black, White, None,  None,  None,  White, White)] = Moves((2, 4), (2, 5), (3, 6)),
    -            [new(Black, Black, Black, None,  White, None,  White, None,  White)] = Moves((1, 4), (1, 5), (3, 6)),
    -            [new(Black, None,  Black, Black, White, None,  None,  None,  White)] = Moves((1, 5), (3, 5), (3, 6), (4, 7)),
    -            [new(None,  Black, Black, White, Black, None,  None,  None,  White)] = Moves((3, 6), (5, 8), (5, 9)),
    -            [new(Black, None,  Black, White, White, None,  None,  White, None)]  = Moves((1, 5), (3, 5), (3, 6)),
    -            [new(Black, Black, None,  White, None,  White, None,  None,  White)] = Moves((2, 4), (2, 5), (2, 6)),
    -            [new(None,  Black, Black, None,  Black, White, White, None,  None)]  = Moves((2, 6), (5, 7), (5, 8)),
    -            [new(None,  Black, Black, Black, White, White, White, None,  None)]  = Moves((2, 6), (3, 5)),
    -            [new(Black, None,  Black, Black, None,  White, None,  White, None)]  = Moves((4, 7), (4, 8)),
    -            [new(None,  Black, Black, None,  White, None,  None,  None,  White)] = Moves((3, 5), (3, 6)),
    -            [new(None,  Black, Black, None,  White, None,  White, None,  None)]  = Moves((3, 5), (3, 6)),
    -            [new(Black, None,  Black, White, None,  None,  None,  None,  White)] = Moves((3, 6)),
    -            [new(None,  None,  Black, Black, Black, White, None,  None,  None)]  = Moves((4, 7), (5, 8)),
    -            [new(Black, None,  None,  White, White, White, None,  None,  None)]  = Moves((1, 5)),
    -            [new(None,  Black, None,  Black, White, White, None,  None,  None)]  = Moves((2, 6), (4, 7)),
    -            [new(Black, None,  None,  Black, Black, White, None,  None,  None)]  = Moves((4, 7), (5, 8)),
    -            [new(None,  None,  Black, Black, White, None,  None,  None,  None)]  = Moves((3, 5), (3, 6), (4, 7)),
    -            [new(None,  Black, None,  White, Black, None,  None,  None,  None)]  = Moves((2, 8), (5, 8)),
    -            [new(Black, None,  None,  Black, White, None,  None,  None,  None)]  = Moves((1, 5), (4, 7))
    -        };
    -    }
    -
    -    // Try to make a move. We first try to find a legal move for the current board position.
    -    public bool TryMove(Board board)
    -    {
    -        if (TryGetMoves(board, out var moves, out var reflected) &&
    -            TrySelectMove(moves, out var move))
    -        {
    -            // We've found a move, so we record it as the last move made, and then announce and make the move.
    -            _lastMove = (moves, move);
    -            // If we found the move from a reflacted match of the board we need to make the reflected move.
    -            if (reflected) { move = move.Reflected; }
    -            _io.WriteLine($"I move {move}");
    -            move.Execute(board);
    -            return true;
    -        }
    -        // We haven't found a move for this board position, so remove the previous move that led to this board
    -        // position from future consideration. We don't want to make that move again, because we now know it's a
    -        // non-winning move.
    -        ExcludeLastMoveFromFuturePlay();
    -        return false;
    -    }
    -
    -    // Looks up the given board and its reflection in the potential moves dictionary. If it's found then we have a
    -    // list of potential moves. If the board is not found in the dictionary then the computer has no legal moves,
    -    // and the human player wins.
    -    private bool TryGetMoves(Board board, out List moves, out bool reflected)
    -    {
    -        if (_potentialMoves.TryGetValue(board, out moves))
    -        {
    -            reflected = false;
    -            return true;
    -        }
    -        if (_potentialMoves.TryGetValue(board.Reflected, out moves))
    -        {
    -            reflected = true;
    -            return true;
    -        }
    -        reflected = default;
    -        return false;
    -    }
    -
    -    // Get a random move from the list. If the list is empty, then we've previously eliminated all the moves for
    -    // this board position as being non-winning moves. We therefore resign the game.
    -    private bool TrySelectMove(List moves, out Move move)
    -    {
    -        if (moves.Any())
    -        {
    -            move = moves[_random.Next(moves.Count)];
    -            return true;
    -        }
    -        _io.WriteLine("I resign.");
    -        move = null;
    -        return false;
    -    }
    -
    -    private void ExcludeLastMoveFromFuturePlay()
    -    {
    -        var (moves, move) = _lastMove;
    -        moves.Remove(move);
    -    }
    -
    -    private static List Moves(params Move[] moves) => moves.ToList();
    -
    -    public bool IsFullyAdvanced(Board board) =>
    -        board[9] == Black || board[8] == Black || board[7] == Black;
    -}
    diff --git a/46_Hexapawn/csharp/Game.cs b/46_Hexapawn/csharp/Game.cs
    deleted file mode 100644
    index 335da020c..000000000
    --- a/46_Hexapawn/csharp/Game.cs
    +++ /dev/null
    @@ -1,41 +0,0 @@
    -using System;
    -using Games.Common.IO;
    -
    -namespace Hexapawn;
    -
    -// A single game of Hexapawn
    -internal class Game
    -{
    -    private readonly TextIO _io;
    -    private readonly Board _board;
    -
    -    public Game(TextIO io)
    -    {
    -        _board = new Board();
    -        _io = io;
    -    }
    -
    -    public object Play(Human human, Computer computer)
    -    {
    -        _io.WriteLine(_board);
    -        while(true)
    -        {
    -            human.Move(_board);
    -            _io.WriteLine(_board);
    -            if (!computer.TryMove(_board))
    -            {
    -                return human;
    -            }
    -            _io.WriteLine(_board);
    -            if (computer.IsFullyAdvanced(_board) || human.HasNoPawns(_board))
    -            {
    -                return computer;
    -            }
    -            if (!human.HasLegalMove(_board))
    -            {
    -                _io.Write("You can't move, so ");
    -                return computer;
    -            }
    -        }
    -    }
    -}
    diff --git a/46_Hexapawn/csharp/GameSeries.cs b/46_Hexapawn/csharp/GameSeries.cs
    deleted file mode 100644
    index 2c021cc51..000000000
    --- a/46_Hexapawn/csharp/GameSeries.cs
    +++ /dev/null
    @@ -1,47 +0,0 @@
    -using System.Collections.Generic;
    -using System.Linq;
    -using Games.Common.IO;
    -using Games.Common.Randomness;
    -using Hexapawn.Resources;
    -
    -namespace Hexapawn;
    -
    -// Runs series of games between the computer and the human player
    -internal class GameSeries
    -{
    -    private readonly TextIO _io;
    -    private readonly Computer _computer;
    -    private readonly Human _human;
    -    private readonly Dictionary _wins;
    -
    -    public GameSeries(TextIO io, IRandom random)
    -    {
    -        _io = io;
    -        _computer = new(io, random);
    -        _human = new(io);
    -        _wins = new() { [_computer] = 0, [_human] = 0 };
    -    }
    -
    -    public void Play()
    -    {
    -        _io.Write(Resource.Streams.Title);
    -
    -        if (_io.GetYesNo("Instructions") == 'Y')
    -        {
    -            _io.Write(Resource.Streams.Instructions);
    -        }
    -
    -        while (true)
    -        {
    -            var game = new Game(_io);
    -
    -            var winner = game.Play(_human, _computer);
    -            _wins[winner]++;
    -            _io.WriteLine(winner == _computer ? "I win." : "You win.");
    -
    -            _io.Write($"I have won {_wins[_computer]} and you {_wins[_human]}");
    -            _io.WriteLine($" out of {_wins.Values.Sum()} games.");
    -            _io.WriteLine();
    -        }
    -    }
    -}
    diff --git a/46_Hexapawn/csharp/Hexapawn.csproj b/46_Hexapawn/csharp/Hexapawn.csproj
    deleted file mode 100644
    index de228ec6e..000000000
    --- a/46_Hexapawn/csharp/Hexapawn.csproj
    +++ /dev/null
    @@ -1,16 +0,0 @@
    -
    -
    -  
    -    Exe
    -    net6.0
    -  
    -
    -  
    -    
    -  
    -
    -  
    -    
    -  
    -
    -
    diff --git a/46_Hexapawn/csharp/Hexapawn.sln b/46_Hexapawn/csharp/Hexapawn.sln
    index 06e7b32fc..6cfc8a8fd 100644
    --- a/46_Hexapawn/csharp/Hexapawn.sln
    +++ b/46_Hexapawn/csharp/Hexapawn.sln
    @@ -1,25 +1,34 @@
     
     Microsoft Visual Studio Solution File, Format Version 12.00
    -# Visual Studio Version 17
    -VisualStudioVersion = 17.0.32014.148
    +# Visual Studio 15
    +VisualStudioVersion = 15.0.26124.0
     MinimumVisualStudioVersion = 15.0.26124.0
    -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hexapawn", "Hexapawn.csproj", "{785DA416-2609-4DB1-9F18-63CF6AC9927E}"
    +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hexapawn", "Hexapawn\Hexapawn.csproj", "{679D95BE-6E0C-4D8C-A2D4-0957576B63F3}"
     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
    -	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
    +		Release|x64 = Release|x64
    +		Release|x86 = Release|x86
     	EndGlobalSection
     	GlobalSection(SolutionProperties) = preSolution
     		HideSolutionNode = FALSE
     	EndGlobalSection
    -	GlobalSection(ExtensibilityGlobals) = postSolution
    -		SolutionGuid = {D662AD9F-88B1-4AC9-83AD-DBFC08F384A8}
    +	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
     	EndGlobalSection
     EndGlobal
    diff --git a/46_Hexapawn/csharp/Hexapawn/Board.cs b/46_Hexapawn/csharp/Hexapawn/Board.cs
    new file mode 100644
    index 000000000..ba7d19ada
    --- /dev/null
    +++ b/46_Hexapawn/csharp/Hexapawn/Board.cs
    @@ -0,0 +1,73 @@
    +using System;
    +using System.Collections;
    +using System.Collections.Generic;
    +using System.Linq;
    +using System.Text;
    +
    +using static Hexapawn.Pawn;
    +
    +namespace Hexapawn
    +{
    +    internal class Board : IEnumerable, IEquatable
    +    {
    +        private readonly Pawn[] _cells;
    +
    +        public Board()
    +        {
    +            _cells = new[]
    +            {
    +                Black, Black, Black,
    +                None,  None,  None,
    +                White, White, White
    +            };
    +        }
    +
    +        public Board(params Pawn[] cells)
    +        {
    +            _cells = cells;
    +        }
    +
    +        public Pawn this[int index]
    +        {
    +            get => _cells[index - 1];
    +            set => _cells[index - 1] = value;
    +        }
    +
    +        public Board Reflected => new(Cell.AllCells.Select(c => this[c.Reflected]).ToArray());
    +
    +        public IEnumerator GetEnumerator() => _cells.OfType().GetEnumerator();
    +
    +        IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
    +
    +        public override string ToString()
    +        {
    +            var builder = new StringBuilder().AppendLine();
    +            for (int row = 0; row < 3; row++)
    +            {
    +                builder.Append("          ");
    +                for (int col = 0; col < 3; col++)
    +                {
    +                    builder.Append(_cells[row * 3 + col]);
    +                }
    +                builder.AppendLine();
    +            }
    +            return builder.ToString();
    +        }
    +
    +        public bool Equals(Board other) => other?.Zip(this).All(x => x.First == x.Second) ?? false;
    +
    +        public override bool Equals(object obj) => Equals(obj as Board);
    +
    +        public override int GetHashCode()
    +        {
    +            var hash = 19;
    +
    +            for (int i = 0; i < 9; i++)
    +            {
    +                hash = hash * 53 + _cells[i].GetHashCode();
    +            }
    +
    +            return hash;
    +        }
    +    }
    +}
    diff --git a/46_Hexapawn/csharp/Hexapawn/Cell.cs b/46_Hexapawn/csharp/Hexapawn/Cell.cs
    new file mode 100644
    index 000000000..7647e0bca
    --- /dev/null
    +++ b/46_Hexapawn/csharp/Hexapawn/Cell.cs
    @@ -0,0 +1,53 @@
    +using System;
    +using System.Collections.Generic;
    +
    +namespace Hexapawn
    +{
    +    // Represents a cell on the board, numbered 1 to 9, with support for finding the reflection of the reference around
    +    // the middle column of the board.
    +    internal class Cell
    +    {
    +        private static readonly Cell[] _cells = new Cell[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    +        private static readonly Cell[] _reflected = new Cell[] { 3, 2, 1, 6, 5, 4, 9, 8, 7 };
    +
    +        private readonly int _number;
    +
    +        private Cell(int number)
    +        {
    +            if (number < 1 || number > 9)
    +            {
    +                throw new ArgumentOutOfRangeException(nameof(number), number, "Must be from 1 to 9");
    +            }
    +
    +            _number = number;
    +        }
    +
    +        // Facilitates enumerating all the cells.
    +        public static IEnumerable AllCells => _cells;
    +
    +        // Takes a value input by the user and attempts to create a Cell reference
    +        public static bool TryCreate(float input, out Cell cell)
    +        {
    +            if (IsInteger(input) && input >= 1 && input <= 9)
    +            {
    +                cell = (int)input;
    +                return true;
    +            }
    +
    +            cell = default;
    +            return false;
    +
    +            static bool IsInteger(float value) => value - (int)value == 0;
    +        }
    +
    +        // Returns the reflection of the cell reference about the middle column of the board.
    +        public Cell Reflected => _reflected[_number - 1];
    +
    +        // Allows the cell reference to be used where an int is expected, such as the indexer in Board.
    +        public static implicit operator int(Cell c) => c._number;
    +
    +        public static implicit operator Cell(int number) => new(number);
    +
    +        public override string ToString() => _number.ToString();
    +    }
    +}
    diff --git a/46_Hexapawn/csharp/Hexapawn/Computer.cs b/46_Hexapawn/csharp/Hexapawn/Computer.cs
    new file mode 100644
    index 000000000..41e2b4a2b
    --- /dev/null
    +++ b/46_Hexapawn/csharp/Hexapawn/Computer.cs
    @@ -0,0 +1,146 @@
    +using System;
    +using System.Collections.Generic;
    +using System.Linq;
    +using static Hexapawn.Pawn;
    +using static Hexapawn.Cell;
    +
    +namespace Hexapawn
    +{
    +    /// 
    +    /// Encapsulates the logic of the computer player.
    +    /// 
    +    internal class Computer : IPlayer
    +    {
    +        private readonly Random _random = new();
    +        private readonly Dictionary> _potentialMoves;
    +        private (List, Move) _lastMove;
    +
    +        public Computer()
    +        {
    +            // This dictionary implements the data in the original code, which encodes board positions for which the
    +            // computer has a legal move, and the list of possible moves for each position:
    +            //   900 DATA -1,-1,-1,1,0,0,0,1,1,-1,-1,-1,0,1,0,1,0,1
    +            //   905 DATA -1,0,-1,-1,1,0,0,0,1,0,-1,-1,1,-1,0,0,0,1
    +            //   910 DATA -1,0,-1,1,1,0,0,1,0,-1,-1,0,1,0,1,0,0,1
    +            //   915 DATA 0,-1,-1,0,-1,1,1,0,0,0,-1,-1,-1,1,1,1,0,0
    +            //   920 DATA -1,0,-1,-1,0,1,0,1,0,0,-1,-1,0,1,0,0,0,1
    +            //   925 DATA 0,-1,-1,0,1,0,1,0,0,-1,0,-1,1,0,0,0,0,1
    +            //   930 DATA 0,0,-1,-1,-1,1,0,0,0,-1,0,0,1,1,1,0,0,0
    +            //   935 DATA 0,-1,0,-1,1,1,0,0,0,-1,0,0,-1,-1,1,0,0,0
    +            //   940 DATA 0,0,-1,-1,1,0,0,0,0,0,-1,0,1,-1,0,0,0,0
    +            //   945 DATA -1,0,0,-1,1,0,0,0,0
    +            //   950 DATA 24,25,36,0,14,15,36,0,15,35,36,47,36,58,59,0
    +            //   955 DATA 15,35,36,0,24,25,26,0,26,57,58,0
    +            //   960 DATA 26,35,0,0,47,48,0,0,35,36,0,0,35,36,0,0
    +            //   965 DATA 36,0,0,0,47,58,0,0,15,0,0,0
    +            //   970 DATA 26,47,0,0,47,58,0,0,35,36,47,0,28,58,0,0,15,47,0,0
    +            //
    +            // The original code loaded this data into two arrays.
    +            //   40 FOR I=1 TO 19: FOR J=1 TO 9: READ B(I,J): NEXT J: NEXT I
    +            //   45 FOR I=1 TO 19: FOR J=1 TO 4: READ M(I,J): NEXT J: NEXT I
    +            //
    +            // When finding moves for the computer the first array was searched for the current board position, or the
    +            // reflection of it, and the resulting index was used in the second array to get the possible moves.
    +            // With this dictionary we can just use the current board as the index, and retrieve a list of moves for
    +            // consideration by the computer.
    +            _potentialMoves = new()
    +            {
    +                [new(Black, Black, Black, White, None,  None,  None,  White, White)] = Moves((2, 4), (2, 5), (3, 6)),
    +                [new(Black, Black, Black, None,  White, None,  White, None,  White)] = Moves((1, 4), (1, 5), (3, 6)),
    +                [new(Black, None,  Black, Black, White, None,  None,  None,  White)] = Moves((1, 5), (3, 5), (3, 6), (4, 7)),
    +                [new(None,  Black, Black, White, Black, None,  None,  None,  White)] = Moves((3, 6), (5, 8), (5, 9)),
    +                [new(Black, None,  Black, White, White, None,  None,  White, None)]  = Moves((1, 5), (3, 5), (3, 6)),
    +                [new(Black, Black, None,  White, None,  White, None,  None,  White)] = Moves((2, 4), (2, 5), (2, 6)),
    +                [new(None,  Black, Black, None,  Black, White, White, None,  None)]  = Moves((2, 6), (5, 7), (5, 8)),
    +                [new(None,  Black, Black, Black, White, White, White, None,  None)]  = Moves((2, 6), (3, 5)),
    +                [new(Black, None,  Black, Black, None,  White, None,  White, None)]  = Moves((4, 7), (4, 8)),
    +                [new(None,  Black, Black, None,  White, None,  None,  None,  White)] = Moves((3, 5), (3, 6)),
    +                [new(None,  Black, Black, None,  White, None,  White, None,  None)]  = Moves((3, 5), (3, 6)),
    +                [new(Black, None,  Black, White, None,  None,  None,  None,  White)] = Moves((3, 6)),
    +                [new(None,  None,  Black, Black, Black, White, None,  None,  None)]  = Moves((4, 7), (5, 8)),
    +                [new(Black, None,  None,  White, White, White, None,  None,  None)]  = Moves((1, 5)),
    +                [new(None,  Black, None,  Black, White, White, None,  None,  None)]  = Moves((2, 6), (4, 7)),
    +                [new(Black, None,  None,  Black, Black, White, None,  None,  None)]  = Moves((4, 7), (5, 8)),
    +                [new(None,  None,  Black, Black, White, None,  None,  None,  None)]  = Moves((3, 5), (3, 6), (4, 7)),
    +                [new(None,  Black, None,  White, Black, None,  None,  None,  None)]  = Moves((2, 8), (5, 8)),
    +                [new(Black, None,  None,  Black, White, None,  None,  None,  None)]  = Moves((1, 5), (4, 7))
    +            };
    +        }
    +
    +        public int Wins { get; private set; }
    +
    +        public void AddWin() => Wins++;
    +
    +        // Try to make a move. We first try to find a legal move for the current board position.
    +        public bool TryMove(Board board)
    +        {
    +            if (TryGetMoves(board, out var moves, out var reflected) &&
    +                TrySelectMove(moves, out var move))
    +            {
    +                // We've found a move, so we record it as the last move made, and then announce and make the move.
    +                _lastMove = (moves, move);
    +
    +                // If we found the move from a reflacted match of the board we need to make the reflected move.
    +                if (reflected) { move = move.Reflected; }
    +
    +                Console.WriteLine($"I move {move}");
    +                move.Execute(board);
    +                return true;
    +            }
    +
    +            // We haven't found a move for this board position, so remove the previous move that led to this board
    +            // position from future consideration. We don't want to make that move again, because we now know it's a
    +            // non-winning move.
    +            ExcludeLastMoveFromFuturePlay();
    +
    +            return false;
    +        }
    +
    +        // Looks up the given board and its reflection in the potential moves dictionary. If it's found then we have a
    +        // list of potential moves. If the board is not found in the dictionary then the computer has no legal moves,
    +        // and the human player wins.
    +        private bool TryGetMoves(Board board, out List moves, out bool reflected)
    +        {
    +            if (_potentialMoves.TryGetValue(board, out moves))
    +            {
    +                reflected = false;
    +                return true;
    +            }
    +
    +            if (_potentialMoves.TryGetValue(board.Reflected, out moves))
    +            {
    +                reflected = true;
    +                return true;
    +            }
    +
    +            reflected = default;
    +            return false;
    +        }
    +
    +        // Get a random move from the list. If the list is empty, then we've previously eliminated all the moves for
    +        // this board position as being non-winning moves. We therefore resign the game.
    +        private bool TrySelectMove(List moves, out Move move)
    +        {
    +            if (moves.Any())
    +            {
    +                move = moves[_random.Next(moves.Count)];
    +                return true;
    +            }
    +
    +            Console.Write("I resign.");
    +            move = null;
    +            return false;
    +        }
    +
    +        private void ExcludeLastMoveFromFuturePlay()
    +        {
    +            var (moves, move) = _lastMove;
    +            moves.Remove(move);
    +        }
    +
    +        private static List Moves(params Move[] moves) => moves.ToList();
    +
    +        public bool IsFullyAdvanced(Board board) =>
    +            board[9] == Black || board[8] == Black || board[7] == Black;
    +    }
    +}
    diff --git a/46_Hexapawn/csharp/Hexapawn/Game.cs b/46_Hexapawn/csharp/Hexapawn/Game.cs
    new file mode 100644
    index 000000000..95e321ff6
    --- /dev/null
    +++ b/46_Hexapawn/csharp/Hexapawn/Game.cs
    @@ -0,0 +1,49 @@
    +using System;
    +
    +namespace Hexapawn
    +{
    +    // Runs a single game of Hexapawn
    +    internal class Game
    +    {
    +        private readonly Board _board;
    +        private readonly Human _human;
    +        private readonly Computer _computer;
    +
    +        public Game(Human human, Computer computer)
    +        {
    +            _board = new Board();
    +            _human = human;
    +            _computer = computer;
    +        }
    +
    +        public IPlayer Play()
    +        {
    +            Console.WriteLine(_board);
    +
    +            while(true)
    +            {
    +                _human.Move(_board);
    +
    +                Console.WriteLine(_board);
    +
    +                if (!_computer.TryMove(_board))
    +                {
    +                    return _human;
    +                }
    +
    +                Console.WriteLine(_board);
    +
    +                if (_computer.IsFullyAdvanced(_board) || _human.HasNoPawns(_board))
    +                {
    +                    return _computer;
    +                }
    +
    +                if (!_human.HasLegalMove(_board))
    +                {
    +                    Console.Write("You can't move, so ");
    +                    return _computer;
    +                }
    +            }
    +        }
    +    }
    +}
    diff --git a/46_Hexapawn/csharp/Hexapawn/GameSeries.cs b/46_Hexapawn/csharp/Hexapawn/GameSeries.cs
    new file mode 100644
    index 000000000..6f45cab77
    --- /dev/null
    +++ b/46_Hexapawn/csharp/Hexapawn/GameSeries.cs
    @@ -0,0 +1,27 @@
    +using System;
    +
    +namespace Hexapawn
    +{
    +    // Runs series of games between the computer and the human player
    +    internal class GameSeries
    +    {
    +        private readonly Computer _computer = new();
    +        private readonly Human _human = new();
    +
    +        public void Play()
    +        {
    +            while (true)
    +            {
    +                var game = new Game(_human, _computer);
    +
    +                var winner = game.Play();
    +                winner.AddWin();
    +                Console.WriteLine(winner == _computer ? "I win." : "You win.");
    +
    +                Console.Write($"I have won {_computer.Wins} and you {_human.Wins}");
    +                Console.WriteLine($" out of {_computer.Wins + _human.Wins} games.");
    +                Console.WriteLine();
    +            }
    +        }
    +    }
    +}
    diff --git a/43_Hammurabi/csharp/Hammurabi.csproj b/46_Hexapawn/csharp/Hexapawn/Hexapawn.csproj
    similarity index 100%
    rename from 43_Hammurabi/csharp/Hammurabi.csproj
    rename to 46_Hexapawn/csharp/Hexapawn/Hexapawn.csproj
    diff --git a/46_Hexapawn/csharp/Hexapawn/Human.cs b/46_Hexapawn/csharp/Hexapawn/Human.cs
    new file mode 100644
    index 000000000..d2d241184
    --- /dev/null
    +++ b/46_Hexapawn/csharp/Hexapawn/Human.cs
    @@ -0,0 +1,64 @@
    +using System;
    +using System.Linq;
    +using static Hexapawn.Cell;
    +using static Hexapawn.Move;
    +using static Hexapawn.Pawn;
    +
    +namespace Hexapawn
    +{
    +    internal class Human : IPlayer
    +    {
    +        public int Wins { get; private set; }
    +
    +        public void Move(Board board)
    +        {
    +            while (true)
    +            {
    +                var move = Input.GetMove("Your move");
    +
    +                if (TryExecute(board, move)) { return; }
    +
    +                Console.WriteLine("Illegal move.");
    +            }
    +        }
    +
    +        public void AddWin() => Wins++;
    +
    +        public bool HasLegalMove(Board board)
    +        {
    +            foreach (var from in AllCells.Where(c => c > 3))
    +            {
    +                if (board[from] != White) { continue; }
    +
    +                if (HasLegalMove(board, from))
    +                {
    +                    return true;
    +                }
    +            }
    +
    +            return false;
    +        }
    +
    +        private bool HasLegalMove(Board board, Cell from) =>
    +            Right(from).IsRightDiagonalToCapture(board) ||
    +            Straight(from).IsStraightMoveToEmptySpace(board) ||
    +            from > 4 && Left(from).IsLeftDiagonalToCapture(board);
    +
    +        public bool HasNoPawns(Board board) => board.All(c => c != White);
    +
    +        public bool TryExecute(Board board, Move move)
    +        {
    +            if (board[move.From] != White) { return false; }
    +
    +            if (move.IsStraightMoveToEmptySpace(board) ||
    +                move.IsLeftDiagonalToCapture(board) ||
    +                move.IsRightDiagonalToCapture(board))
    +            {
    +                move.Execute(board);
    +                return true;
    +            }
    +
    +            return false;
    +        }
    +    }
    +}
    diff --git a/46_Hexapawn/csharp/Hexapawn/IPlayer.cs b/46_Hexapawn/csharp/Hexapawn/IPlayer.cs
    new file mode 100644
    index 000000000..7313904e7
    --- /dev/null
    +++ b/46_Hexapawn/csharp/Hexapawn/IPlayer.cs
    @@ -0,0 +1,8 @@
    +namespace Hexapawn
    +{
    +    // An interface implemented by a player of the game to track the number of wins.
    +    internal interface IPlayer
    +    {
    +        void AddWin();
    +    }
    +}
    diff --git a/46_Hexapawn/csharp/Hexapawn/Input.cs b/46_Hexapawn/csharp/Hexapawn/Input.cs
    new file mode 100644
    index 000000000..d169f2f6a
    --- /dev/null
    +++ b/46_Hexapawn/csharp/Hexapawn/Input.cs
    @@ -0,0 +1,112 @@
    +using System;
    +using System.Linq;
    +
    +namespace Hexapawn
    +{
    +    // Provides input methods which emulate the BASIC interpreter's keyboard input routines
    +    internal static class Input
    +    {
    +        internal static char GetYesNo(string prompt)
    +        {
    +            while (true)
    +            {
    +                Console.Write($"{prompt} (Y-N)? ");
    +                var response = Console.ReadLine().FirstOrDefault();
    +                if ("YyNn".Contains(response))
    +                {
    +                    return char.ToUpperInvariant(response);
    +                }
    +            }
    +        }
    +
    +        // Implements original code:
    +        //   120 PRINT "YOUR MOVE";
    +        //   121 INPUT M1,M2
    +        //   122 IF M1=INT(M1)AND M2=INT(M2)AND M1>0 AND M1<10 AND M2>0 AND M2<10 THEN 130
    +        //   123 PRINT "ILLEGAL CO-ORDINATES."
    +        //   124 GOTO 120
    +        internal static Move GetMove(string prompt)
    +        {
    +            while(true)
    +            {
    +                ReadNumbers(prompt, out var from, out var to);
    +
    +                if (Move.TryCreate(from, to, out var move))
    +                {
    +                    return move;
    +                }
    +
    +                Console.WriteLine("Illegal Coordinates.");
    +            }
    +        }
    +
    +        internal static void Prompt(string text = "") => Console.Write($"{text}? ");
    +
    +        internal static void ReadNumbers(string prompt, out float number1, out float number2)
    +        {
    +            while (!TryReadNumbers(prompt, out number1, out number2))
    +            {
    +                prompt = "";
    +            }
    +        }
    +
    +        private static bool TryReadNumbers(string prompt, out float number1, out float number2)
    +        {
    +            Prompt(prompt);
    +            var inputValues = ReadStrings();
    +
    +            if (!TryParseNumber(inputValues[0], out number1))
    +            {
    +                number2 = default;
    +                return false;
    +            }
    +
    +            if (inputValues.Length == 1)
    +            {
    +                return TryReadNumber("?", out number2);
    +            }
    +
    +            if (!TryParseNumber(inputValues[1], out number2))
    +            {
    +                number2 = default;
    +                return false;
    +            }
    +
    +            if (inputValues.Length > 2)
    +            {
    +                Console.WriteLine("!Extra input ingored");
    +            }
    +
    +            return true;
    +        }
    +
    +        private static bool TryReadNumber(string prompt, out float number)
    +        {
    +            Prompt(prompt);
    +            var inputValues = ReadStrings();
    +
    +            if (!TryParseNumber(inputValues[0], out number))
    +            {
    +                return false;
    +            }
    +
    +            if (inputValues.Length > 1)
    +            {
    +                Console.WriteLine("!Extra input ingored");
    +            }
    +
    +            return true;
    +        }
    +
    +        private static string[] ReadStrings() => Console.ReadLine().Split(',', StringSplitOptions.TrimEntries);
    +
    +        private static bool TryParseNumber(string text, out float number)
    +        {
    +            if (float.TryParse(text, out number)) { return true; }
    +
    +            Console.WriteLine("!Number expected - retry input line");
    +            number = default;
    +            return false;
    +        }
    +    }
    +}
    diff --git a/46_Hexapawn/csharp/Hexapawn/Move.cs b/46_Hexapawn/csharp/Hexapawn/Move.cs
    new file mode 100644
    index 000000000..9581a959b
    --- /dev/null
    +++ b/46_Hexapawn/csharp/Hexapawn/Move.cs
    @@ -0,0 +1,68 @@
    +using static Hexapawn.Pawn;
    +
    +namespace Hexapawn
    +{
    +    /// 
    +    /// Represents a move which may, or may not, be legal.
    +    /// 
    +    internal class Move
    +    {
    +        private readonly Cell _from;
    +        private readonly Cell _to;
    +        private readonly int _metric;
    +
    +        public Move(Cell from, Cell to)
    +        {
    +            _from = from;
    +            _to = to;
    +            _metric = _from - _to;
    +        }
    +
    +        public void Deconstruct(out Cell from, out Cell to)
    +        {
    +            from = _from;
    +            to = _to;
    +        }
    +
    +        public Cell From => _from;
    +
    +        // Produces the mirror image of the current moved, reflected around the central column of the board.
    +        public Move Reflected => (_from.Reflected, _to.Reflected);
    +
    +        // Allows a tuple of two ints to be implicitly converted to a Move.
    +        public static implicit operator Move((int From, int To) value) => new(value.From, value.To);
    +
    +        // Takes floating point coordinates, presumably from keyboard input, and attempts to create a Move object.
    +        public static bool TryCreate(float input1, float input2, out Move move)
    +        {
    +            if (Cell.TryCreate(input1, out var from) &&
    +                Cell.TryCreate(input2, out var to))
    +            {
    +                move = (from, to);
    +                return true;
    +            }
    +
    +            move = default;
    +            return false;
    +        }
    +
    +        public static Move Right(Cell from) => (from, from - 2);
    +        public static Move Straight(Cell from) => (from, from - 3);
    +        public static Move Left(Cell from) => (from, from - 4);
    +
    +        public bool IsStraightMoveToEmptySpace(Board board) => _metric == 3 && board[_to] == None;
    +
    +        public bool IsLeftDiagonalToCapture(Board board) => _metric == 4 && _from != 7 && board[_to] == Black;
    +
    +        public bool IsRightDiagonalToCapture(Board board) =>
    +            _metric == 2 && _from != 9 && _from != 6 && board[_to] == Black;
    +
    +        public void Execute(Board board)
    +        {
    +            board[_to] = board[_from];
    +            board[_from] = None;
    +        }
    +
    +        public override string ToString() => $"from {_from} to {_to}";
    +    }
    +}
    diff --git a/46_Hexapawn/csharp/Hexapawn/Pawn.cs b/46_Hexapawn/csharp/Hexapawn/Pawn.cs
    new file mode 100644
    index 000000000..7a4c56337
    --- /dev/null
    +++ b/46_Hexapawn/csharp/Hexapawn/Pawn.cs
    @@ -0,0 +1,19 @@
    +namespace Hexapawn
    +{
    +    // Represents the contents of a cell on the board
    +    internal class Pawn
    +    {
    +        public static readonly Pawn Black = new('X');
    +        public static readonly Pawn White = new('O');
    +        public static readonly Pawn None = new('.');
    +
    +        private readonly char _symbol;
    +
    +        private Pawn(char symbol)
    +        {
    +            _symbol = symbol;
    +        }
    +
    +        public override string ToString() => _symbol.ToString();
    +    }
    +}
    diff --git a/46_Hexapawn/csharp/Hexapawn/Program.cs b/46_Hexapawn/csharp/Hexapawn/Program.cs
    new file mode 100644
    index 000000000..59917dfaa
    --- /dev/null
    +++ b/46_Hexapawn/csharp/Hexapawn/Program.cs
    @@ -0,0 +1,71 @@
    +using System;
    +
    +namespace Hexapawn
    +{
    +    // Hexapawn:  Interpretation of hexapawn game as presented in
    +    // Martin Gardner's "The Unexpected Hanging and Other Mathematic
    +    // al Diversions", Chapter Eight:  A Matchbox Game-Learning Machine.
    +    // Original version for H-P timeshare system by R.A. Kaapke 5/5/76
    +    // Instructions by Jeff Dalton
    +    // Conversion to MITS BASIC by Steve North
    +    // Conversion to C# by Andrew Cooper
    +    class Program
    +    {
    +        static void Main()
    +        {
    +            DisplayTitle();
    +
    +            if (Input.GetYesNo("Instructions") == 'Y')
    +            {
    +                DisplayInstructions();
    +            }
    +
    +            var games = new GameSeries();
    +
    +            games.Play();
    +        }
    +
    +        private static void DisplayTitle()
    +        {
    +            Console.WriteLine("                                Hexapawn");
    +            Console.WriteLine("               Creative Computing  Morristown, New Jersey");
    +            Console.WriteLine();
    +            Console.WriteLine();
    +            Console.WriteLine();
    +        }
    +
    +        private static void DisplayInstructions()
    +        {
    +            Console.WriteLine();
    +            Console.WriteLine("This program plays the game of Hexapawn.");
    +            Console.WriteLine("Hexapawn is played with Chess pawns on a 3 by 3 board.");
    +            Console.WriteLine("The pawns are move as in Chess - one space forward to");
    +            Console.WriteLine("an empty space, or one space forward and diagonally to");
    +            Console.WriteLine("capture an opposing man.  On the board, your pawns");
    +            Console.WriteLine("are 'O', the computer's pawns are 'X', and empty");
    +            Console.WriteLine("squares are '.'.  To enter a move, type the number of");
    +            Console.WriteLine("the square you are moving from, followed by the number");
    +            Console.WriteLine("of the square you will move to.  The numbers must be");
    +            Console.WriteLine("separated by a comma.");
    +            Console.WriteLine();
    +            Console.WriteLine("The computer starts a series of games knowing only when");
    +            Console.WriteLine("the game is won (a draw is impossible) and how to move.");
    +            Console.WriteLine("It has no strategy at first and just moves randomly.");
    +            Console.WriteLine("However, it learns from each game.  Thus winning becomes");
    +            Console.WriteLine("more and more difficult.  Also, to help offset your");
    +            Console.WriteLine("initial advantage, you will not be told how to win the");
    +            Console.WriteLine("game but must learn this by playing.");
    +            Console.WriteLine();
    +            Console.WriteLine("The numbering of the board is as follows:");
    +            Console.WriteLine("          123");
    +            Console.WriteLine("          456");
    +            Console.WriteLine("          789");
    +            Console.WriteLine();
    +            Console.WriteLine("For example, to move your rightmost pawn forward,");
    +            Console.WriteLine("you would type 9,6 in response to the question");
    +            Console.WriteLine("'Your move ?'.  Since I'm a good sport, you'll always");
    +            Console.WriteLine("go first.");
    +            Console.WriteLine();
    +        }
    +    }
    +}
    diff --git a/46_Hexapawn/csharp/Human.cs b/46_Hexapawn/csharp/Human.cs
    deleted file mode 100644
    index 7d21d0049..000000000
    --- a/46_Hexapawn/csharp/Human.cs
    +++ /dev/null
    @@ -1,67 +0,0 @@
    -using System;
    -using System.Linq;
    -using Games.Common.IO;
    -using static Hexapawn.Cell;
    -using static Hexapawn.Move;
    -using static Hexapawn.Pawn;
    -
    -namespace Hexapawn;
    -
    -internal class Human
    -{
    -    private readonly TextIO _io;
    -
    -    public Human(TextIO io)
    -    {
    -        _io = io;
    -    }
    -
    -    public void Move(Board board)
    -    {
    -        while (true)
    -        {
    -            var move = _io.ReadMove("Your move");
    -
    -            if (TryExecute(board, move)) { return; }
    -
    -            _io.WriteLine("Illegal move.");
    -        }
    -    }
    -
    -    public bool HasLegalMove(Board board)
    -    {
    -        foreach (var from in AllCells.Where(c => c > 3))
    -        {
    -            if (board[from] != White) { continue; }
    -
    -            if (HasLegalMove(board, from))
    -            {
    -                return true;
    -            }
    -        }
    -
    -        return false;
    -    }
    -
    -    private bool HasLegalMove(Board board, Cell from) =>
    -        Right(from).IsRightDiagonalToCapture(board) ||
    -        Straight(from).IsStraightMoveToEmptySpace(board) ||
    -        from > 4 && Left(from).IsLeftDiagonalToCapture(board);
    -
    -    public bool HasNoPawns(Board board) => board.All(c => c != White);
    -
    -    public bool TryExecute(Board board, Move move)
    -    {
    -        if (board[move.From] != White) { return false; }
    -
    -        if (move.IsStraightMoveToEmptySpace(board) ||
    -            move.IsLeftDiagonalToCapture(board) ||
    -            move.IsRightDiagonalToCapture(board))
    -        {
    -            move.Execute(board);
    -            return true;
    -        }
    -
    -        return false;
    -    }
    -}
    diff --git a/46_Hexapawn/csharp/IReadWriteExtensions.cs b/46_Hexapawn/csharp/IReadWriteExtensions.cs
    deleted file mode 100644
    index 7b11354ad..000000000
    --- a/46_Hexapawn/csharp/IReadWriteExtensions.cs
    +++ /dev/null
    @@ -1,42 +0,0 @@
    -using System;
    -using System.Linq;
    -using Games.Common.IO;
    -
    -namespace Hexapawn;
    -
    -// Provides input methods which emulate the BASIC interpreter's keyboard input routines
    -internal static class IReadWriteExtensions
    -{
    -    internal static char GetYesNo(this IReadWrite io, string prompt)
    -    {
    -        while (true)
    -        {
    -            var response = io.ReadString($"{prompt} (Y-N)").FirstOrDefault();
    -            if ("YyNn".Contains(response))
    -            {
    -                return char.ToUpperInvariant(response);
    -            }
    -        }
    -    }
    -
    -    // Implements original code:
    -    //   120 PRINT "YOUR MOVE";
    -    //   121 INPUT M1,M2
    -    //   122 IF M1=INT(M1)AND M2=INT(M2)AND M1>0 AND M1<10 AND M2>0 AND M2<10 THEN 130
    -    //   123 PRINT "ILLEGAL CO-ORDINATES."
    -    //   124 GOTO 120
    -    internal static Move ReadMove(this IReadWrite io, string prompt)
    -    {
    -        while(true)
    -        {
    -            var (from, to) = io.Read2Numbers(prompt);
    -
    -            if (Move.TryCreate(from, to, out var move))
    -            {
    -                return move;
    -            }
    -
    -            io.WriteLine("Illegal Coordinates.");
    -        }
    -    }
    -}
    diff --git a/46_Hexapawn/csharp/Move.cs b/46_Hexapawn/csharp/Move.cs
    deleted file mode 100644
    index 0d4655759..000000000
    --- a/46_Hexapawn/csharp/Move.cs
    +++ /dev/null
    @@ -1,67 +0,0 @@
    -using static Hexapawn.Pawn;
    -
    -namespace Hexapawn;
    -
    -/// 
    -/// Represents a move which may, or may not, be legal.
    -/// 
    -internal class Move
    -{
    -    private readonly Cell _from;
    -    private readonly Cell _to;
    -    private readonly int _metric;
    -
    -    public Move(Cell from, Cell to)
    -    {
    -        _from = from;
    -        _to = to;
    -        _metric = _from - _to;
    -    }
    -
    -    public void Deconstruct(out Cell from, out Cell to)
    -    {
    -        from = _from;
    -        to = _to;
    -    }
    -
    -    public Cell From => _from;
    -
    -    // Produces the mirror image of the current moved, reflected around the central column of the board.
    -    public Move Reflected => (_from.Reflected, _to.Reflected);
    -
    -    // Allows a tuple of two ints to be implicitly converted to a Move.
    -    public static implicit operator Move((int From, int To) value) => new(value.From, value.To);
    -
    -    // Takes floating point coordinates, presumably from keyboard input, and attempts to create a Move object.
    -    public static bool TryCreate(float input1, float input2, out Move move)
    -    {
    -        if (Cell.TryCreate(input1, out var from) &&
    -            Cell.TryCreate(input2, out var to))
    -        {
    -            move = (from, to);
    -            return true;
    -        }
    -
    -        move = default;
    -        return false;
    -    }
    -
    -    public static Move Right(Cell from) => (from, from - 2);
    -    public static Move Straight(Cell from) => (from, from - 3);
    -    public static Move Left(Cell from) => (from, from - 4);
    -
    -    public bool IsStraightMoveToEmptySpace(Board board) => _metric == 3 && board[_to] == None;
    -
    -    public bool IsLeftDiagonalToCapture(Board board) => _metric == 4 && _from != 7 && board[_to] == Black;
    -
    -    public bool IsRightDiagonalToCapture(Board board) =>
    -        _metric == 2 && _from != 9 && _from != 6 && board[_to] == Black;
    -
    -    public void Execute(Board board)
    -    {
    -        board[_to] = board[_from];
    -        board[_from] = None;
    -    }
    -
    -    public override string ToString() => $"from {_from} to {_to}";
    -}
    diff --git a/46_Hexapawn/csharp/Pawn.cs b/46_Hexapawn/csharp/Pawn.cs
    deleted file mode 100644
    index f8bcae222..000000000
    --- a/46_Hexapawn/csharp/Pawn.cs
    +++ /dev/null
    @@ -1,19 +0,0 @@
    -namespace Hexapawn;
    -
    -// Represents the contents of a cell on the board
    -internal class Pawn
    -{
    -    public static readonly Pawn Black = new('X');
    -    public static readonly Pawn White = new('O');
    -    public static readonly Pawn None = new('.');
    -
    -    private readonly char _symbol;
    -
    -    private Pawn(char symbol)
    -    {
    -        _symbol = symbol;
    -    }
    -
    -    public override string ToString() => _symbol.ToString();
    -}
    -
    diff --git a/46_Hexapawn/csharp/Program.cs b/46_Hexapawn/csharp/Program.cs
    deleted file mode 100644
    index d00a7056d..000000000
    --- a/46_Hexapawn/csharp/Program.cs
    +++ /dev/null
    @@ -1,6 +0,0 @@
    -using Games.Common.IO;
    -using Games.Common.Randomness;
    -using Hexapawn;
    -
    -new GameSeries(new ConsoleIO(), new RandomNumberGenerator()).Play();
    -
    diff --git a/46_Hexapawn/csharp/Resources/Instructions.txt b/46_Hexapawn/csharp/Resources/Instructions.txt
    deleted file mode 100644
    index 9c96a266a..000000000
    --- a/46_Hexapawn/csharp/Resources/Instructions.txt
    +++ /dev/null
    @@ -1,30 +0,0 @@
    -
    -This program plays the game of Hexapawn.
    -Hexapawn is played with Chess pawns on a 3 by 3 board.
    -The pawns are move as in Chess - one space forward to
    -an empty space, or one space forward and diagonally to
    -capture an opposing man.  On the board, your pawns
    -are 'O', the computer's pawns are 'X', and empty
    -squares are '.'.  To enter a move, type the number of
    -the square you are moving from, followed by the number
    -of the square you will move to.  The numbers must be
    -separated by a comma.
    -
    -The computer starts a series of games knowing only when
    -the game is won (a draw is impossible) and how to move.
    -It has no strategy at first and just moves randomly.
    -However, it learns from each game.  Thus winning becomes
    -more and more difficult.  Also, to help offset your
    -initial advantage, you will not be told how to win the
    -game but must learn this by playing.
    -
    -The numbering of the board is as follows:
    -          123
    -          456
    -          789
    -
    -For example, to move your rightmost pawn forward,
    -you would type 9,6 in response to the question
    -'Your move ?'.  Since I'm a good sport, you'll always
    -go first.
    -
    diff --git a/46_Hexapawn/csharp/Resources/Resource.cs b/46_Hexapawn/csharp/Resources/Resource.cs
    deleted file mode 100644
    index 49eaa08d1..000000000
    --- a/46_Hexapawn/csharp/Resources/Resource.cs
    +++ /dev/null
    @@ -1,17 +0,0 @@
    -using System.IO;
    -using System.Reflection;
    -using System.Runtime.CompilerServices;
    -
    -namespace Hexapawn.Resources;
    -
    -internal static class Resource
    -{
    -    internal static class Streams
    -    {
    -        public static Stream Instructions => GetStream();
    -        public static Stream Title => GetStream();
    -    }
    -
    -    private static Stream GetStream([CallerMemberName] string name = null)
    -        => Assembly.GetExecutingAssembly().GetManifestResourceStream($"Hexapawn.Resources.{name}.txt");
    -}
    \ No newline at end of file
    diff --git a/46_Hexapawn/csharp/Resources/Title.txt b/46_Hexapawn/csharp/Resources/Title.txt
    deleted file mode 100644
    index df31d6b9e..000000000
    --- a/46_Hexapawn/csharp/Resources/Title.txt
    +++ /dev/null
    @@ -1,5 +0,0 @@
    -                                Hexapawn
    -               Creative Computing  Morristown, New Jersey
    -
    -
    -
    diff --git a/46_Hexapawn/javascript/hexapawn.html b/46_Hexapawn/javascript/hexapawn.html
    index be651674a..5ac2b08c5 100644
    --- a/46_Hexapawn/javascript/hexapawn.html
    +++ b/46_Hexapawn/javascript/hexapawn.html
    @@ -1,10 +1,9 @@
     
     
     HEXAPAWN
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/46_Hexapawn/javascript/hexapawn.js b/46_Hexapawn/javascript/hexapawn.js
    index 4a4e3397c..6e36428cb 100644
    --- a/46_Hexapawn/javascript/hexapawn.js
    +++ b/46_Hexapawn/javascript/hexapawn.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    @@ -199,12 +199,12 @@ async function main()
                         print("ILLEGAL CO-ORDINATES.\n");
                     }
                 }
    -
    +            
                 // Move player's pawn
                 s[m1] = 0;
                 s[m2] = 1;
                 show_board();
    -
    +            
                 // Find computer pawns
                 for (i = 1; i <= 9; i++) {
                     if (s[i] == -1)
    @@ -313,7 +313,7 @@ async function main()
                         if (s[i - 2] == -1 || s[i - 4] == -1)
                             break;
                     }
    -
    +                
                 }
                 if (i > 9) {
                     print("YOU CAN'T MOVE, SO ");
    diff --git a/46_Hexapawn/kotlin/README.md b/46_Hexapawn/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/46_Hexapawn/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/46_Hexapawn/lua/README.md b/46_Hexapawn/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/46_Hexapawn/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/46_Hexapawn/pascal/README.md b/46_Hexapawn/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/46_Hexapawn/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/46_Hexapawn/python/hexapawn.py b/46_Hexapawn/python/hexapawn.py
    index f5cac438b..e89e34262 100644
    --- a/46_Hexapawn/python/hexapawn.py
    +++ b/46_Hexapawn/python/hexapawn.py
    @@ -4,48 +4,50 @@
     A machine learning game, an interpretation of HEXAPAWN game as
     presented in Martin Gardner's "The Unexpected Hanging and Other
     Mathematical Diversions", Chapter Eight: A Matchbox Game-Learning
    -Machine.
    +Machine. 
     
    -Original version for H-P timeshare system by R.A. Kaapke 5/5/76
    -Instructions by Jeff Dalton
    +Original version for H-P timeshare system by R.A. Kaapke 5/5/76 
    +Instructions by Jeff Dalton 
     Conversion to MITS BASIC by Steve North
     
     
     Port to Python by Dave LeCompte
     """
     
    -# PORTING NOTES:
    -#
    -# I printed out the BASIC code and hand-annotated what each little block
    -# of code did, which feels amazingly retro.
    -#
    -# I encourage other porters that have a complex knot of GOTOs and
    -# semi-nested subroutines to do hard-copy hacking, it might be a
    -# different perspective that helps.
    -#
    -# A spoiler - the objective of the game is not documented, ostensibly to
    -# give the human player a challenge. If a player (human or computer)
    -# advances a pawn across the board to the far row, that player wins. If
    -# a player has no legal moves (either by being blocked, or all their
    -# pieces having been captured), that player loses.
    -#
    -# The original BASIC had 2 2-dimensional tables stored in DATA at the
    -# end of the program. This encoded all 19 different board configurations
    -# (Hexapawn is a small game), with reflections in one table, and then in
    -# a parallel table, for each of the 19 rows, a list of legal moves was
    -# encoded by turning them into 2-digit decimal numbers. As gameplay
    -# continued, the AI would overwrite losing moves with 0 in the second
    -# array.
    -#
    -# My port takes this "parallel array" structure and turns that
    -# information into a small Python class, BoardLayout. BoardLayout stores
    -# the board description and legal moves, but stores the moves as (row,
    -# column) 2-tuples, which is easier to read. The logic for checking if a
    -# BoardLayout matches the current board, as well as removing losing move
    -# have been moved into methods of this class.
    +"""
    +PORTING NOTES:
    +
    +I printed out the BASIC code and hand-annotated what each little block
    +of code did, which feels amazingly retro.
    +
    +I encourage other porters that have a complex knot of GOTOs and
    +semi-nested subroutines to do hard-copy hacking, it might be a
    +different perspective that helps.
    +
    +A spoiler - the objective of the game is not documented, ostensibly to
    +give the human player a challenge. If a player (human or computer)
    +advances a pawn across the board to the far row, that player wins. If
    +a player has no legal moves (either by being blocked, or all their
    +pieces having been captured), that player loses.
    +
    +The original BASIC had 2 2-dimensional tables stored in DATA at the
    +end of the program. This encoded all 19 different board configurations
    +(Hexapawn is a small game), with reflections in one table, and then in
    +a parallel table, for each of the 19 rows, a list of legal moves was
    +encoded by turning them into 2-digit decimal numbers. As gameplay
    +continued, the AI would overwrite losing moves with 0 in the second
    +array.
    +
    +My port takes this "parallel array" structure and turns that
    +information into a small Python class, BoardLayout. BoardLayout stores
    +the board description and legal moves, but stores the moves as (row,
    +column) 2-tuples, which is easier to read. The logic for checking if a
    +BoardLayout matches the current board, as well as removing losing move
    +have been moved into methods of this class.
    +"""
     
    +import collections
     import random
    -from typing import Iterator, List, NamedTuple, Optional, Tuple
     
     PAGE_WIDTH = 64
     
    @@ -53,29 +55,28 @@
     EMPTY_SPACE = 0
     COMPUTER_PIECE = -1
     
    -
    -class ComputerMove(NamedTuple):
    -    board_index: int
    -    move_index: int
    -    m1: int
    -    m2: int
    -
    +ComputerMove = collections.namedtuple(
    +    "ComputerMove", ["board_index", "move_index", "m1", "m2"]
    +)
     
     wins = 0
     losses = 0
     
     
    -def print_centered(msg: str) -> None:
    +def print_centered(msg):
         spaces = " " * ((PAGE_WIDTH - len(msg)) // 2)
         print(spaces + msg)
     
     
    -def print_header(title: str) -> None:
    +def print_header(title):
         print_centered(title)
    -    print_centered("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n")
    +    print_centered("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
    +    print()
    +    print()
    +    print()
     
     
    -def print_instructions() -> None:
    +def print_instructions():
         print(
             """
     THIS PROGRAM PLAYS THE GAME OF HEXAPAWN.
    @@ -83,7 +84,7 @@ def print_instructions() -> None:
     THE PAWNS ARE MOVED AS IN CHESS - ONE SPACE FORWARD TO
     AN EMPTY SPACE OR ONE SPACE FORWARD AND DIAGONALLY TO
     CAPTURE AN OPPOSING MAN.  ON THE BOARD, YOUR PAWNS
    -ARE 'O', THE COMPUTER'S PAWNS ARE 'X', AND EMPTY
    +ARE 'O', THE COMPUTER'S PAWNS ARE 'X', AND EMPTY 
     SQUARES ARE '.'.  TO ENTER A MOVE, TYPE THE NUMBER OF
     THE SQUARE YOU ARE MOVING FROM, FOLLOWED BY THE NUMBER
     OF THE SQUARE YOU WILL MOVE TO.  THE NUMBERS MUST BE
    @@ -111,7 +112,7 @@ def print_instructions() -> None:
         )
     
     
    -def prompt_yes_no(msg: str) -> bool:
    +def prompt_yes_no(msg):
         while True:
             print(msg)
             response = input().upper()
    @@ -121,7 +122,7 @@ def prompt_yes_no(msg: str) -> bool:
                 return False
     
     
    -def reverse_space_name(space_name: int) -> int:
    +def reverse_space_name(space_name):
         # reverse a space name in the range 1-9 left to right
         assert 1 <= space_name <= 9
     
    @@ -129,38 +130,36 @@ def reverse_space_name(space_name: int) -> int:
         return reflections[space_name]
     
     
    -def is_space_in_center_column(space_name: int) -> bool:
    +def is_space_in_center_column(space_name):
         return reverse_space_name(space_name) == space_name
     
     
     class BoardLayout:
    -    def __init__(self, cells: List[int], move_list: List[Tuple[int, int]]) -> None:
    +    def __init__(self, cells, move_list):
             self.cells = cells
             self.moves = move_list
     
    -    def _check_match_no_mirror(self, cell_list: List[int]) -> bool:
    -        return all(
    -            board_contents == cell_list[space_index]
    -            for space_index, board_contents in enumerate(self.cells)
    -        )
    +    def _check_match_no_mirror(self, cell_list):
    +        for space_index, board_contents in enumerate(self.cells):
    +            if board_contents != cell_list[space_index]:
    +                return False
    +        return True
     
    -    def _check_match_with_mirror(self, cell_list: List[int]) -> bool:
    +    def _check_match_with_mirror(self, cell_list):
             for space_index, board_contents in enumerate(self.cells):
                 reversed_space_index = reverse_space_name(space_index + 1) - 1
                 if board_contents != cell_list[reversed_space_index]:
                     return False
             return True
     
    -    def check_match(self, cell_list: List[int]) -> Tuple[bool, Optional[bool]]:
    +    def check_match(self, cell_list):
             if self._check_match_with_mirror(cell_list):
                 return True, True
             elif self._check_match_no_mirror(cell_list):
                 return True, False
             return False, None
     
    -    def get_random_move(
    -        self, reverse_board: Optional[bool]
    -    ) -> Optional[Tuple[int, int, int]]:
    +    def get_random_move(self, reverse_board):
             if not self.moves:
                 return None
             move_index = random.randrange(len(self.moves))
    @@ -196,7 +195,7 @@ def get_random_move(
     ]
     
     
    -def get_move(board_index: int, move_index: int) -> Tuple[int, int]:
    +def get_move(board_index, move_index):
         assert board_index >= 0 and board_index < len(boards)
         board = boards[board_index]
     
    @@ -205,7 +204,7 @@ def get_move(board_index: int, move_index: int) -> Tuple[int, int]:
         return board.moves[move_index]
     
     
    -def remove_move(board_index: int, move_index: int) -> None:
    +def remove_move(board_index, move_index):
         assert board_index >= 0 and board_index < len(boards)
         board = boards[board_index]
     
    @@ -214,11 +213,11 @@ def remove_move(board_index: int, move_index: int) -> None:
         del board.moves[move_index]
     
     
    -def init_board() -> List[int]:
    +def init_board():
         return [COMPUTER_PIECE] * 3 + [EMPTY_SPACE] * 3 + [HUMAN_PIECE] * 3
     
     
    -def print_board(board: List[int]) -> None:
    +def print_board(board):
         piece_dict = {COMPUTER_PIECE: "X", EMPTY_SPACE: ".", HUMAN_PIECE: "O"}
     
         space = " " * 10
    @@ -234,30 +233,30 @@ def print_board(board: List[int]) -> None:
         print()
     
     
    -def get_coordinates() -> Tuple[int, int]:
    +def get_coordinates():
         while True:
             try:
                 print("YOUR MOVE?")
                 response = input()
    -            m1, m2 = (int(c) for c in response.split(","))
    +            m1, m2 = [int(c) for c in response.split(",")]
                 return m1, m2
    -        except ValueError:
    +        except ValueError as ve:
                 print_illegal()
     
     
    -def print_illegal() -> None:
    +def print_illegal():
         print("ILLEGAL MOVE.")
     
     
    -def board_contents(board: List[int], space_number: int) -> int:
    +def board_contents(board, space_number):
         return board[space_number - 1]
     
     
    -def set_board(board: List[int], space_number: int, new_value: int) -> None:
    +def set_board(board, space_number, new_value):
         board[space_number - 1] = new_value
     
     
    -def is_legal_human_move(board: List[int], m1: int, m2: int) -> bool:
    +def is_legal_human_move(board, m1, m2):
         if board_contents(board, m1) != HUMAN_PIECE:
             # Start space doesn't contain player's piece
             return False
    @@ -278,44 +277,62 @@ def is_legal_human_move(board: List[int], m1: int, m2: int) -> bool:
             # Destination is not open
             return False
     
    -    return False if m2 - m1 < -4 else m1 != 7 or m2 != 3
    +    if m2 - m1 < -4:
    +        # too far
    +        return False
    +
    +    if m1 == 7 and m2 == 3:
    +        # can't jump corner to corner (wrapping around the board)
    +        return False
    +    return True
     
     
    -def player_piece_on_back_row(board: List[int]) -> bool:
    -    return any(board_contents(board, space) == HUMAN_PIECE for space in range(1, 4))
    +def player_piece_on_back_row(board):
    +    for space in range(1, 4):
    +        if board_contents(board, space) == HUMAN_PIECE:
    +            return True
    +    return False
     
     
    -def computer_piece_on_front_row(board: List[int]) -> bool:
    -    return any(board_contents(board, space) == COMPUTER_PIECE for space in range(7, 10))
    +def computer_piece_on_front_row(board):
    +    for space in range(7, 10):
    +        if board_contents(board, space) == COMPUTER_PIECE:
    +            return True
    +    return False
     
     
    -def all_human_pieces_captured(board: List[int]) -> bool:
    -    return not list(get_human_spaces(board))
    +def all_human_pieces_captured(board):
    +    return len(list(get_human_spaces(board))) == 0
     
     
    -def all_computer_pieces_captured(board: List[int]) -> bool:
    -    return not list(get_computer_spaces(board))
    +def all_computer_pieces_captured(board):
    +    return len(list(get_computer_spaces(board))) == 0
     
     
    -def human_win(last_computer_move: ComputerMove) -> None:
    +def human_win(last_computer_move):
         print("YOU WIN")
         remove_move(last_computer_move.board_index, last_computer_move.move_index)
         global losses
         losses += 1
     
     
    -def computer_win(has_moves: bool) -> None:
    -    msg = ("YOU CAN'T MOVE, SO " if not has_moves else "") + "I WIN"
    +def computer_win(has_moves):
    +    if not has_moves:
    +        msg = "YOU CAN'T MOVE, SO "
    +    else:
    +        msg = ""
    +    msg += "I WIN"
         print(msg)
         global wins
         wins += 1
     
     
    -def show_scores() -> None:
    -    print(f"I HAVE WON {wins} AND YOU {losses} OUT OF {wins + losses} GAMES.\n")
    +def show_scores():
    +    print(f"I HAVE WON {wins} AND YOU {losses} OUT OF {wins + losses} GAMES.")
    +    print()
     
     
    -def human_has_move(board: List[int]) -> bool:
    +def human_has_move(board):
         for i in get_human_spaces(board):
             if board_contents(board, i - 3) == EMPTY_SPACE:
                 # can move piece forward
    @@ -329,14 +346,14 @@ def human_has_move(board: List[int]) -> bool:
                 else:
                     continue
             elif i < 7:
    -            assert i in [4, 6]
    +            assert (i == 4) or (i == 6)
                 if board_contents(board, 2) == COMPUTER_PIECE:
                     # can capture computer piece at 2
                     return True
                 else:
                     continue
             elif board_contents(board, 5) == COMPUTER_PIECE:
    -            assert i in [7, 9]
    +            assert (i == 7) or (i == 9)
                 # can capture computer piece at 5
                 return True
             else:
    @@ -344,32 +361,33 @@ def human_has_move(board: List[int]) -> bool:
         return False
     
     
    -def get_board_spaces() -> Iterator[int]:
    -    """generates the space names (1-9)"""
    +def get_board_spaces():
    +    """ generates the space names (1-9)"""
         yield from range(1, 10)
     
     
    -def get_board_spaces_with(board: List[int], val: int) -> Iterator[int]:
    -    """generates spaces containing pieces of type val"""
    +def get_board_spaces_with(board, val):
    +    """ generates spaces containing pieces of type val"""
         for i in get_board_spaces():
             if board_contents(board, i) == val:
                 yield i
     
     
    -def get_human_spaces(board: List[int]) -> Iterator[int]:
    +def get_human_spaces(board):
         yield from get_board_spaces_with(board, HUMAN_PIECE)
     
     
    -def get_empty_spaces(board: List[int]) -> Iterator[int]:
    +def get_empty_spaces(board):
         yield from get_board_spaces_with(board, EMPTY_SPACE)
     
     
    -def get_computer_spaces(board: List[int]) -> Iterator[int]:
    +def get_computer_spaces(board):
         yield from get_board_spaces_with(board, COMPUTER_PIECE)
     
     
    -def has_computer_move(board: List[int]) -> bool:
    +def has_computer_move(board):
         for i in get_computer_spaces(board):
    +        found_move = False
             if board_contents(board, i + 3) == EMPTY_SPACE:
                 # can move forward (down)
                 return True
    @@ -380,31 +398,35 @@ def has_computer_move(board: List[int]) -> bool:
                     board_contents(board, i + 4) == HUMAN_PIECE
                 ):
                     return True
    -        elif (
    -            i > 3
    -            and board_contents(board, 8) == HUMAN_PIECE
    -            or i <= 3
    -            and board_contents(board, 5) == HUMAN_PIECE
    -        ):
    -            # can capture on 8
    -            return True
    -        elif i <= 3 or board_contents(board, 8) == HUMAN_PIECE:
    -            continue
    +        else:
    +            if i > 3:
    +                # beyond the first row
    +                if board_contents(board, 8) == HUMAN_PIECE:
    +                    # can capture on 8
    +                    return True
    +                else:
    +                    continue
    +            else:
    +                if board_contents(board, 5) == HUMAN_PIECE:
    +                    # can capture on 5
    +                    return True
    +                else:
    +                    continue
         return False
     
     
    -def find_board_index_that_matches_board(board: List[int]) -> Tuple[int, Optional[bool]]:
    +def find_board_index_that_matches_board(board):
         for board_index, board_layout in enumerate(boards):
             matches, is_reversed = board_layout.check_match(board)
             if matches:
                 return board_index, is_reversed
     
    -    # This point should never be reached
    -    # In future, mypy might be able to check exhaustiveness via assert_never
    -    raise RuntimeError("ILLEGAL BOARD PATTERN.")
    +    # THE TERMINATION OF THIS LOOP IS IMPOSSIBLE
    +    print("ILLEGAL BOARD PATTERN.")
    +    assert False
     
     
    -def pick_computer_move(board: List[int]) -> Optional[ComputerMove]:
    +def pick_computer_move(board):
         if not has_computer_move(board):
             return None
     
    @@ -421,7 +443,7 @@ def pick_computer_move(board: List[int]) -> Optional[ComputerMove]:
         return ComputerMove(board_index, move_index, m1, m2)
     
     
    -def get_human_move(board: List[int]) -> Tuple[int, int]:
    +def get_human_move(board):
         while True:
             m1, m2 = get_coordinates()
     
    @@ -431,12 +453,12 @@ def get_human_move(board: List[int]) -> Tuple[int, int]:
                 return m1, m2
     
     
    -def apply_move(board: List[int], m1: int, m2: int, piece_value: int) -> None:
    +def apply_move(board, m1, m2, piece_value):
         set_board(board, m1, EMPTY_SPACE)
         set_board(board, m2, piece_value)
     
     
    -def play_game() -> None:
    +def play_game():
         last_computer_move = None
     
         board = init_board()
    @@ -451,13 +473,11 @@ def play_game() -> None:
             print_board(board)
     
             if player_piece_on_back_row(board) or all_computer_pieces_captured(board):
    -            assert last_computer_move is not None
                 human_win(last_computer_move)
                 return
     
             computer_move = pick_computer_move(board)
             if computer_move is None:
    -            assert last_computer_move is not None
                 human_win(last_computer_move)
                 return
     
    @@ -478,7 +498,7 @@ def play_game() -> None:
                 return
     
     
    -def main() -> None:
    +def main():
         print_header("HEXAPAWN")
         if prompt_yes_no("INSTRUCTIONS (Y-N)?"):
             print_instructions()
    diff --git a/46_Hexapawn/vbnet/Hexapawn.sln b/46_Hexapawn/vbnet/Hexapawn.sln
    deleted file mode 100644
    index 5aff142be..000000000
    --- a/46_Hexapawn/vbnet/Hexapawn.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 4ed34b92b..000000000
    --- a/46_Hexapawn/vbnet/Hexapawn.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Hexapawn
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/47_Hi-Lo/README.md b/47_Hi-Lo/README.md
    index f9b09c14f..7fb372212 100644
    --- a/47_Hi-Lo/README.md
    +++ b/47_Hi-Lo/README.md
    @@ -19,7 +19,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/47_Hi-Lo/csharp/HiLo.sln b/47_Hi-Lo/csharp/HiLo.sln
    deleted file mode 100644
    index 225235b80..000000000
    --- a/47_Hi-Lo/csharp/HiLo.sln
    +++ /dev/null
    @@ -1,25 +0,0 @@
    -
    -Microsoft Visual Studio Solution File, Format Version 12.00
    -# Visual Studio Version 16
    -VisualStudioVersion = 16.0.30114.105
    -MinimumVisualStudioVersion = 10.0.40219.1
    -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(ExtensibilityGlobals) = postSolution
    -		SolutionGuid = {BF77DB59-426B-4A01-A8AC-09AAF42DA633}
    -	EndGlobalSection
    -EndGlobal
    diff --git a/47_Hi-Lo/csharp/Program.cs b/47_Hi-Lo/csharp/Program.cs
    deleted file mode 100644
    index 24971be0b..000000000
    --- a/47_Hi-Lo/csharp/Program.cs
    +++ /dev/null
    @@ -1,82 +0,0 @@
    -using System;
    -
    -Console.WriteLine(Tab(34) +                 "HI LO");
    -Console.WriteLine(Tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY");
    -Console.WriteLine();
    -Console.WriteLine();
    -Console.WriteLine();
    -Console.WriteLine("THIS IS THE GAME OF HI LO.");
    -Console.WriteLine();
    -Console.WriteLine("YOU WILL HAVE 6 TRIES TO GUESS THE AMOUNT OF MONEY IN THE");
    -Console.WriteLine("HI LO JACKPOT, WHICH IS BETWEEN 1 AND 100 DOLLARS.  IF YOU");
    -Console.WriteLine("GUESS THE AMOUNT, YOU WIN ALL THE MONEY IN THE JACKPOT!");
    -Console.WriteLine("THEN YOU GET ANOTHER CHANCE TO WIN MORE MONEY.  HOWEVER,");
    -Console.WriteLine("IF YOU DO NOT GUESS THE AMOUNT, THE GAME ENDS.");
    -Console.WriteLine();
    -
    -// rnd is our random number generator
    -Random rnd = new();
    -
    -bool playAgain = false;
    -int totalWinnings = 0;
    -
    -do // Our game loop
    -{
    -    int jackpot = rnd.Next(100) + 1; // [0..99] + 1 -> [1..100]
    -    int guess = 1;
    -
    -    while (true) // Our guessing loop
    -    {
    -        Console.WriteLine();
    -        int amount = ReadInt("YOUR GUESS ");
    -
    -        if (amount == jackpot)
    -        {
    -            Console.WriteLine($"GOT IT!!!!!!!!!!   YOU WIN {jackpot} DOLLARS.");
    -            totalWinnings += jackpot;
    -            Console.WriteLine($"YOUR TOTAL WINNINGS ARE NOW {totalWinnings} DOLLARS.");
    -            break;
    -        }
    -        else if (amount > jackpot)
    -        {
    -            Console.WriteLine("YOUR GUESS IS TOO HIGH.");
    -        }
    -        else
    -        {
    -            Console.WriteLine("YOUR GUESS IS TOO LOW.");
    -        }
    -
    -        guess++;
    -        if (guess > 6)
    -        {
    -            Console.WriteLine($"YOU BLEW IT...TOO BAD...THE NUMBER WAS {jackpot}");
    -            break;
    -        }
    -    }
    -
    -    Console.WriteLine();
    -    Console.Write("PLAY AGAIN (YES OR NO) ");
    -    playAgain = Console.ReadLine().ToUpper().StartsWith("Y");
    -
    -} while (playAgain);
    -
    -Console.WriteLine();
    -Console.WriteLine("SO LONG.  HOPE YOU ENJOYED YOURSELF!!!");
    -
    -// Tab(n) returns n spaces
    -static string Tab(int n) => new String(' ', n);
    -
    -// ReadInt asks the user to enter a number
    -static int ReadInt(string question)
    -{
    -    while (true)
    -    {
    -        Console.Write(question);
    -        var input = Console.ReadLine().Trim();
    -        if (int.TryParse(input, out int value))
    -        {
    -            return value;
    -        }
    -        Console.WriteLine("!Invalid Number Entered.");
    -    }
    -}
    diff --git a/47_Hi-Lo/csharp/hi-lo.cs b/47_Hi-Lo/csharp/hi-lo.cs
    new file mode 100644
    index 000000000..c5cfb3ec3
    --- /dev/null
    +++ b/47_Hi-Lo/csharp/hi-lo.cs
    @@ -0,0 +1,83 @@
    +using System;
    +
    +Console.WriteLine(Tab(34) +                 "HI LO");
    +Console.WriteLine(Tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY");
    +Console.WriteLine();
    +Console.WriteLine();
    +Console.WriteLine();
    +Console.WriteLine("THIS IS THE GAME OF HI LO.");
    +Console.WriteLine();
    +Console.WriteLine("YOU WILL HAVE 6 TRIES TO GUESS THE AMOUNT OF MONEY IN THE");
    +Console.WriteLine("HI LO JACKPOT, WHICH IS BETWEEN 1 AND 100 DOLLARS.  IF YOU");
    +Console.WriteLine("GUESS THE AMOUNT, YOU WIN ALL THE MONEY IN THE JACKPOT!");
    +Console.WriteLine("THEN YOU GET ANOTHER CHANCE TO WIN MORE MONEY.  HOWEVER,");
    +Console.WriteLine("IF YOU DO NOT GUESS THE AMOUNT, THE GAME ENDS.");
    +Console.WriteLine();
    +
    +// rnd is our random number generator
    +Random rnd = new();
    +
    +bool playAgain = false;
    +int totalWinnings = 0;
    +
    +do // Our game loop
    +{
    +    int jackpot = rnd.Next(100) + 1; // [0..99] + 1 -> [1..100]
    +    int guess = 1;
    +
    +    while (true) // Our guessing loop
    +    {
    +        Console.WriteLine();
    +        int amount = ReadInt("YOUR GUESS ");
    +
    +        if (amount == jackpot)
    +        {
    +            Console.WriteLine($"GOT IT!!!!!!!!!!   YOU WIN {jackpot} DOLLARS.");
    +            totalWinnings += jackpot;
    +            Console.WriteLine($"YOUR TOTAL WINNINGS ARE NOW {totalWinnings} DOLLARS.");
    +            break;
    +        }
    +        else if (amount > jackpot)
    +        {
    +            Console.WriteLine("YOUR GUESS IS TOO HIGH.");
    +        }
    +        else
    +        {
    +            Console.WriteLine("YOUR GUESS IS TOO LOW.");
    +        }
    +
    +        guess++;
    +        if (guess > 6)
    +        {
    +            Console.WriteLine($"YOU BLEW IT...TOO BAD...THE NUMBER WAS {jackpot}");
    +            break;
    +        }
    +    }
    +
    +    Console.WriteLine();
    +    Console.Write("PLAY AGAIN (YES OR NO) ");
    +    playAgain = Console.ReadLine().ToUpper().StartsWith("Y");
    +
    +} while (playAgain);
    +
    +Console.WriteLine();
    +Console.WriteLine("SO LONG.  HOPE YOU ENJOYED YOURSELF!!!");
    +
    +// Tab(n) returns n spaces
    +static string Tab(int n) => new String(' ', n);
    +
    +// ReadInt asks the user to enter a number
    +static int ReadInt(string question)
    +{
    +    while (true)
    +    {
    +        Console.Write(question);
    +        var input = Console.ReadLine().Trim();
    +        if (int.TryParse(input, out int value))
    +        {
    +            return value;
    +        }
    +        Console.WriteLine("!Invalid Number Entered.");
    +    }
    +}
    +
    diff --git a/47_Hi-Lo/csharp/HiLo.csproj b/47_Hi-Lo/csharp/hi-lo.csproj
    similarity index 100%
    rename from 47_Hi-Lo/csharp/HiLo.csproj
    rename to 47_Hi-Lo/csharp/hi-lo.csproj
    diff --git a/47_Hi-Lo/java/src/HiLo.java b/47_Hi-Lo/java/src/HiLo.java
    index b7b3e106f..2d0263e9b 100644
    --- a/47_Hi-Lo/java/src/HiLo.java
    +++ b/47_Hi-Lo/java/src/HiLo.java
    @@ -211,4 +211,4 @@ private int randomNumber() {
             return (int) (Math.random()
                     * (HIGH_NUMBER_RANGE - LOW_NUMBER_RANGE + 1) + LOW_NUMBER_RANGE);
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/47_Hi-Lo/javascript/hi-lo.html b/47_Hi-Lo/javascript/hi-lo.html
    index 2a0f2d0d3..2610591d3 100644
    --- a/47_Hi-Lo/javascript/hi-lo.html
    +++ b/47_Hi-Lo/javascript/hi-lo.html
    @@ -1,10 +1,9 @@
     
     
     HI-LO
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/47_Hi-Lo/javascript/hi-lo.js b/47_Hi-Lo/javascript/hi-lo.js
    index 6964570d8..fc7b1dbf3 100644
    --- a/47_Hi-Lo/javascript/hi-lo.js
    +++ b/47_Hi-Lo/javascript/hi-lo.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    @@ -86,7 +86,6 @@ async function main()
             print("\n");
             print("PLAY AGAIN (YES OR NO)");
             str = await input();
    -        str = str.toUpperCase();
             if (str != "YES")
                 break;
         }
    diff --git a/47_Hi-Lo/kotlin/HiLo.kt b/47_Hi-Lo/kotlin/HiLo.kt
    index de52f573a..7c4b6b65f 100644
    --- a/47_Hi-Lo/kotlin/HiLo.kt
    +++ b/47_Hi-Lo/kotlin/HiLo.kt
    @@ -6,7 +6,7 @@ fun main() {
             winnings += playGame()
             println("YOUR TOTAL WINNINGS ARE NOW $winnings DOLLARS")
         } while(playAgain())
    -
    +    
         println("SO LONG.  HOPE YOU ENJOYED YOURSELF!!!")
     }
     
    @@ -37,14 +37,14 @@ fun playAgain():Boolean {
     val introText = """
         HI LO
         CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY
    -
    -
    +    
    +    
         THIS IS THE GAME OF HI LO.
    -
    +    
         YOU WILL HAVE 6 TRIES TO GUESS THE AMOUNT OF MONEY IN THE
         HI LO JACKPOT, WHICH IS BETWEEN 1 AND 100 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
     
    -""".trimIndent()
    +""".trimIndent()
    \ No newline at end of file
    diff --git a/47_Hi-Lo/lua/README.md b/47_Hi-Lo/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/47_Hi-Lo/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/47_Hi-Lo/lua/hilo.lua b/47_Hi-Lo/lua/hilo.lua
    deleted file mode 100644
    index 42284f28b..000000000
    --- a/47_Hi-Lo/lua/hilo.lua
    +++ /dev/null
    @@ -1,86 +0,0 @@
    -local function hilo (randomNum)
    -   local numTries = 0
    -   math.randomseed(os.time())
    -
    -   local randomNum = math.random(1, 100)
    -   print(randomNum)
    -
    -   while numTries < 6 do
    -      print("")
    -
    -      io.write("YOUR GUESS? ")
    -   
    -      local guess = io.read("*n")
    -
    -      numTries = numTries + 1
    -
    -      if guess < randomNum then
    -         print("YOUR GUESS IS TOO LOW")
    -      end
    -
    -      if guess > randomNum then
    -         print("YOUR GUESS IS TOO HIGH")
    -      end
    -
    -      if guess == randomNum then
    -         print("GOT IT!!!!!!!!!!   YOU WIN " .. randomNum .. " DOLLARS.")
    -         break
    -      end
    -    end
    - 
    -    if numTries == 6 then
    -       print("")
    -       print("YOU BLEW IT...TOO BAD...THE NUMBER WAS " .. randomNum)
    -       return 0
    -    else
    -       return randomNum
    -    end
    -end
    -
    -local THIRTY_FOUR_TABS=string.rep("\t",34)
    -print(THIRTY_FOUR_TABS, "HI LO")
    -
    -local FIFTEEN_TABS=string.rep("\t",15)
    -print(FIFTEEN_TABS, "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
    -
    -local THREE_NEWLINES=string.rep("\n", 3)
    -print(THREE_NEWLINES)
    -
    -print("THIS IS THE GAME OF HI LO.")
    -print("")
    -print("YOU WILL HAVE 6 TRIES TO GUESS THE AMOUNT OF MONEY IN THE")
    -print("HI LO JACKPOT, WHICH IS BETWEEN 1 AND 100 DOLLARS.  IF YOU")
    -print("GUESS THE AMOUNT, YOU WIN ALL THE MONEY IN THE JACKPOT!")
    -print("THEN YOU GET ANOTHER CHANCE TO WIN MORE MONEY.  HOWEVER,")
    -print("IF YOU DO NOT GUESS THE AMOUNT, THE GAME ENDS.")
    -
    -local wonSoFar = 0
    -
    -::continue::
    -local won = 0
    -local won = hilo(randomNum)
    -wonSoFar = won + wonSoFar
    -print("YOUR TOTAL WINNINGS ARE NOW " .. wonSoFar .. " DOLLARS.")
    -
    ---- This flush is here because if not then it will keep the newline in the
    ---- input buffer and cause the program to inadvertantly go to the 
    ---- Invalid Answer!
    ---- part of the code which we don't want the program to do. Appears to be a
    ---- Lua-ism.
    -
    -io.stdin:flush()
    -io.write("PLAY AGAIN (YES OR NO)? ")
    -answer = io.read()
    -
    -while(not(answer == "YES" or answer == "NO")) do
    -   io.write("Invalid Answer! Try again (YES/NO): ")
    -   answer = io.read()
    -end
    -
    -if answer == "YES" then
    -   goto continue
    -else
    -   print("")
    -   print("SO LONG.  HOPE YOU ENJOYED YOURSELF!!!") 
    -   os.exit()
    -end
    \ No newline at end of file
    diff --git a/47_Hi-Lo/pascal/README.md b/47_Hi-Lo/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/47_Hi-Lo/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/47_Hi-Lo/perl/hi-lo.pl b/47_Hi-Lo/perl/hi-lo.pl
    index 234c59816..08173a56c 100755
    --- a/47_Hi-Lo/perl/hi-lo.pl
    +++ b/47_Hi-Lo/perl/hi-lo.pl
    @@ -25,7 +25,7 @@
     			} else {
     			print "YOUR GUESS IS TOO LOW.\n";
     			}
    -		print "\n";
    +		print "\n"; 
     		}
     
     	if ($A==$Y) {
    @@ -41,3 +41,5 @@
     	} until (uc($A) ne "YES");
     print "\n"; print "SO LONG. HOPE YOU ENJOYED YOURSELF!!!\n";
     exit;
    +
    +
    diff --git a/47_Hi-Lo/python/hilo.py b/47_Hi-Lo/python/hilo.py
    index 5850b3f7b..370999a78 100755
    --- a/47_Hi-Lo/python/hilo.py
    +++ b/47_Hi-Lo/python/hilo.py
    @@ -2,18 +2,17 @@
     import random
     
     MAX_ATTEMPTS = 6
    -QUESTION_PROMPT = "? "
    -
    -
    -def main() -> None:
    -    print("HI LO")
    -    print("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n")
    -    print("THIS IS THE GAME OF HI LO.\n")
    -    print("YOU WILL HAVE 6 TRIES TO GUESS THE AMOUNT OF MONEY IN THE")
    -    print("HI LO JACKPOT, WHICH IS BETWEEN 1 AND 100 DOLLARS.  IF YOU")
    -    print("GUESS THE AMOUNT, YOU WIN ALL THE MONEY IN THE JACKPOT!")
    -    print("THEN YOU GET ANOTHER CHANCE TO WIN MORE MONEY.  HOWEVER,")
    -    print("IF YOU DO NOT GUESS THE AMOUNT, THE GAME ENDS.\n\n")
    +QUESTION_PROMPT='? '
    +
    +def play():
    +    print('HI LO')
    +    print('CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n')
    +    print('THIS IS THE GAME OF HI LO.\n')
    +    print('YOU WILL HAVE 6 TRIES TO GUESS THE AMOUNT OF MONEY IN THE')
    +    print('HI LO JACKPOT, WHICH IS BETWEEN 1 AND 100 DOLLARS.  IF YOU')
    +    print('GUESS THE AMOUNT, YOU WIN ALL THE MONEY IN THE JACKPOT!')
    +    print('THEN YOU GET ANOTHER CHANCE TO WIN MORE MONEY.  HOWEVER,')
    +    print('IF YOU DO NOT GUESS THE AMOUNT, THE GAME ENDS.\n\n')
     
         total_winnings = 0
         while True:
    @@ -21,33 +20,32 @@ def main() -> None:
             secret = random.randint(1, 100)
             guessed_correctly = False
     
    -        for _attempt in range(MAX_ATTEMPTS):
    -            print("YOUR GUESS", end=QUESTION_PROMPT)
    +        for attempt in range(MAX_ATTEMPTS):
    +            print('YOUR GUESS', end=QUESTION_PROMPT)
                 guess = int(input())
     
                 if guess == secret:
    -                print(f"GOT IT!!!!!!!!!!   YOU WIN {secret} DOLLARS.")
    +                print('GOT IT!!!!!!!!!!   YOU WIN {} DOLLARS.'.format(secret))
                     guessed_correctly = True
                     break
                 elif guess > secret:
    -                print("YOUR GUESS IS TOO HIGH.")
    +                print('YOUR GUESS IS TOO HIGH.')
                 else:
    -                print("YOUR GUESS IS TOO LOW.")
    +                print('YOUR GUESS IS TOO LOW.')
     
             if guessed_correctly:
                 total_winnings += secret
    -            print(f"YOUR TOTAL WINNINGS ARE NOW {total_winnings} DOLLARS.")
    +            print('YOUR TOTAL WINNINGS ARE NOW {} DOLLARS.'.format(total_winnings))
             else:
    -            print(f"YOU BLEW IT...TOO BAD...THE NUMBER WAS {secret}")
    +            print('YOU BLEW IT...TOO BAD...THE NUMBER WAS {}'.format(secret))
     
    -        print("\n")
    -        print("PLAY AGAIN (YES OR NO)", end=QUESTION_PROMPT)
    +        print('\n')
    +        print('PLAY AGAIN (YES OR NO)', end=QUESTION_PROMPT)
             answer = input().upper()
    -        if answer != "YES":
    +        if answer != 'YES':
                 break
     
    -    print("\nSO LONG.  HOPE YOU ENJOYED YOURSELF!!!")
    -
    +    print('\nSO LONG.  HOPE YOU ENJOYED YOURSELF!!!')
     
    -if __name__ == "__main__":
    -    main()
    +if __name__ == '__main__':
    +    play()
    diff --git a/47_Hi-Lo/ruby/README.md b/47_Hi-Lo/ruby/README.md
    index 241656ad8..fb32811e2 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/) by [R.T. Lechow](https://github.com/rtlechow)
    +Conversion to [Ruby](https://www.ruby-lang.org/en/)
    diff --git a/47_Hi-Lo/ruby/hi_lo.rb b/47_Hi-Lo/ruby/hi_lo.rb
    deleted file mode 100644
    index 02989a914..000000000
    --- a/47_Hi-Lo/ruby/hi_lo.rb
    +++ /dev/null
    @@ -1,59 +0,0 @@
    -#!/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
    diff --git a/47_Hi-Lo/rust/Cargo.lock b/47_Hi-Lo/rust/Cargo.lock
    deleted file mode 100644
    index 937c07c63..000000000
    --- a/47_Hi-Lo/rust/Cargo.lock
    +++ /dev/null
    @@ -1,75 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.10"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "guessing_game"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.147"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/47_Hi-Lo/rust/Cargo.toml b/47_Hi-Lo/rust/Cargo.toml
    deleted file mode 100644
    index d39f66411..000000000
    --- a/47_Hi-Lo/rust/Cargo.toml
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -[package]
    -name = "guessing_game"
    -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.3"
    \ No newline at end of file
    diff --git a/47_Hi-Lo/rust/README.md b/47_Hi-Lo/rust/README.md
    deleted file mode 100644
    index fc6468b9f..000000000
    --- a/47_Hi-Lo/rust/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Rust](https://www.rust-lang.org/)
    diff --git a/47_Hi-Lo/rust/src/main.rs b/47_Hi-Lo/rust/src/main.rs
    deleted file mode 100644
    index 0b821c3b8..000000000
    --- a/47_Hi-Lo/rust/src/main.rs
    +++ /dev/null
    @@ -1,73 +0,0 @@
    -use rand::Rng;
    -use std::io;
    -
    -fn main() {
    -    println!(
    -        "{: >39}\n{: >57}\n\n\n",
    -        "HI LO", "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY"
    -    );
    -    println!("THIS IS THE GAME OF HI LO.\n");
    -    println!("YOU WILL HAVE 6 TRIES TO GUESS THE AMOUNT OF MONEY IN THE");
    -    println!("HI LO JACKPOT, WHICH IS BETWEEN 1 AND 100 DOLLARS.  IF YOU");
    -    println!("GUESS THE AMOUNT, YOU WIN ALL THE MONEY IN THE JACKPOT!");
    -    println!("THEN YOU GET ANOTHER CHANCE TO WIN MORE MONEY.  HOWEVER,");
    -    println!("IF YOU DO NOT GUESS THE AMOUNT, THE GAME ENDS.\n");
    -
    -    let mut total: u32 = 0;
    -    loop {
    -        let jackpot_amount = rand::thread_rng().gen_range(1..101); // generates a random number between 1 and 100
    -        for i in 0..6 {
    -            println!("YOUR GUESS?");
    -
    -            let mut guess = String::new();
    -
    -            io::stdin()
    -                .read_line(&mut guess)
    -                .expect("Failed to read the line");
    -
    -            // this converts the input string into unsigned 32bit number and if the input entered is not a number
    -            // it will again prompt the user to enter the guess number
    -            let guess: u32 = match guess.trim().parse() {
    -                Ok(num) => num,
    -                Err(_) => {
    -                    println!("PLEASE ENTER A NUMBER VALUE.\n");
    -                    continue;
    -                }
    -            };
    -
    -            // compare it with the jackpot amount
    -            if guess == jackpot_amount {
    -                println!("\nGOT IT!!!!!!!!!!   YOU WIN {} DOLLARS.", jackpot_amount);
    -                total += jackpot_amount;
    -                println!("YOUR TOTAL WINNINGS ARE NOW {} DOLLARS.\n", total);
    -                break;
    -            } else if guess < jackpot_amount {
    -                println!("YOUR GUESS IS TOO LOW.\n");
    -            } else {
    -                println!("YOUR GUESS IS TOO HIGH.\n");
    -            }
    -
    -            // if 6 tries are over make total jackpot amount to zero
    -            if i == 5 {
    -                total = 0;
    -                println!(
    -                    "YOU BLEW IT...TOO BAD...THE NUMBER WAS {}\n",
    -                    jackpot_amount
    -                );
    -            }
    -        }
    -        println!("PLAY AGAIN (YES OR NO)?");
    -        let mut tocontinue = String::new();
    -        io::stdin()
    -            .read_line(&mut tocontinue)
    -            .expect("Error Getting your input");
    -        let tocontinue = tocontinue.trim().to_ascii_uppercase();
    -        if tocontinue.eq("YES") {
    -            println!("\n");
    -            continue;
    -        } else {
    -            println!("\nSO LONG.  HOPE YOU ENJOYED YOURSELF!!!\n");
    -            break;
    -        }
    -    }
    -}
    diff --git a/47_Hi-Lo/vbnet/HiLo.sln b/47_Hi-Lo/vbnet/HiLo.sln
    deleted file mode 100644
    index fbd97f943..000000000
    --- a/47_Hi-Lo/vbnet/HiLo.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 634099d3d..000000000
    --- a/47_Hi-Lo/vbnet/HiLo.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    HiLo
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/48_High_IQ/README.md b/48_High_IQ/README.md
    index 2922f9209..7dee9c951 100644
    --- a/48_High_IQ/README.md
    +++ b/48_High_IQ/README.md
    @@ -14,7 +14,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/48_High_IQ/csharp/HighIQ.csproj b/48_High_IQ/csharp/HighIQ.csproj
    deleted file mode 100644
    index d3fe4757c..000000000
    --- a/48_High_IQ/csharp/HighIQ.csproj
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    diff --git a/48_High_IQ/csharp/HighIQ.sln b/48_High_IQ/csharp/HighIQ.sln
    deleted file mode 100644
    index 2cdbddc4c..000000000
    --- a/48_High_IQ/csharp/HighIQ.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/d/highiq.d b/48_High_IQ/d/highiq.d
    index f6016bcf4..784455452 100644
    --- a/48_High_IQ/d/highiq.d
    +++ b/48_High_IQ/d/highiq.d
    @@ -63,7 +63,7 @@ struct Board
                                (" 6_         │   │   │   │        ").to!(dchar[]),
                                ("            ├───┼───┼───┤        ").to!(dchar[]),
                                (" 7_         │   │   │   │        ").to!(dchar[]),
    -                           ("            └───┴───┴───┘        ").to!(dchar[])];
    +                           ("            └───┴───┴───┘        ").to!(dchar[])]; 
             foreach (y, row; state)
                 foreach (x, field; row)
                     if (field == taken)
    diff --git a/48_High_IQ/javascript/highiq.html b/48_High_IQ/javascript/highiq.html
    index ec4b84ddc..03ea2f26b 100644
    --- a/48_High_IQ/javascript/highiq.html
    +++ b/48_High_IQ/javascript/highiq.html
    @@ -1,10 +1,9 @@
     
     
     H-I-Q
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/48_High_IQ/javascript/highiq.js b/48_High_IQ/javascript/highiq.js
    index e3b4f1b0f..3dbb6aa15 100644
    --- a/48_High_IQ/javascript/highiq.js
    +++ b/48_High_IQ/javascript/highiq.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/48_High_IQ/kotlin/README.md b/48_High_IQ/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/48_High_IQ/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/48_High_IQ/lua/README.md b/48_High_IQ/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/48_High_IQ/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/48_High_IQ/pascal/README.md b/48_High_IQ/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/48_High_IQ/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/48_High_IQ/python/High_IQ.py b/48_High_IQ/python/High_IQ.py
    index 5b8c2204f..4e14ddc13 100644
    --- a/48_High_IQ/python/High_IQ.py
    +++ b/48_High_IQ/python/High_IQ.py
    @@ -1,51 +1,15 @@
    -from typing import Dict
    -
    -
    -def new_board() -> Dict[int, str]:
    -    """
    -    Using a dictionary in python to store the board,
    -    since we are not including all numbers within a given range.
    -    """
    -    return {
    -        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: "!",
    -        41: "O",
    -    }
    -
    -
    -def print_instructions() -> None:
    -    print(
    -        """
    +
    +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] = '!'
    +    board[41] = 'O'
    +    return board
    +
    +
    +def print_instructions():
    +    print("""
     HERE IS THE BOARD:
     
               !    !    !
    @@ -72,46 +36,19 @@ def print_instructions() -> None:
     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: Dict[int, str]) -> None:
    +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]
    -    )
    -    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(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(" " * 2 + board[58] + board[59] + board[60])
         print(" " * 2 + board[67] + board[68] + board[69])
     
    -
    -def play_game() -> None:
    +def play_game():
         # Create new board
         board = new_board()
     
    @@ -120,70 +57,68 @@ def play_game() -> None:
             print_board(board)
             while not move(board):
                 print("ILLEGAL MOVE! TRY AGAIN")
    -
    -    peg_count = sum(1 for key in board.keys() if board[key] == "!")
    -    print(f"YOU HAD {str(peg_count)} PEGS REMAINING")
    -
    +    
    +    # Check peg count and print the user's score
    +    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: Dict[int, str]) -> bool:
    +        
    +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"""
         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] != "!":
    +    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] != "O":
    +    if end not in board or board[end] != 'O':
             return False
    -
    +    
         difference = abs(start - end)
    -    center = int((end + start) / 2)
    -    if difference in [2, 18] and board[center] == "!":
    -        board[start] = "O"
    -        board[center] = "O"
    -        board[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() -> None:
    +def main():
         print(" " * 33 + "H-I-Q")
         print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
         print_instructions()
         play_game()
     
    -
    -def is_game_finished(board) -> bool:
    -    """Check all locations and whether or not a move is possible at that location."""
    +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] == "!":
    -            for space in [1, 9]:
    +        if board[pos] == '!':
    +            for space in [1,9]:
                     # Checks if the next location has a peg
    -                next_to_peg = ((pos + space) in board) and board[pos + space] == "!"
    +                nextToPeg = ((pos + space) in board) and board[pos + space] == '!'
                     # Checks both going forward (+ location) or backwards (-location)
    -                has_movable_space = (
    -                    pos - space not in board
    -                    or board[pos - space] != "!"
    -                    or pos + space * 2 not in board
    -                    or board[pos + space * 2] != "!"
    -                )
    -                if next_to_peg and has_movable_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
     
    diff --git a/48_High_IQ/python/README.md b/48_High_IQ/python/README.md
    index bc04457a6..a0738c90b 100644
    --- a/48_High_IQ/python/README.md
    +++ b/48_High_IQ/python/README.md
    @@ -2,4 +2,4 @@ Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/gam
     
     Conversion to [Python](https://www.python.org/about/)
     
    -[Implementation](./High_IQ.py) by [Thomas Kwashnak](https://github.com/LittleTealeaf)
    +[Implementation](./High_IQ.py) by [Thomas Kwashnak](https://github.com/LittleTealeaf)
    \ No newline at end of file
    diff --git a/48_High_IQ/vbnet/HighIQ.sln b/48_High_IQ/vbnet/HighIQ.sln
    deleted file mode 100644
    index ca1f79c5c..000000000
    --- a/48_High_IQ/vbnet/HighIQ.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index c37eb8db4..000000000
    --- a/48_High_IQ/vbnet/HighIQ.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    HighIQ
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/49_Hockey/README.md b/49_Hockey/README.md
    index 98db22d58..41e6950eb 100644
    --- a/49_Hockey/README.md
    +++ b/49_Hockey/README.md
    @@ -14,12 +14,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Known Bugs
    -
    -- An apparent missing line 430 causes the code to fall through from the "FLIPS A WRISTSHOT" case directly to the "BACKHANDS ONE" case.
    -- The author consistently misspells the verb "lets" (writing it like the contraction "let's"), while having no trouble with "leads", "gets", "hits", etc.
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/49_Hockey/csharp/Hockey.csproj b/49_Hockey/csharp/Hockey.csproj
    deleted file mode 100644
    index d3fe4757c..000000000
    --- a/49_Hockey/csharp/Hockey.csproj
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    diff --git a/49_Hockey/csharp/Hockey.sln b/49_Hockey/csharp/Hockey.sln
    deleted file mode 100644
    index d2ca8d362..000000000
    --- a/49_Hockey/csharp/Hockey.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/hockey.bas b/49_Hockey/hockey.bas
    index f0b5a8298..626b4f561 100644
    --- a/49_Hockey/hockey.bas
    +++ b/49_Hockey/hockey.bas
    @@ -8,37 +8,37 @@
     55 PRINT
     60 IF C$="NO" THEN 90
     65 IF C$="YES" THEN 80
    -70 PRINT "ANSWER YES OR NO!!":GOTO 50
    +70 PRINT "ANSWER YES OR NO!!":GOTO 50 
     80 GOTO 1720
     90 DIM A$(7),B$(7),H(20),T(5),T1(5),T2(5),T3(5)
    -100 PRINT "ENTER THE TWO TEAMS";:INPUT A$(7),B$(7)
    +100 PRINT "ENTER THE TWO TEAMS";:INPUT A$(7),B$(7) 
     105 PRINT
     110 PRINT "ENTER THE NUMBER OF MINUTES IN A GAME";:INPUT T6
     115 PRINT
    -120 IF T6<1 THEN 110:PRINT
    -130 PRINT "WOULD THE " A$(7) " COACH ENTER HIS TEAM"
    +120 IF T6<1 THEN 110:PRINT 
    +130 PRINT "WOULD THE " A$(7) " COACH ENTER HIS TEAM" 
     135 PRINT
    -140 FOR I=1 TO 6:PRINT "PLAYER"I;:INPUT A$(I):NEXT I:PRINT
    +140 FOR I=1 TO 6:PRINT "PLAYER"I;:INPUT A$(I):NEXT I:PRINT 
     150 PRINT "WOULD THE " B$(7) " COACH DO THE SAME"
     155 PRINT
    -160 FOR T=1 TO 6:PRINT "PLAYER"T;:INPUT B$(T):NEXT T:PRINT
    -170 PRINT "INPUT THE REFEREE FOR THIS GAME";:INPUT R$
    -180 PRINT:PRINT TAB(10);A$(7) " STARTING LINEUP"
    -190 FOR T=1 TO 6:PRINT A$(T):NEXT T
    +160 FOR T=1 TO 6:PRINT "PLAYER"T;:INPUT B$(T):NEXT T:PRINT 
    +170 PRINT "INPUT THE REFEREE FOR THIS GAME";:INPUT R$  
    +180 PRINT:PRINT TAB(10);A$(7) " STARTING LINEUP" 
    +190 FOR T=1 TO 6:PRINT A$(T):NEXT T  
     200 PRINT:PRINT TAB(10);B$(7)" STARTING LINEUP"
     210 FOR T=1 TO 6:PRINT B$(T):NEXT T:PRINT
     220 PRINT "WE'RE READY FOR TONIGHTS OPENING FACE-OFF."
     230 PRINT R$ " WILL DROP THE PUCK BETWEEN " A$(2) " AND " B$(2)
     240 FOR L=1 TO T6:IF L=1 THEN 260
    -250 PRINT "AND WE'RE READY FOR THE FACE-OFF"
    +250 PRINT "AND WE'RE READY FOR THE FACE-OFF" 
     260 C=INT(2*RND(X))+1:ON C GOTO 270,280
     270 PRINT A$(7) " HAS CONTROL OF THE PUCK":GOTO 290
    -280 PRINT B$(7) " HAS CONTROL."
    -290 PRINT "PASS";:INPUT P:FOR N=1 TO 3:H(N)=0:NEXT N
    +280 PRINT B$(7) " HAS CONTROL." 
    +290 PRINT "PASS";:INPUT P:FOR N=1 TO 3:H(N)=0:NEXT N 
     300 IF P<0 THEN 290
     305 IF P>3 THEN 290
    -310 FOR J=1 TO (P+2)
    -320 H(J)=INT(5*RND(X))+1
    +310 FOR J=1 TO (P+2) 
    +320 H(J)=INT(5*RND(X))+1 
     330 NEXT J:IF H(J-1)=H(J-2) THEN 310
     331 IF P+2<3 THEN 350
     335 IF H(J-1)=H(J-3) THEN 310
    @@ -48,19 +48,19 @@
     360 INPUT "SHOT";S:IF S<1 THEN 360
     365 IF S>4 THEN 360
     370 ON C GOTO 380,480
    -380 PRINT A$(H(J-1));:G=H(J-1):G1=0:G2=0
    +380 PRINT A$(H(J-1));:G=H(J-1):G1=0:G2=0 
     390 ON S GOTO 400,420,440,460
    -400 PRINT " LET'S A BOOMER GO FROM THE RED LINE!!"
    +400 PRINT " LET'S A BOOMER GO FROM THE RED LINE!!" 
     410 Z=10:GOTO 890
     420 PRINT " FLIPS A WRISTSHOT DOWN THE ICE"
    -440 PRINT " BACKHANDS ONE IN ON THE GOALTENDER"
    +440 PRINT " BACKHANDS ONE IN ON THE GOALTENDER" 
     450 Z=25:GOTO 890
     460 PRINT " SNAPS A LONG FLIP SHOT"
     470 Z=17:GOTO 890
     480 PRINT B$(H(J-1));:G1=0:G2=0:G=H(J-1):GOTO 390
     490 ON C GOTO 500,640
     500 ON P GOTO 510,540,570
    -510 PRINT A$(H(J-2)) " LEADS " A$(H(J-1)) " WITH A PERFECT PASS."
    +510 PRINT A$(H(J-2)) " LEADS " A$(H(J-1)) " WITH A PERFECT PASS." 
     520 PRINT A$(H(J-1)) " CUTTING IN!!!"
     530 G=H(J-1):G1=H(J-2):G2=0:Z1=3:GOTO 770
     540 PRINT A$(H(J-2)) " GIVES TO A STREAKING " A$(H(J-1))
    @@ -74,56 +74,56 @@
     620 PRINT A$(H(J-1)) " DROPS IT TO " A$(H(J-4))
     630 G=H(J-4):G1=H(J-1):G2=H(J-2):Z1=1:GOTO 770
     640 ON P GOTO 650,670,720
    -650 PRINT B$(H(J-1)) " HITS " B$(H(J-2)) " FLYING DOWN THE LEFT SIDE"
    +650 PRINT B$(H(J-1)) " HITS " B$(H(J-2)) " FLYING DOWN THE LEFT SIDE" 
     660 G=H(J-2):G1=H(J-1):G2=0:Z1=3:GOTO 770
     670 PRINT "IT'S A ' 3 ON 2 '!"
     680 PRINT "ONLY " A$(4) " AND " A$(5) " ARE BACK."
     690 PRINT B$(H(J-2)) " GIVES OFF TO " B$(H(J-1))
     700 PRINT B$(H(J-1)) " DROPS TO " B$(H(J-3))
    -710 G=H(J-3):G1=H(J-1):G2=H(J-2):Z1=2:GOTO 770
    -720 PRINT " A ' 3 ON 2 ' WITH A ' TRAILER '!"
    -730 PRINT B$(H(J-4)) " GIVES TO " B$(H(J-2)) " WHO SHUFFLES IT OFF TO"
    +710 G=H(J-3):G1=H(J-1):G2=H(J-2):Z1=2:GOTO 770 
    +720 PRINT " A ' 3 ON 2 ' WITH A ' TRAILER '!" 
    +730 PRINT B$(H(J-4)) " GIVES TO " B$(H(J-2)) " WHO SHUFFLES IT OFF TO" 
     740 PRINT B$(H(J-1)) " WHO FIRES A WING TO WING PASS TO "
    -750 PRINT B$(H(J-3)) " AS HE CUTS IN ALONE!!"
    -760 G=H(J-3):G1=H(J-1):G2=H(J-2):Z1=1:GOTO 770
    +750 PRINT B$(H(J-3)) " AS HE CUTS IN ALONE!!"    
    +760 G=H(J-3):G1=H(J-1):G2=H(J-2):Z1=1:GOTO 770 
     770 PRINT "SHOT";:INPUT S:IF S>4 THEN 770:IF S<1 THEN 770
     780 ON C GOTO 790,880
    -790 PRINT A$(G);:ON S GOTO 800,820,840,860
    -800 PRINT " LET'S A BIG SLAP SHOT GO!!"
    +790 PRINT A$(G);:ON S GOTO 800,820,840,860 
    +800 PRINT " LET'S A BIG SLAP SHOT GO!!"  
     810 Z=4:Z=Z+Z1:GOTO 890
    -820 PRINT " RIPS A WRIST SHOT OFF"
    +820 PRINT " RIPS A WRIST SHOT OFF" 
     830 Z=2:Z=Z+Z1:GOTO 890
    -840 PRINT " GETS A BACKHAND OFF"
    +840 PRINT " GETS A BACKHAND OFF" 
     850 Z=3:Z=Z+Z1:GOTO 890
    -860 PRINT " SNAPS OFF A SNAP SHOT"
    +860 PRINT " SNAPS OFF A SNAP SHOT"   
     870 Z=2:Z=Z+Z1:GOTO 890
    -880 PRINT B$(G);:ON S GOTO 800,820,840,860
    +880 PRINT B$(G);:ON S GOTO 800,820,840,860 
     890 PRINT "AREA";:INPUT A:IF A<1 THEN 890
     895 IF A>4 THEN 890
     900 ON C GOTO 910,920
    -910 S2=S2+1:GOTO 930
    +910 S2=S2+1:GOTO 930 
     920 S3=S3+1
     930 A1=INT(4*RND(X))+1:IF A<>A1 THEN 1200
     940 H(20)=INT(100*RND(X))+1
     950 IF INT(H(20)/Z)=H(20)/Z THEN 1160
     960 ON C GOTO 970,980
    -970 PRINT "GOAL " A$(7):H(9)=H(9)+1:GOTO 990
    -980 PRINT "SCORE " B$(7):H(8)=H(8)+1
    +970 PRINT "GOAL " A$(7):H(9)=H(9)+1:GOTO 990 
    +980 PRINT "SCORE " B$(7):H(8)=H(8)+1   
     990 FOR B1=1 TO 25:PRINT CHR$(7);:NEXT B1:PRINT
     1000 PRINT "SCORE: ";:IF H(8)>H(9) THEN 1020
     1010 PRINT A$(7)":";H(9),B$(7)":";H(8):GOTO 1030
    -1020 PRINT B$(7)":";H(8),A$(7)":";H(9)
    +1020 PRINT B$(7)":";H(8),A$(7)":";H(9)  
     1030 ON C GOTO 1040,1100
     1040 PRINT "GOAL SCORED BY: " A$(G):IF G1=0 THEN 1070
     1050 IF G2=0 THEN 1080
    -1060 PRINT " ASSISTED BY: " A$(G1) " AND " A$(G2):GOTO 1090
    +1060 PRINT " ASSISTED BY: " A$(G1) " AND " A$(G2):GOTO 1090 
     1070 PRINT " UNASSISTED.":GOTO 1090
     1080 PRINT " ASSISTED BY: " A$(G1)
     1090 T(G)=T(G)+1:T1(G1)=T1(G1)+1:T1(G2)=T1(G2)+1:GOTO 1540
     1100 PRINT "GOAL SCORED BY: " B$(G);
     1110 IF G1=0 THEN 1130
     1115 IF G2=0 THEN 1140
    -1120 PRINT " ASSISTED BY: " B$(G1) " AND " B$(G2):GOTO 1150
    +1120 PRINT " ASSISTED BY: " B$(G1) " AND " B$(G2):GOTO 1150 
     1130 PRINT " UNASSISTED":GOTO 1150
     1140 PRINT " ASSISTED BY: " B$(G1):GOTO 1150
     1150 T2(G)=T2(G)+1:T3(G1)=T3(G1)+1:T3(G2)=T3(G2)+1:GOTO 1540
    @@ -132,39 +132,39 @@
     1170 ON C GOTO 1180,1190
     1180 PRINT "SAVE " B$(6) " --  REBOUND":GOTO 940
     1190 PRINT "SAVE " A$(6) " --  FOLLOW UP":GOTO 940
    -1200 S1=INT(6*RND(X))+1
    +1200 S1=INT(6*RND(X))+1 
     1210 ON C GOTO 1220,1380
    -1220 ON S1 GOTO 1230,1260,1290,1300,1330,1350
    +1220 ON S1 GOTO 1230,1260,1290,1300,1330,1350 
     1230 PRINT "KICK SAVE AND A BEAUTY BY " B$(6)
     1240 PRINT "CLEARED OUT BY " B$(3)
    -1250 GOTO 260
    +1250 GOTO 260 
     1260 PRINT "WHAT A SPECTACULAR GLOVE SAVE BY " B$(6)
     1270 PRINT "AND " B$(6) " GOLFS IT INTO THE CROWD"
     1280 GOTO 1540
    -1290 PRINT "SKATE SAVE ON A LOW STEAMER BY " B$(6):GOTO 260
    -1300 PRINT "PAD SAVE BY " B$(6) " OFF THE STICK"
    +1290 PRINT "SKATE SAVE ON A LOW STEAMER BY " B$(6):GOTO 260 
    +1300 PRINT "PAD SAVE BY " B$(6) " OFF THE STICK" 
     1310 PRINT "OF "A$(G) " AND " B$(6) " COVERS UP"
     1320 GOTO 1540
    -1330 PRINT "WHISTLES ONE OVER THE HEAD OF " B$(6)
    -1340 GOTO 260
    +1330 PRINT "WHISTLES ONE OVER THE HEAD OF " B$(6) 
    +1340 GOTO 260 
     1350 PRINT B$(6) " MAKES A FACE SAVE!! AND HE IS HURT"
    -1360 PRINT "THE DEFENSEMAN " B$(5) " COVERS UP FOR HIM"
    +1360 PRINT "THE DEFENSEMAN " B$(5) " COVERS UP FOR HIM" 
     1370 GOTO 1540
    -1380 ON S1 GOTO 1390,1410,1440,1470,1490,1520
    -1390 PRINT "STICK SAVE BY " A$(6)
    -1400 PRINT "AND CLEARED OUT BY " A$(4):GOTO 260
    -1410 PRINT "OH MY GOD!! " B$(G) " RATTLES ONE OFF THE POST"
    -1420 PRINT "TO THE RIGHT OF " A$(6) " AND " A$(6) " COVERS ";
    -1430 PRINT "ON THE LOOSE PUCK!":GOTO 1540
    +1380 ON S1 GOTO 1390,1410,1440,1470,1490,1520 
    +1390 PRINT "STICK SAVE BY " A$(6) 
    +1400 PRINT "AND CLEARED OUT BY " A$(4):GOTO 260 
    +1410 PRINT "OH MY GOD!! " B$(G) " RATTLES ONE OFF THE POST" 
    +1420 PRINT "TO THE RIGHT OF " A$(6) " AND " A$(6) " COVERS "; 
    +1430 PRINT "ON THE LOOSE PUCK!":GOTO 1540 
     1440 PRINT "SKATE SAVE BY " A$(6)
    -1450 PRINT A$(6) " WHACKS THE LOOSE PUCK INTO THE STANDS"
    +1450 PRINT A$(6) " WHACKS THE LOOSE PUCK INTO THE STANDS" 
     1460 GOTO 1540
    -1470 PRINT "STICK SAVE BY " A$(6) " AND HE CLEARS IT OUT HIMSELF"
    -1480 GOTO 260
    -1490 PRINT "KICKED OUT BY " A$(6)
    -1500 PRINT "AND IT REBOUNDS ALL THE WAY TO CENTER ICE"
    -1510 GOTO 260
    -1520 PRINT "GLOVE SAVE " A$(6) " AND HE HANGS ON"
    +1470 PRINT "STICK SAVE BY " A$(6) " AND HE CLEARS IT OUT HIMSELF" 
    +1480 GOTO 260 
    +1490 PRINT "KICKED OUT BY " A$(6) 
    +1500 PRINT "AND IT REBOUNDS ALL THE WAY TO CENTER ICE"  
    +1510 GOTO 260 
    +1520 PRINT "GLOVE SAVE " A$(6) " AND HE HANGS ON" 
     1530 GOTO 1540
     1540 NEXT L:FOR N=1 TO 30:PRINT CHR$(7);:NEXT N:PRINT "THAT'S THE SIREN"
     1550 PRINT:PRINT TAB(15);"FINAL SCORE:"
    @@ -175,14 +175,14 @@
     1600 PRINT TAB(25);A$(7)
     1610 PRINT TAB(5);"NAME";TAB(20);"GOALS";TAB(35);"ASSISTS"
     1620 PRINT TAB(5);"----";TAB(20);"-----";TAB(35);"-------"
    -1630 FOR I=1 TO 5:PRINT TAB(5);A$(I);TAB(21);T(I);TAB(36);T1(I)
    -1640 NEXT I:PRINT
    +1630 FOR I=1 TO 5:PRINT TAB(5);A$(I);TAB(21);T(I);TAB(36);T1(I) 
    +1640 NEXT I:PRINT 
     1650 PRINT TAB(25);B$(7)
    -1660 PRINT TAB(5);"NAME";TAB(20);"GOALS";TAB(35);"ASSISTS"
    +1660 PRINT TAB(5);"NAME";TAB(20);"GOALS";TAB(35);"ASSISTS"  
     1670 PRINT TAB(5);"----";TAB(20);"-----";TAB(35);"-------"
     1680 FOR T=1 TO 5:PRINT TAB(5);B$(T);TAB(21);T2(T);TAB(36);T3(T)
    -1690 NEXT T:PRINT
    -1700 PRINT "SHOTS ON NET":PRINT A$(7)":";S2:PRINT B$(7)":";S3
    +1690 NEXT T:PRINT 
    +1700 PRINT "SHOTS ON NET":PRINT A$(7)":";S2:PRINT B$(7)":";S3 
     1710 END
     1720 PRINT: PRINT "THIS IS A SIMULATED HOCKEY GAME."
     1730 PRINT "QUESTION     RESPONSE"
    diff --git a/49_Hockey/javascript/hockey.html b/49_Hockey/javascript/hockey.html
    index 43df11cb9..fb26a5c6e 100644
    --- a/49_Hockey/javascript/hockey.html
    +++ b/49_Hockey/javascript/hockey.html
    @@ -1,10 +1,9 @@
     
     
     HOCKEY
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/49_Hockey/javascript/hockey.js b/49_Hockey/javascript/hockey.js
    index d58a56a97..16d5f19e2 100644
    --- a/49_Hockey/javascript/hockey.js
    +++ b/49_Hockey/javascript/hockey.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    @@ -154,7 +154,7 @@ async function main()
             else
                 print(bs[7] + " HAS CONTROL.\n");
             do {
    -
    +            
                 print("PASS");
                 p = parseInt(await input());
                 for (n = 1; n <= 3; n++)
    diff --git a/49_Hockey/kotlin/README.md b/49_Hockey/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/49_Hockey/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/49_Hockey/lua/README.md b/49_Hockey/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/49_Hockey/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/49_Hockey/pascal/README.md b/49_Hockey/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/49_Hockey/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/49_Hockey/python/README.md b/49_Hockey/python/README.md
    index 2d8807aa8..781945ec4 100644
    --- a/49_Hockey/python/README.md
    +++ b/49_Hockey/python/README.md
    @@ -1,27 +1,3 @@
     Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
     
     Conversion to [Python](https://www.python.org/about/)
    -
    -
    -## Porting Notes
    -
    -Variables:
    -
    -* C: Do you want instructions?
    -* A$(7): Team name + player names (6 players)
    -* B$(7): Team name + player names (6 players)
    -* T6: Minutes per game
    -* R: REFEREE
    -
    -Functions:
    -
    -* REM: A line comment
    -* `INT(2*RND(X))+1`: X is constantly 1. That means that this expression is simpler expressed as `randint(1,2)`
    -
    ----
    -
    -Looking at the JS implementation:
    -
    -* as[7] / bs[7]: The team name
    -* ha[8] : Score of team B
    -* ha[9] : Score of team A
    diff --git a/49_Hockey/python/hockey.py b/49_Hockey/python/hockey.py
    deleted file mode 100644
    index 7b1e1ecf6..000000000
    --- a/49_Hockey/python/hockey.py
    +++ /dev/null
    @@ -1,561 +0,0 @@
    -"""
    -HOCKEY
    -
    -A simulation of an ice hockey game.
    -
    -The original author is Robert Puopolo;
    -modifications by Steve North of Creative Computing.
    -
    -Ported to Python by Martin Thoma in 2022
    -"""
    -
    -from dataclasses import dataclass, field
    -from random import randint
    -from typing import List, Tuple
    -
    -NB_PLAYERS = 6
    -
    -
    -@dataclass
    -class Team:
    -    # TODO: It would be better to use a Player-class (name, goals, assits)
    -    #       and have the attributes directly at each player. This would avoid
    -    #       dealing with indices that much
    -    #
    -    #       I'm also rather certain that I messed up somewhere with the indices
    -    #       - instead of using those, one could use actual player positions:
    -    #       LEFT WING,    CENTER,        RIGHT WING
    -    #       LEFT DEFENSE, RIGHT DEFENSE, GOALKEEPER
    -    name: str
    -    players: List[str]  # 6 players
    -    shots_on_net: int = 0
    -    goals: List[int] = field(default_factory=lambda: [0 for _ in range(NB_PLAYERS)])
    -    assists: List[int] = field(default_factory=lambda: [0 for _ in range(NB_PLAYERS)])
    -    score: int = 0
    -
    -    def show_lineup(self) -> None:
    -        print(" " * 10 + f"{self.name} STARTING LINEUP")
    -        for player in self.players:
    -            print(player)
    -
    -
    -def ask_binary(prompt: str, error_msg: str) -> bool:
    -    while True:
    -        answer = input(prompt).lower()
    -        if answer in ["y", "yes"]:
    -            return True
    -        if answer in ["n", "no"]:
    -            return False
    -        print(error_msg)
    -
    -
    -def get_team_names() -> Tuple[str, str]:
    -    while True:
    -        answer = input("ENTER THE TWO TEAMS: ")
    -        if answer.count(",") == 1:
    -            return answer.split(",")  # type: ignore
    -        print("separated by a single comma")
    -
    -
    -def get_pass() -> int:
    -    while True:
    -        answer = input("PASS? ")
    -        try:
    -            passes = int(answer)
    -            if passes >= 0 and passes <= 3:
    -                return passes
    -        except ValueError:
    -            print("ENTER A NUMBER BETWEEN 0 AND 3")
    -
    -
    -def get_minutes_per_game() -> int:
    -    while True:
    -        answer = input("ENTER THE NUMBER OF MINUTES IN A GAME ")
    -        try:
    -            minutes = int(answer)
    -            if minutes >= 1:
    -                return minutes
    -        except ValueError:
    -            print("ENTER A NUMBER")
    -
    -
    -def get_player_names(prompt: str) -> List[str]:
    -    players = []
    -    print(prompt)
    -    for i in range(1, 7):
    -        player = input(f"PLAYER {i}: ")
    -        players.append(player)
    -    return players
    -
    -
    -def make_shot(
    -    controlling_team: int, team_a: Team, team_b: Team, player_index: List[int], j: int
    -) -> Tuple[int, int, int, int]:
    -    while True:
    -        try:
    -            s = int(input("SHOT? "))
    -        except ValueError:
    -            continue
    -        if s >= 1 and s <= 4:
    -            break
    -    if controlling_team == 1:
    -        print(team_a.players[player_index[j - 1]])
    -    else:
    -        print(team_b.players[player_index[j - 1]])
    -    g = player_index[j - 1]
    -    g1 = 0
    -    g2 = 0
    -    if s == 1:
    -        print(" LET'S A BOOMER GO FROM THE RED LINE!!\n")  # line 400
    -        z = 10
    -    elif s == 2:
    -        print(" FLIPS A WRISTSHOT DOWN THE ICE\n")  # line 420
    -        # Probable missing line 430 in original
    -    elif s == 3:
    -        print(" BACKHANDS ONE IN ON THE GOALTENDER\n")
    -        z = 25
    -    elif s == 4:
    -        print(" SNAPS A LONG FLIP SHOT\n")
    -        # line 460
    -        z = 17
    -    return z, g, g1, g2
    -
    -
    -def print_header() -> None:
    -    print(" " * 33 + "HOCKEY")
    -    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n")
    -
    -
    -def instructions() -> None:
    -    if ask_binary(
    -        "WOULD YOU LIKE THE INSTRUCTIONS? ", "ANSWER YES OR NO!!"
    -    ):
    -        print()
    -        print("THIS IS A SIMULATED HOCKEY GAME.")
    -        print("QUESTION     RESPONSE")
    -        print("PASS         TYPE IN THE NUMBER OF PASSES YOU WOULD")
    -        print("             LIKE TO MAKE, FROM 0 TO 3.")
    -        print("SHOT         TYPE THE NUMBER CORRESPONDING TO THE SHOT")
    -        print("             YOU WANT TO MAKE.  ENTER:")
    -        print("             1 FOR A SLAPSHOT")
    -        print("             2 FOR A WRISTSHOT")
    -        print("             3 FOR A BACKHAND")
    -        print("             4 FOR A SNAP SHOT")
    -        print("AREA         TYPE IN THE NUMBER CORRESPONDING TO")
    -        print("             THE AREA YOU ARE AIMING AT.  ENTER:")
    -        print("             1 FOR UPPER LEFT HAND CORNER")
    -        print("             2 FOR UPPER RIGHT HAND CORNER")
    -        print("             3 FOR LOWER LEFT HAND CORNER")
    -        print("             4 FOR LOWER RIGHT HAND CORNER")
    -        print("AT THE START OF THE GAME, YOU WILL BE ASKED FOR THE NAMES")
    -        print("OF YOUR PLAYERS.  THEY ARE ENTERED IN THE ORDER: ")
    -        print("LEFT WING, CENTER, RIGHT WING, LEFT DEFENSE,")
    -        print("RIGHT DEFENSE, GOALKEEPER.  ANY OTHER INPUT REQUIRED WILL")
    -        print("HAVE EXPLANATORY INSTRUCTIONS.")
    -
    -
    -def team1_action(
    -    pass_value: int, player_index: List[int], team_a: Team, team_b: Team, j: int
    -) -> Tuple[int, int, int, int]:
    -    if pass_value == 1:
    -        print(
    -            team_a.players[player_index[j - 2]]
    -            + " LEADS "
    -            + team_a.players[player_index[j - 1]]
    -            + " WITH A PERFECT PASS.\n"
    -        )
    -        print(team_a.players[player_index[j - 1]] + " CUTTING IN!!!\n")
    -        scoring_player = player_index[j - 1]
    -        goal_assistant1 = player_index[j - 2]
    -        goal_assistant2 = 0
    -        z1 = 3
    -    elif pass_value == 2:
    -        print(
    -            team_a.players[player_index[j - 2]]
    -            + " GIVES TO A STREAKING "
    -            + team_a.players[player_index[j - 1]]
    -        )
    -        print(
    -            team_a.players[player_index[j - 3]]
    -            + " COMES DOWN ON "
    -            + team_b.players[4]
    -            + " AND "
    -            + team_b.players[3]
    -        )
    -        scoring_player = player_index[j - 3]
    -        goal_assistant1 = player_index[j - 1]
    -        goal_assistant2 = player_index[j - 2]
    -        z1 = 2
    -    elif pass_value == 3:
    -        print("OH MY GOD!! A ' 4 ON 2 ' SITUATION\n")
    -        print(
    -            team_a.players[player_index[j - 3]]
    -            + " LEADS "
    -            + team_a.players[player_index[j - 2]]
    -            + "\n"
    -        )
    -        print(team_a.players[player_index[j - 2]] + " IS WHEELING THROUGH CENTER.\n")
    -        print(
    -            team_a.players[player_index[j - 2]]
    -            + " GIVES AND GOEST WITH "
    -            + team_a.players[player_index[j - 1]]
    -        )
    -        print("PRETTY PASSING!\n")
    -        print(
    -            team_a.players[player_index[j - 1]]
    -            + " DROPS IT TO "
    -            + team_a.players[player_index[j - 4]]
    -        )
    -        scoring_player = player_index[j - 4]
    -        goal_assistant1 = player_index[j - 1]
    -        goal_assistant2 = player_index[j - 2]
    -        z1 = 1
    -    return scoring_player, goal_assistant1, goal_assistant2, z1
    -
    -
    -def team2_action(
    -    pass_value: int, player_index: List[int], team_a: Team, team_b: Team, j: int
    -) -> Tuple[int, int, int, int]:
    -    if pass_value == 1:
    -        print(
    -            team_b.players[player_index[j - 1]]
    -            + " HITS "
    -            + team_b.players[player_index[j - 2]]
    -            + " FLYING DOWN THE LEFT SIDE\n"
    -        )
    -        scoring_player = player_index[j - 2]
    -        goal_assistant1 = player_index[j - 1]
    -        goal_assistant2 = 0
    -        z1 = 3
    -    elif pass_value == 2:
    -        print("IT'S A ' 3 ON 2 '!\n")
    -        print(f"ONLY {team_a.players[3]} AND {team_a.players[4]} ARE BACK.\n")
    -        print(
    -            team_b.players[player_index[j - 2]]
    -            + " GIVES OFF TO "
    -            + team_b.players[player_index[j - 1]]
    -        )
    -        print(
    -            team_b.players[player_index[j - 1]]
    -            + " DROPS TO "
    -            + team_b.players[player_index[j - 3]]
    -        )
    -        scoring_player = player_index[j - 3]
    -        goal_assistant1 = player_index[j - 1]
    -        goal_assistant2 = player_index[j - 2]
    -        z1 = 2
    -    elif pass_value == 3:
    -        print(" A '3 ON 2 ' WITH A ' TRAILER '!\n")
    -        print(
    -            team_b.players[player_index[j - 4]]
    -            + " GIVES TO "
    -            + team_b.players[player_index[j - 2]]
    -            + " WHO SHUFFLES IT OFF TO\n"
    -        )
    -        print(
    -            team_b.players[player_index[j - 1]] + " WHO FIRES A WING TO WING PASS TO \n"
    -        )
    -        print(team_b.players[player_index[j - 3]] + " AS HE CUTS IN ALONE!!\n")
    -        scoring_player = player_index[j - 3]
    -        goal_assistant1 = player_index[j - 1]
    -        goal_assistant2 = player_index[j - 2]
    -        z1 = 1
    -    return scoring_player, goal_assistant1, goal_assistant2, z1
    -
    -
    -def final_message(team_a: Team, team_b: Team, player_index: List[int]) -> None:
    -    # Bells chime
    -    print("THAT'S THE SIREN\n")
    -    print("\n")
    -    print(" " * 15 + "FINAL SCORE:\n")
    -    if team_b.score <= team_a.score:
    -        print(f"{team_a.name}: {team_a.score}\t{team_b.name}: {team_b.score}\n")
    -    else:
    -        print(f"{team_b.name}: {team_b.score}\t{team_a.name}\t:{team_a.score}\n")
    -    print("\n")
    -    print(" " * 10 + "SCORING SUMMARY\n")
    -    print("\n")
    -    print(" " * 25 + team_a.name + "\n")
    -    print("\tNAME\tGOALS\tASSISTS\n")
    -    print("\t----\t-----\t-------\n")
    -    for i in range(1, 6):
    -        print(f"\t{team_a.players[i]}\t{team_a.goals[i]}\t{team_a.assists[i]}\n")
    -    print("\n")
    -    print(" " * 25 + team_b.name + "\n")
    -    print("\tNAME\tGOALS\tASSISTS\n")
    -    print("\t----\t-----\t-------\n")
    -    for t in range(1, 6):
    -        print(f"\t{team_b.players[t]}\t{team_b.goals[t]}\t{team_b.assists[t]}\n")
    -    print("\n")
    -    print("SHOTS ON NET\n")
    -    print(f"{team_a.name}: {team_a.shots_on_net}\n")
    -    print(f"{team_b.name}: {team_b.shots_on_net}\n")
    -
    -
    -def main() -> None:
    -    # Intro
    -    print_header()
    -    player_index: List[int] = [0 for _ in range(21)]
    -    print("\n" * 3)
    -    instructions()
    -
    -    # Gather input
    -    team_name_a, team_name_b = get_team_names()
    -    print()
    -    minutes_per_game = get_minutes_per_game()
    -    print()
    -    players_a = get_player_names(f"WOULD THE {team_name_a} COACH ENTER HIS TEAM")
    -    print()
    -    players_b = get_player_names(f"WOULD THE {team_name_b} COACH DO THE SAME")
    -    team_a = Team(team_name_a, players_a)
    -    team_b = Team(team_name_b, players_b)
    -    print()
    -    referee = input("INPUT THE REFEREE FOR THIS GAME: ")
    -    print()
    -    team_a.show_lineup()
    -    print()
    -    team_b.show_lineup()
    -    print("WE'RE READY FOR TONIGHTS OPENING FACE-OFF.")
    -    print(
    -        f"{referee} WILL DROP THE PUCK BETWEEN "
    -        f"{team_a.players[0]} AND {team_b.players[0]}"
    -    )
    -    remaining_time = minutes_per_game
    -
    -    # Play the game
    -    while remaining_time > 0:
    -        cont, remaining_time = simulate_game_round(
    -            team_a, team_b, player_index, remaining_time
    -        )
    -        remaining_time -= 1
    -        if cont == "break":
    -            break
    -
    -    # Outro
    -    final_message(team_a, team_b, player_index)
    -
    -
    -def handle_hit(
    -    controlling_team: int,
    -    team_a: Team,
    -    team_b: Team,
    -    player_index: List[int],
    -    goal_player: int,
    -    goal_assistant1: int,
    -    goal_assistant2: int,
    -    hit_area: int,
    -    z: int,
    -) -> int:
    -    while True:
    -        player_index[20] = randint(1, 100)
    -        if player_index[20] % z != 0:
    -            break
    -        a2 = randint(1, 100)
    -        if a2 % 4 == 0:
    -            if controlling_team == 1:
    -                print(f"SAVE {team_b.players[5]} --  REBOUND\n")
    -            else:
    -                print(f"SAVE {team_a.players[5]} --  FOLLOW up\n")
    -            continue
    -        else:
    -            hit_area += 1
    -    if player_index[20] % z != 0:
    -        if controlling_team == 1:
    -            print(f"GOAL {team_a.name}\n")
    -            team_a.score += 1
    -        else:
    -            print(f"SCORE {team_b.name}\n")
    -            team_b.score += 1
    -        # Bells in origninal
    -        print("\n")
    -        print("SCORE: ")
    -        if team_b.score <= team_a.score:
    -            print(f"{team_a.name}: {team_a.score}\t{team_b.name}: {team_b.score}\n")
    -        else:
    -            print(f"{team_b.name}: {team_b.score}\t{team_a.name}: {team_a.score}\n")
    -        team = team_a if controlling_team == 1 else team_b
    -        print(f"GOAL SCORED BY: {team.players[goal_player]}\n")
    -        if goal_assistant1 != 0:
    -            if goal_assistant2 != 0:
    -                print(
    -                    f" ASSISTED BY: {team.players[goal_assistant1]}"
    -                    f" AND {team.players[goal_assistant2]}"
    -                )
    -            else:
    -                print(f" ASSISTED BY: {team.players[goal_assistant1]}")
    -            team.assists[goal_assistant1] += 1
    -            team.assists[goal_assistant2] += 1
    -        else:
    -            print(" UNASSISTED.\n")
    -        team.goals[goal_player] += 1
    -
    -    return hit_area
    -
    -
    -def handle_miss(
    -    controlling_team: int,
    -    team_a: Team,
    -    team_b: Team,
    -    remaining_time: int,
    -    goal_player: int,
    -) -> Tuple[str, int]:
    -    saving_player = randint(1, 7)
    -    if controlling_team == 1:
    -        if saving_player == 1:
    -            print(f"KICK SAVE AND A BEAUTY BY {team_b.players[5]}\n")
    -            print(f"CLEARED OUT BY {team_b.players[3]}\n")
    -            remaining_time -= 1
    -            return ("continue", remaining_time)
    -        if saving_player == 2:
    -            print(f"WHAT A SPECTACULAR GLOVE SAVE BY {team_b.players[5]}\n")
    -            print(f"AND {team_b.players[5]} GOLFS IT INTO THE CROWD\n")
    -            return ("break", remaining_time)
    -        if saving_player == 3:
    -            print(f"SKATE SAVE ON A LOW STEAMER BY {team_b.players[5]}\n")
    -            remaining_time -= 1
    -            return ("continue", remaining_time)
    -        if saving_player == 4:
    -            print(f"PAD SAVE BY {team_b.players[5]} OFF THE STICK\n")
    -            print(
    -                f"OF {team_a.players[goal_player]} AND "
    -                f"{team_b.players[5]} COVERS UP\n"
    -            )
    -            return ("break", remaining_time)
    -        if saving_player == 5:
    -            print(f"WHISTLES ONE OVER THE HEAD OF {team_b.players[5]}\n")
    -            remaining_time -= 1
    -            return ("continue", remaining_time)
    -        if saving_player == 6:
    -            print(f"{team_b.players[5]} MAKES A FACE SAVE!! AND HE IS HURT\n")
    -            print(f"THE DEFENSEMAN {team_b.players[5]} COVERS UP FOR HIM\n")
    -            return ("break", remaining_time)
    -    else:
    -        if saving_player == 1:
    -            print(f"STICK SAVE BY {team_a.players[5]}\n")
    -            print(f"AND CLEARED OUT BY {team_a.players[3]}\n")
    -            remaining_time -= 1
    -            return ("continue", remaining_time)
    -        if saving_player == 2:
    -            print(
    -                "OH MY GOD!! "
    -                f"{team_b.players[goal_player]} RATTLES ONE OFF THE POST\n"
    -            )
    -            print(
    -                f"TO THE RIGHT OF {team_a.players[5]} AND "
    -                f"{team_a.players[5]} COVERS "
    -            )
    -            print("ON THE LOOSE PUCK!\n")
    -            return ("break", remaining_time)
    -        if saving_player == 3:
    -            print(f"SKATE SAVE BY {team_a.players[5]}\n")
    -            print(team_a.players[5] + " WHACKS THE LOOSE PUCK INTO THE STANDS\n")
    -            return ("break", remaining_time)
    -        if saving_player == 4:
    -            print(f"STICK SAVE BY {team_a.players[5]} AND HE CLEARS IT OUT HIMSELF\n")
    -            remaining_time -= 1
    -            return ("continue", remaining_time)
    -        if saving_player == 5:
    -            print(f"KICKED OUT BY {team_a.players[5]}\n")
    -            print("AND IT REBOUNDS ALL THE WAY TO CENTER ICE\n")
    -            remaining_time -= 1
    -            return ("continue", remaining_time)
    -        if saving_player == 6:
    -            print(f"GLOVE SAVE {team_a.players[5]} AND HE HANGS ON\n")
    -            return ("break", remaining_time)
    -    return ("continue", remaining_time)
    -
    -
    -def simulate_game_round(
    -    team_a: Team, team_b: Team, player_index: List[int], remaining_time: int
    -) -> Tuple[str, int]:
    -    controlling_team = randint(1, 2)
    -    if controlling_team == 1:
    -        print(f"{team_a.name} HAS CONTROL OF THE PUCK.")
    -    else:
    -        print(f"{team_b.name} HAS CONTROL.")
    -    pass_value = get_pass()
    -    for i in range(1, 4):
    -        player_index[i] = 0
    -
    -    # Line 310:
    -    while True:
    -        j = 0
    -        for j in range(1, (pass_value + 2) + 1):
    -            player_index[j] = randint(1, 5)
    -        if (
    -            player_index[j - 1] == player_index[j - 2]
    -            or pass_value >= 1
    -            and (
    -                player_index[j - 1] == player_index[j - 3]
    -                or player_index[j - 2] == player_index[j - 3]
    -            )
    -        ):
    -            break
    -    if pass_value == 0:  # line 350
    -        z, goal_player, goal_assistant1, goal_assistant2 = make_shot(
    -            controlling_team, team_a, team_b, player_index, j
    -        )
    -    else:
    -        if controlling_team == 1:
    -            goal_player, goal_assistant1, goal_assistant2, z1 = team1_action(
    -                pass_value, player_index, team_a, team_b, j
    -            )
    -        else:
    -            goal_player, goal_assistant1, goal_assistant2, z1 = team2_action(
    -                pass_value, player_index, team_a, team_b, j
    -            )
    -        while True:
    -            shot_type = int(input("SHOT? "))
    -            if shot_type >= 1 and shot_type <= 4:
    -                break
    -        if controlling_team == 1:
    -            print(team_a.players[goal_player], end="")
    -        else:
    -            print(team_b.players[goal_player], end="")
    -        if shot_type == 1:
    -            print(" LET'S A BIG SLAP SHOT GO!!\n")
    -            z = 4
    -            z += z1
    -        elif shot_type == 2:
    -            print(" RIPS A WRIST SHOT OFF\n")
    -            z = 2
    -            z += z1
    -        elif shot_type == 3:
    -            print(" GETS A BACKHAND OFF\n")
    -            z = 3
    -            z += z1
    -        elif shot_type == 4:
    -            print(" SNAPS OFF A SNAP SHOT\n")
    -            z = 2
    -            z += z1
    -    while True:
    -        goal_area = int(input("AREA? "))
    -        if goal_area >= 1 and goal_area <= 4:
    -            break
    -    if controlling_team == 1:
    -        team_a.shots_on_net += 1
    -    else:
    -        team_b.shots_on_net += 1
    -    hit_area = randint(1, 5)
    -    if goal_area == hit_area:
    -        hit_area = handle_hit(
    -            controlling_team,
    -            team_a,
    -            team_b,
    -            player_index,
    -            goal_player,
    -            goal_assistant1,
    -            goal_assistant2,
    -            hit_area,
    -            z,
    -        )
    -    if goal_area != hit_area:
    -        return handle_miss(
    -            controlling_team, team_a, team_b, remaining_time, goal_player
    -        )
    -    print("AND WE'RE READY FOR THE FACE-OFF\n")
    -    return ("continue", remaining_time)
    -
    -
    -if __name__ == "__main__":
    -    main()
    diff --git a/49_Hockey/vbnet/Hockey.sln b/49_Hockey/vbnet/Hockey.sln
    deleted file mode 100644
    index 396cfe92d..000000000
    --- a/49_Hockey/vbnet/Hockey.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 59df31bf0..000000000
    --- a/49_Hockey/vbnet/Hockey.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Hockey
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/50_Horserace/README.md b/50_Horserace/README.md
    index 25bec0dd0..00e24df5d 100644
    --- a/50_Horserace/README.md
    +++ b/50_Horserace/README.md
    @@ -12,7 +12,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/50_Horserace/csharp/Horserace.csproj b/50_Horserace/csharp/Horserace.csproj
    deleted file mode 100644
    index d3fe4757c..000000000
    --- a/50_Horserace/csharp/Horserace.csproj
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    diff --git a/50_Horserace/csharp/Horserace.sln b/50_Horserace/csharp/Horserace.sln
    deleted file mode 100644
    index 17d7fae3e..000000000
    --- a/50_Horserace/csharp/Horserace.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/java/Horserace.java b/50_Horserace/java/Horserace.java
    deleted file mode 100644
    index 9a5a7651b..000000000
    --- a/50_Horserace/java/Horserace.java
    +++ /dev/null
    @@ -1,313 +0,0 @@
    -import java.util.ArrayList;
    -import java.util.Arrays;
    -import java.util.HashMap;
    -import java.util.List;
    -import java.util.Map;
    -import java.util.Random;
    -import java.util.Scanner;
    -
    -/**
    - * HORSERACE
    - * 

    - * Converted from BASIC to Java by Aldrin Misquitta (@aldrinm) - */ -public class Horserace { - - private static final String[] horseNames = { - "JOE MAW", - "L.B.J.", - "MR.WASHBURN", - "MISS KAREN", - "JOLLY", - "HORSE", - "JELLY DO NOT", - "MIDNIGHT" - }; - public static final int MAX_DISTANCE = 28; - public static final int NUM_HORSES = 8; - - public static void main(String[] args) { - printHeader(); - - Scanner scanner = new Scanner(System.in); - Random random = new Random(); - - printHelp(scanner); - - List betNames = readBetNames(scanner); - - boolean donePlaying = false; - while (!donePlaying) { - - int[] odds = generateOdds(random); - int sumOdds = Arrays.stream(odds).sum(); - printOdds(sumOdds, odds); - - Map bets = takeBets(scanner, betNames); - - var horsePositions = runRace(horseNames.length, sumOdds, odds, random); - - printRaceResults(horsePositions, bets, sumOdds, odds); - - donePlaying = readDonePlaying(scanner); - } - } - - private static int[] generateOdds(Random random) { - int[] odds = new int[NUM_HORSES]; - for (int i = 0; i < NUM_HORSES; i++) { - odds[i] = (int) (10 * random.nextFloat() + 1); - } - return odds; - } - - private static void printOdds(int R, int[] D) { - System.out.printf("%n%-28s%-14s%-14s%n%n", "HORSE", "NUMBER", "ODDS"); - for (int n = 0; n < horseNames.length; n++) { - System.out.printf("%-28s% -14d%.6f :1%n", horseNames[n], n + 1, ((float) R / D[n])); - } - } - - private static boolean readDonePlaying(Scanner scan) { - System.out.println("DO YOU WANT TO BET ON THE NEXT RACE ?"); - System.out.print("YES OR NO? "); - String choice = scan.nextLine(); - return !choice.equalsIgnoreCase("YES"); - } - - /** - * Simulate the race run, returning the final positions of the horses. - */ - private static int[] runRace(int numberOfHorses, int sumOdds, int[] odds, Random random) { - int[] positionChange = new int[numberOfHorses]; - - System.out.println(); - System.out.println("1 2 3 4 5 6 7 8"); - - int totalDistance = 0; - int[] currentPositions = new int[NUM_HORSES]; - int[] horsePositions = new int[NUM_HORSES]; - - while (totalDistance < MAX_DISTANCE) { - System.out.println("XXXXSTARTXXXX"); - - for (int i = 0; i < numberOfHorses; i++) { - horsePositions[i] = i + 1; - positionChange[i] = calculatePositionChanges(sumOdds, odds[i], random); - currentPositions[i] += positionChange[i]; - } - - sortHorsePositionsBasedOnCurrent(currentPositions, horsePositions); - - totalDistance = currentPositions[horsePositions[7] - 1]; - - boolean raceFinished = false; - int i = 0; - while (i < NUM_HORSES && !raceFinished) { - int distanceToNextHorse = currentPositions[(horsePositions[i] - 1)] - (i < 1 ? 0 : currentPositions[(horsePositions[i - 1] - 1)]); - if (distanceToNextHorse != 0) { - int a = 0; - while (a < distanceToNextHorse && !raceFinished) { - System.out.println(); - if (currentPositions[horsePositions[i] - 1] >= MAX_DISTANCE) { - raceFinished = true; - } - a++; - } - } - - if (!raceFinished) { - System.out.print(" " + horsePositions[i] + " "); // Print horse number - } - i++; - } - - if (!raceFinished) { - //Print additional empty lines - for (int a = 0; a < MAX_DISTANCE - totalDistance; a++) { - System.out.println(); - } - } - - System.out.println("XXXXFINISHXXXX"); - System.out.println("\n"); - System.out.println("---------------------------------------------"); - System.out.println("\n"); - } - - return horsePositions; - } - - /** - * Sorts the horsePositions array in place, based on the currentPositions of the horses. - * (bubble sort) - */ - private static void sortHorsePositionsBasedOnCurrent(int[] currentPositions, int[] horsePositions) { - for (int l = 0; l < NUM_HORSES; l++) { - int i = 0; - /* - uses a do-while instead of a for loop here, because in BASIC - a FOR I=1 TO 0 causes at least one execution of the loop - */ - do { - if (currentPositions[horsePositions[i] - 1] >= currentPositions[horsePositions[i + 1] - 1]) { - int h = horsePositions[i]; - horsePositions[i] = horsePositions[i + 1]; - horsePositions[i + 1] = h; - } - i++; - } while (i < (7 - l)); - } - } - - private static int calculatePositionChanges(int r, int d, Random random) { - int positionChange = (int) (100 * random.nextFloat() + 1); - - if (positionChange < 10) { - positionChange = 1; - } else { - int s = (int) ((float) r / d + 0.5); - if (positionChange < (s + 17)) { - positionChange = 2; - } else if (positionChange < s + 37) { - positionChange = 3; - } else if (positionChange < s + 57) { - positionChange = 4; - } else if (positionChange < s + 77) { - positionChange = 5; - } else if (positionChange < s + 92) { - positionChange = 6; - } else { - positionChange = 7; - } - } - - return positionChange; - } - - private static void printRaceResults(int[] m, Map bets, int r, int[] d) { - System.out.println("THE RACE RESULTS ARE:"); - int z9 = 1; - for (int i = 7; i >= 0; i--) { - int f = m[i]; - System.out.println(); - System.out.println(z9 + " PLACE HORSE NO. " + f + " AT " + (r / d[f - 1]) + ":1"); - z9++; - } - bets.forEach((betName, bet) -> { - if (bet.horseNumber == m[7]) { - int n = bet.horseNumber; - System.out.println(); - System.out.printf("%s WINS $ %.2f %n", bet.betName, ((float) r / d[n]) * bet.amount); - } - }); - } - - private static Map takeBets(Scanner scanner, List betNames) { - Map bets = new HashMap<>(); - System.out.println("--------------------------------------------------"); - System.out.println("PLACE YOUR BETS...HORSE # THEN AMOUNT"); - for (String betName : betNames) { - boolean validInput = false; - while (!validInput) { - int horseNumber = readInt(betName, scanner);//Q in the original - double betAmount = readDouble("?", scanner); //P in the original - if (betAmount < 1 || betAmount > 100000) { - System.out.println(" YOU CAN'T DO THAT!"); - } else { - bets.put(betName, new Bet(betName, horseNumber, betAmount)); - validInput = true; - } - } - } - - return bets; - } - - private static void printHelp(Scanner scanner) { - System.out.print("DO YOU WANT DIRECTIONS"); - - String directions = readChoice(scanner); - - if (!directions.equalsIgnoreCase("NO")) { - System.out.println("UP TO 10 MAY PLAY. A TABLE OF ODDS WILL BE PRINTED. YOU"); - System.out.println("MAY BET ANY + AMOUNT UNDER 100000 ON ONE HORSE."); - System.out.println("DURING THE RACE, A HORSE WILL BE SHOWN BY ITS"); - System.out.println("NUMBER. THE HORSES RACE DOWN THE PAPER!"); - System.out.println(); - } - } - - private static String readChoice(Scanner scanner) { - System.out.print("? "); - return scanner.nextLine(); - } - - private static int readInt(String prompt, Scanner scanner) { - System.out.print(prompt); - while (true) { - System.out.print("? "); - String input = scanner.nextLine(); - try { - return Integer.parseInt(input); - } catch (NumberFormatException e) { - System.out.println("!NUMBER EXPECTED - RETRY INPUT LINE"); - } - } - } - - private static double readDouble(String prompt, Scanner scanner) { - System.out.print(prompt); - while (true) { - System.out.print("? "); - String input = scanner.nextLine(); - try { - return Double.parseDouble(input); - } catch (NumberFormatException e) { - System.out.println("!NUMBER EXPECTED - RETRY INPUT LINE"); - } - } - } - - private static List readBetNames(Scanner scanner) { - int c = readInt("HOW MANY WANT TO BET ", scanner); - System.out.println("WHEN ? APPEARS,TYPE NAME"); - List names = new ArrayList<>(); - for (int i = 1; i <= c; i++) { - System.out.print("? "); - names.add(scanner.nextLine()); - } - - return names; - } - - private static void printHeader() { - System.out.println(" HORSERACE"); - System.out.println(" CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n"); - System.out.println("\n\n"); - System.out.println("WELCOME TO SOUTH PORTLAND HIGH RACETRACK"); - System.out.println(" ...OWNED BY LAURIE CHEVALIER"); - } - - private static class Bet { - String betName; - int horseNumber; - double amount; - - public Bet(String betName, int horseNumber, double amount) { - this.betName = betName; - this.horseNumber = horseNumber; - this.amount = amount; - } - - @Override - public String toString() { - return "Bet{" + - "betName='" + betName + '\'' + - ", horseNumber=" + horseNumber + - ", amount=" + amount + - '}'; - } - } -} - diff --git a/50_Horserace/javascript/horserace.html b/50_Horserace/javascript/horserace.html index 9383afb8e..2809ec394 100644 --- a/50_Horserace/javascript/horserace.html +++ b/50_Horserace/javascript/horserace.html @@ -1,10 +1,9 @@ HORSERACE - -

    
    +
    
     
     
     
    diff --git a/50_Horserace/javascript/horserace.js b/50_Horserace/javascript/horserace.js
    index 39e12b0fd..882e66e69 100644
    --- a/50_Horserace/javascript/horserace.js
    +++ b/50_Horserace/javascript/horserace.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/50_Horserace/kotlin/README.md b/50_Horserace/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/50_Horserace/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/50_Horserace/lua/README.md b/50_Horserace/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/50_Horserace/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/50_Horserace/pascal/README.md b/50_Horserace/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/50_Horserace/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/50_Horserace/python/horserace.py b/50_Horserace/python/horserace.py
    index 075c4573a..cf7c266e6 100644
    --- a/50_Horserace/python/horserace.py
    +++ b/50_Horserace/python/horserace.py
    @@ -1,10 +1,8 @@
    -import math
     import random
    +import math
     import time
    -from typing import List, Tuple
    -
     
    -def basic_print(*zones, **kwargs) -> None:
    +def basic_print(*zones, **kwargs):
         """Simulates the PRINT command from BASIC to some degree.
         Supports `printing zones` if given multiple arguments."""
     
    @@ -12,13 +10,13 @@ def basic_print(*zones, **kwargs) -> None:
         if len(zones) == 1:
             line = str(zones[0])
         else:
    -        line = "".join([f"{str(zone):<14}" for zone in zones])
    +        line = "".join(["{:<14}".format(str(zone)) for zone in zones])
         identation = kwargs.get("indent", 0)
         end = kwargs.get("end", "\n")
         print(" " * identation + line, end=end)
     
     
    -def basic_input(prompt: str, type_conversion=None):
    +def basic_input(prompt, type_conversion=None):
         """BASIC INPUT command with optional type conversion"""
     
         while True:
    @@ -42,11 +40,11 @@ def basic_input(prompt: str, type_conversion=None):
         "JOLLY",
         "HORSE",
         "JELLY DO NOT",
    -    "MIDNIGHT",
    +    "MIDNIGHT"
     ]
     
     
    -def introduction() -> None:
    +def introduction():
         """Print the introduction, and optional the instructions"""
     
         basic_print("HORSERACE", indent=31)
    @@ -67,17 +65,21 @@ def introduction() -> None:
         basic_print("")
     
     
    -def setup_players() -> List[str]:
    +def setup_players():
         """Gather the number of players and their names"""
     
         # ensure we get an integer value from the user
         number_of_players = basic_input("HOW MANY WANT TO BET", int)
     
    +    # for each user query their name and return the list of names
    +    player_names = []
         basic_print("WHEN ? APPEARS,TYPE NAME")
    -    return [basic_input("") for _ in range(number_of_players)]
    +    for _ in range(number_of_players):
    +        player_names.append(basic_input(""))
    +    return player_names
     
     
    -def setup_horses() -> List[float]:
    +def setup_horses():
         """Generates random odds for each horse. Returns a list of
         odds, indexed by the order of the global HORSE_NAMES."""
     
    @@ -86,10 +88,10 @@ def setup_horses() -> List[float]:
     
         # rounding odds to two decimals for nicer output,
         # this is not in the origin implementation
    -    return [round(total / odd, 2) for odd in odds]
    +    return [round(total/odd, 2) for odd in odds]
     
     
    -def print_horse_odds(odds) -> None:
    +def print_horse_odds(odds):
         """Print the odds for each horse"""
     
         basic_print("")
    @@ -98,14 +100,14 @@ def print_horse_odds(odds) -> None:
         basic_print("")
     
     
    -def get_bets(player_names: List[str]) -> List[Tuple[int, float]]:
    +def get_bets(player_names):
         """For each player, get the number of the horse to bet on,
         as well as the amount of money to bet"""
     
         basic_print("--------------------------------------------------")
         basic_print("PLACE YOUR BETS...HORSE # THEN AMOUNT")
     
    -    bets: List[Tuple[int, float]] = []
    +    bets = []
         for name in player_names:
             horse = basic_input(name, int)
             amount = None
    @@ -115,17 +117,17 @@ def get_bets(player_names: List[str]) -> List[Tuple[int, float]]:
                     basic_print("  YOU CAN'T DO THAT!")
                     amount = None
             bets.append((horse, amount))
    -
    +    
         basic_print("")
     
         return bets
     
     
    -def get_distance(odd: float) -> int:
    +def get_distance(odd):
         """Advances a horse during one step of the racing simulation.
         The amount travelled is random, but scaled by the odds of the horse"""
     
    -    d = random.randrange(1, 100)
    +    d = random.randrange(1,100)
         s = math.ceil(odd)
         if d < 10:
             return 1
    @@ -137,13 +139,15 @@ def get_distance(odd: float) -> int:
             return 4
         elif d < s + 77:
             return 5
    +    elif d < s + 77:
    +        return 5
         elif d < s + 92:
             return 6
         else:
             return 7
     
     
    -def print_race_state(total_distance, race_pos) -> None:
    +def print_race_state(total_distance, race_pos):
         """Outputs the current state/stop of the race.
         Each horse is placed according to the distance they have travelled. In
         case some horses travelled the same distance, their numbers are printed
    @@ -156,17 +160,17 @@ def print_race_state(total_distance, race_pos) -> None:
         # race_pos is stored by last to first horse in the race.
         # we get the next horse we need to print out
         next_pos = next(race_pos_iter)
    -
    +    
         # start line
         basic_print("XXXXSTARTXXXX")
     
         # print all 28 lines/unit of the race course
    -    for line in range(28):
    +    for l in range(28):
     
             # ensure we still have a horse to print and if so, check if the
             # next horse to print is not the current line
             # needs iteration, since multiple horses can share the same line
    -        while next_pos is not None and line == total_distance[next_pos]:
    +        while next_pos is not None and l == total_distance[next_pos]:
                 basic_print(f"{next_pos} ", end="")
                 next_pos = next(race_pos_iter, None)
             else:
    @@ -177,7 +181,7 @@ def print_race_state(total_distance, race_pos) -> None:
         basic_print("XXXXFINISHXXXX")
     
     
    -def simulate_race(odds) -> List[int]:
    +def simulate_race(odds):
         num_horses = len(HORSE_NAMES)
     
         # in spirit of the original implementation, using two arrays to
    @@ -191,7 +195,7 @@ def simulate_race(odds) -> List[int]:
         # e.g. race_pos[0] => last horse
         #      race_pos[-1] => winning horse
         race_pos = list(range(num_horses))
    -
    +    
         basic_print("\n1 2 3 4 5 6 7 8")
     
         while True:
    @@ -201,14 +205,14 @@ def simulate_race(odds) -> List[int]:
                 total_distance[i] += get_distance(odds[i])
     
             # bubble sort race_pos based on total distance travelled
    -        # in the original implementation, race_pos is reset for each
    +        # in the original implementation, race_pos is reset for each 
             # simulation step, so we keep this behaviour here
             race_pos = list(range(num_horses))
    -        for line in range(num_horses):
    -            for i in range(num_horses - 1 - line):
    -                if total_distance[race_pos[i]] < total_distance[race_pos[i + 1]]:
    +        for l in range(num_horses):
    +            for i in range(num_horses-1-l):
    +                if total_distance[race_pos[i]] < total_distance[race_pos[i+1]]:
                         continue
    -                race_pos[i], race_pos[i + 1] = race_pos[i + 1], race_pos[i]
    +                race_pos[i], race_pos[i+1] = race_pos[i+1], race_pos[i]
     
             # print current state of the race
             print_race_state(total_distance, race_pos)
    @@ -217,21 +221,23 @@ def simulate_race(odds) -> List[int]:
             # check if the winning horse is already over the finish line
             if total_distance[race_pos[-1]] >= 28:
                 return race_pos
    -
    +        
             # this was not in the original BASIC implementation, but it makes the
             # race visualization a nice animation (if the terminal size is set to 31 rows)
             time.sleep(1)
     
     
    -def print_race_results(race_positions, odds, bets, player_names) -> None:
    +def print_race_results(race_positions, odds, bets, player_names):
         """Print the race results, as well as the winnings of each player"""
     
         # print the race positions first
         basic_print("THE RACE RESULTS ARE:")
    -    for position, horse_idx in enumerate(reversed(race_positions), start=1):
    +    position = 1
    +    for horse_idx in reversed(race_positions):
             line = f"{position} PLACE HORSE NO. {horse_idx} AT {odds[horse_idx]}:1"
             basic_print("")
             basic_print(line)
    +        position += 1
     
         # followed by the amount the players won
         winning_horse_idx = race_positions[-1]
    @@ -240,9 +246,9 @@ def print_race_results(race_positions, odds, bets, player_names) -> None:
             if horse == winning_horse_idx:
                 basic_print("")
                 basic_print(f"{name} WINS ${amount * odds[winning_horse_idx]}")
    +    
     
    -
    -def main_loop(player_names, horse_odds) -> None:
    +def main_loop(player_names, horse_odds):
         """Main game loop"""
     
         while True:
    @@ -257,7 +263,7 @@ def main_loop(player_names, horse_odds) -> None:
                 break
     
     
    -def main() -> None:
    +def main():
         # introduction, player names and horse odds are only generated once
         introduction()
         player_names = setup_players()
    @@ -266,7 +272,7 @@ def main() -> None:
         # main loop of the game, the player can play multiple races, with the
         # same odds
         main_loop(player_names, horse_odds)
    -
    +    
     
     if __name__ == "__main__":
    -    main()
    +    main()
    \ No newline at end of file
    diff --git a/50_Horserace/rust/Cargo.lock b/50_Horserace/rust/Cargo.lock
    deleted file mode 100644
    index 4fe2abbea..000000000
    --- a/50_Horserace/rust/Cargo.lock
    +++ /dev/null
    @@ -1,75 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.10"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.147"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/50_Horserace/rust/Cargo.toml b/50_Horserace/rust/Cargo.toml
    deleted file mode 100644
    index 3b1d02f52..000000000
    --- a/50_Horserace/rust/Cargo.toml
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -[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/50_Horserace/rust/src/game.rs b/50_Horserace/rust/src/game.rs
    deleted file mode 100644
    index 079e397e2..000000000
    --- a/50_Horserace/rust/src/game.rs
    +++ /dev/null
    @@ -1,57 +0,0 @@
    -use std::{thread, time::Duration};
    -
    -use crate::{horses::Horses, players::Players};
    -
    -pub struct Game {
    -    horses: Horses,
    -    players: Players,
    -}
    -
    -impl Game {
    -    pub fn new() -> Self {
    -        Game {
    -            horses: Horses::new(),
    -            players: Players::new(),
    -        }
    -    }
    -
    -    pub fn play(&mut self) -> bool {
    -        self.horses.randomize_odds();
    -        self.horses.print_table();
    -
    -        self.players.make_bets();
    -
    -        println!("\n1 2 3 4 5 6 7 8");
    -
    -        for _ in 1..=7 {
    -            self.horses.advance();
    -            self.draw();
    -            thread::sleep(Duration::from_secs(1));
    -        }
    -
    -        let winner = self.horses.print_placements();
    -        self.players.process_winner(winner);
    -
    -        return self.players.prompt_next_round();
    -    }
    -
    -    pub fn draw(&self) {
    -        println!("=============");
    -        println!("XXXXSTARTXXXX");
    -        for row in 1..=28 {
    -            let neighbors = self.horses.get_at(row);
    -
    -            match neighbors.len() {
    -                0 => println!(),
    -                1 => println!("{}", neighbors[0].no),
    -                _ => {
    -                    for h in neighbors {
    -                        print!("{} ", h.no);
    -                    }
    -                    println!();
    -                }
    -            }
    -        }
    -        println!("XXXXFINISHXXXX");
    -    }
    -}
    diff --git a/50_Horserace/rust/src/horses.rs b/50_Horserace/rust/src/horses.rs
    deleted file mode 100644
    index 825042aa2..000000000
    --- a/50_Horserace/rust/src/horses.rs
    +++ /dev/null
    @@ -1,114 +0,0 @@
    -use rand::Rng;
    -
    -pub struct Horse {
    -    pub name: String,
    -    pub no: u8,
    -    pub odd: f32,
    -    pub position: u8,
    -}
    -
    -impl Horse {
    -    fn new(name: &str, no: u8) -> Self {
    -        Horse {
    -            name: name.to_string(),
    -            no,
    -            odd: 0.,
    -            position: 0,
    -        }
    -    }
    -}
    -
    -pub struct Horses {
    -    horses: [Horse; 8],
    -}
    -
    -impl Horses {
    -    pub fn new() -> Self {
    -        Horses {
    -            horses: [
    -                Horse::new("JOE MAW", 1),
    -                Horse::new("L.B.J.", 2),
    -                Horse::new("MR.WASHBURN", 3),
    -                Horse::new("MISS KAREN", 4),
    -                Horse::new("JOLLY", 5),
    -                Horse::new("HORSE", 6),
    -                Horse::new("JELLY DO NOT", 7),
    -                Horse::new("MIDNIGHT", 8),
    -            ],
    -        }
    -    }
    -
    -    pub fn randomize_odds(&mut self) {
    -        let mut odds = Vec::new();
    -
    -        for _ in 1..=8 {
    -            odds.push(rand::thread_rng().gen_range(1.0..=10.));
    -        }
    -
    -        let total: f32 = odds.iter().sum();
    -
    -        for (i, o) in odds.iter().enumerate() {
    -            let o = total / o;
    -            self.horses[i].odd = o;
    -        }
    -    }
    -
    -    pub fn advance(&mut self) {
    -        for h in self.horses.iter_mut() {
    -            let distance = rand::thread_rng().gen_range(1..=100);
    -            let scale = h.odd.ceil() as i32;
    -
    -            let dt = if distance < 10 {
    -                1
    -            } else if distance < scale + 17 {
    -                2
    -            } else if distance < scale + 37 {
    -                3
    -            } else if distance < scale + 57 {
    -                4
    -            } else if distance < scale + 77 {
    -                5
    -            } else if distance < scale + 92 {
    -                6
    -            } else {
    -                7
    -            };
    -
    -            h.position += dt as u8;
    -        }
    -    }
    -
    -    pub fn get_at(&self, row: usize) -> Vec<&Horse> {
    -        self.horses
    -            .iter()
    -            .filter(|h| h.position == row as u8)
    -            .collect()
    -    }
    -
    -    pub fn print_table(&self) {
    -        println!("HORSE\t\tNUMBER\t\tODDS\t\t\n");
    -        for horse in self.horses.iter() {
    -            let (h, n, o) = (horse.name.clone(), horse.no, horse.odd);
    -
    -            if h.len() > 7 {
    -                println!("{}\t{}\t\t{:.2} :1", h, n, o);
    -            } else {
    -                println!("{}\t\t{}\t\t{:.2} :1", h, n, o);
    -            }
    -        }
    -        println!("-----------------------------------------\n")
    -    }
    -
    -    pub fn print_placements(&mut self) -> u8 {
    -        self.horses.sort_by(|a, b| b.position.cmp(&a.position));
    -
    -        println!("\nTHE RACE RESULTS ARE:\n");
    -
    -        for (i, h) in self.horses.iter_mut().enumerate() {
    -            println!("{} PLACE HORSE NO. {}\t\tAT {:.2} :1", i + 1, h.no, h.odd);
    -            h.position = 0;
    -        }
    -
    -        self.horses[0].no
    -    }
    -}
    diff --git a/50_Horserace/rust/src/main.rs b/50_Horserace/rust/src/main.rs
    deleted file mode 100644
    index fc8a5d1af..000000000
    --- a/50_Horserace/rust/src/main.rs
    +++ /dev/null
    @@ -1,28 +0,0 @@
    -use crate::{game::Game, util::PromptResult};
    -
    -mod game;
    -mod horses;
    -mod players;
    -mod util;
    -
    -fn main() {
    -    println!("\n\n\t\tHORSERACE");
    -    println!("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
    -    println!("WELCOME TO SOUTH PORTLAND HIGH RACETRACK\n\t\t...OWNED BY LAURIE CHEVALIER");
    -
    -    if let PromptResult::YesNo(yes) = util::prompt(Some(false), "DO YOU WANT DIRECTIONS?") {
    -        if yes {
    -            println!("UP TO 10 MAY PLAY.  A TABLE OF ODDS WILL BE PRINTED.  YOU");
    -            println!("MAY BET ANY AMOUNT UNDER $100,000 ON ONE HORSE.");
    -            println!("DURING THE RACE, A HORSE WILL BE SHOWN BY ITS");
    -            println!("NUMBER.  THE HORSES RACE DOWN THE PAPER!\n");
    -        }
    -    }
    -
    -    let mut game = Game::new();
    -    let mut again = true;
    -
    -    while again {
    -        again = game.play();
    -    }
    -}
    diff --git a/50_Horserace/rust/src/players.rs b/50_Horserace/rust/src/players.rs
    deleted file mode 100644
    index 5aa891b71..000000000
    --- a/50_Horserace/rust/src/players.rs
    +++ /dev/null
    @@ -1,156 +0,0 @@
    -use crate::util::{self, PromptResult};
    -
    -#[derive(Debug)]
    -pub struct Player {
    -    pub name: String,
    -    pub money: u32,
    -    pub playing: bool,
    -    pub horse_no: u8,
    -    pub bet: u32,
    -}
    -
    -impl Player {
    -    fn new(name: String) -> Self {
    -        Player {
    -            name,
    -            money: 100000,
    -            playing: true,
    -            horse_no: 0,
    -            bet: 0,
    -        }
    -    }
    -}
    -
    -#[derive(Debug)]
    -pub struct Players {
    -    players: Vec,
    -}
    -
    -impl Players {
    -    pub fn new() -> Self {
    -        let players;
    -
    -        loop {
    -            if let PromptResult::Numeric(n) = util::prompt(Some(true), "HOW MANY WANT TO BET?") {
    -                if n <= 0 {
    -                    println!("THERE CAN'T BE (LESS THAN) ZERO PLAYERS!");
    -                } else if n > 10 {
    -                    println!("THERE CAN'T BE MORE THAN TEN PLAYERS!");
    -                } else {
    -                    println!("WHEN ? APPEARS, TYPE NAME");
    -                    players = Players::generate_players(n);
    -                    break;
    -                }
    -            }
    -        }
    -
    -        Players { players }
    -    }
    -
    -    pub fn make_bets(&mut self) {
    -        println!("PLACE YOUR BETS...HORSE # THEN AMOUNT");
    -
    -        for p in self.players.iter_mut() {
    -            if !p.playing {
    -                continue;
    -            }
    -
    -            let name = format!("{}?", p.name);
    -
    -            'prompt: loop {
    -                if let PromptResult::Normal(response) = util::prompt(None, name.as_str()) {
    -                    let response: Vec<&str> = response.trim().split(",").collect();
    -
    -                    for (i, n) in response.iter().enumerate() {
    -                        if let Ok(n) = n.parse::() {
    -                            if n.is_negative() {
    -                                println!("YOU CAN'T ENTER A NEGATIVE NUMBER!")
    -                            } else {
    -                                match i {
    -                                    0 => {
    -                                        if n > 8 {
    -                                            println!("INVALID HORSE #")
    -                                        } else {
    -                                            p.horse_no = n as u8;
    -                                        }
    -                                    }
    -                                    1 => {
    -                                        if n == 0 {
    -                                            println!("YOU CAN'T BET NOTHING!");
    -                                        } else if n > p.money as i32 {
    -                                            println!("YOU DON'T HAVE ENOUGH MONEY!")
    -                                        } else {
    -                                            p.bet = n as u32;
    -                                            break 'prompt;
    -                                        }
    -                                    }
    -                                    _ => println!("YOU CAN'T ENTER MORE THAN 2 NUMBERS!"),
    -                                }
    -                            }
    -                        } else {
    -                            println!("ONLY ENTER NUMBERS PLEASE!");
    -                        }
    -                    }
    -                }
    -            }
    -        }
    -    }
    -
    -    fn generate_players(n: i32) -> Vec {
    -        let mut players: Vec = Vec::new();
    -
    -        for _ in 0..n {
    -            loop {
    -                if let PromptResult::Normal(name) = util::prompt(None, "?") {
    -                    let name = name.trim().to_uppercase();
    -
    -                    if name.is_empty() {
    -                        println!("NAME CAN'T BE EMPTY!");
    -                    } else if let Some(_) = players.iter().find(|p| p.name == name) {
    -                        println!("THERE IS ALREADY A PLAYER WITH THAT NAME!");
    -                    } else {
    -                        players.push(Player::new(name));
    -                        break;
    -                    }
    -                }
    -            }
    -        }
    -
    -        players
    -    }
    -
    -    pub fn process_winner(&mut self, no: u8) {
    -        println!();
    -        for p in self.players.iter_mut() {
    -            if !p.playing {
    -                continue;
    -            }
    -
    -            if p.horse_no == no {
    -                p.money += p.bet;
    -                println!("{} WON ${}! THEY HAVE ${}.", p.name, p.bet, p.money);
    -            } else {
    -                p.money -= p.bet;
    -                println!("{} LOST ${}. THEY HAVE ${} LEFT.", p.name, p.bet, p.money);
    -            }
    -            p.bet = 0;
    -            p.horse_no = 0;
    -        }
    -        println!();
    -    }
    -
    -    pub fn prompt_next_round(&mut self) -> bool {
    -        for p in self.players.iter_mut() {
    -            let msg = format!("{}, DO YOU WANT TO BET ON THE NEXT RACE?", p.name);
    -            if let PromptResult::YesNo(yes) = util::prompt(Some(false), msg.as_str()) {
    -                p.playing = yes;
    -            }
    -        }
    -
    -        if let None = self.players.iter().find(|p| p.playing) {
    -            return false;
    -        }
    -
    -        true
    -    }
    -}
    diff --git a/50_Horserace/rust/src/util.rs b/50_Horserace/rust/src/util.rs
    deleted file mode 100644
    index f1944bad3..000000000
    --- a/50_Horserace/rust/src/util.rs
    +++ /dev/null
    @@ -1,40 +0,0 @@
    -use std::io;
    -
    -pub enum PromptResult {
    -    Normal(String),
    -    YesNo(bool),
    -    Numeric(i32),
    -}
    -
    -pub fn prompt(is_numeric: Option, msg: &str) -> PromptResult {
    -    use PromptResult::*;
    -
    -    println!("{msg}");
    -
    -    loop {
    -        let mut input = String::new();
    -
    -        io::stdin()
    -            .read_line(&mut input)
    -            .expect("Failed to read input.");
    -
    -        if let Some(is_numeric) = is_numeric {
    -            let input = input.trim();
    -
    -            if is_numeric {
    -                if let Ok(n) = input.parse::() {
    -                    return Numeric(n);
    -                }
    -                println!("PLEASE ENTER A VALID NUMBER!");
    -            } else {
    -                match input.to_uppercase().as_str() {
    -                    "YES" | "Y" => return YesNo(true),
    -                    "NO" | "N" => return YesNo(false),
    -                    _ => println!("PLEASE ENTER (Y)ES OR (N)O."),
    -                }
    -            }
    -        } else {
    -            return Normal(input);
    -        }
    -    }
    -}
    diff --git a/50_Horserace/vbnet/Horserace.sln b/50_Horserace/vbnet/Horserace.sln
    deleted file mode 100644
    index 63adf3100..000000000
    --- a/50_Horserace/vbnet/Horserace.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 245d90985..000000000
    --- a/50_Horserace/vbnet/Horserace.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Horserace
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/51_Hurkle/README.md b/51_Hurkle/README.md
    index be94172a0..0204e4057 100644
    --- a/51_Hurkle/README.md
    +++ b/51_Hurkle/README.md
    @@ -14,7 +14,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/51_Hurkle/csharp/.gitignore b/51_Hurkle/csharp/.gitignore
    index 468a39766..d417b1866 100644
    --- a/51_Hurkle/csharp/.gitignore
    +++ b/51_Hurkle/csharp/.gitignore
    @@ -357,4 +357,4 @@ MigrationBackup/
     # Ionide (cross platform F# VS Code tools) working folder
     .ionide/
     
    -# End of https://www.toptal.com/developers/gitignore/api/csharp
    +# End of https://www.toptal.com/developers/gitignore/api/csharp
    \ No newline at end of file
    diff --git a/51_Hurkle/csharp/Hurkle.sln b/51_Hurkle/csharp/Hurkle.sln
    deleted file mode 100644
    index d1a6fb257..000000000
    --- a/51_Hurkle/csharp/Hurkle.sln
    +++ /dev/null
    @@ -1,25 +0,0 @@
    -
    -Microsoft Visual Studio Solution File, Format Version 12.00
    -# Visual Studio Version 16
    -VisualStudioVersion = 16.0.30114.105
    -MinimumVisualStudioVersion = 10.0.40219.1
    -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(ExtensibilityGlobals) = postSolution
    -		SolutionGuid = {42DC6AE5-5127-4B1B-BD5E-F3B1CCDC3822}
    -	EndGlobalSection
    -EndGlobal
    diff --git a/51_Hurkle/csharp/Program.cs b/51_Hurkle/csharp/Program.cs
    deleted file mode 100644
    index 483aa2b04..000000000
    --- a/51_Hurkle/csharp/Program.cs
    +++ /dev/null
    @@ -1,64 +0,0 @@
    -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/CardinalDirection.cs b/51_Hurkle/csharp/src/hurkle/CardinalDirection.cs
    similarity index 99%
    rename from 51_Hurkle/csharp/CardinalDirection.cs
    rename to 51_Hurkle/csharp/src/hurkle/CardinalDirection.cs
    index 324edbd29..969c9b2b1 100644
    --- a/51_Hurkle/csharp/CardinalDirection.cs
    +++ b/51_Hurkle/csharp/src/hurkle/CardinalDirection.cs
    @@ -12,4 +12,4 @@ internal enum CardinalDirection
             West,
             NorthWest
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/51_Hurkle/csharp/ConsoleHurkleView.cs b/51_Hurkle/csharp/src/hurkle/ConsoleHurkleView.cs
    similarity index 99%
    rename from 51_Hurkle/csharp/ConsoleHurkleView.cs
    rename to 51_Hurkle/csharp/src/hurkle/ConsoleHurkleView.cs
    index b587d12ce..40366ad27 100644
    --- a/51_Hurkle/csharp/ConsoleHurkleView.cs
    +++ b/51_Hurkle/csharp/src/hurkle/ConsoleHurkleView.cs
    @@ -64,4 +64,4 @@ public void ShowVictory(VictoryViewModel victoryViewModel)
                 Console.WriteLine($"YOU FOUND HIM IN {victoryViewModel.CurrentGuessNumber} GUESSES!");
             }
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/51_Hurkle/csharp/FailedGuessViewModel.cs b/51_Hurkle/csharp/src/hurkle/FailedGuessViewModel.cs
    similarity index 98%
    rename from 51_Hurkle/csharp/FailedGuessViewModel.cs
    rename to 51_Hurkle/csharp/src/hurkle/FailedGuessViewModel.cs
    index 541573e44..25042dde0 100644
    --- a/51_Hurkle/csharp/FailedGuessViewModel.cs
    +++ b/51_Hurkle/csharp/src/hurkle/FailedGuessViewModel.cs
    @@ -4,4 +4,4 @@ internal class FailedGuessViewModel
         {
             public CardinalDirection Direction { get; init; }
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/51_Hurkle/csharp/GamePoint.cs b/51_Hurkle/csharp/src/hurkle/GamePoint.cs
    similarity index 99%
    rename from 51_Hurkle/csharp/GamePoint.cs
    rename to 51_Hurkle/csharp/src/hurkle/GamePoint.cs
    index 7abde808c..f715a41d2 100644
    --- a/51_Hurkle/csharp/GamePoint.cs
    +++ b/51_Hurkle/csharp/src/hurkle/GamePoint.cs
    @@ -6,7 +6,7 @@ internal class GamePoint
             public int Y {get;init;}
     
             public CardinalDirection GetDirectionTo(GamePoint target)
    -        {
    +        {   
                 if(X == target.X)
                 {
                     if(Y > target.Y)
    @@ -53,4 +53,4 @@ public CardinalDirection GetDirectionTo(GamePoint target)
                 }
             }
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/51_Hurkle/csharp/GuessViewModel.cs b/51_Hurkle/csharp/src/hurkle/GuessViewModel.cs
    similarity index 98%
    rename from 51_Hurkle/csharp/GuessViewModel.cs
    rename to 51_Hurkle/csharp/src/hurkle/GuessViewModel.cs
    index fe8524a98..b0c5227c2 100644
    --- a/51_Hurkle/csharp/GuessViewModel.cs
    +++ b/51_Hurkle/csharp/src/hurkle/GuessViewModel.cs
    @@ -4,4 +4,4 @@ internal class GuessViewModel
         {
             public int CurrentGuessNumber {get;init;}
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/51_Hurkle/csharp/HurkleGame.cs b/51_Hurkle/csharp/src/hurkle/HurkleGame.cs
    similarity index 98%
    rename from 51_Hurkle/csharp/HurkleGame.cs
    rename to 51_Hurkle/csharp/src/hurkle/HurkleGame.cs
    index 438676a89..88620bbcc 100644
    --- a/51_Hurkle/csharp/HurkleGame.cs
    +++ b/51_Hurkle/csharp/src/hurkle/HurkleGame.cs
    @@ -25,7 +25,7 @@ public void PlayGame()
                     X = _random.Next(0, gridSize),
                     Y = _random.Next(0, gridSize)
                 };
    -
    +            
                 for(var K=1;K<=guesses;K++)
                 {
                     var guessPoint = _view.GetGuess(new GuessViewModel{CurrentGuessNumber = K});
    @@ -41,8 +41,8 @@ public void PlayGame()
                             continue;
                     }
                 }
    -
    +            
                 _view.ShowLoss(new LossViewModel{MaxGuesses = guesses, HurkleLocation = hurklePoint } );
             }
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/51_Hurkle/csharp/IHurkleView.cs b/51_Hurkle/csharp/src/hurkle/IHurkleView.cs
    similarity index 99%
    rename from 51_Hurkle/csharp/IHurkleView.cs
    rename to 51_Hurkle/csharp/src/hurkle/IHurkleView.cs
    index dbaf00f38..e5ce3a1a7 100644
    --- a/51_Hurkle/csharp/IHurkleView.cs
    +++ b/51_Hurkle/csharp/src/hurkle/IHurkleView.cs
    @@ -7,4 +7,4 @@ internal interface IHurkleView
             void ShowDirection(FailedGuessViewModel failedGuessViewModel);
             void ShowLoss(LossViewModel lossViewModel);
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/51_Hurkle/csharp/LossViewModel.cs b/51_Hurkle/csharp/src/hurkle/LossViewModel.cs
    similarity index 98%
    rename from 51_Hurkle/csharp/LossViewModel.cs
    rename to 51_Hurkle/csharp/src/hurkle/LossViewModel.cs
    index fe6eb1a9b..2329be873 100644
    --- a/51_Hurkle/csharp/LossViewModel.cs
    +++ b/51_Hurkle/csharp/src/hurkle/LossViewModel.cs
    @@ -5,4 +5,4 @@ internal class LossViewModel
             public int MaxGuesses { get; init; }
             public GamePoint HurkleLocation { get; init; }
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/51_Hurkle/csharp/src/hurkle/Program.cs b/51_Hurkle/csharp/src/hurkle/Program.cs
    new file mode 100644
    index 000000000..148308d15
    --- /dev/null
    +++ b/51_Hurkle/csharp/src/hurkle/Program.cs
    @@ -0,0 +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;
    +                }
    +                
    +            }
    +        }
    +    }
    +}
    diff --git a/51_Hurkle/csharp/VictoryViewModel.cs b/51_Hurkle/csharp/src/hurkle/VictoryViewModel.cs
    similarity index 92%
    rename from 51_Hurkle/csharp/VictoryViewModel.cs
    rename to 51_Hurkle/csharp/src/hurkle/VictoryViewModel.cs
    index f19f6f864..ce25311c1 100644
    --- a/51_Hurkle/csharp/VictoryViewModel.cs
    +++ b/51_Hurkle/csharp/src/hurkle/VictoryViewModel.cs
    @@ -1,7 +1,7 @@
     namespace hurkle
     {
         internal class VictoryViewModel
    -    {
    +    {  
             public int CurrentGuessNumber {get; init;}
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/51_Hurkle/csharp/src/hurkle/hurkle.csproj b/51_Hurkle/csharp/src/hurkle/hurkle.csproj
    new file mode 100644
    index 000000000..1d2d39a9e
    --- /dev/null
    +++ b/51_Hurkle/csharp/src/hurkle/hurkle.csproj
    @@ -0,0 +1,8 @@
    +
    +
    +  
    +    Exe
    +    net5.0
    +  
    +
    +
    diff --git a/51_Hurkle/javascript/hurkle.html b/51_Hurkle/javascript/hurkle.html
    index 49a107dce..8d2a50227 100644
    --- a/51_Hurkle/javascript/hurkle.html
    +++ b/51_Hurkle/javascript/hurkle.html
    @@ -1,10 +1,9 @@
     
     
     HURKLE
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/51_Hurkle/javascript/hurkle.js b/51_Hurkle/javascript/hurkle.js
    index 94d992a80..1e3301e52 100644
    --- a/51_Hurkle/javascript/hurkle.js
    +++ b/51_Hurkle/javascript/hurkle.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/51_Hurkle/kotlin/README.md b/51_Hurkle/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/51_Hurkle/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/51_Hurkle/lua/README.md b/51_Hurkle/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/51_Hurkle/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/51_Hurkle/pascal/README.md b/51_Hurkle/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/51_Hurkle/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/51_Hurkle/perl/hurkle.pl b/51_Hurkle/perl/hurkle.pl
    index aef3ee7a2..1497e50c0 100755
    --- a/51_Hurkle/perl/hurkle.pl
    +++ b/51_Hurkle/perl/hurkle.pl
    @@ -29,7 +29,7 @@
     HERE
     
     # The PLAY block is a complete game from start
    -# to finish. The continue block prints the
    +# to finish. The continue block prints the 
     # "let's play again" message and then a new
     # game is started.
     PLAY: while (1) {
    @@ -42,11 +42,11 @@
             my($G1,$G2);
             # The CHECK loop will execute while we
             # attempt to collect valid input from
    -        # the player
    +        # the player 
             CHECK: while (1) {
     
                 chomp(my $in = );
    -            # Use a regex to attempt to parse out
    +            # Use a regex to attempt to parse out 
                 # two integers separated by a comma.
                 if ($in =~ m{(\d+)\s*,\s*(\d+)}) {
                     $G1 = $1; $G2 = $2;
    diff --git a/51_Hurkle/python/hurkle.py b/51_Hurkle/python/hurkle.py
    index c8e2ca9bf..dfe40d8df 100644
    --- a/51_Hurkle/python/hurkle.py
    +++ b/51_Hurkle/python/hurkle.py
    @@ -1,12 +1,12 @@
     #!/usr/bin/env python3
    -
    -"""Ported to Python by @iamtraction"""
    +#
    +# Ported to Python by @iamtraction
     
     from random import random
     
     
    -def direction(A, B, X, Y) -> None:
    -    """Print the direction hint for finding the hurkle."""
    +def direction(A, B, X, Y):
    +    """Prints the direction hint for finding the hurkle."""
     
         print("GO ", end="")
         if Y < B:
    @@ -22,7 +22,7 @@ def direction(A, B, X, Y) -> None:
         print()
     
     
    -def main() -> None:
    +if __name__ == "__main__":
         print(" " * 33 + "HURKLE")
         print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
     
    @@ -53,7 +53,7 @@ def main() -> None:
                 # read coordinates in `X, Y` format, split the string
                 # at `,`, and then parse the coordinates to `int` and
                 # store them in `X` and `Y` respectively.
    -            [X, Y] = [int(c) for c in input("X,Y? ").split(",")]
    +            [ X, Y ] = [int(c) for c in input("X,Y? ").split(",")]
     
                 if abs(X - A) + abs(Y - B) == 0:
                     print("\nYOU FOUND HIM IN", k + 1, "GUESSES!")
    @@ -63,7 +63,3 @@ def main() -> None:
                     continue
     
             print("\n\nLET'S PLAY AGAIN, HURKLE IS HIDING.\n")
    -
    -
    -if __name__ == "__main__":
    -    main()
    diff --git a/51_Hurkle/rust/Cargo.lock b/51_Hurkle/rust/Cargo.lock
    deleted file mode 100644
    index 4fe2abbea..000000000
    --- a/51_Hurkle/rust/Cargo.lock
    +++ /dev/null
    @@ -1,75 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.10"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.147"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/51_Hurkle/rust/Cargo.toml b/51_Hurkle/rust/Cargo.toml
    deleted file mode 100644
    index 3b1d02f52..000000000
    --- a/51_Hurkle/rust/Cargo.toml
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -[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/51_Hurkle/rust/src/game.rs b/51_Hurkle/rust/src/game.rs
    deleted file mode 100644
    index 471889858..000000000
    --- a/51_Hurkle/rust/src/game.rs
    +++ /dev/null
    @@ -1,103 +0,0 @@
    -use std::io;
    -
    -use rand::Rng;
    -
    -type Position = (u8, u8);
    -
    -pub struct Game {
    -    hurkle: Position,
    -    tries: u8,
    -}
    -
    -impl Game {
    -    pub fn new() -> Self {
    -        let x: u8 = rand::thread_rng().gen_range(1..=10);
    -        let y: u8 = rand::thread_rng().gen_range(1..=10);
    -        let hurkle = (x, y);
    -
    -        Game { hurkle, tries: 0 }
    -    }
    -
    -    pub fn update(&mut self) -> bool {
    -        if self.tries >= 5 {
    -            println!("SORRY, THAT'S {} GUESSES.", self.tries);
    -            println!("THE HURKLE IS AT {}, {}", self.hurkle.0, self.hurkle.1);
    -            return true;
    -        }
    -        self.tries += 1;
    -        self.process_guess(self.get_guess())
    -    }
    -
    -    fn get_guess(&self) -> Position {
    -        let mut pos = (0, 0);
    -
    -        'guess: loop {
    -            println!("GUESS # {}?", self.tries);
    -
    -            let mut input = String::new();
    -
    -            io::stdin()
    -                .read_line(&mut input)
    -                .expect("**Failed to read line**");
    -
    -            let input: Vec<&str> = input.trim().split(",").collect();
    -
    -            let mut is_y = false;
    -            for a in input {
    -                match a.parse::() {
    -                    Ok(a) => {
    -                        if a > 10 || a == 0 {
    -                            println!("GUESS AXIS CANNOT BE ZERO OR LARGER THAN TEN!");
    -                            break;
    -                        }
    -                        if is_y {
    -                            pos.1 = a;
    -                            break 'guess;
    -                        } else {
    -                            pos.0 = a;
    -                            is_y = true;
    -                        }
    -                    }
    -                    Err(e) => println!("{} - TRY AGAIN!", e.to_string().to_uppercase()),
    -                }
    -            }
    -        }
    -
    -        pos
    -    }
    -
    -    fn process_guess(&self, p: Position) -> bool {
    -        if p == self.hurkle {
    -            println!("\nYOU FOUND HIM IN {} GUESSES!", self.tries);
    -            return true;
    -        }
    -
    -        let (x, y) = (p.0, p.1);
    -        let (hx, hy) = (self.hurkle.0, self.hurkle.1);
    -
    -        let mut dir_x = "WEST";
    -        let mut dir_y = "SOUTH";
    -
    -        let mut set_y_dir = || {
    -            if y < hy {
    -                dir_y = "NORTH";
    -            } else {
    -                dir_y = "";
    -            }
    -        };
    -
    -        if x > hx {
    -            set_y_dir();
    -        } else if x < hx {
    -            dir_x = "EAST";
    -            set_y_dir();
    -        } else {
    -            dir_x = "";
    -            set_y_dir();
    -        }
    -
    -        println!("GO {}{}\n", dir_y, dir_x);
    -
    -        false
    -    }
    -}
    diff --git a/51_Hurkle/rust/src/main.rs b/51_Hurkle/rust/src/main.rs
    deleted file mode 100644
    index 70b07abd3..000000000
    --- a/51_Hurkle/rust/src/main.rs
    +++ /dev/null
    @@ -1,29 +0,0 @@
    -use game::Game;
    -
    -mod game;
    -
    -fn main() {
    -    println!("\n\n\t\tHURKLE");
    -    println!("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
    -
    -    println!("A HURKLE IS HIDING ON A 10 BY 10 GRID. HOMEBASE");
    -    println!("ON THE GRID IS POINT 0,0 IN THE SOUTHWEST CORNER,");
    -    println!("AND ANY POINT ON THE GRID IS DESIGNATED BY A");
    -    println!("PAIR OF WHOLE NUMBERS SEPERATED BY A COMMA. THE FIRST");
    -    println!("NUMBER IS THE HORIZONTAL POSITION AND THE SECOND NUMBER");
    -    println!("IS THE VERTICAL POSITION. YOU MUST TRY TO");
    -    println!("GUESS THE HURKLE'S GRIDPOINT. YOU GET 5 TRIES.");
    -    println!("AFTER EACH TRY, I WILL TELL YOU THE APPROXIMATE");
    -    println!("DIRECTION TO GO TO LOOK FOR THE HURKLE.\n");
    -
    -    loop {
    -        let mut game = Game::new();
    -
    -        loop {
    -            if game.update() {
    -                println!("\nLET'S PLAY AGAIN. HURKLE IS HIDING.");
    -                break;
    -            }
    -        }
    -    }
    -}
    diff --git a/51_Hurkle/vbnet/Hurkle.sln b/51_Hurkle/vbnet/Hurkle.sln
    deleted file mode 100644
    index dda015020..000000000
    --- a/51_Hurkle/vbnet/Hurkle.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 9d93e823d..000000000
    --- a/51_Hurkle/vbnet/Hurkle.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Hurkle
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/52_Kinema/README.md b/52_Kinema/README.md
    index 26821b0e9..31a691998 100644
    --- a/52_Kinema/README.md
    +++ b/52_Kinema/README.md
    @@ -17,7 +17,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/52_Kinema/csharp/Kinema.csproj b/52_Kinema/csharp/Kinema.csproj
    deleted file mode 100644
    index d3fe4757c..000000000
    --- a/52_Kinema/csharp/Kinema.csproj
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    diff --git a/52_Kinema/csharp/Kinema.sln b/52_Kinema/csharp/Kinema.sln
    deleted file mode 100644
    index ddd986625..000000000
    --- a/52_Kinema/csharp/Kinema.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/javascript/kinema.html b/52_Kinema/javascript/kinema.html
    index fceaf2f2f..0e41284e4 100644
    --- a/52_Kinema/javascript/kinema.html
    +++ b/52_Kinema/javascript/kinema.html
    @@ -1,10 +1,9 @@
     
     
     KINEMA
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/52_Kinema/javascript/kinema.js b/52_Kinema/javascript/kinema.js
    index 91cd443ba..abd2bb1c5 100644
    --- a/52_Kinema/javascript/kinema.js
    +++ b/52_Kinema/javascript/kinema.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/52_Kinema/kotlin/README.md b/52_Kinema/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/52_Kinema/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/52_Kinema/lua/README.md b/52_Kinema/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/52_Kinema/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/52_Kinema/pascal/README.md b/52_Kinema/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/52_Kinema/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/52_Kinema/python/kinema.py b/52_Kinema/python/kinema.py
    index 2a4831a77..e5529d683 100644
    --- a/52_Kinema/python/kinema.py
    +++ b/52_Kinema/python/kinema.py
    @@ -20,7 +20,15 @@
     EXPECTED_ACCURACY_PERCENT = 15
     
     
    -def do_quiz() -> None:
    +def print_with_tab(spaces_count, msg):
    +    if spaces_count > 0:
    +        spaces = " " * spaces_count
    +    else:
    +        spaces = ""
    +    print(spaces + msg)
    +
    +
    +def do_quiz():
         print()
         print()
         num_questions_correct = 0
    @@ -30,7 +38,7 @@ def do_quiz() -> None:
         print(f"A BALL IS THROWN UPWARDS AT {v0} METERS PER SECOND.")
         print()
     
    -    answer = v0**2 / (2 * g)
    +    answer = v0 ** 2 / (2 * g)
         num_questions_correct += ask_player("HOW HIGH WILL IT GO (IN METERS)?", answer)
     
         answer = 2 * v0 / g
    @@ -50,7 +58,7 @@ def do_quiz() -> None:
             print("  NOT BAD.")
     
     
    -def ask_player(question: str, answer) -> int:
    +def ask_player(question, answer):
         print(question)
         player_answer = float(input())
     
    @@ -66,9 +74,12 @@ def ask_player(question: str, answer) -> int:
         return score
     
     
    -def main() -> None:
    -    print(" " * 33 + "KINEMA")
    -    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n")
    +def main():
    +    print_with_tab(33, "KINEMA")
    +    print_with_tab(15, "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
    +    print()
    +    print()
    +    print()
     
         while True:
             do_quiz()
    diff --git a/52_Kinema/ruby/kinema.rb b/52_Kinema/ruby/kinema.rb
    deleted file mode 100644
    index 27ed2aa26..000000000
    --- a/52_Kinema/ruby/kinema.rb
    +++ /dev/null
    @@ -1,45 +0,0 @@
    -#!/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
    diff --git a/52_Kinema/rust/Cargo.toml b/52_Kinema/rust/Cargo.toml
    deleted file mode 100644
    index 3a87396aa..000000000
    --- a/52_Kinema/rust/Cargo.toml
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -[package]
    -name = "rust"
    -version = "0.1.0"
    -edition = "2021"
    -
    -[dependencies]
    -rand = "0.9.0"
    \ No newline at end of file
    diff --git a/52_Kinema/rust/src/main.rs b/52_Kinema/rust/src/main.rs
    deleted file mode 100644
    index 9ce5c29ed..000000000
    --- a/52_Kinema/rust/src/main.rs
    +++ /dev/null
    @@ -1,114 +0,0 @@
    -/** KINEMA BY RICHARD PAV
    - * https://github.com/coding-horror/basic-computer-games/blob/main/52_Kinema/kinema.bas
    - * Direct conversion from BASIC to Rust by Pablo Marques (marquesrs).
    - * As a faithful translation, many of the code here are done in an unrecommended way by
    - *  today's standards.
    - * 
    - * ATTENTION: The original code has mathematical imprecision and uses simplifications
    - * instead of the real formulation, which could lead to incorrect results. I have solved
    - * this issue, but kept the old lines. To compile the original version, just uncomment the 
    - * code with the OLD label and comment the lines with the NEW label.
    - * example: gravity is now 9.81 instead of 10; Inputs and outputs are now float not integers...
    - * 
    - * FORMULATION
    - * A BALL IS THROWN UPWARDS AT 9,36 METERS PER SECOND.
    - * HOW HIGH WILL IT GO (IN METERS)? (9,36 ^2) / (2 * 9,81) = 4,465321101
    - * HOW LONG UNTIL IT RETURNS (IN SECONDS)? 2*(9,36 / 9,81) = 1,908256881
    - * WHAT WILL ITS VELOCITY BE AFTER 1,09 SECONDS? 9,36- 9,81 * 1,09 = −1,3329
    - * 
    - * 17/02/25
    -*/
    -
    -use std::io::Write;
    -use rand::Rng;
    -
    -fn subroutine(a: f64, q: &mut i32) {
    -    std::io::stdout().flush().unwrap();
    -    //500 INPUT G
    -    let mut input = String::new();
    -    let g;
    -    loop {
    -        std::io::stdin().read_line(&mut input).unwrap();
    -        match input.trim().parse::() {
    -            Ok(e) => { g = e; break; },
    -            Err(_) => { print!("\nINVALID. TRY AGAIN: "); continue; },
    -        };
    -    }
    -    //502 IF ABS((G-A)/A)<.15 THEN 510
    -    if f64::abs((g-a)/a) < 0.15 {
    -        //510 PRINT "CLOSE ENOUGH."        
    -        print!("CLOSE ENOUGH.");
    -        //511 Q=Q+1
    -        *q = *q + 1;
    -    }
    -    else {
    -        //504 PRINT "NOT EVEN CLOSE...."
    -        print!("NOT EVEN CLOSE...");
    -        //506 GOTO 512
    -    }
    -    //512 PRINT "CORRECT ANSWER IS ";A
    -    print!("\nCORRECT ANSWER IS {a:.2}\n");
    -    //520 PRINT
    -    //530 RETURN
    -}
    -
    -fn main() {
    -    let mut rng = rand::rng();
    -
    -    //10 PRINT TAB(33);"KINEMA"
    -    //20 PRINT TAB(15);"CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY"
    -    //30 PRINT: PRINT: PRINT
    -    //100 PRINT
    -    //105 PRINT
    -    print!("{}KINEMA\n{}CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n\n", 
    -        " ".repeat(33),
    -        " ".repeat(15)
    -    );
    -    loop {
    -        //106 Q=0
    -        let mut q = 0;
    -        //110 V=5+INT(35*RND(1))
    -        let v: f64 = 5.0 + 35.0 * rng.random_range(0.0..1.0);
    -        //111 PRINT "A BALL IS THROWN UPWARDS AT";V;"METERS PER SECOND."
    -        //112 PRINT
    -        print!("\nA BALL IS THROWN UPWARDS AT {v:.2} METERS PER SECOND.\n");
    -        //115 A=.05*V^2
    -        //let a = 0.05 * v.powf(2.0); // OLD
    -        let mut a = v.powf(2.0) / (2.0 * 9.81); // NEW
    -        //116 PRINT "HOW HIGH WILL IT GO (IN METERS)";
    -        print!("\nHOW HIGH WILL IT GO (IN METERS)? ");
    -        
    -        //117 GOSUB 500
    -        subroutine(a, &mut q);
    -        
    -        //120 A=V/5
    -        //a = v / 5.0; // OLD
    -        a = 2.0 * v / 9.81; // NEW
    -        //122 PRINT "HOW LONG UNTIL IT RETURNS (IN SECONDS)";
    -        print!("\nHOW LONG UNTIL IT RETURNS (IN SECONDS)? ");
    -        //124 GOSUB 500
    -        subroutine(a, &mut q);
    -
    -        //130 T=1+INT(2*V*RND(1))/10
    -        let t = 1.0 + (2.0 * v * rng.random_range(0.0..1.0) / 10.0);
    -        //132 A=V-10*T
    -        a = v + (-9.81 * t);
    -        //134 PRINT "WHAT WILL ITS VELOCITY BE AFTER";T;"SECONDS";
    -        print!("\nWHAT WILL ITS VELOCITY BE AFTER {t:.2} SECONDS? ");
    -
    -        //136 GOSUB 500
    -        subroutine(a, &mut q);
    -
    -        //140 PRINT
    -        //150 PRINT Q;"RIGHT OUT OF 3.";
    -        print!("\n{q} RIGHT OUT OF 3.\n");
    -        //160 IF Q<2 THEN 100
    -        if q < 2 {
    -            continue;
    -        }
    -        //170 PRINT "  NOT BAD."
    -        //print!("  NOT BAD.");
    -        //180 GOTO 100
    -    }
    -    //999 END
    -}
    diff --git a/52_Kinema/vbnet/Kinema.sln b/52_Kinema/vbnet/Kinema.sln
    deleted file mode 100644
    index a669536cb..000000000
    --- a/52_Kinema/vbnet/Kinema.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index b779698b1..000000000
    --- a/52_Kinema/vbnet/Kinema.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Kinema
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/53_King/README.md b/53_King/README.md
    index 83fb61c33..0687224d4 100644
    --- a/53_King/README.md
    +++ b/53_King/README.md
    @@ -1,29 +1,18 @@
     ## King
     
    -This is one of the most comprehensive, difficult, and interesting games. (If you've never played one of these games, start with HAMMURABI.)
    +This is one of the most comprehensive, difficult, and interesting games. (If you’ve never played one of these games, start with HAMMURABI.)
     
     In this game, you are Premier of Setats Detinu, a small communist island 30 by 70 miles long. Your job is to decide upon the budget of your country and distribute money to your country from the communal treasury.
     
    -The money system is Rollods; each person needs 100 Rallods per year to survive. Your country's income comes from farm produce and tourists visiting your magnificent forests, hunting, fishing, etc. Part of your land is farm land but it also has an excellent mineral content and may be sold to foreign industry for strip mining. Industry import and support their own workers. Crops cost between 10 and 15 Rallods per square mile to plant, cultivate, and harvest. Your goal is to complete an eight-year term of office without major mishap. A word of warning: it isn't easy!
    +The money system is Rollods; each person needs 100 Rallods per year to survive. Your country’s income comes from farm produce and tourists visiting your magnificent forests, hunting, fishing, etc. Part of your land is farm land but it also has an excellent mineral content and may be sold to foreign industry for strip mining. Industry import and support their own workers. Crops cost between 10 and 15 Rallods per square mile to plant, cultivate, and harvest. Your goal is to complete an eight-year term of office without major mishap. A word of warning: it isn’t easy!
     
     The author of this program is James A. Storer who wrote it while a student at Lexington High School.
     
     ⚠️ This game includes references to suicide or self-harm.
     
    ----
    -
    -As published in Basic Computer Games (1978):
    -- [Atari Archives](https://www.atariarchives.org/basicgames/showpage.php?page=96)
    -- [Annarchive](https://annarchive.com/files/Basic_Computer_Games_Microcomputer_Edition.pdf#page=111)
    -
    -Downloaded from Vintage Basic at
    -http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    +### Bugs
     
    -Implementers should be aware that this game contains bugs.
    -
    -### Bug 1
    +Implementers should be aware that this game contains at least one bug.
     
     On basic line 1450
     
    @@ -38,58 +27,16 @@ A quick fix for this bug in the original code would be
     
         1450 V3=ABS(INT(V1-V2))
         1451 A=INT(A+V3)
    -
    +    
     ...judging from the description of tourist income on basic line 1410
     
         1410 PRINT " YOU MADE";ABS(INT(V1-V2));"RALLODS FROM TOURIST TRADE."
     
    -### Bug 2
    -
    -On basic line 1330 following was the variable T1 never assigned:
    -
    -    1330 PRINT " YOU HARVESTED ";INT(J-U2);"SQ. MILES OF CROPS."
    -    1340 IF U2=0 THEN 1370
    -    1344 IF T1>=2 THEN 1370
    -    1350 PRINT "   (DUE TO ";
    -    1355 IF T1=0 THEN 1365
    -    1360 PRINT "INCREASED ";
    -
    -Likely it should be the difference of the current years crop loss compared to the
    -last years crop loss.
    -
    -### Bug 3
    -
    -On basic line 1997 it is:
    -
    -    1997 PRINT "   AND 10,000 SQ. MILES OF FOREST LAND."
    -
    -but it should be:
    -
    -    1997 PRINT "   AND 1,000 SQ. MILES OF FOREST LAND."
    -
    -### Bug 4
    -
    -On basic line 1310 we see this:
    -
    -    1310 IF C=0 THEN 1324
    -    1320 PRINT "OF ";INT(J);"SQ. MILES PLANTED,";
    -    1324 ...
    -
    -but it should probably be:
    -
    -    1310 IF J=0 THEN 1324
    -
    -### Bug 5
    -
    -On basic line 1390 the income from tourism is calculated:
    -
    -```
    -1390 A=INT(A+Q)
    -1400 V1=INT(((B-P1)*22)+(RND(1)*500))
    -1405 V2=INT((2000-D)*15)
    -1410 PRINT " YOU MADE";ABS(INT(V1-V2));"RALLODS FROM TOURIST TRADE."
    -```
    +---
     
    -It is very easily possible that `V2` is larger than `V1` e.g. if all of the land has been sold. In the original game this does not make a difference because of Bug 1 (see above).
    +As published in Basic Computer Games (1978):
    +- [Atari Archives](https://www.atariarchives.org/basicgames/showpage.php?page=96)
    +- [Annarchive](https://annarchive.com/files/Basic_Computer_Games_Microcomputer_Edition.pdf#page=111)
     
    -However, judging by how `V1` and `V2` are handled in the code, it looks like `V1` is the basic income from tourism and `V2` is a deduction for pollution. When `ABS(INT(V1-V2))` is used as earnings from tourism, the player actually _gets_ money for a large enough pollution. So a better solution would be to let `V1 - V2` cap out at 0, so once the pollution is large enough, there is no income from tourists anymore.
    +Downloaded from Vintage Basic at
    +http://www.vintage-basic.net/games.html
    diff --git a/53_King/csharp/Country.cs b/53_King/csharp/Country.cs
    deleted file mode 100644
    index 1a37bcd88..000000000
    --- a/53_King/csharp/Country.cs
    +++ /dev/null
    @@ -1,133 +0,0 @@
    -namespace King;
    -
    -internal class Country
    -{
    -    private const int InitialLand = 1000;
    -
    -    private readonly IReadWrite _io;
    -    private readonly IRandom _random;
    -    private float _rallods;
    -    private float _countrymen;
    -    private float _foreigners;
    -    private float _arableLand;
    -    private float _industryLand;
    -
    -    public Country(IReadWrite io, IRandom random)
    -        : this(
    -            io,
    -            random,
    -            (int)(60000 + random.NextFloat(1000) - random.NextFloat(1000)),
    -            (int)(500 + random.NextFloat(10) - random.NextFloat(10)),
    -            0,
    -            InitialLand)
    -    {
    -    }
    -
    -    public Country(IReadWrite io, IRandom random, float rallods, float countrymen, float foreigners, float land)
    -    {
    -        _io = io;
    -        _random = random;
    -        _rallods = rallods;
    -        _countrymen = countrymen;
    -        _foreigners = foreigners;
    -        _arableLand = land;
    -    }
    -
    -    public string GetStatus(int landValue, int plantingCost) 
    -        => Resource.Status(_rallods, _countrymen, _foreigners, _arableLand, landValue, plantingCost);
    -    
    -    public float Countrymen => _countrymen;
    -    public float Workers => _foreigners;
    -    public bool HasWorkers => _foreigners > 0;
    -    private float FarmLand => _arableLand;
    -    public bool HasRallods => _rallods > 0;
    -    public float Rallods => _rallods;
    -    public float IndustryLand => InitialLand - _arableLand;
    -    public int PreviousTourismIncome { get; private set; }
    -
    -    public bool SellLand(int landValue, out float landSold)
    -    {
    -        if (_io.TryReadValue(
    -                SellLandPrompt, 
    -                out landSold, 
    -                new ValidityTest(v => v <= FarmLand, () => SellLandError(FarmLand))))
    -        {
    -            _arableLand = (int)(_arableLand - landSold);
    -            _rallods = (int)(_rallods + landSold * landValue);
    -            return true;
    -        }
    -
    -        return false;
    -    }
    -
    -    public bool DistributeRallods(out float rallodsGiven)
    -    {
    -        if (_io.TryReadValue(
    -                GiveRallodsPrompt,
    -                out rallodsGiven, 
    -                new ValidityTest(v => v <= _rallods, () => GiveRallodsError(_rallods))))
    -        {
    -            _rallods = (int)(_rallods - rallodsGiven);
    -            return true;
    -        }
    -
    -        return false;
    -    }
    -
    -    public bool PlantLand(int plantingCost, out float landPlanted)
    -    {
    -        if (_io.TryReadValue(
    -                PlantLandPrompt, 
    -                out landPlanted, 
    -                new ValidityTest(v => v <= _countrymen * 2, PlantLandError1),
    -                new ValidityTest(v => v <= FarmLand, PlantLandError2(FarmLand)),
    -                new ValidityTest(v => v * plantingCost <= _rallods, PlantLandError3(_rallods))))
    -        {
    -            _rallods -= (int)(landPlanted * plantingCost);
    -            return true;
    -        }
    -
    -        return false;
    -    }
    -
    -    public bool ControlPollution(out float rallodsSpent)
    -    {
    -        if (_io.TryReadValue(
    -                PollutionPrompt,
    -                out rallodsSpent, 
    -                new ValidityTest(v => v <= _rallods, () => PollutionError(_rallods))))
    -        {
    -            _rallods = (int)(_rallods - rallodsSpent);
    -            return true;
    -        }
    -
    -        return false;
    -    }
    -
    -    public bool TrySpend(float amount, float landValue)
    -    {
    -        if (_rallods >= amount)
    -        {
    -            _rallods -= amount;
    -            return true;
    -        }
    -        
    -        _arableLand = (int)(_arableLand - (int)(amount - _rallods) / landValue);
    -        _rallods = 0;
    -        return false;
    -    }
    -
    -    public void RemoveTheDead(int deaths) => _countrymen = (int)(_countrymen - deaths);
    -
    -    public void Migration(int migration) => _countrymen = (int)(_countrymen + migration);
    -
    -    public void AddWorkers(int newWorkers) => _foreigners = (int)(_foreigners + newWorkers);
    -
    -    public void SellCrops(int income) => _rallods = (int)(_rallods + income);
    -
    -    public void EntertainTourists(int income)
    -    {
    -        PreviousTourismIncome = income;
    -        _rallods = (int)(_rallods + income);
    -    }
    -}
    diff --git a/53_King/csharp/Game.cs b/53_King/csharp/Game.cs
    deleted file mode 100644
    index 6a91010ce..000000000
    --- a/53_King/csharp/Game.cs
    +++ /dev/null
    @@ -1,47 +0,0 @@
    -namespace King;
    -
    -internal class Game
    -{
    -    const int TermOfOffice = 8;
    -
    -    private readonly IReadWrite _io;
    -    private readonly IRandom _random;
    -
    -    public Game(IReadWrite io, IRandom random)
    -    {
    -        _io = io;
    -        _random = random;
    -    }
    -
    -    public void Play()
    -    {
    -        _io.Write(Title);
    -
    -        var reign = SetUpReign();
    -        if (reign != null)
    -        {
    -            while (reign.PlayYear());
    -        }
    -
    -        _io.WriteLine();
    -        _io.WriteLine();
    -    }
    -
    -    private Reign? SetUpReign()
    -    {
    -        var response = _io.ReadString(InstructionsPrompt).ToUpper();
    -
    -        if (response.Equals("Again", StringComparison.InvariantCultureIgnoreCase))
    -        {
    -            return _io.TryReadGameData(_random, out var reign) ? reign : null;
    -        }
    -        
    -        if (!response.StartsWith("N", StringComparison.InvariantCultureIgnoreCase))
    -        {
    -            _io.Write(InstructionsText(TermOfOffice));
    -        }
    -
    -        _io.WriteLine();
    -        return new Reign(_io, _random);
    -    }
    -}
    diff --git a/53_King/csharp/IOExtensions.cs b/53_King/csharp/IOExtensions.cs
    deleted file mode 100644
    index dbb3079ad..000000000
    --- a/53_King/csharp/IOExtensions.cs
    +++ /dev/null
    @@ -1,61 +0,0 @@
    -using System.Diagnostics.CodeAnalysis;
    -using static King.Resources.Resource;
    -
    -namespace King;
    -
    -internal static class IOExtensions
    -{
    -    internal static bool TryReadGameData(this IReadWrite io, IRandom random, [NotNullWhen(true)] out Reign? reign)
    -    {
    -        if (io.TryReadValue(SavedYearsPrompt, v => v < Reign.MaxTerm, SavedYearsError(Reign.MaxTerm), out var years) &&
    -            io.TryReadValue(SavedTreasuryPrompt, out var rallods) &&
    -            io.TryReadValue(SavedCountrymenPrompt, out var countrymen) &&
    -            io.TryReadValue(SavedWorkersPrompt, out var workers) &&
    -            io.TryReadValue(SavedLandPrompt, v => v is > 1000 and <= 2000, SavedLandError, out var land))
    -        {
    -            reign = new Reign(io, random, new Country(io, random, rallods, countrymen, workers, land), years + 1);
    -            return true;
    -        }
    -
    -        reign = default;
    -        return false;
    -    }
    -
    -    internal static bool TryReadValue(this IReadWrite io, string prompt, out float value, params ValidityTest[] tests)
    -    {
    -        while (true)
    -        {
    -            var response = value = io.ReadNumber(prompt);
    -            if (response == 0) { return false; }
    -            if (tests.All(test => test.IsValid(response, io))) { return true; }
    -        } 
    -    }
    -
    -    internal static bool TryReadValue(this IReadWrite io, string prompt, out float value)
    -        => io.TryReadValue(prompt, _ => true, "", out value);
    -    
    -    internal static bool TryReadValue(
    -        this IReadWrite io,
    -        string prompt,
    -        Predicate isValid,
    -        string error,
    -        out float value)
    -        => io.TryReadValue(prompt, isValid, () => error, out value);
    -
    -    internal static bool TryReadValue(
    -        this IReadWrite io,
    -        string prompt,
    -        Predicate isValid,
    -        Func getError,
    -        out float value)
    -    {
    -        while (true)
    -        {
    -            value = io.ReadNumber(prompt);
    -            if (value < 0) { return false; }
    -            if (isValid(value)) { return true; }
    -            
    -            io.Write(getError());
    -        }
    -    }
    -}
    diff --git a/53_King/csharp/King.csproj b/53_King/csharp/King.csproj
    deleted file mode 100644
    index 3870320c9..000000000
    --- a/53_King/csharp/King.csproj
    +++ /dev/null
    @@ -1,17 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    -  
    -    
    -  
    -
    -  
    -    
    -  
    -
    diff --git a/53_King/csharp/King.sln b/53_King/csharp/King.sln
    deleted file mode 100644
    index 94eb4d7de..000000000
    --- a/53_King/csharp/King.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/csharp/Program.cs b/53_King/csharp/Program.cs
    deleted file mode 100644
    index 5aae4ccbc..000000000
    --- a/53_King/csharp/Program.cs
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -global using Games.Common.IO;
    -global using Games.Common.Randomness;
    -global using King.Resources;
    -global using static King.Resources.Resource;
    -using King;
    -
    -new Game(new ConsoleIO(), new RandomNumberGenerator()).Play();
    diff --git a/53_King/csharp/Reign.cs b/53_King/csharp/Reign.cs
    deleted file mode 100644
    index 7a96a30fa..000000000
    --- a/53_King/csharp/Reign.cs
    +++ /dev/null
    @@ -1,45 +0,0 @@
    -namespace King;
    -
    -internal class Reign
    -{
    -    public const int MaxTerm = 8;
    -
    -    private readonly IReadWrite _io;
    -    private readonly IRandom _random;
    -    private readonly Country _country;
    -    private float _yearNumber;
    -
    -    public Reign(IReadWrite io, IRandom random)
    -        : this(io, random, new Country(io, random), 1)
    -    {
    -    }
    -
    -    public Reign(IReadWrite io, IRandom random, Country country, float year)
    -    {
    -        _io = io;
    -        _random = random;
    -        _country = country;
    -        _yearNumber = year;
    -    }
    -
    -    public bool PlayYear()
    -    {
    -        var year = new Year(_country, _random, _io);
    -
    -        _io.Write(year.Status);
    -
    -        var result = year.GetPlayerActions() ?? year.EvaluateResults() ?? IsAtEndOfTerm();
    -        if (result.IsGameOver)
    -        {
    -            _io.WriteLine(result.Message);
    -            return false;
    -        }
    -
    -        return true;
    -    }
    -
    -    private Result IsAtEndOfTerm() 
    -        => _yearNumber == MaxTerm 
    -            ? Result.GameOver(EndCongratulations(MaxTerm)) 
    -            : Result.Continue;
    -}
    diff --git a/53_King/csharp/Resources/DeathsPollution.txt b/53_King/csharp/Resources/DeathsPollution.txt
    deleted file mode 100644
    index bf28d9a76..000000000
    --- a/53_King/csharp/Resources/DeathsPollution.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    - {0} countrymen died of carbon-monoxide and dust inhalation
    \ No newline at end of file
    diff --git a/53_King/csharp/Resources/DeathsStarvation.txt b/53_King/csharp/Resources/DeathsStarvation.txt
    deleted file mode 100644
    index af275cf40..000000000
    --- a/53_King/csharp/Resources/DeathsStarvation.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    - {0} countrymen died of starvation
    \ No newline at end of file
    diff --git a/53_King/csharp/Resources/Emigration.txt b/53_King/csharp/Resources/Emigration.txt
    deleted file mode 100644
    index 01f67094e..000000000
    --- a/53_King/csharp/Resources/Emigration.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    - {0} countrymen left the island.
    \ No newline at end of file
    diff --git a/53_King/csharp/Resources/EndAlso.txt b/53_King/csharp/Resources/EndAlso.txt
    deleted file mode 100644
    index 084b9a823..000000000
    --- a/53_King/csharp/Resources/EndAlso.txt
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -also had your left eye gouged out!
    -;have also gained a very bad reputation.
    -;have also been declared national fink.
    diff --git a/53_King/csharp/Resources/EndCongratulations.txt b/53_King/csharp/Resources/EndCongratulations.txt
    deleted file mode 100644
    index ef1ff2038..000000000
    --- a/53_King/csharp/Resources/EndCongratulations.txt
    +++ /dev/null
    @@ -1,10 +0,0 @@
    -
    -
    -Congratulations!!!!!!!!!!!!!!!!!!
    -You have successfully completed your {0} year term
    -of office. You were, of course, extremely lucky, but
    -nevertheless, it's quite an achievement. Goodbye and good
    -luck - you'll probably need it if you're the type that
    -plays this game.
    -
    -
    diff --git a/53_King/csharp/Resources/EndConsequences.txt b/53_King/csharp/Resources/EndConsequences.txt
    deleted file mode 100644
    index 61ebfd253..000000000
    --- a/53_King/csharp/Resources/EndConsequences.txt
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -You have been thrown out of office and are now
    -residing in prison.;
    -You have been assassinated.
    diff --git a/53_King/csharp/Resources/EndForeignWorkers.txt b/53_King/csharp/Resources/EndForeignWorkers.txt
    deleted file mode 100644
    index 76c04c3d0..000000000
    --- a/53_King/csharp/Resources/EndForeignWorkers.txt
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -
    -
    -The number of foreign workers has exceeded the number
    -of countrymen. As a minority, they have revolted and
    -taken over the country.
    -{0}
    -
    diff --git a/53_King/csharp/Resources/EndManyDead.txt b/53_King/csharp/Resources/EndManyDead.txt
    deleted file mode 100644
    index 70cd95f05..000000000
    --- a/53_King/csharp/Resources/EndManyDead.txt
    +++ /dev/null
    @@ -1,5 +0,0 @@
    -{0} countrymen died in one year!!!!!
    -due to this extreme mismanagement, you have not only
    -been impeached and thrown out of office, but you
    -{1}
    -
    diff --git a/53_King/csharp/Resources/EndMoneyLeftOver.txt b/53_King/csharp/Resources/EndMoneyLeftOver.txt
    deleted file mode 100644
    index e194a9fd7..000000000
    --- a/53_King/csharp/Resources/EndMoneyLeftOver.txt
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -
    -Money was left over in the treasury which you did
    -not spend. As a result, some of your countrymen died
    -of starvation. The public is enraged and you have
    -been forced to resign.
    -
    -
    diff --git a/53_King/csharp/Resources/EndOneThirdDead.txt b/53_King/csharp/Resources/EndOneThirdDead.txt
    deleted file mode 100644
    index e1761dfe4..000000000
    --- a/53_King/csharp/Resources/EndOneThirdDead.txt
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -
    -
    -Over one third of the population has died since you
    -were elected to office. The people (remaining)
    -hate your guts.
    -{0}
    -
    diff --git a/53_King/csharp/Resources/FuneralExpenses.txt b/53_King/csharp/Resources/FuneralExpenses.txt
    deleted file mode 100644
    index 3aff58ebe..000000000
    --- a/53_King/csharp/Resources/FuneralExpenses.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -   You were forced to spend {0} rallods on funeral expenses
    \ No newline at end of file
    diff --git a/53_King/csharp/Resources/GiveRallodsError.txt b/53_King/csharp/Resources/GiveRallodsError.txt
    deleted file mode 100644
    index df0d7cc00..000000000
    --- a/53_King/csharp/Resources/GiveRallodsError.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -   Think again. You've only got {0}  rallods in the treasury.
    diff --git a/53_King/csharp/Resources/GiveRallodsPrompt.txt b/53_King/csharp/Resources/GiveRallodsPrompt.txt
    deleted file mode 100644
    index e8bd345b8..000000000
    --- a/53_King/csharp/Resources/GiveRallodsPrompt.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -How many rallods will you distribute among your countrymen
    \ No newline at end of file
    diff --git a/53_King/csharp/Resources/Goodbye.txt b/53_King/csharp/Resources/Goodbye.txt
    deleted file mode 100644
    index 67543c040..000000000
    --- a/53_King/csharp/Resources/Goodbye.txt
    +++ /dev/null
    @@ -1,4 +0,0 @@
    -Goodbye.
    -(If you wish to continue this game at a later date, answer
    -'again' when asked if you want instructions at the start
    -of the game).
    diff --git a/53_King/csharp/Resources/Harvest.txt b/53_King/csharp/Resources/Harvest.txt
    deleted file mode 100644
    index 287e0c427..000000000
    --- a/53_King/csharp/Resources/Harvest.txt
    +++ /dev/null
    @@ -1,2 +0,0 @@
    - you harvested  {0} sq. miles of crops.
    -{1}making {2} rallods.
    diff --git a/53_King/csharp/Resources/HarvestReason.txt b/53_King/csharp/Resources/HarvestReason.txt
    deleted file mode 100644
    index 82faccb53..000000000
    --- a/53_King/csharp/Resources/HarvestReason.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -   (Due to increased air and water pollution from foreign industry.)
    diff --git a/53_King/csharp/Resources/Immigration.txt b/53_King/csharp/Resources/Immigration.txt
    deleted file mode 100644
    index 30d8b6b37..000000000
    --- a/53_King/csharp/Resources/Immigration.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    - {0} countrymen came to the island.
    \ No newline at end of file
    diff --git a/53_King/csharp/Resources/InstructionsPrompt.txt b/53_King/csharp/Resources/InstructionsPrompt.txt
    deleted file mode 100644
    index 0d311b605..000000000
    --- a/53_King/csharp/Resources/InstructionsPrompt.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Do you want instructions
    \ No newline at end of file
    diff --git a/53_King/csharp/Resources/InstructionsText.txt b/53_King/csharp/Resources/InstructionsText.txt
    deleted file mode 100644
    index c576123b3..000000000
    --- a/53_King/csharp/Resources/InstructionsText.txt
    +++ /dev/null
    @@ -1,17 +0,0 @@
    -
    -
    -
    -Congratulations! You've just been elected Premier of Setats
    -Detinu, a small communist island 30 by 70 miles long. Your
    -job is to decide upon the country's budget and distribute
    -money to your countrymen from the communal treasury.
    -The money system is rallods, and each person needs 100
    -rallods per year to survive. Your country's income comes
    -from farm produce and tourists visiting your magnificent
    -forests, hunting, fishing, etc. Half your land if farm land
    -which also has an excellent mineral content and may be sold
    -to foreign industry (strip mining) who import and support
    -their own workers. Crops cost between 10 and 15 rallods per
    -square mile to plant.
    -Your goal is to complete your {0} year term of office.
    -Good luck!
    diff --git a/53_King/csharp/Resources/InsufficientReserves.txt b/53_King/csharp/Resources/InsufficientReserves.txt
    deleted file mode 100644
    index e69de29bb..000000000
    diff --git a/53_King/csharp/Resources/LandPlanted.txt b/53_King/csharp/Resources/LandPlanted.txt
    deleted file mode 100644
    index e52529aac..000000000
    --- a/53_King/csharp/Resources/LandPlanted.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Of  {0} sq. miles planted,
    \ No newline at end of file
    diff --git a/53_King/csharp/Resources/PlantLandError1.txt b/53_King/csharp/Resources/PlantLandError1.txt
    deleted file mode 100644
    index ef959f9fb..000000000
    --- a/53_King/csharp/Resources/PlantLandError1.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -   Sorry, but each countryman can only plant 2 sq. miles.
    \ No newline at end of file
    diff --git a/53_King/csharp/Resources/PlantLandError2.txt b/53_King/csharp/Resources/PlantLandError2.txt
    deleted file mode 100644
    index e5844aa1c..000000000
    --- a/53_King/csharp/Resources/PlantLandError2.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -   Sorry, but you've only {0} sq. miles of farm land.
    \ No newline at end of file
    diff --git a/53_King/csharp/Resources/PlantLandError3.txt b/53_King/csharp/Resources/PlantLandError3.txt
    deleted file mode 100644
    index 38264442e..000000000
    --- a/53_King/csharp/Resources/PlantLandError3.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -   Think again, You've only {0}  rallods left in the treasury.
    diff --git a/53_King/csharp/Resources/PlantLandPrompt.txt b/53_King/csharp/Resources/PlantLandPrompt.txt
    deleted file mode 100644
    index f2fe448ef..000000000
    --- a/53_King/csharp/Resources/PlantLandPrompt.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -How many square miles do you wish to plant
    \ No newline at end of file
    diff --git a/53_King/csharp/Resources/PollutionError.txt b/53_King/csharp/Resources/PollutionError.txt
    deleted file mode 100644
    index f99644e3b..000000000
    --- a/53_King/csharp/Resources/PollutionError.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -   Think again. You only have  {0}  rallods remaining.
    diff --git a/53_King/csharp/Resources/PollutionPrompt.txt b/53_King/csharp/Resources/PollutionPrompt.txt
    deleted file mode 100644
    index 252fb3339..000000000
    --- a/53_King/csharp/Resources/PollutionPrompt.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -How many rallods do you wish to spend on pollution control
    \ No newline at end of file
    diff --git a/53_King/csharp/Resources/Resource.cs b/53_King/csharp/Resources/Resource.cs
    deleted file mode 100644
    index 5ea09e1ce..000000000
    --- a/53_King/csharp/Resources/Resource.cs
    +++ /dev/null
    @@ -1,112 +0,0 @@
    -using System.Reflection;
    -using System.Runtime.CompilerServices;
    -
    -namespace King.Resources;
    -
    -internal static class Resource
    -{
    -    private static bool _sellLandErrorShown;
    -
    -    public static Stream Title => GetStream();
    -    
    -    public static string InstructionsPrompt => GetString();
    -    public static string InstructionsText(int years) => string.Format(GetString(), years);
    -
    -    public static string Status(
    -        float rallods,
    -        float countrymen,
    -        float workers,
    -        float land,
    -        float landValue,
    -        float plantingCost)
    -        => string.Format(
    -            workers == 0 ? StatusWithWorkers : StatusSansWorkers,
    -            rallods,
    -            (int)countrymen,
    -            (int)workers,
    -            (int)land,
    -            landValue,
    -            plantingCost);
    -
    -    private static string StatusWithWorkers => GetString();
    -    private static string StatusSansWorkers => GetString();
    -
    -    public static string SellLandPrompt => GetString();
    -    public static string SellLandError(float farmLand)
    -    {
    -        var error = string.Format(GetString(), farmLand, _sellLandErrorShown ? "" : SellLandErrorReason);
    -        _sellLandErrorShown = true;
    -        return error;
    -    }
    -    private static string SellLandErrorReason => GetString();
    -
    -    public static string GiveRallodsPrompt => GetString();
    -    public static string GiveRallodsError(float rallods) => string.Format(GetString(), rallods);
    -
    -    public static string PlantLandPrompt => GetString();
    -    public static string PlantLandError1 => GetString();
    -    public static string PlantLandError2(float farmLand) => string.Format(GetString(), farmLand);
    -    public static string PlantLandError3(float rallods) => string.Format(GetString(), rallods);
    -
    -    public static string PollutionPrompt => GetString();
    -    public static string PollutionError(float rallods) => string.Format(GetString(), rallods);
    -
    -    public static string DeathsStarvation(float deaths) => string.Format(GetString(), (int)deaths);
    -    public static string DeathsPollution(int deaths) => string.Format(GetString(), deaths);
    -    public static string FuneralExpenses(int expenses) => string.Format(GetString(), expenses);
    -    public static string InsufficientReserves => GetString();
    -
    -    public static string WorkerMigration(int newWorkers) => string.Format(GetString(), newWorkers);
    -    public static string Migration(int migration) 
    -        => string.Format(migration < 0 ? Emigration : Immigration, Math.Abs(migration));
    -    public static string Emigration => GetString();
    -    public static string Immigration => GetString();
    -
    -    public static string LandPlanted(float landPlanted) 
    -        => landPlanted > 0 ? string.Format(GetString(), (int)landPlanted) : "";
    -    public static string Harvest(int yield, int income, bool hasIndustry) 
    -        => string.Format(GetString(), yield, HarvestReason(hasIndustry), income);
    -    private static string HarvestReason(bool hasIndustry) => hasIndustry ? GetString() : "";
    -
    -    public static string TourismEarnings(int income) => string.Format(GetString(), income);
    -    public static string TourismDecrease(IRandom random) => string.Format(GetString(), TourismReason(random));
    -    private static string TourismReason(IRandom random) => GetStrings()[random.Next(5)];
    -
    -    private static string EndAlso(IRandom random)
    -        => random.Next(10) switch
    -        {
    -            <= 3 => GetStrings()[0],
    -            <= 6 => GetStrings()[1],
    -            _ => GetStrings()[2]
    -        };
    -
    -    public static string EndCongratulations(int termLength) => string.Format(GetString(), termLength);
    -    private static string EndConsequences(IRandom random) => GetStrings()[random.Next(2)];
    -    public static string EndForeignWorkers(IRandom random) => string.Format(GetString(), EndConsequences(random));
    -    public static string EndManyDead(int deaths, IRandom random) => string.Format(GetString(), deaths, EndAlso(random));
    -    public static string EndMoneyLeftOver() => GetString();
    -    public static string EndOneThirdDead(IRandom random) => string.Format(GetString(), EndConsequences(random));
    -    
    -    public static string SavedYearsPrompt => GetString();
    -    public static string SavedYearsError(int years) => string.Format(GetString(), years);
    -    public static string SavedTreasuryPrompt => GetString();
    -    public static string SavedCountrymenPrompt => GetString();
    -    public static string SavedWorkersPrompt => GetString();
    -    public static string SavedLandPrompt => GetString();
    -    public static string SavedLandError => GetString();
    -
    -    public static string Goodbye => GetString();
    -
    -    private static string[] GetStrings([CallerMemberName] string? name = null) => GetString(name).Split(';');
    -
    -    private static string GetString([CallerMemberName] string? name = null)
    -    {
    -        using var stream = GetStream(name);
    -        using var reader = new StreamReader(stream);
    -        return reader.ReadToEnd();
    -    }
    -
    -    private static Stream GetStream([CallerMemberName] string? name = null) =>
    -        Assembly.GetExecutingAssembly().GetManifestResourceStream($"{typeof(Resource).Namespace}.{name}.txt")
    -            ?? throw new Exception($"Could not find embedded resource stream '{name}'.");
    -}
    \ No newline at end of file
    diff --git a/53_King/csharp/Resources/SavedCountrymenPrompt.txt b/53_King/csharp/Resources/SavedCountrymenPrompt.txt
    deleted file mode 100644
    index 120718d29..000000000
    --- a/53_King/csharp/Resources/SavedCountrymenPrompt.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -How many countrymen
    \ No newline at end of file
    diff --git a/53_King/csharp/Resources/SavedLandError.txt b/53_King/csharp/Resources/SavedLandError.txt
    deleted file mode 100644
    index 9ac66dad2..000000000
    --- a/53_King/csharp/Resources/SavedLandError.txt
    +++ /dev/null
    @@ -1,2 +0,0 @@
    -   Come on, you started with 1000 sq. miles of farm land
    -   and 10,000 sq. miles of forest land
    diff --git a/53_King/csharp/Resources/SavedLandPrompt.txt b/53_King/csharp/Resources/SavedLandPrompt.txt
    deleted file mode 100644
    index e8afdf723..000000000
    --- a/53_King/csharp/Resources/SavedLandPrompt.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -How many square miles of land
    \ No newline at end of file
    diff --git a/53_King/csharp/Resources/SavedTreasuryPrompt.txt b/53_King/csharp/Resources/SavedTreasuryPrompt.txt
    deleted file mode 100644
    index f4a50f58f..000000000
    --- a/53_King/csharp/Resources/SavedTreasuryPrompt.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -How much did you have in the treasury
    \ No newline at end of file
    diff --git a/53_King/csharp/Resources/SavedWorkersPrompt.txt b/53_King/csharp/Resources/SavedWorkersPrompt.txt
    deleted file mode 100644
    index b88a9c107..000000000
    --- a/53_King/csharp/Resources/SavedWorkersPrompt.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -How many workers
    \ No newline at end of file
    diff --git a/53_King/csharp/Resources/SavedYearsError.txt b/53_King/csharp/Resources/SavedYearsError.txt
    deleted file mode 100644
    index 1c8c3c992..000000000
    --- a/53_King/csharp/Resources/SavedYearsError.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -   Come on, your term in office is only {0} years.
    diff --git a/53_King/csharp/Resources/SavedYearsPrompt.txt b/53_King/csharp/Resources/SavedYearsPrompt.txt
    deleted file mode 100644
    index afbda229e..000000000
    --- a/53_King/csharp/Resources/SavedYearsPrompt.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -How many years had you been in office when interrupted
    \ No newline at end of file
    diff --git a/53_King/csharp/Resources/SellLandError.txt b/53_King/csharp/Resources/SellLandError.txt
    deleted file mode 100644
    index 83e0266c2..000000000
    --- a/53_King/csharp/Resources/SellLandError.txt
    +++ /dev/null
    @@ -1,2 +0,0 @@
    -*** Think again. You only have {0} square miles of farm land.
    -{1}
    \ No newline at end of file
    diff --git a/53_King/csharp/Resources/SellLandErrorReason.txt b/53_King/csharp/Resources/SellLandErrorReason.txt
    deleted file mode 100644
    index 836352bbf..000000000
    --- a/53_King/csharp/Resources/SellLandErrorReason.txt
    +++ /dev/null
    @@ -1,4 +0,0 @@
    -
    -(Foreign industry will only buy farm land because
    -forest land is uneconomical to strip mine due to trees,
    -thicker top soil, etc.)
    diff --git a/53_King/csharp/Resources/SellLandPrompt.txt b/53_King/csharp/Resources/SellLandPrompt.txt
    deleted file mode 100644
    index 8d01c2c23..000000000
    --- a/53_King/csharp/Resources/SellLandPrompt.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -How many square miles do you wish to sell to industry
    \ No newline at end of file
    diff --git a/53_King/csharp/Resources/StatusSansWorkers.txt b/53_King/csharp/Resources/StatusSansWorkers.txt
    deleted file mode 100644
    index 7efb84e76..000000000
    --- a/53_King/csharp/Resources/StatusSansWorkers.txt
    +++ /dev/null
    @@ -1,6 +0,0 @@
    -
    -You now have  {0}  rallods in the treasury.
    - {1} countrymen, and {3} sq. miles of land.
    -This year industry will buy land for {4} rallods per square mile.
    -Land currently costs {5} rallods per square mile to plant.
    -
    diff --git a/53_King/csharp/Resources/StatusWithWorkers.txt b/53_King/csharp/Resources/StatusWithWorkers.txt
    deleted file mode 100644
    index e7bc5c4a8..000000000
    --- a/53_King/csharp/Resources/StatusWithWorkers.txt
    +++ /dev/null
    @@ -1,6 +0,0 @@
    -
    -You now have  {0}  rallods in the treasury.
    - {1} countrymen,  {2} foreign workers and {3} sq. miles of land.
    -This year industry will buy land for {4} rallods per square mile.
    -Land currently costs {5} rallods per square mile to plant.
    -
    diff --git a/53_King/csharp/Resources/Title.txt b/53_King/csharp/Resources/Title.txt
    deleted file mode 100644
    index f9f7854da..000000000
    --- a/53_King/csharp/Resources/Title.txt
    +++ /dev/null
    @@ -1,5 +0,0 @@
    -                                  King
    -               Creative Computing  Morristown, New Jersey
    -
    -
    -
    diff --git a/53_King/csharp/Resources/TourismDecrease.txt b/53_King/csharp/Resources/TourismDecrease.txt
    deleted file mode 100644
    index dcb45fc70..000000000
    --- a/53_King/csharp/Resources/TourismDecrease.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -   Decrease because {0}
    \ No newline at end of file
    diff --git a/53_King/csharp/Resources/TourismEarnings.txt b/53_King/csharp/Resources/TourismEarnings.txt
    deleted file mode 100644
    index db9251dd5..000000000
    --- a/53_King/csharp/Resources/TourismEarnings.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    - You made {0} rallods from tourist trade.
    \ No newline at end of file
    diff --git a/53_King/csharp/Resources/TourismReason.txt b/53_King/csharp/Resources/TourismReason.txt
    deleted file mode 100644
    index b3535c3dc..000000000
    --- a/53_King/csharp/Resources/TourismReason.txt
    +++ /dev/null
    @@ -1,5 +0,0 @@
    -fish population has dwindled due to water pollution.
    -;air pollution is killing game bird population.
    -;mineral baths are being ruined by water pollution.
    -;unpleasant smog is discouraging sun bathers.
    -;hotels are looking shabby due to smog grit.
    diff --git a/53_King/csharp/Resources/WorkerMigration.txt b/53_King/csharp/Resources/WorkerMigration.txt
    deleted file mode 100644
    index d2f3b378e..000000000
    --- a/53_King/csharp/Resources/WorkerMigration.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    - {0} workers came to the country and
    \ No newline at end of file
    diff --git a/53_King/csharp/Result.cs b/53_King/csharp/Result.cs
    deleted file mode 100644
    index 185f4617a..000000000
    --- a/53_King/csharp/Result.cs
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -namespace King;
    -
    -internal record struct Result (bool IsGameOver, string Message)
    -{
    -    internal static Result GameOver(string message) => new(true, message);
    -    internal static Result Continue => new(false, "");
    -}
    diff --git a/53_King/csharp/ValidityTest.cs b/53_King/csharp/ValidityTest.cs
    deleted file mode 100644
    index f1aeb5ec6..000000000
    --- a/53_King/csharp/ValidityTest.cs
    +++ /dev/null
    @@ -1,26 +0,0 @@
    -namespace King;
    -
    -internal class ValidityTest
    -{
    -    private readonly Predicate _isValid;
    -    private readonly Func _getError;
    -
    -    public ValidityTest(Predicate isValid, string error)
    -        : this(isValid, () => error)
    -    {
    -    }
    -
    -    public ValidityTest(Predicate isValid, Func getError)
    -    {
    -        _isValid = isValid;
    -        _getError = getError;
    -    }
    -
    -    public bool IsValid(float value, IReadWrite io)
    -    {
    -        if (_isValid(value)) { return true; }
    -        
    -        io.Write(_getError());
    -        return false;
    -    }
    -}
    \ No newline at end of file
    diff --git a/53_King/csharp/Year.cs b/53_King/csharp/Year.cs
    deleted file mode 100644
    index 8e6bb0b41..000000000
    --- a/53_King/csharp/Year.cs
    +++ /dev/null
    @@ -1,154 +0,0 @@
    -using System.Text;
    -
    -namespace King;
    -
    -internal class Year
    -{
    -    private readonly Country _country;
    -    private readonly IRandom _random;
    -    private readonly IReadWrite _io;
    -    private readonly int _plantingCost;
    -    private readonly int _landValue;
    -
    -    private float _landSold;
    -    private float _rallodsDistributed;
    -    private float _landPlanted;
    -    private float _pollutionControlCost;
    -
    -    private float _citizenSupport;
    -    private int _deaths;
    -    private float _starvationDeaths;
    -    private int _pollutionDeaths;
    -    private int _migration;
    -
    -    public Year(Country country, IRandom random, IReadWrite io)
    -    {
    -        _country = country;
    -        _random = random;
    -        _io = io;
    -        
    -        _plantingCost = random.Next(10, 15);
    -        _landValue = random.Next(95, 105);
    -    }
    -
    -    public string Status => _country.GetStatus(_landValue, _plantingCost);
    -
    -    public Result? GetPlayerActions()
    -    {
    -        var playerSoldLand = _country.SellLand(_landValue, out _landSold);
    -        var playerDistributedRallods = _country.DistributeRallods(out _rallodsDistributed);
    -        var playerPlantedLand = _country.HasRallods && _country.PlantLand(_plantingCost, out _landPlanted);
    -        var playerControlledPollution = _country.HasRallods && _country.ControlPollution(out _pollutionControlCost);
    -
    -        return playerSoldLand || playerDistributedRallods || playerPlantedLand || playerControlledPollution
    -            ? null
    -            : Result.GameOver(Goodbye);
    -    }
    -
    -    public Result? EvaluateResults()
    -    {
    -        var rallodsUnspent = _country.Rallods;
    -
    -        _io.WriteLine();
    -        _io.WriteLine();
    -
    -        return EvaluateDeaths() 
    -            ?? EvaluateMigration() 
    -            ?? EvaluateAgriculture()
    -            ?? EvaluateTourism()
    -            ?? DetermineResult(rallodsUnspent);
    -    }
    -
    -    public Result? EvaluateDeaths()
    -    {
    -        var supportedCountrymen = _rallodsDistributed / 100;
    -        _citizenSupport = supportedCountrymen - _country.Countrymen;
    -        _starvationDeaths = -_citizenSupport;
    -        if (_starvationDeaths > 0)
    -        {
    -            if (supportedCountrymen < 50) { return Result.GameOver(EndOneThirdDead(_random)); }
    -            _io.WriteLine(DeathsStarvation(_starvationDeaths));
    -        }
    -
    -        var pollutionControl = _pollutionControlCost >= 25 ? _pollutionControlCost / 25 : 1;
    -        _pollutionDeaths = (int)(_random.Next((int)_country.IndustryLand) / pollutionControl);
    -        if (_pollutionDeaths > 0)
    -        {
    -            _io.WriteLine(DeathsPollution(_pollutionDeaths));
    -        }
    -
    -        _deaths = (int)(_starvationDeaths + _pollutionDeaths);
    -        if (_deaths > 0)
    -        {
    -            var funeralCosts = _deaths * 9;
    -            _io.WriteLine(FuneralExpenses(funeralCosts));
    -
    -            if (!_country.TrySpend(funeralCosts, _landValue))
    -            {
    -                _io.WriteLine(InsufficientReserves);
    -            }
    -
    -            _country.RemoveTheDead(_deaths);
    -        }
    -
    -        return null;
    -    }
    -
    -    private Result? EvaluateMigration()
    -    {
    -        if (_landSold > 0)
    -        {
    -            var newWorkers = (int)(_landSold + _random.NextFloat(10) - _random.NextFloat(20));
    -            if (!_country.HasWorkers) { newWorkers += 20; }
    -            _io.Write(WorkerMigration(newWorkers));
    -            _country.AddWorkers(newWorkers);
    -        }
    -
    -        _migration = 
    -            (int)(_citizenSupport / 10 + _pollutionControlCost / 25 - _country.IndustryLand / 50 - _pollutionDeaths / 2);
    -        _io.WriteLine(Migration(_migration));
    -        _country.Migration(_migration);
    -
    -        return null;
    -    }
    -
    -    private Result? EvaluateAgriculture()
    -    {
    -        var ruinedCrops = (int)Math.Min(_country.IndustryLand * (_random.NextFloat() + 1.5f) / 2, _landPlanted);
    -        var yield = (int)(_landPlanted - ruinedCrops);
    -        var income = (int)(yield * _landValue / 2f);
    -
    -        _io.Write(LandPlanted(_landPlanted));
    -        _io.Write(Harvest(yield, income, _country.IndustryLand > 0));
    -
    -        _country.SellCrops(income);
    -
    -        return null;
    -    }
    -
    -    private Result? EvaluateTourism()
    -    {
    -        var reputationValue = (int)((_country.Countrymen - _migration) * 22 + _random.NextFloat(500));
    -        var industryAdjustment = (int)(_country.IndustryLand * 15);
    -        var tourismIncome = Math.Abs(reputationValue - industryAdjustment);
    -
    -        _io.WriteLine(TourismEarnings(tourismIncome));
    -        if (industryAdjustment > 0 && tourismIncome < _country.PreviousTourismIncome)
    -        {
    -            _io.Write(TourismDecrease(_random));
    -        }
    -
    -        _country.EntertainTourists(tourismIncome);
    -
    -        return null;
    -    }
    -
    -    private Result? DetermineResult(float rallodsUnspent)
    -    {
    -        if (_deaths > 200) { return Result.GameOver(EndManyDead(_deaths, _random)); }
    -        if (_country.Countrymen < 343) { return Result.GameOver(EndOneThirdDead(_random)); }
    -        if (rallodsUnspent / 100 > 5 && _starvationDeaths >= 2) { return Result.GameOver(EndMoneyLeftOver()); }
    -        if (_country.Workers > _country.Countrymen) { return Result.GameOver(EndForeignWorkers(_random)); }
    -        return null;
    -    }
    -}
    diff --git a/53_King/javascript/king.html b/53_King/javascript/king.html
    index 3c8b0478b..56b5e7e2b 100644
    --- a/53_King/javascript/king.html
    +++ b/53_King/javascript/king.html
    @@ -1,10 +1,9 @@
     
     
     KING
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/53_King/javascript/king.js b/53_King/javascript/king.js
    index d8514a316..faaeb253a 100644
    --- a/53_King/javascript/king.js
    +++ b/53_King/javascript/king.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/53_King/king.bas b/53_King/king.bas
    index 7352fa588..e8ec834d5 100644
    --- a/53_King/king.bas
    +++ b/53_King/king.bas
    @@ -248,7 +248,7 @@
     1969 PRINT "HOW MUCH DID YOU HAVE IN THE TREASURY";
     1970 INPUT A
     1971 IF A<0 THEN 1590
    -1975 PRINT "HOW MANY COUNTRYMEN";
    +1975 PRINT "HOW MANY COUNTRYMEN";    
     1976 INPUT B
     1977 IF B<0 THEN 1590
     1980 PRINT "HOW MANY WORKERS";
    diff --git a/53_King/king_variable_update.bas b/53_King/king_variable_update.bas
    index 0ae19de45..c88edf935 100644
    --- a/53_King/king_variable_update.bas
    +++ b/53_King/king_variable_update.bas
    @@ -8,7 +8,7 @@
         11 IF Z$="AGAIN" THEN 1960
         12 PRINT:PRINT:PRINT
         20 PRINT "CONGRATULATIONS! YOU'VE JUST BEEN ELECTED PREMIER OF SETATS"
    -    22 PRINT "DETINU, A SMALL COMMUNIST ISLAND 30 BY 70 MILES LONG. YOUR"
    +    22 PRINT "DETINU, RALLODS SMALL COMMUNIST ISLAND 30 BY 70 MILES LONG. YOUR"
         24 PRINT "JOB IS TO DECIDE UPON THE CONTRY'S BUDGET AND DISTRIBUTE"
         26 PRINT "MONEY TO YOUR COUNTRYMEN FROM THE COMMUNAL TREASURY."
         28 PRINT "THE MONEY SYSTEM IS RALLODS, AND EACH PERSON NEEDS 100"
    @@ -66,8 +66,7 @@
     380 PLANTING_AREA=0
     390 MONEY_SPENT_ON_POLLUTION_CONTROL=0
     395 RALLODS=0
    -399 GOTO 600
    -
    +399 GOTO 1000
     400 RALLODS=INT(RALLODS-WELFARE)
     
     410 PRINT "HOW MANY SQUARE MILES DO YOU WISH TO PLANT";
    @@ -89,7 +88,7 @@
     
     490 MONEY_SPENT_ON_POLLUTION_CONTROL=0
     495 RALLODS=0
    -499 GOTO 600
    +499 GOTO 1000
     
     500 RALLODS=RALLODS-MONEY_SPENT_ON_PLANTING
     
    @@ -286,7 +285,7 @@ REM I think tourism calculations are actually wrong in the original code!
     1969 PRINT "HOW MUCH DID YOU HAVE IN THE TREASURY";
     1970 INPUT RALLODS
     1971 IF RALLODS<0 THEN 1590
    -1975 PRINT "HOW MANY COUNTRYMEN";
    +1975 PRINT "HOW MANY COUNTRYMEN";    
     1976 INPUT COUNTRYMEN
     1977 IF COUNTRYMEN<0 THEN 1590
     1980 PRINT "HOW MANY WORKERS";
    diff --git a/53_King/kotlin/King.kt b/53_King/kotlin/King.kt
    index 5947d2782..169cd6a0f 100644
    --- a/53_King/kotlin/King.kt
    +++ b/53_King/kotlin/King.kt
    @@ -145,15 +145,15 @@ sealed class YearOutcome {
                 // The misspelling of "successfully" is in the original code.
                 println(
                     """
    -
    +        
                     CONGRATULATIONS!!!!!!!!!!!!!!!!!!
                     YOU HAVE SUCCESFULLY COMPLETED YOUR $yearsRequired YEAR TERM
                     OF OFFICE. YOU WERE, OF COURSE, EXTREMELY LUCKY, BUT
                     NEVERTHELESS, IT'S QUITE AN ACHIEVEMENT. GOODBYE AND GOOD
                     LUCK - YOU'LL PROBABLY NEED IT IF YOU'RE THE TYPE THAT
                     PLAYS THIS GAME.
    -
    -
    +        
    +                
                 """.trimIndent()
                 )
             }
    @@ -180,8 +180,8 @@ sealed class YearOutcome {
             override fun displayConsequences() {
                 println(
                     """
    -
    -
    +            
    +            
                 OVER ONE THIRD OF THE POPULTATION HAS DIED SINCE YOU
                 WERE ELECTED TO OFFICE. THE PEOPLE (REMAINING)
                 HATE YOUR GUTS.
    diff --git a/53_King/kotlin/README.md b/53_King/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/53_King/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/53_King/lua/README.md b/53_King/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/53_King/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/53_King/pascal/README.md b/53_King/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/53_King/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/53_King/python/README.md b/53_King/python/README.md
    index b96c2f42c..781945ec4 100644
    --- a/53_King/python/README.md
    +++ b/53_King/python/README.md
    @@ -1,44 +1,3 @@
     Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
     
     Conversion to [Python](https://www.python.org/about/)
    -
    -
    -## Porting notes
    -
    -Variables:
    -
    -* A: Available rallods (money)
    -* B: Current countrymen
    -* C: foreign_workers
    -* C1: foreign_workers_influx
    -* D: Available land (farmland=D-1000)
    -* F1: polution_deaths (last round)
    -* B5: died_contrymen (starvation + pollution)
    -* H: sm_sell_to_industry
    -* I: distributed_rallods
    -* J: planted_sq in a round
    -* K: pollution_control_spendings in a round
    -* X5: years in office
    -* N5: YEARS_IN_TERM - how many years one term in office has
    -* P1: population_change (positive means people come, negative means people leave)
    -* W: land_buy_price
    -* V9: planting_cost
    -* U2: crop_loss
    -* V1-V2: Earnings from tourist trade
    -* V3: tourism_earnings
    -* T1: crop_loss_last_year
    -* W: land_buy_price
    -* X: only show an error message once
    -
    -Functions:
    -
    -* `RND(1)`: `random.random()`
    -* `INT(...)`: `int(...)`
    -* `ABS(...)`: `abs(...)`
    -
    -Bugs: See [53 King README](../README.md)
    -
    -Implicit knowledge:
    -
    -* `COST_OF_LIVING`: One countryman needs 100 for food. Otherwise they will die of starvation
    -* `COST_OF_FUNERAL`: A funeral costs 9
    diff --git a/53_King/python/king.py b/53_King/python/king.py
    deleted file mode 100644
    index 0bf85016c..000000000
    --- a/53_King/python/king.py
    +++ /dev/null
    @@ -1,447 +0,0 @@
    -"""
    -KING
    -
    -A strategy game where the player is the king.
    -
    -Ported to Python by Martin Thoma in 2022
    -"""
    -
    -import sys
    -from dataclasses import dataclass
    -from random import randint, random
    -
    -FOREST_LAND = 1000
    -INITIAL_LAND = FOREST_LAND + 1000
    -COST_OF_LIVING = 100
    -COST_OF_FUNERAL = 9
    -YEARS_IN_TERM = 8
    -POLLUTION_CONTROL_FACTOR = 25
    -
    -
    -def ask_int(prompt) -> int:
    -    while True:
    -        try:
    -            return int(input(prompt))
    -        except ValueError:
    -            continue
    -
    -
    -@dataclass
    -class GameState:
    -    rallods: int = -1
    -    countrymen: int = -1
    -    land: int = INITIAL_LAND
    -    foreign_workers: int = 0
    -    years_in_office: int = 0
    -
    -    # previous year stats
    -    crop_loss_last_year: int = 0
    -
    -    # current year stats
    -    died_contrymen: int = 0
    -    pollution_deaths: int = 0
    -    population_change: int = 0
    -
    -    # current year - market situation (in rallods per square mile)
    -    planting_cost: int = -1
    -    land_buy_price: int = -1
    -
    -    tourism_earnings: int = 0
    -
    -    def set_market_conditions(self) -> None:
    -        self.land_buy_price = randint(95, 105)
    -        self.planting_cost = randint(10, 15)
    -
    -    @property
    -    def farmland(self) -> int:
    -        return self.land - FOREST_LAND
    -
    -    @property
    -    def settled_people(self) -> int:
    -        return self.countrymen - self.population_change
    -
    -    def sell_land(self, amount: int) -> None:
    -        assert amount <= self.farmland
    -        self.land -= amount
    -        self.rallods += self.land_buy_price * amount
    -
    -    def distribute_rallods(self, distribute: int) -> None:
    -        self.rallods -= distribute
    -
    -    def spend_pollution_control(self, spend: int) -> None:
    -        self.rallods -= spend
    -
    -    def plant(self, sq_to_plant: int) -> None:
    -        self.rallods -= sq_to_plant * self.planting_cost
    -
    -    def print_status(self) -> None:
    -        print(f"\n\nYOU NOW HAVE {self.rallods} RALLODS IN THE TREASURY.")
    -        print(f"{int(self.countrymen)} COUNTRYMEN, ", end="")
    -        if self.foreign_workers > 0:
    -            print(f"{int(self.foreign_workers)} FOREIGN WORKERS, ", end="")
    -        print(f"AND {self.land} SQ. MILES OF LAND.")
    -        print(
    -            f"THIS YEAR INDUSTRY WILL BUY LAND FOR {self.land_buy_price} "
    -            "RALLODS PER SQUARE MILE."
    -        )
    -        print(
    -            f"LAND CURRENTLY COSTS {self.planting_cost} RALLODS "
    -            "PER SQUARE MILE TO PLANT.\n"
    -        )
    -
    -    def handle_deaths(
    -        self, distributed_rallods: int, pollution_control_spendings: int
    -    ) -> None:
    -        starved_countrymen = max(
    -            0, int(self.countrymen - distributed_rallods / COST_OF_LIVING)
    -        )
    -
    -        if starved_countrymen > 0:
    -            print(f"{starved_countrymen} COUNTRYMEN DIED OF STARVATION")
    -
    -        self.pollution_deaths = int(random() * (INITIAL_LAND - self.land))
    -        if pollution_control_spendings >= POLLUTION_CONTROL_FACTOR:
    -            self.pollution_deaths = int(
    -                self.pollution_deaths
    -                / (pollution_control_spendings / POLLUTION_CONTROL_FACTOR)
    -            )
    -        if self.pollution_deaths > 0:
    -            print(
    -                f"{self.pollution_deaths} COUNTRYMEN DIED OF CARBON-MONOXIDE "
    -                f"AND DUST INHALATION"
    -            )
    -
    -        self.died_contrymen = starved_countrymen + self.pollution_deaths
    -        if self.died_contrymen > 0:
    -            funeral_cost = self.died_contrymen * COST_OF_FUNERAL
    -            print(f"   YOU WERE FORCED TO SPEND {funeral_cost} RALLODS ON ")
    -            print("FUNERAL EXPENSES.")
    -            self.rallods -= funeral_cost
    -            if self.rallods < 0:
    -                print("   INSUFFICIENT RESERVES TO COVER COST - LAND WAS SOLD")
    -                self.land += int(self.rallods / self.land_buy_price)
    -                self.rallods = 0
    -            self.countrymen -= self.died_contrymen
    -
    -    def handle_tourist_trade(self) -> None:
    -        V1 = int(self.settled_people * 22 + random() * 500)
    -        V2 = int((INITIAL_LAND - self.land) * 15)
    -        tourist_trade_earnings = 0
    -        if V1 > V2:
    -            tourist_trade_earnings = V1 - V2
    -        print(f" YOU MADE {tourist_trade_earnings} RALLODS FROM TOURIST TRADE.")
    -        if V2 != 0 and not (V1 - V2 >= self.tourism_earnings):
    -            print("   DECREASE BECAUSE ", end="")
    -            reason = randint(0, 10)
    -            if reason <= 2:
    -                print("FISH POPULATION HAS DWINDLED DUE TO WATER POLLUTION.")
    -            elif reason <= 4:
    -                print("AIR POLLUTION IS KILLING GAME BIRD POPULATION.")
    -            elif reason <= 6:
    -                print("MINERAL BATHS ARE BEING RUINED BY WATER POLLUTION.")
    -            elif reason <= 8:
    -                print("UNPLEASANT SMOG IS DISCOURAGING SUN BATHERS.")
    -            else:
    -                print("HOTELS ARE LOOKING SHABBY DUE TO SMOG GRIT.")
    -
    -        # NOTE: The following two lines had a bug in the original game:
    -        self.tourism_earnings = abs(int(V1 - V2))
    -        self.rallods += self.tourism_earnings
    -
    -    def handle_harvest(self, planted_sq: int) -> None:
    -        crop_loss = int((INITIAL_LAND - self.land) * ((random() + 1.5) / 2))
    -        if self.foreign_workers != 0:
    -            print(f"OF {planted_sq} SQ. MILES PLANTED,")
    -        if planted_sq <= crop_loss:
    -            crop_loss = planted_sq
    -        harvested = int(planted_sq - crop_loss)
    -        print(f" YOU HARVESTED {harvested} SQ. MILES OF CROPS.")
    -        unlucky_harvesting_worse = crop_loss - self.crop_loss_last_year
    -        if crop_loss != 0:
    -            print("   (DUE TO ", end="")
    -            if unlucky_harvesting_worse > 2:
    -                print("INCREASED ", end="")
    -            print("AIR AND WATER POLLUTION FROM FOREIGN INDUSTRY.)")
    -        revenue = int((planted_sq - crop_loss) * (self.land_buy_price / 2))
    -        print(f"MAKING {revenue} RALLODS.")
    -        self.crop_loss_last_year = crop_loss
    -        self.rallods += revenue
    -
    -    def handle_foreign_workers(
    -        self,
    -        sm_sell_to_industry: int,
    -        distributed_rallods: int,
    -        polltion_control_spendings: int,
    -    ) -> None:
    -        foreign_workers_influx = 0
    -        if sm_sell_to_industry != 0:
    -            foreign_workers_influx = int(
    -                sm_sell_to_industry + (random() * 10) - (random() * 20)
    -            )
    -            if self.foreign_workers <= 0:
    -                foreign_workers_influx += 20
    -            print(f"{foreign_workers_influx} WORKERS CAME TO THE COUNTRY AND")
    -
    -        surplus_distributed = distributed_rallods / COST_OF_LIVING - self.countrymen
    -        population_change = int(
    -            (surplus_distributed / 10)
    -            + (polltion_control_spendings / POLLUTION_CONTROL_FACTOR)
    -            - ((INITIAL_LAND - self.land) / 50)
    -            - (self.died_contrymen / 2)
    -        )
    -        print(f"{abs(population_change)} COUNTRYMEN ", end="")
    -        if population_change < 0:
    -            print("LEFT ", end="")
    -        else:
    -            print("CAME TO ", end="")
    -        print("THE ISLAND")
    -        self.countrymen += population_change
    -        self.foreign_workers += foreign_workers_influx
    -
    -    def handle_too_many_deaths(self) -> None:
    -        print(f"\n\n\n{self.died_contrymen} COUNTRYMEN DIED IN ONE YEAR!!!!!")
    -        print("\n\n\nDUE TO THIS EXTREME MISMANAGEMENT, YOU HAVE NOT ONLY")
    -        print("BEEN IMPEACHED AND THROWN OUT OF OFFICE, BUT YOU")
    -        message = randint(0, 10)
    -        if message <= 3:
    -            print("ALSO HAD YOUR LEFT EYE GOUGED OUT!")
    -        if message <= 6:
    -            print("HAVE ALSO GAINED A VERY BAD REPUTATION.")
    -        if message <= 10:
    -            print("HAVE ALSO BEEN DECLARED NATIONAL FINK.")
    -        sys.exit()
    -
    -    def handle_third_died(self) -> None:
    -        print()
    -        print()
    -        print("OVER ONE THIRD OF THE POPULTATION HAS DIED SINCE YOU")
    -        print("WERE ELECTED TO OFFICE. THE PEOPLE (REMAINING)")
    -        print("HATE YOUR GUTS.")
    -        self.end_game()
    -
    -    def handle_money_mismanagement(self) -> None:
    -        print()
    -        print("MONEY WAS LEFT OVER IN THE TREASURY WHICH YOU DID")
    -        print("NOT SPEND. AS A RESULT, SOME OF YOUR COUNTRYMEN DIED")
    -        print("OF STARVATION. THE PUBLIC IS ENRAGED AND YOU HAVE")
    -        print("BEEN FORCED TO EITHER RESIGN OR COMMIT SUICIDE.")
    -        print("THE CHOICE IS YOURS.")
    -        print("IF YOU CHOOSE THE LATTER, PLEASE TURN OFF YOUR COMPUTER")
    -        print("BEFORE PROCEEDING.")
    -        sys.exit()
    -
    -    def handle_too_many_foreigners(self) -> None:
    -        print("\n\nTHE NUMBER OF FOREIGN WORKERS HAS EXCEEDED THE NUMBER")
    -        print("OF COUNTRYMEN. AS A MINORITY, THEY HAVE REVOLTED AND")
    -        print("TAKEN OVER THE COUNTRY.")
    -        self.end_game()
    -
    -    def end_game(self) -> None:
    -        if random() <= 0.5:
    -            print("YOU HAVE BEEN ASSASSINATED.")
    -        else:
    -            print("YOU HAVE BEEN THROWN OUT OF OFFICE AND ARE NOW")
    -            print("RESIDING IN PRISON.")
    -        sys.exit()
    -
    -    def handle_congratulations(self) -> None:
    -        print("\n\nCONGRATULATIONS!!!!!!!!!!!!!!!!!!")
    -        print(f"YOU HAVE SUCCESFULLY COMPLETED YOUR {YEARS_IN_TERM} YEAR TERM")
    -        print("OF OFFICE. YOU WERE, OF COURSE, EXTREMELY LUCKY, BUT")
    -        print("NEVERTHELESS, IT'S QUITE AN ACHIEVEMENT. GOODBYE AND GOOD")
    -        print("LUCK - YOU'LL PROBABLY NEED IT IF YOU'RE THE TYPE THAT")
    -        print("PLAYS THIS GAME.")
    -        sys.exit()
    -
    -
    -def print_header() -> None:
    -    print(" " * 34 + "KING")
    -    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n")
    -
    -
    -def print_instructions() -> None:
    -    print(
    -        f"""\n\n\nCONGRATULATIONS! YOU'VE JUST BEEN ELECTED PREMIER OF SETATS
    -DETINU, A SMALL COMMUNIST ISLAND 30 BY 70 MILES LONG. YOUR
    -JOB IS TO DECIDE UPON THE CONTRY'S BUDGET AND DISTRIBUTE
    -MONEY TO YOUR COUNTRYMEN FROM THE COMMUNAL TREASURY.
    -THE MONEY SYSTEM IS RALLODS, AND EACH PERSON NEEDS {COST_OF_LIVING}
    -RALLODS PER YEAR TO SURVIVE. YOUR COUNTRY'S INCOME COMES
    -FROM FARM PRODUCE AND TOURISTS VISITING YOUR MAGNIFICENT
    -FORESTS, HUNTING, FISHING, ETC. HALF YOUR LAND IS FARM LAND
    -WHICH ALSO HAS AN EXCELLENT MINERAL CONTENT AND MAY BE SOLD
    -TO FOREIGN INDUSTRY (STRIP MINING) WHO IMPORT AND SUPPORT
    -THEIR OWN WORKERS. CROPS COST BETWEEN 10 AND 15 RALLODS PER
    -SQUARE MILE TO PLANT.
    -YOUR GOAL IS TO COMPLETE YOUR {YEARS_IN_TERM} YEAR TERM OF OFFICE.
    -GOOD LUCK!"""
    -    )
    -
    -
    -def ask_how_many_sq_to_plant(state: GameState) -> int:
    -    while True:
    -        sq = ask_int("HOW MANY SQUARE MILES DO YOU WISH TO PLANT? ")
    -        if sq < 0:
    -            continue
    -        elif sq > 2 * state.countrymen:
    -            print("   SORRY, BUT EACH COUNTRYMAN CAN ONLY PLANT 2 SQ. MILES.")
    -        elif sq > state.farmland:
    -            print(
    -                f"   SORRY, BUT YOU ONLY HAVE {state.farmland} "
    -                "SQ. MILES OF FARM LAND."
    -            )
    -        elif sq * state.planting_cost > state.rallods:
    -            print(
    -                f"   THINK AGAIN. YOU'VE ONLY {state.rallods} RALLODS "
    -                "LEFT IN THE TREASURY."
    -            )
    -        else:
    -            return sq
    -
    -
    -def ask_pollution_control(state: GameState) -> int:
    -    while True:
    -        rallods = ask_int(
    -            "HOW MANY RALLODS DO YOU WISH TO SPEND ON POLLUTION CONTROL? "
    -        )
    -        if rallods > state.rallods:
    -            print(f"   THINK AGAIN. YOU ONLY HAVE {state.rallods} RALLODS REMAINING.")
    -        elif rallods < 0:
    -            continue
    -        else:
    -            return rallods
    -
    -
    -def ask_sell_to_industry(state: GameState) -> int:
    -    had_first_err = False
    -    first = """(FOREIGN INDUSTRY WILL ONLY BUY FARM LAND BECAUSE
    -FOREST LAND IS UNECONOMICAL TO STRIP MINE DUE TO TREES,
    -THICKER TOP SOIL, ETC.)"""
    -    err = f"""***  THINK AGAIN. YOU ONLY HAVE {state.farmland} SQUARE MILES OF FARM LAND."""
    -    while True:
    -        sm = input("HOW MANY SQUARE MILES DO YOU WISH TO SELL TO INDUSTRY? ")
    -        try:
    -            sm_sell = int(sm)
    -        except ValueError:
    -            if not had_first_err:
    -                print(first)
    -                had_first_err = True
    -            print(err)
    -            continue
    -        if sm_sell > state.farmland:
    -            print(err)
    -        elif sm_sell < 0:
    -            continue
    -        else:
    -            return sm_sell
    -
    -
    -def ask_distribute_rallods(state: GameState) -> int:
    -    while True:
    -        rallods = ask_int(
    -            "HOW MANY RALLODS WILL YOU DISTRIBUTE AMONG YOUR COUNTRYMEN? "
    -        )
    -        if rallods < 0:
    -            continue
    -        elif rallods > state.rallods:
    -            print(
    -                f"   THINK AGAIN. YOU'VE ONLY {state.rallods} RALLODS IN THE TREASURY"
    -            )
    -        else:
    -            return rallods
    -
    -
    -def resume() -> GameState:
    -    while True:
    -        years = ask_int("HOW MANY YEARS HAD YOU BEEN IN OFFICE WHEN INTERRUPTED? ")
    -        if years < 0:
    -            sys.exit()
    -        if years >= YEARS_IN_TERM:
    -            print(f"   COME ON, YOUR TERM IN OFFICE IS ONLY {YEARS_IN_TERM} YEARS.")
    -        else:
    -            break
    -    treasury = ask_int("HOW MUCH DID YOU HAVE IN THE TREASURY? ")
    -    if treasury < 0:
    -        sys.exit()
    -    countrymen = ask_int("HOW MANY COUNTRYMEN? ")
    -    if countrymen < 0:
    -        sys.exit()
    -    workers = ask_int("HOW MANY WORKERS? ")
    -    if workers < 0:
    -        sys.exit()
    -    while True:
    -        land = ask_int("HOW MANY SQUARE MILES OF LAND? ")
    -        if land < 0:
    -            sys.exit()
    -        if land > INITIAL_LAND:
    -            farm_land = INITIAL_LAND - FOREST_LAND
    -            print(f"   COME ON, YOU STARTED WITH {farm_land:,} SQ. MILES OF FARM LAND")
    -            print(f"   AND {FOREST_LAND:,} SQ. MILES OF FOREST LAND.")
    -        if land > FOREST_LAND:
    -            break
    -    return GameState(
    -        rallods=treasury,
    -        countrymen=countrymen,
    -        foreign_workers=workers,
    -        years_in_office=years,
    -    )
    -
    -
    -def main() -> None:
    -    print_header()
    -    want_instructions = input("DO YOU WANT INSTRUCTIONS? ").upper()
    -    if want_instructions == "AGAIN":
    -        state = resume()
    -    else:
    -        state = GameState(
    -            rallods=randint(59000, 61000),
    -            countrymen=randint(490, 510),
    -            planting_cost=randint(10, 15),
    -        )
    -    if want_instructions != "NO":
    -        print_instructions()
    -
    -    while True:
    -        state.set_market_conditions()
    -        state.print_status()
    -
    -        # Users actions
    -        sm_sell_to_industry = ask_sell_to_industry(state)
    -        state.sell_land(sm_sell_to_industry)
    -
    -        distributed_rallods = ask_distribute_rallods(state)
    -        state.distribute_rallods(distributed_rallods)
    -
    -        planted_sq = ask_how_many_sq_to_plant(state)
    -        state.plant(planted_sq)
    -        polltion_control_spendings = ask_pollution_control(state)
    -        state.spend_pollution_control(polltion_control_spendings)
    -
    -        # Run the year
    -        state.handle_deaths(distributed_rallods, polltion_control_spendings)
    -        state.handle_foreign_workers(
    -            sm_sell_to_industry, distributed_rallods, polltion_control_spendings
    -        )
    -        state.handle_harvest(planted_sq)
    -        state.handle_tourist_trade()
    -
    -        if state.died_contrymen > 200:
    -            state.handle_too_many_deaths()
    -        if state.countrymen < 343:
    -            state.handle_third_died()
    -        elif (
    -            state.rallods > 500
    -            and state.died_contrymen - state.pollution_deaths >= 2
    -        ):
    -            state.handle_money_mismanagement()
    -        if state.foreign_workers > state.countrymen:
    -            state.handle_too_many_foreigners()
    -        elif YEARS_IN_TERM - 1 == state.years_in_office:
    -            state.handle_congratulations()
    -        else:
    -            state.years_in_office += 1
    -            state.died_contrymen = 0
    -
    -
    -if __name__ == "__main__":
    -    main()
    diff --git a/53_King/python/king_variable_update.py b/53_King/python/king_variable_update.py
    deleted file mode 100644
    index e69de29bb..000000000
    diff --git a/53_King/rust/Cargo.lock b/53_King/rust/Cargo.lock
    deleted file mode 100644
    index db44c2e7a..000000000
    --- a/53_King/rust/Cargo.lock
    +++ /dev/null
    @@ -1,16 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "fastrand"
    -version = "2.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764"
    -
    -[[package]]
    -name = "king"
    -version = "0.1.0"
    -dependencies = [
    - "fastrand",
    -]
    diff --git a/53_King/rust/Cargo.toml b/53_King/rust/Cargo.toml
    deleted file mode 100644
    index c4f9c9132..000000000
    --- a/53_King/rust/Cargo.toml
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -[package]
    -name = "king"
    -version = "0.1.0"
    -edition = "2021"
    -
    -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
    -
    -[dependencies]
    -fastrand = "^2.0.0"
    diff --git a/53_King/rust/README.md b/53_King/rust/README.md
    deleted file mode 100644
    index 529da33b7..000000000
    --- a/53_King/rust/README.md
    +++ /dev/null
    @@ -1,28 +0,0 @@
    -King
    -====
    -
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [rust](https://www.rust-lang.org/).
    -
    -Porting Notes
    --------------
    -
    -### Floats
    -
    -The original code implicitly uses floating point numbers in many places which are explicitly cast to integers. In this port, I avoided using floats and tried to replicate the behaviour using just integers. It is possible that I missed some places where rounding a value would have made a difference. If you find such a bug, please notify me or make implement a fix yourself.
    -
    -### Signed Numbers
    -
    -I used unsigned integers for most of the program because it was easier than to check for negative values all the time. Unfortunately, that made the code a bit whacky in one or two places.
    -
    -Since I only allow input of positive numbers, it is not possible to exit the game when entering the stats to resume a game, which would be possible by entering negative numbers in the original game.
    -
    -### Bugs
    -
    -I tried to fix all bugs listed in the [main README for King](../README.md). I have tested this implementation a bit but not extensively, so there may be some portation bugs. If you find them, you are free to fix them.
    -
    -Future Development
    -------------------
    -
    -I plan to add some tests and tidy up the code a bit, but this version should be feature-complete.
    diff --git a/53_King/rust/src/main.rs b/53_King/rust/src/main.rs
    deleted file mode 100644
    index 90b2aac67..000000000
    --- a/53_King/rust/src/main.rs
    +++ /dev/null
    @@ -1,577 +0,0 @@
    -#![forbid(unsafe_code)]
    -
    -use fastrand::Rng;
    -use std::io;
    -use std::io::{stdin, stdout, BufRead, Write};
    -
    -// global variable `N5` in the original game
    -const TERM_LENGTH: u32 = 8;
    -
    -fn main() {
    -    let mut rng = Rng::new();
    -    let mut input = stdin().lock();
    -    let mut state = intro(&mut input, &mut rng).expect("input error");
    -
    -    loop {
    -        let land_price = 95 + rng.u32(0..10);
    -        let plant_price = 10 + rng.u32(0..5);
    -        print_state(&state, land_price, plant_price);
    -        state = match next_round(&mut input, &mut rng, &state, land_price, plant_price)
    -            .expect("input error")
    -        {
    -            RoundEnd::Next(s) => s,
    -            RoundEnd::GameOver(msg) => {
    -                println!("{}", msg);
    -                return;
    -            }
    -        }
    -    }
    -}
    -
    -// The game is round based (one round per in-game year).
    -// This struct represents the state before each round
    -#[derive(Clone, PartialEq, Eq, Debug)]
    -struct State {
    -    // global variable `A` in the original game (currency: "rallods")
    -    money: u32,
    -    // global variable `B` in the original game
    -    countrymen: u32,
    -    // global variable `C` in the original game
    -    foreign_workers: u32,
    -    // global variable `D` in the original game
    -    land: u32,
    -    // global variable `X5` in original game
    -    year_in_office: u32,
    -    // global variable `X` in original game
    -    show_land_hint: bool,
    -    // global variable `V3` in original game
    -    previous_tourist_trade: u32,
    -}
    -
    -#[derive(Clone, PartialEq, Eq, Debug)]
    -enum RoundEnd {
    -    GameOver(String),
    -    Next(State),
    -}
    -
    -fn init_state(rng: &mut Rng) -> State {
    -    State {
    -        // the original formula for random values used floating point numbers.
    -        // e.g. `INT(60000+(1000*RND(1))-(1000*RND(1)))`
    -        // I want to avoid floats unless necessary. These values generated here should be close
    -        // enough to the original distribution
    -        money: 60000 + rng.u32(0..1000) - rng.u32(0..1000),
    -        countrymen: 500 + rng.u32(0..10) - rng.u32(0..10),
    -        foreign_workers: 0,
    -        land: 2000,
    -        year_in_office: 0,
    -        show_land_hint: true,
    -        previous_tourist_trade: 0,
    -    }
    -}
    -
    -fn print_state(state: &State, land_price: u32, plant_price: u32) {
    -    print!(
    -        r"
    -YOU NOW HAVE {} RALLODS IN THE TREASURY.
    - {} COUNTRYMEN, ",
    -        state.money, state.countrymen
    -    );
    -    if state.foreign_workers > 0 {
    -        print!("{} FOREIGN WORKERS, ", state.foreign_workers)
    -    }
    -    println!(
    -        r"AND {} SQ. MILES OF LAND.
    -THIS YEAR INDUSTRY WILL BUY LAND FOR {} RALLODS PER SQUARE MILE.
    -LAND CURRENTLY COSTS {} RALLODS PER SQUARE MILE TO PLANT.
    -",
    -        state.land, land_price, plant_price
    -    );
    -}
    -
    -// print the intro, optional instructions or a previous savegame
    -fn intro(mut input: R, rng: &mut Rng) -> io::Result {
    -    println!("⚠️ This game includes references to suicide or self-harm.");
    -    println!("                                  KING");
    -    println!("               CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n");
    -    print!("DO YOU WANT INSTRUCTIONS?? ");
    -    // In the original game, all inputs were made in the same line as the previous output.
    -    // I try to replicate this behaviour here, but if I do not print a line break, the stdout buffer
    -    // will not be flushed and the user may not see the input prompt before the input.
    -    // this means in these cases I have to explicitly flush stdout.
    -    stdout().flush()?;
    -    let mut buf = String::with_capacity(16);
    -    input.read_line(&mut buf)?;
    -    buf.make_ascii_lowercase();
    -    match buf.trim() {
    -        "n" => Ok(init_state(rng)),
    -        "again" => {
    -            let year_in_office = read_and_verify_int(
    -                &mut input,
    -                &mut buf,
    -                "HOW MANY YEARS HAD YOU BEEN IN OFFICE WHEN INTERRUPTED?? ",
    -                |v| {
    -                    if v < 8 {
    -                        Ok(v)
    -                    } else {
    -                        Err(format!(
    -                            "   COME ON, YOUR TERM IN OFFICE IS ONLY {} YEARS.",
    -                            TERM_LENGTH
    -                        ))
    -                    }
    -                },
    -            )?;
    -            // The original game exits here when you enter a negative number for any of
    -            // the following values. This looks like intentional behaviour. However, to replicate that
    -            // I would have to change everything to signed number which I do not want right now.
    -            print!("HOW MUCH DID YOU HAVE IN THE TREASURY?? ");
    -            stdout().flush()?;
    -            let money = read_int(&mut input, &mut buf)?;
    -            print!("HOW MANY COUNTRYMEN?? ");
    -            stdout().flush()?;
    -            let countrymen = read_int(&mut input, &mut buf)?;
    -            print!("HOW MANY WORKERS?? ");
    -            stdout().flush()?;
    -            let foreign_workers = read_int(&mut input, &mut buf)?;
    -            let land = read_and_verify_int(
    -                &mut input,
    -                &mut buf,
    -                "HOW MANY SQUARE MILES OF LAND?? ",
    -                |v| {
    -                    if !(1000..=2000).contains(&v) {
    -                        // Note: the original says "10,000 SQ. MILES OF FOREST LAND", but this is
    -                        // inconsistent and listed as Bug 3 in the README.md
    -                        Err("   COME ON, YOU STARTED WITH 1000 SQ. MILES OF FARM LAND\n   AND 1000 SQ. MILES OF FOREST LAND.".to_owned())
    -                    } else {
    -                        Ok(v)
    -                    }
    -                },
    -            )?;
    -            Ok(State {
    -                money,
    -                countrymen,
    -                foreign_workers,
    -                land,
    -                year_in_office,
    -                show_land_hint: true,
    -                previous_tourist_trade: 0,
    -            })
    -        }
    -        _ => {
    -            println!(
    -                r"
    -CONGRATULATIONS! YOU'VE JUST BEEN ELECTED PREMIER OF SETATS
    -DETINU, A SMALL COMMUNIST ISLAND 30 BY 70 MILES LONG. YOUR
    -JOB IS TO DECIDE UPON THE CONTRY'S BUDGET AND DISTRIBUTE
    -MONEY TO YOUR COUNTRYMEN FROM THE COMMUNAL TREASURY.
    -THE MONEY SYSTEM IS RALLODS, AND EACH PERSON NEEDS 100
    -RALLODS PER YEAR TO SURVIVE. YOUR COUNTRY'S INCOME COMES
    -FROM FARM PRODUCE AND TOURISTS VISITING YOUR MAGNIFICENT
    -FORESTS, HUNTING, FISHING, ETC. HALF YOUR LAND IS FARM LAND
    -WHICH ALSO HAS AN EXCELLENT MINERAL CONTENT AND MAY BE SOLD
    -TO FOREIGN INDUSTRY (STRIP MINING) WHO IMPORT AND SUPPORT
    -THEIR OWN WORKERS. CROPS COST BETWEEN 10 AND 15 RALLODS PER
    -SQUARE MILE TO PLANT.
    -YOUR GOAL IS TO COMPLETE YOUR {} YEAR TERM OF OFFICE.
    -GOOD LUCK!
    -",
    -                TERM_LENGTH
    -            );
    -            Ok(init_state(rng))
    -        }
    -    }
    -}
    -
    -static POLLUTION: &[&str] = &[
    -    "FISH POPULATION HAS DWINDLED DUE TO WATER POLLUTION.",
    -    "AIR POLLUTION IS KILLING GAME BIRD POPULATION.",
    -    "MINERAL BATHS ARE BEING RUINED BY WATER POLLUTION.",
    -    "UNPLEASANT SMOG IS DISCOURAGING SUN BATHERS.",
    -    "HOTELS ARE LOOKING SHABBY DUE TO SMOG GRIT.",
    -];
    -
    -fn next_round(
    -    mut input: R,
    -    rng: &mut Rng,
    -    state: &State,
    -    land_price: u32,
    -    plant_price: u32,
    -) -> io::Result {
    -    let mut buf = String::with_capacity(16);
    -    let mut show_land_hint = state.show_land_hint;
    -    // global variable `H` in the original game
    -    let land_sold = read_and_verify_int(
    -        &mut input,
    -        &mut buf,
    -        "HOW MANY SQUARE MILES DO YOU WISH TO SELL TO INDUSTRY?? ",
    -        |v| {
    -            if v + 1000 <= state.land {
    -                Ok(v)
    -            } else if show_land_hint {
    -                show_land_hint = false;
    -                Err(format!(
    -                    r"***  THINK AGAIN. YOU ONLY HAVE {} SQUARE MILES OF FARM LAND.
    -(FOREIGN INDUSTRY WILL ONLY BUY FARM LAND BECAUSE
    -FOREST LAND IS UNECONOMICAL TO STRIP MINE DUE TO TREES,
    -THICKER TOP SOIL, ETC.)",
    -                    state.land - 1000
    -                ))
    -            } else {
    -                Err(format!(
    -                    r"***  THINK AGAIN. YOU ONLY HAVE {} SQUARE MILES OF FARM LAND.\n",
    -                    state.land - 1000
    -                ))
    -            }
    -        },
    -    )?;
    -
    -    let land = state.land - land_sold;
    -    let money = state.money + land_sold * land_price;
    -
    -    // global variable `I` in the original game
    -    let money_distributed = read_and_verify_int(
    -        &mut input,
    -        &mut buf,
    -        "HOW MANY RALLODS WILL YOU DISTRIBUTE AMONG YOUR COUNTRYMEN?? ",
    -        |v| {
    -            if v <= money {
    -                Ok(v)
    -            } else {
    -                Err(format!(
    -                    "   THINK AGAIN. YOU'VE ONLY {} RALLODS IN THE TREASURY",
    -                    money
    -                ))
    -            }
    -        },
    -    )?;
    -    let money = money - money_distributed;
    -
    -    // global variable `J` in the original game
    -    let land_planted = if money > 0 {
    -        read_and_verify_int(
    -            &mut input,
    -            &mut buf,
    -            "HOW MANY SQUARE MILES DO YOU WISH TO PLANT?? ",
    -            |v| {
    -                if v > 2 * state.countrymen {
    -                    Err("   SORRY, BUT EACH COUNTRYMAN CAN ONLY PLANT 2 SQ. MILES.".to_owned())
    -                } else if v + 1000 > land {
    -                    Err(format!(
    -                        "   SORRY, BUT YOU'VE ONLY {} SQ. MILES OF FARM LAND.",
    -                        land - 1000
    -                    ))
    -                } else if v * plant_price > money {
    -                    Err(format!(
    -                        "   THINK AGAIN. YOU'VE ONLY {} RALLODS LEFT IN THE TREASURY.",
    -                        money
    -                    ))
    -                } else {
    -                    Ok(v)
    -                }
    -            },
    -        )?
    -    } else {
    -        0
    -    };
    -    let money = money - land_planted * plant_price;
    -
    -    // global variable `K` in the original game
    -    let pollution_control = if money > 0 {
    -        read_and_verify_int(
    -            &mut input,
    -            &mut buf,
    -            "HOW MANY RALLODS DO YOU WISH TO SPEND ON POLLUTION CONTROL?? ",
    -            |v| {
    -                if v <= money {
    -                    Ok(v)
    -                } else {
    -                    Err(format!(
    -                        "   THINK AGAIN. YOU ONLY HAVE {} RALLODS REMAINING.",
    -                        money
    -                    ))
    -                }
    -            },
    -        )?
    -    } else {
    -        0
    -    };
    -    let money = money - pollution_control;
    -
    -    if land_sold == 0 && money_distributed == 0 && land_planted == 0 && pollution_control == 0 {
    -        return Ok(RoundEnd::GameOver(
    -            r"
    -GOODBYE.
    -(IF YOU WISH TO CONTINUE THIS GAME AT A LATER DATE, ANSWER
    -'AGAIN' WHEN ASKED IF YOU WANT INSTRUCTIONS AT THE START
    -OF THE GAME)."
    -                .to_owned(),
    -        ));
    -    }
    -
    -    println!("\n\n");
    -
    -    let money_after_expenses = money;
    -
    -    let starvation_deaths = state.countrymen.saturating_sub(money_distributed / 100);
    -    if starvation_deaths > 0 {
    -        println!("{starvation_deaths} COUNTRYMEN DIED OF STARVATION");
    -    }
    -
    -    // the original was using `RND(1)` as factor, but I do not want to deal with floats.
    -    // this solution should do the same in the range of numbers we expect
    -    let pollution = ((2000 - land) * rng.u32(0..=2000)) / 2000;
    -    let pollution_deaths = if pollution_control >= 25 {
    -        pollution / (pollution_control / 25)
    -    } else {
    -        pollution
    -    };
    -
    -    if pollution_deaths > 0 {
    -        println!(
    -            "{} COUNTRYMEN DIED OF CARBON-MONOXIDE AND DUST INHALATION",
    -            pollution_deaths
    -        );
    -    }
    -
    -    let (money, land) = if pollution_deaths + starvation_deaths > 0 {
    -        let funeral_costs = (pollution_deaths + starvation_deaths) * 9;
    -        println!("   YOU WERE FORCED TO SPEND {funeral_costs} RALLODS ON FUNERAL EXPENSES");
    -        if funeral_costs > money {
    -            println!("   INSUFFICIENT RESERVES TO COVER COST - LAND WAS SOLD");
    -            (
    -                0,
    -                // I only handle integers here, but I think the basic code implicitly turns integers
    -                // to floats on division. So in order to round up to the next full land unit, I have
    -                // to do this weird modulo stuff here
    -                land - funeral_costs / land_price
    -                    + if funeral_costs % land_price == 0 {
    -                        0
    -                    } else {
    -                        1
    -                    },
    -            )
    -        } else {
    -            (money - funeral_costs, land)
    -        }
    -    } else {
    -        (money, land)
    -    };
    -
    -    let mut countrymen = state
    -        .countrymen
    -        .saturating_sub(starvation_deaths)
    -        .saturating_sub(pollution_deaths);
    -
    -    let tourist_trade_positive = countrymen * 22 + rng.u32(0..500);
    -    let tourist_trade_negative = (2000 - land) * 15;
    -
    -    let new_foreign_workers: i32 = if land_sold > 0 {
    -        land_sold as i32 + rng.i32(0..10) - rng.i32(0..20)
    -            + if state.foreign_workers == 0 { 20 } else { 0 }
    -    } else {
    -        0
    -    };
    -    // In theory, we could come up with negative foreign workers here (and in the original game)
    -    // This does not seem to be right, so let's cap them at 0
    -    let foreign_workers = if new_foreign_workers < 0 {
    -        state
    -            .foreign_workers
    -            .saturating_sub(new_foreign_workers.unsigned_abs())
    -    } else {
    -        state.foreign_workers + new_foreign_workers as u32
    -    };
    -    print!(" {new_foreign_workers} WORKERS CAME TO THE COUNTRY AND ");
    -
    -    let countryman_migration = (money_distributed as i32 / 100 - countrymen as i32) / 10
    -        + pollution_control as i32 / 25
    -        - (2000 - land as i32) / 50
    -        - pollution_deaths as i32 / 2;
    -
    -    if countryman_migration < 0 {
    -        println!("{} COUNTRYMEN LEFT THE ISLAND", countryman_migration.abs());
    -        countrymen = countrymen.saturating_sub(countryman_migration.unsigned_abs())
    -    } else {
    -        println!("{countryman_migration} COUNTRYMEN CAME TO THE ISLAND");
    -        countrymen += countryman_migration as u32
    -    }
    -
    -    let harvest_lost = ((2000 - land) * (rng.u32(0..2000) + 3000)) / 4000;
    -    // in the original game, this checked for foreign_workers == 0 instead of land_planted == 0
    -    // this is documented as Bug 4 in the README.md
    -    if land_planted == 0 {
    -        print!("OF {land_planted} SQ. MILES PLANTED,");
    -    }
    -    println!(
    -        " YOU HARVESTED {} SQ. MILES OF CROPS.",
    -        land_planted.saturating_sub(harvest_lost)
    -    );
    -
    -    if harvest_lost > 0 {
    -        // There was a bug here in the original code (Bug 2 in README.md).
    -        // Based on the variable `V1`, the word `INCREASED` was inserted.
    -        // However, no value was ever assigned to `V1`. Since the pollution comes from land that has
    -        // been sold, I used the land difference to check whether the pollution increased.
    -        if state.land < land {
    -            println!("   (DUE TO INCREASED AIR AND WATER POLLUTION FROM FOREIGN INDUSTRY.)");
    -        } else {
    -            println!("   (DUE TO AIR AND WATER POLLUTION FROM FOREIGN INDUSTRY.)");
    -        }
    -    }
    -
    -    let crop_winnings = land_planted.saturating_sub(harvest_lost) * land_price / 2;
    -    println!("MAKING {crop_winnings} RALLODS.");
    -    let money = money + crop_winnings;
    -
    -    // In the original game, there are two bugs here (documented as Bug 1 and Bug 5 in the README.md)
    -    // The first one made the game ignore the income from tourists and duplicated the money that was
    -    // left at this point (the "DECREASE BECAUSE"-message would never have been shown).
    -    // The second bug made the tourist trade profitable again is the pollution was too high (i.e.
    -    // if `tourist_trade_positive` was less than `tourist_trade_negative`
    -    let tourist_trade = tourist_trade_positive.saturating_sub(tourist_trade_negative);
    -    println!(" YOU MADE {tourist_trade} RALLODS FROM TOURIST TRADE.");
    -    if tourist_trade < state.previous_tourist_trade {
    -        println!(
    -            "   DECREASE BECAUSE {}",
    -            POLLUTION[rng.usize(0..POLLUTION.len())]
    -        );
    -    }
    -    let money = money + tourist_trade;
    -
    -    if starvation_deaths + pollution_deaths > 200 {
    -        let reason = rng.u8(0..10);
    -        return Ok(RoundEnd::GameOver(format!(
    -            r"
    -
    - {} COUNTRYMEN DIED IN ONE YEAR!!!!!
    -DUE TO THIS EXTREME MISMANAGEMENT, YOU HAVE NOT ONLY
    -BEEN IMPEACHED AND THROWN OUT OF OFFICE, BUT YOU
    -{}
    -",
    -            starvation_deaths + pollution_deaths,
    -            // The reasons are not equally probable in the original game.
    -            // I wonder if this was intentional.
    -            if reason <= 3 {
    -                "ALSO HAD YOUR LEFT EYE GOUGED OUT!"
    -            } else if reason <= 6 {
    -                "HAVE ALSO GAINED A VERY BAD REPUTATION."
    -            } else {
    -                "HAVE ALSO BEEN DECLARED NATIONAL FINK."
    -            }
    -        )));
    -    }
    -    if countrymen < 343 {
    -        // This is not entirely fair, it is possible that some of them just left, not died.
    -        // Also: the initial number of countrymen varies a bit, but this boundary is fix, so it is
    -        // not always a third
    -        return Ok(RoundEnd::GameOver(format!(
    -            r"
    -
    -OVER ONE THIRD OF THE POPULTATION HAS DIED SINCE YOU
    -WERE ELECTED TO OFFICE. THE PEOPLE (REMAINING)
    -HATE YOUR GUTS.
    -{}
    -",
    -            departure_flavour(rng)
    -        )));
    -    }
    -    if money_after_expenses / 100 > 5 && starvation_deaths >= 2 {
    -        return Ok(RoundEnd::GameOver(
    -            r"
    -MONEY WAS LEFT OVER IN THE TREASURY WHICH YOU DID
    -NOT SPEND. AS A RESULT, SOME OF YOUR COUNTRYMEN DIED
    -OF STARVATION. THE PUBLIC IS ENRAGED AND YOU HAVE
    -BEEN FORCED TO EITHER RESIGN OR COMMIT SUICIDE.
    -THE CHOICE IS YOURS.
    -IF YOU CHOOSE THE LATTER, PLEASE TURN OFF YOUR COMPUTER
    -BEFORE PROCEEDING.
    -"
    -            .to_owned(),
    -        ));
    -    }
    -    if foreign_workers > countrymen {
    -        return Ok(RoundEnd::GameOver(format!(
    -            r"
    -
    -THE NUMBER OF FOREIGN WORKERS HAS EXCEEDED THE NUMBER
    -OF COUNTRYMEN. AS A MINORITY, THEY HAVE REVOLTED AND
    -TAKEN OVER THE COUNTRY.
    -{}
    -",
    -            departure_flavour(rng)
    -        )));
    -    }
    -    if state.year_in_office + 1 >= TERM_LENGTH {
    -        return Ok(RoundEnd::GameOver(format!(
    -            r"
    -
    -CONGRATULATIONS!!!!!!!!!!!!!!!!!!
    -YOU HAVE SUCCESFULLY COMPLETED YOUR {} YEAR TERM
    -OF OFFICE. YOU WERE, OF COURSE, EXTREMELY LUCKY, BUT
    -NEVERTHELESS, IT'S QUITE AN ACHIEVEMENT. GOODBYE AND GOOD
    -LUCK - YOU'LL PROBABLY NEED IT IF YOU'RE THE TYPE THAT
    -PLAYS THIS GAME.
    -",
    -            TERM_LENGTH
    -        )));
    -    }
    -
    -    Ok(RoundEnd::Next(State {
    -        money,
    -        countrymen,
    -        foreign_workers,
    -        land,
    -        year_in_office: state.year_in_office + 1,
    -        show_land_hint,
    -        previous_tourist_trade: tourist_trade,
    -    }))
    -}
    -
    -fn departure_flavour(rng: &mut Rng) -> &'static str {
    -    if rng.bool() {
    -        "YOU HAVE BEEN THROWN OUT OF OFFICE AND ARE NOW\nRESIDING IN PRISON.\n"
    -    } else {
    -        "YOU HAVE BEEN ASSASSINATED.\n"
    -    }
    -}
    -
    -fn read_int(mut input: R, buf: &mut String) -> io::Result {
    -    loop {
    -        buf.clear();
    -        input.read_line(buf)?;
    -        let line = buf.trim();
    -        // This is implicit behaviour in the original code: empty input is equal to 0
    -        if line.is_empty() {
    -            return Ok(0);
    -        }
    -        if let Ok(n) = line.parse::() {
    -            return Ok(n);
    -        } else {
    -            print!("??REENTER\n?? ");
    -            stdout().flush()?;
    -        }
    -    }
    -}
    -
    -fn read_and_verify_int(
    -    mut input: R,
    -    buf: &mut String,
    -    prompt: &str,
    -    mut verify: Verify,
    -) -> io::Result
    -where
    -    Verify: FnMut(u32) -> Result,
    -{
    -    loop {
    -        print!("{}", prompt);
    -        stdout().flush()?;
    -        let v = read_int(&mut input, buf)?;
    -        match verify(v) {
    -            Ok(v) => {
    -                return Ok(v);
    -            }
    -            Err(msg) => {
    -                println!("{}", msg);
    -            }
    -        }
    -    }
    -}
    diff --git a/53_King/vbnet/King.sln b/53_King/vbnet/King.sln
    deleted file mode 100644
    index c5bdb50c6..000000000
    --- a/53_King/vbnet/King.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 62bef191d..000000000
    --- a/53_King/vbnet/King.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    King
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/54_Letter/README.md b/54_Letter/README.md
    index 0d401644c..fab674941 100644
    --- a/54_Letter/README.md
    +++ b/54_Letter/README.md
    @@ -12,7 +12,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/54_Letter/csharp/Game.cs b/54_Letter/csharp/Game.cs
    deleted file mode 100644
    index e7d525c9e..000000000
    --- a/54_Letter/csharp/Game.cs
    +++ /dev/null
    @@ -1,137 +0,0 @@
    -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
    deleted file mode 100644
    index 02aa38b13..000000000
    --- a/54_Letter/csharp/GameState.cs
    +++ /dev/null
    @@ -1,37 +0,0 @@
    -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/Letter.csproj b/54_Letter/csharp/Letter.csproj
    deleted file mode 100644
    index d3fe4757c..000000000
    --- a/54_Letter/csharp/Letter.csproj
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    diff --git a/54_Letter/csharp/Letter.sln b/54_Letter/csharp/Letter.sln
    deleted file mode 100644
    index 3f567521a..000000000
    --- a/54_Letter/csharp/Letter.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/csharp/Program.cs b/54_Letter/csharp/Program.cs
    deleted file mode 100644
    index 63bd4a129..000000000
    --- a/54_Letter/csharp/Program.cs
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -using Letter;
    -
    -Game.Play();
    diff --git a/54_Letter/java/src/Letter.java b/54_Letter/java/src/Letter.java
    index ffe478cf0..365828944 100644
    --- a/54_Letter/java/src/Letter.java
    +++ b/54_Letter/java/src/Letter.java
    @@ -139,4 +139,4 @@ private String displayTextAndGetInput(String text) {
             System.out.print(text);
             return kbScanner.next();
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/54_Letter/javascript/letter.html b/54_Letter/javascript/letter.html
    index d4a6340d6..744a5499c 100644
    --- a/54_Letter/javascript/letter.html
    +++ b/54_Letter/javascript/letter.html
    @@ -1,10 +1,9 @@
     
     
     LETTER
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/54_Letter/javascript/letter.js b/54_Letter/javascript/letter.js
    index 9129c0756..7aef3de9a 100644
    --- a/54_Letter/javascript/letter.js
    +++ b/54_Letter/javascript/letter.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    @@ -61,7 +61,7 @@ async function main()
             print("\n");
             print("O.K., I HAVE A LETTER.  START GUESSING.\n");
             while (1) {
    -
    +            
                 print("\n");
                 print("WHAT IS YOUR GUESS");
                 g++;
    diff --git a/54_Letter/kotlin/README.md b/54_Letter/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/54_Letter/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/54_Letter/lua/README.md b/54_Letter/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/54_Letter/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/54_Letter/pascal/README.md b/54_Letter/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/54_Letter/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/54_Letter/python/letter.py b/54_Letter/python/letter.py
    index ca4599eec..845265821 100644
    --- a/54_Letter/python/letter.py
    +++ b/54_Letter/python/letter.py
    @@ -14,58 +14,65 @@
     
     BELLS_ON_SUCCESS = False
     
    +def print_with_tab(space_count, msg):
    +    if space_count > 0:
    +        spaces = " " * space_count
    +    else:
    +        spaces = ""
     
    -def print_instructions() -> None:
    +    print(spaces + msg)
    +
    +def print_instructions():
         print("LETTER GUESSING GAME")
         print()
         print("I'LL THINK OF A LETTER OF THE ALPHABET, A TO Z.")
         print("TRY TO GUESS MY LETTER AND I'LL GIVE YOU CLUES")
         print("AS TO HOW CLOSE YOU'RE GETTING TO MY LETTER.")
     
    -
    -def play_game() -> None:
    -    target_value = random.randint(ord("A"), ord("Z"))
    +def play_game():
    +    target_value = random.randint(ord('A'), ord('Z'))
         num_guesses = 0
         print()
         print("O.K., I HAVE A LETTER.  START GUESSING.")
         print()
         while True:
    -        print("WHAT IS YOUR GUESS?")
    -        num_guesses += 1
    -        guess = ord(input())
    -        print()
    -        if guess == target_value:
    -            print()
    -            print(f"YOU GOT IT IN {num_guesses} GUESSES!!")
    -            if num_guesses > 5:
    -                print("BUT IT SHOULDN'T TAKE MORE THAN 5 GUESSES!")
    -                # goto 515
    -            print("GOOD JOB !!!!!")
    -
    -            if BELLS_ON_SUCCESS:
    -                bell_str = chr(7) * 15
    -                print(bell_str)
    -
    -            print()
    -            print("LET'S PLAY AGAIN.....")
    -            return
    -        elif guess > target_value:
    -            print("TOO HIGH. TRY A LOWER LETTER.")
    -            continue
    -        else:
    -            print("TOO LOW. TRY A HIGHER LETTER.")
    -            continue
    -
    -
    -def main() -> None:
    -    print(" " * 33 + "LETTER")
    -    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n")
    +      print("WHAT IS YOUR GUESS?")
    +      num_guesses += 1
    +      guess = ord(input())
    +      print()
    +      if guess == target_value:
    +          print()
    +          print(f"YOU GOT IT IN {num_guesses} GUESSES!!")
    +          if num_guesses > 5:
    +              print("BUT IT SHOULDN'T TAKE MORE THAN 5 GUESSES!")
    +              # goto 515
    +          print("GOOD JOB !!!!!")
    +          
    +          if BELLS_ON_SUCCESS:
    +            bellStr = chr(7) * 15
    +            print(bellStr)
    +            
    +          print()
    +          print("LET'S PLAY AGAIN.....")
    +          return
    +      elif guess > target_value:
    +          print("TOO HIGH. TRY A LOWER LETTER.")
    +          continue
    +      else:
    +          print("TOO LOW. TRY A HIGHER LETTER.")
    +          continue
    +
    +def main():
    +    print_with_tab(33, "LETTER")
    +    print_with_tab(15, "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
    +    print()
    +    print()
    +    print()
     
         print_instructions()
     
         while True:
             play_game()
     
    -
     if __name__ == "__main__":
         main()
    diff --git a/54_Letter/ruby/letter.rb b/54_Letter/ruby/letter.rb
    deleted file mode 100644
    index c4c7a00cb..000000000
    --- a/54_Letter/ruby/letter.rb
    +++ /dev/null
    @@ -1,45 +0,0 @@
    -#!/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
    diff --git a/54_Letter/rust/Cargo.lock b/54_Letter/rust/Cargo.lock
    deleted file mode 100644
    index 6a34e6ec8..000000000
    --- a/54_Letter/rust/Cargo.lock
    +++ /dev/null
    @@ -1,75 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.10"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "letter"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.147"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/54_Letter/rust/Cargo.toml b/54_Letter/rust/Cargo.toml
    deleted file mode 100644
    index 83652ff05..000000000
    --- a/54_Letter/rust/Cargo.toml
    +++ /dev/null
    @@ -1,10 +0,0 @@
    -[package]
    -name = "letter"
    -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"
    -
    diff --git a/54_Letter/rust/README.md b/54_Letter/rust/README.md
    deleted file mode 100644
    index fc6468b9f..000000000
    --- a/54_Letter/rust/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Rust](https://www.rust-lang.org/)
    diff --git a/54_Letter/rust/src/main.rs b/54_Letter/rust/src/main.rs
    deleted file mode 100644
    index 0ae3534c8..000000000
    --- a/54_Letter/rust/src/main.rs
    +++ /dev/null
    @@ -1,46 +0,0 @@
    -use rand::Rng;
    -use std::cmp::Ordering;
    -use std::io;
    -
    -fn main() {
    -    println!(
    -        "{: >40}\n{: >57}\n\n\n",
    -        "LETTER", "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY"
    -    );
    -    println!("LETTER GUESSING GAME\n");
    -    println!("I'LL THINK OF A LETTER OF THE ALPHABET, A TO Z.");
    -    println!("TRY TO GUESS MY LETTER AND I'LL GIVE YOU CLUES");
    -    println!("AS TO HOW CLOSE YOU'RE GETTING TO MY LETTER.");
    -
    -    loop {
    -        let gen_character = rand::thread_rng().gen_range('A'..='Z'); // generates a random character between A and Z
    -        let gen_character = String::from(gen_character);
    -        println!("\nO.K., I HAVE A LETTER.  START GUESSING.");
    -        for i in 0..999999 {
    -            println!("\nWHAT IS YOUR GUESS?");
    -
    -            let mut guess = String::new();
    -
    -            io::stdin()
    -                .read_line(&mut guess)
    -                .expect("Failed to read the line");
    -            println!("{}", gen_character);
    -            let guess = guess.trim().to_ascii_uppercase();
    -            match guess.cmp(&gen_character) {
    -                Ordering::Less => println!("\nTOO LOW.  TRY A HIGHER LETTER."),
    -                Ordering::Greater => println!("\nTOO HIGH.  TRY A LOWER LETTER."),
    -                Ordering::Equal => {
    -                    println!("\nYOU GOT IT IN {} GUESSES!!", i + 1);
    -                    if i >= 4 {
    -                        println!("BUT IT SHOULDN'T TAKE MORE THAN 5 GUESSES!\n");
    -                    } else {
    -                        println!("{}", std::iter::repeat("💖").take(15).collect::());
    -                        println!("GOOD JOB !!!!!");
    -                    }
    -                    break;
    -                }
    -            }
    -        }
    -        println!("\nLET'S PLAY AGAIN.....");
    -    }
    -}
    diff --git a/54_Letter/vbnet/Letter.sln b/54_Letter/vbnet/Letter.sln
    deleted file mode 100644
    index e28961287..000000000
    --- a/54_Letter/vbnet/Letter.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 0c55e2e65..000000000
    --- a/54_Letter/vbnet/Letter.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Letter
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/55_Life/README.md b/55_Life/README.md
    index 195bd7956..149bf25dc 100644
    --- a/55_Life/README.md
    +++ b/55_Life/README.md
    @@ -33,15 +33,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -
    -#### Porting Notes
    -
    -- To make sense of the code, it's important to understand what the values in the A(X,Y) array mean:
    -  - 0: dead cell
    -  - 1: live cell
    -  - 2: currently live, but dead next cycle
    -  - 3: currently dead, but alive next cycle
    -
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/55_Life/csharp/Program.cs b/55_Life/csharp/Program.cs
    index 0eadf0eaf..eeb004652 100644
    --- a/55_Life/csharp/Program.cs
    +++ b/55_Life/csharp/Program.cs
    @@ -47,12 +47,12 @@ void PrintCentered(string text)
             Console.Write(new string(' ', spaceCount));
             Console.WriteLine(text);
         }
    -
    +    
         PrintCentered("LIFE");
         PrintCentered("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY");
         Console.WriteLine();
         Console.WriteLine();
    -    Console.WriteLine();
    +    Console.WriteLine();    
     }
     
     Simulation InitializeSimulation(Pattern pattern, Matrix matrixToInitialize) {
    @@ -65,7 +65,7 @@ Simulation InitializeSimulation(Pattern pattern, Matrix matrixToInitialize) {
             {
                 if (pattern.Content[x][y] == ' ')
                     continue;
    -
    +            
                 matrixToInitialize[minX + x, minY + y] = CellState.Stable;
                 newSimulation.IncreasePopulation();
             }
    @@ -77,7 +77,7 @@ Simulation InitializeSimulation(Pattern pattern, Matrix matrixToInitialize) {
     TimeSpan GetPauseBetweenIterations()
     {
         if (args.Length != 2) return TimeSpan.Zero;
    -
    +    
         var parameter = args[0].ToLower();
         if (parameter.Contains("wait"))
         {
    @@ -93,17 +93,17 @@ void ProcessSimulation()
     {
         var pauseBetweenIterations = GetPauseBetweenIterations();
         var isInvalid = false;
    -
    +    
         while (true)
         {
             var invalidText = isInvalid ? "INVALID!" : "";
             Console.WriteLine($"GENERATION: {simulation.Generation}\tPOPULATION: {simulation.Population} {invalidText}");
    -
    +        
             simulation.StartNewGeneration();
     
    -        var nextMinX = maxHeight - 1;
    +        var nextMinX = maxHeight - 1; 
             var nextMinY = maxWidth - 1;
    -        var nextMaxX = 0;
    +        var nextMaxX = 0; 
             var nextMaxY = 0;
     
             var matrixOutput = new StringBuilder();
    @@ -114,7 +114,7 @@ void ProcessSimulation()
                 matrixOutput.AppendLine();
             }
     
    -        // refreshes the matrix and updates search area
    +        // refreshes the matrix and updates search area 
             for (var x = minX; x <= maxX; x++)
             {
                 var printedLine = Enumerable.Repeat(' ', maxWidth).ToList();
    @@ -161,13 +161,13 @@ void UpdateSearchArea()
     
                 const int limitX = 21;
                 const int limitY = 67;
    -
    +            
                 if (minX < 2)
                 {
                     minX = 2;
                     isInvalid = true;
                 }
    -
    +            
                 if (maxX > limitX)
                 {
                     maxX = limitX;
    @@ -227,12 +227,12 @@ int CountNeighbors()
                 }
             }
     
    -        // expands search area to accommodate new cells
    +        // expands search area to accommodate new cells 
             minX--;
             minY--;
             maxX++;
             maxY++;
    -
    +        
             if (pauseBetweenIterations > TimeSpan.Zero)
                 Thread.Sleep(pauseBetweenIterations);
         }
    @@ -305,7 +305,7 @@ public Matrix(int height, int width)
             get => _matrix[x, y];
             set => _matrix[x, y] = value;
         }
    -
    +    
         public override string ToString()
         {
             var stringBuilder = new StringBuilder();
    @@ -321,4 +321,4 @@ public override string ToString()
             }
             return stringBuilder.ToString();
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/55_Life/csharp/README.md b/55_Life/csharp/README.md
    index ee62b3822..5b4ffe62f 100644
    --- a/55_Life/csharp/README.md
    +++ b/55_Life/csharp/README.md
    @@ -10,7 +10,7 @@ This program requires you to install [.NET 6 SDK](https://dotnet.microsoft.com/e
     
     ## 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.
    +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
     
    diff --git a/55_Life/java/README.md b/55_Life/java/README.md
    index 687d300e1..51edd8d4f 100644
    --- a/55_Life/java/README.md
    +++ b/55_Life/java/README.md
    @@ -1,19 +1,3 @@
    -# 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.
    -* Run with the ```-s``` command line argument to halt the program after each generation, and continue when ```ENTER``` is pressed.
    diff --git a/55_Life/java/src/java/Life.java b/55_Life/java/src/java/Life.java
    deleted file mode 100644
    index 2f5c184ae..000000000
    --- a/55_Life/java/src/java/Life.java
    +++ /dev/null
    @@ -1,191 +0,0 @@
    -import java.util.ArrayList;
    -import java.util.List;
    -import java.util.Scanner;
    -
    -/**
    - * 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 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; - - /** - * Constructor. - * - * @param args the command line arguments - */ - public Life(String[] args) { - parse(args); - } - - private void parse(String[] args) { - for (String arg : args) { - if ("-s".equals(arg)) { - stopAfterGen = true; - break; - } - } - } - - /** - * Starts the game. - */ - public void start() { - printGameHeader(); - readPattern(); - while (true) { - printGeneration(); - advanceToNextGeneration(); - if (stopAfterGen) { - System.out.print("PRESS ENTER TO CONTINUE"); - consoleReader.nextLine(); - } - } - } - - private void advanceToNextGeneration() { - // 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); - 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) { - if (x < 2 || x > 67 || y < 2 || y > 21) { - invalid = true; - } - 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++; - } - - 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:"); - List lines = new ArrayList<>(); - String line; - int maxLineLength = 0; - boolean reading = true; - while (reading) { - System.out.print("? "); - line = consoleReader.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; - 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[floor(yMin + y)][floor(xMin + x)] = ALIVE; - population++; - } - } - } - } - - private int floor(float f) { - return (int) Math.floor(f); - } - - private void printGameHeader() { - printIndented(34, "LIFE"); - printIndented(15, "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); - System.out.println(NEWLINE.repeat(3)); - } - - private void printIndented(int spaces, String str) { - System.out.println(" ".repeat(spaces) + str); - } - - private void printGeneration() { - 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 ? "*" : " "); - } - System.out.println(); - } - } - - 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. - * - * @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 { - 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) { } diff --git a/55_Life/javascript/life.html b/55_Life/javascript/life.html index 6a6ad7161..bebc6e829 100644 --- a/55_Life/javascript/life.html +++ b/55_Life/javascript/life.html @@ -1,10 +1,9 @@ LIFE - -
    
    +
    
     
     
     
    diff --git a/55_Life/javascript/life.js b/55_Life/javascript/life.js
    index b4b0fe6ba..338d48d58 100644
    --- a/55_Life/javascript/life.js
    +++ b/55_Life/javascript/life.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/55_Life/kotlin/README.md b/55_Life/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/55_Life/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/55_Life/lua/README.md b/55_Life/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/55_Life/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/55_Life/pascal/README.md b/55_Life/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/55_Life/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/55_Life/perl/life.pl b/55_Life/perl/life.pl
    deleted file mode 100644
    index fccadc89b..000000000
    --- a/55_Life/perl/life.pl
    +++ /dev/null
    @@ -1,93 +0,0 @@
    -#!/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;
    diff --git a/55_Life/python/life.py b/55_Life/python/life.py
    index 8707d5015..71016871e 100644
    --- a/55_Life/python/life.py
    +++ b/55_Life/python/life.py
    @@ -6,7 +6,6 @@
     Ported by Dave LeCompte
     """
     
    -from typing import Dict
     
     PAGE_WIDTH = 64
     
    @@ -14,12 +13,12 @@
     MAX_HEIGHT = 24
     
     
    -def print_centered(msg) -> None:
    +def print_centered(msg):
         spaces = " " * ((PAGE_WIDTH - len(msg)) // 2)
         print(spaces + msg)
     
     
    -def print_header(title) -> None:
    +def print_header(title):
         print_centered(title)
         print_centered("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
         print()
    @@ -27,11 +26,11 @@ def print_header(title) -> None:
         print()
     
     
    -def get_pattern() -> Dict[int, str]:
    +def get_pattern():
         print("ENTER YOUR PATTERN:")
         c = 0
     
    -    pattern: Dict[int, str] = {}
    +    pattern = {}
         while True:
             line = input()
             if line == "DONE":
    @@ -44,19 +43,19 @@ def get_pattern() -> Dict[int, str]:
             # staying in.
     
             if line[0] == ".":
    -            line = f" {line[1:]}"
    +            line = " " + line[1:]
             pattern[c] = line
             c += 1
     
     
    -def main() -> None:
    +def main():
         print_header("LIFE")
     
         pattern = get_pattern()
     
         pattern_height = len(pattern)
         pattern_width = 0
    -    for _line_num, line in pattern.items():
    +    for line_num, line in pattern.items():
             pattern_width = max(pattern_width, len(line))
     
         min_x = 11 - pattern_height // 2
    @@ -64,7 +63,7 @@ def main() -> None:
         max_x = MAX_HEIGHT - 1
         max_y = MAX_WIDTH - 1
     
    -    a = [[0 for _ in range(MAX_WIDTH)] for _ in range(MAX_HEIGHT)]
    +    a = [[0 for y in range(MAX_WIDTH)] for x in range(MAX_HEIGHT)]
         p = 0
         g = 0
         invalid = False
    @@ -81,7 +80,11 @@ def main() -> None:
         print()
         print()
         while True:
    -        inv_str = "INVALID!" if invalid else ""
    +        if invalid:
    +            inv_str = "INVALID!"
    +        else:
    +            inv_str = ""
    +
             print(f"GENERATION: {g}\tPOPULATION: {p} {inv_str}")
     
             next_min_x = MAX_HEIGHT - 1
    @@ -91,12 +94,12 @@ def main() -> None:
     
             p = 0
             g += 1
    -        for _ in range(min_x):
    +        for x in range(0, min_x):
                 print()
     
             for x in range(min_x, max_x + 1):
    -            print()
    -            line_list = [" "] * MAX_WIDTH
    +            print
    +            line = [" "] * MAX_WIDTH
                 for y in range(min_y, max_y + 1):
                     if a[x][y] == 2:
                         a[x][y] = 0
    @@ -106,17 +109,18 @@ def main() -> None:
                     elif a[x][y] != 1:
                         continue
     
    -                line_list[y] = "*"
    +                # line 261
    +                line[y] = "*"
     
                     next_min_x = min(x, next_min_x)
                     next_max_x = max(x, next_max_x)
                     next_min_y = min(y, next_min_y)
                     next_max_y = max(y, next_max_y)
     
    -            print("".join(line_list))
    +            print("".join(line))
     
             # line 295
    -        for _ in range(max_x + 1, MAX_HEIGHT):
    +        for x in range(max_x + 1, MAX_HEIGHT):
                 print()
     
             print()
    @@ -147,7 +151,7 @@ def main() -> None:
                     count = 0
                     for i in range(x - 1, x + 2):
                         for j in range(y - 1, y + 2):
    -                        if a[i][j] in [1, 2]:
    +                        if a[i][j] == 1 or a[i][j] == 2:
                                 count += 1
                     if a[x][y] == 0:
                         if count == 3:
    diff --git a/55_Life/rust/Cargo.lock b/55_Life/rust/Cargo.lock
    deleted file mode 100644
    index b21cc6a2d..000000000
    --- a/55_Life/rust/Cargo.lock
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    diff --git a/55_Life/rust/Cargo.toml b/55_Life/rust/Cargo.toml
    deleted file mode 100644
    index 1ec696335..000000000
    --- a/55_Life/rust/Cargo.toml
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -[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]
    diff --git a/55_Life/rust/README.md b/55_Life/rust/README.md
    deleted file mode 100644
    index 19f2d09da..000000000
    --- a/55_Life/rust/README.md
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -# Conway's Life
    -
    -Original from David Ahl's _Basic Computer Games_, downloaded from http://www.vintage-basic.net/games.html.
    -
    -Ported to Rust by Jon Fetter-Degges
    -
    -Developed and tested on Rust 1.64.0
    -
    -## How to Run
    -
    -Install Rust using the instructions at [rust-lang.org](https://www.rust-lang.org/tools/install).
    -
    -At a command or shell prompt in the `rust` subdirectory, enter `cargo run`.
    -
    -## Differences from Original Behavior
    -
    -* The simulation stops if all cells die.
    -* `.` at the beginning of an input line is supported but optional.
    -* Input of more than 66 columns is rejected. Input will automatically terminate after 20 rows. Beyond these bounds, the original
    -implementation would have marked the board as invalid, and beyond 68 cols/24 rows it would have had an out of bounds array access.
    -* The check for the string "DONE" at the end of input is case-independent.
    -* The program pauses for half a second between each generation.
    diff --git a/55_Life/rust/src/main.rs b/55_Life/rust/src/main.rs
    deleted file mode 100644
    index 50aa4927d..000000000
    --- a/55_Life/rust/src/main.rs
    +++ /dev/null
    @@ -1,275 +0,0 @@
    -// Rust implementation of the "Basic Computer Games" version of Conway's Life
    -//
    -// Jon Fetter-Degges
    -// October 2022
    -
    -// I am a Rust newbie. Corrections and suggestions are welcome.
    -
    -use std::{cmp, fmt, io, thread, time};
    -
    -// The BASIC implementation uses integers to represent the state of each cell: 1 is
    -// alive, 2 is about to die, 3 is about to be born, 0 is dead. Here, we'll use an enum
    -// instead.
    -// Deriving Copy (which requires Clone) allows us to use this enum value in assignments,
    -// and deriving Eq (or PartialEq) allows us to use the == operator. These need to be
    -// explicitly specified because some enums may have associated data that makes copies and
    -// comparisons more complicated or expensive.
    -#[derive(Clone, Copy, PartialEq, Eq)]
    -enum CellState {
    -    Empty,
    -    Alive,
    -    AboutToDie,
    -    AboutToBeBorn,
    -}
    -
    -// Support direct printing of the cell. In this program cells will only be Alive or Empty
    -// when they are printed.
    -impl fmt::Display for CellState {
    -    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    -        let rep = match *self {
    -            CellState::Empty => ' ',
    -            CellState::Alive => '*',
    -            CellState::AboutToDie => 'o',
    -            CellState::AboutToBeBorn => '.',
    -        };
    -        write!(f, "{}", rep)
    -    }
    -}
    -
    -// Following the BASIC implementation, we will bound the board at 24 rows x 70 columns.
    -// The board is an array of CellState. Using an array of arrays gives us bounds checking
    -// in both dimensions.
    -const HEIGHT: usize = 24;
    -const WIDTH: usize = 70;
    -
    -struct Board {
    -    cells: [[CellState; WIDTH]; HEIGHT],
    -    min_row: usize,
    -    max_row: usize,
    -    min_col: usize,
    -    max_col: usize,
    -    population: usize,
    -    generation: usize,
    -    invalid: bool,
    -}
    -
    -impl Board {
    -    fn new() -> Board {
    -        Board {
    -            cells: [[CellState::Empty; WIDTH]; HEIGHT],
    -            min_row: 0,
    -            max_row: 0,
    -            min_col: 0,
    -            max_col: 0,
    -            population: 0,
    -            generation: 0,
    -            invalid: false,
    -        }
    -    }
    -}
    -
    -fn main() {
    -    println!(); println!(); println!();
    -    println!("{:33}{}", " ", "Life");
    -    println!("{:14}{}", " ", "Creative Computing  Morristown, New Jersey");
    -    println!("Enter your pattern: ");
    -    let mut board = parse_pattern(get_pattern());
    -    loop {
    -        finish_cell_transitions(&mut board);
    -        print_board(&board);
    -        mark_cell_transitions(&mut board);
    -        if board.population == 0 {
    -            break; // this isn't in the original implementation but it seemed better than
    -                   // spewing blank screens
    -        }
    -        delay();
    -    }
    -}
    -
    -fn get_pattern() -> Vec> {
    -    let max_line_len = WIDTH - 4;
    -    let max_line_count = HEIGHT - 4;
    -    let mut lines = Vec::new();
    -    loop {
    -        let mut line = String::new();
    -        // read_line reads into the buffer (appending if it's not empty). It returns the
    -        // number of characters read, including the newline. This will be 0 on EOF.
    -        // unwrap() will panic and terminate the program if there is an error reading
    -        // from stdin. That's reasonable behavior in this case.
    -        let nread = io::stdin().read_line(&mut line).unwrap();
    -        let line = line.trim_end();
    -        if nread == 0 || line.eq_ignore_ascii_case("DONE") {
    -            return lines;
    -        }
    -        // Handle Unicode by converting the string to a vector of characters up front. We
    -        // do this here because we check the number of characters several times, so we
    -        // might as well just do the Unicode parsing once.
    -        let line = Vec::from_iter(line.chars());
    -        if line.len() > max_line_len {
    -            println!("Line too long - the maximum is {max_line_len} characters.");
    -            continue;
    -        }
    -        lines.push(line);
    -        if lines.len() == max_line_count {
    -            println!("Maximum line count reached. Starting simulation.");
    -            return lines;
    -        }
    -    }
    -}
    -
    -fn parse_pattern(rows: Vec>) -> Board {
    -    // This function assumes that the input pattern in rows is in-bounds. If the pattern
    -    // is too large, this function will panic. get_pattern checks the size of the input,
    -    // so it is safe to call this function with its results.
    -
    -    let mut board = Board::new();
    -
    -    // The BASIC implementation puts the pattern roughly in the center of the board,
    -    // assuming that there are no blank rows at the beginning or end, or blanks entered
    -    // at the beginning or end of every row. It wouldn't be hard to check for that, but
    -    // for now we'll preserve the original behavior.
    -    let nrows = rows.len();
    -    // If rows is empty, the call to max will return None. The unwrap_or then provides a
    -    // default value
    -    let ncols = rows.iter().map(|l| l.len()).max().unwrap_or(0);
    -
    -    // The min and max values here are unsigned. If nrows >= 24 or ncols >= 68, these
    -    // assignments will panic - they do not wrap around unless we use a function with
    -    // that specific behavior. Again, we expect bounds checking on the input before this
    -    // function is called.
    -    board.min_row = 11 - nrows / 2;
    -    board.min_col = 33 - ncols / 2;
    -    board.max_row = board.min_row + nrows - 1;
    -    board.max_col = board.min_col + ncols - 1;
    -
    -    // Loop over the rows provided. enumerate() augments the iterator with an index.
    -    for (row_index, pattern) in rows.iter().enumerate() {
    -        let row = board.min_row + row_index;
    -        // Now loop over the non-empty cells in the current row. filter_map takes a
    -        // closure that returns an Option. If the Option is None, filter_map filters out
    -        // that entry from the for loop. If it's Some(x), filter_map executes the loop
    -        // body with the value x.
    -        for col in pattern.iter().enumerate().filter_map(|(col_index, chr)| {
    -            if *chr == ' ' || (*chr == '.' && col_index == 0) {
    -                None
    -            } else {
    -                Some(board.min_col + col_index)
    -            }
    -        }) {
    -            board.cells[row][col] = CellState::Alive;
    -            board.population += 1;
    -        }
    -    }
    -
    -    board
    -}
    -
    -fn finish_cell_transitions(board: &mut Board) {
    -    // In the BASIC implementation, this happens in the same loop that prints the board.
    -    // We're breaking it out to improve separation of concerns.
    -    let mut min_row = HEIGHT - 1;
    -    let mut max_row = 0usize;
    -    let mut min_col = WIDTH - 1;
    -    let mut max_col = 0usize;
    -    for row_index in board.min_row-1..=board.max_row+1 {
    -        let mut any_alive_this_row = false;
    -        for col_index in board.min_col-1..=board.max_col+1 {
    -            let cell = &mut board.cells[row_index][col_index];
    -            if *cell == CellState::AboutToBeBorn {
    -                *cell = CellState::Alive;
    -                board.population += 1;
    -            } else if *cell == CellState::AboutToDie {
    -                *cell = CellState::Empty;
    -                board.population -= 1;
    -            }
    -            if *cell == CellState::Alive {
    -                any_alive_this_row = true;
    -                min_col = cmp::min(min_col, col_index);
    -                max_col = cmp::max(max_col, col_index);
    -            }
    -        }
    -        if any_alive_this_row {
    -            min_row = cmp::min(min_row, row_index);
    -            max_row = cmp::max(max_row, row_index);
    -    }
    -    }
    -    // If anything is alive within two cells of the boundary, mark the board invalid and
    -    // clamp the bounds. We need a two-cell margin because we'll count neighbors on cells
    -    // one space outside the min/max, and when we count neighbors we go out by an
    -    // additional space.
    -    if min_row < 2 {
    -        min_row = 2;
    -        board.invalid = true;
    -    }
    -    if max_row > HEIGHT - 3 {
    -        max_row = HEIGHT - 3;
    -        board.invalid = true;
    -    }
    -    if min_col < 2 {
    -        min_col = 2;
    -        board.invalid = true;
    -    }
    -    if max_col > WIDTH - 3 {
    -        max_col = WIDTH - 3;
    -        board.invalid = true;
    -    }
    -
    -    board.min_row = min_row;
    -    board.max_row = max_row;
    -    board.min_col = min_col;
    -    board.max_col = max_col;
    -}
    -
    -fn print_board(board: &Board) {
    -    println!(); println!(); println!();
    -    print!("Generation: {}  Population: {}", board.generation, board.population);
    -    if board.invalid {
    -        print!("  Invalid!");
    -    }
    -    println!();
    -    for row_index in 0..HEIGHT {
    -        for col_index in 0..WIDTH {
    -            // This print uses the Display implementation for cell_state, above.
    -            print!("{}", board.cells[row_index][col_index]);
    -        }
    -        println!();
    -    }
    -}
    -
    -fn count_neighbors(board: &Board, row_index: usize, col_index: usize) -> i32 {
    -    // Simply loop over all the immediate neighbors of a cell. We assume that the row and
    -    // column indices are not on (or outside) the boundary of the arrays; if they are,
    -    // the function will panic instead of going out of bounds.
    -    let mut count = 0;
    -    for i in row_index-1..=row_index+1 {
    -        for j in col_index-1..=col_index+1 {
    -            if i == row_index && j == col_index {
    -                continue;
    -            }
    -            if board.cells[i][j] == CellState::Alive || board.cells[i][j] == CellState::AboutToDie {
    -                count += 1;
    -            }
    -        }
    -    }
    -    count
    -}
    -
    -fn mark_cell_transitions(board: &mut Board) {
    -    for row_index in board.min_row-1..=board.max_row+1 {
    -        for col_index in board.min_col-1..=board.max_col+1 {
    -            let neighbors = count_neighbors(board, row_index, col_index);
    -            // Borrow a mutable reference to the array cell
    -            let this_cell_state = &mut board.cells[row_index][col_index];
    -            *this_cell_state = match *this_cell_state {
    -                CellState::Empty if neighbors == 3 => CellState::AboutToBeBorn,
    -                CellState::Alive if !(2..=3).contains(&neighbors) => CellState::AboutToDie,
    -                _ => *this_cell_state,
    -            }
    -        }
    -    }
    -    board.generation += 1;
    -}
    -
    -fn delay() {
    -    thread::sleep(time::Duration::from_millis(500));
    -}
    diff --git a/55_Life/vbnet/Life.sln b/55_Life/vbnet/Life.sln
    deleted file mode 100644
    index 8feae1756..000000000
    --- a/55_Life/vbnet/Life.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 5d62487f6..000000000
    --- a/55_Life/vbnet/Life.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Life
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/56_Life_for_Two/README.md b/56_Life_for_Two/README.md
    index 5ce081d37..d880653d8 100644
    --- a/56_Life_for_Two/README.md
    +++ b/56_Life_for_Two/README.md
    @@ -6,7 +6,6 @@ There are two players; the game is played on a 5x5 board and each player has a s
     
     The # and * are regarded as the same except when deciding whether to generate a live cell. An empty cell having two `#` and one `*` for neighbors will generate a `#`, i.e. the live cell generated belongs to the player who has the majority of the 3 live cells surrounding the empty cell where life is to be generated, for example:
     
    -```
     |   | 1 | 2 | 3 | 4 | 5 |
     |:-:|:-:|:-:|:-:|:-:|:-:|
     | 1 |   |   |   |   |   |
    @@ -14,10 +13,9 @@ The # and * are regarded as the same except when deciding whether to generate a
     | 3 |   |   |   | # |   |
     | 4 |   |   | # |   |   |
     | 5 |   |   |   |   |   |
    -```
     
     A new cell will be generated at (3,3) which will be a `#` since there are two `#` and one `*` surrounding. The board will then become:
    -```
    +
     |   | 1 | 2 | 3 | 4 | 5 |
     |:-:|:-:|:-:|:-:|:-:|:-:|
     | 1 |   |   |   |   |   |
    @@ -25,8 +23,8 @@ A new cell will be generated at (3,3) which will be a `#` since there are two `#
     | 3 |   |   | # | # |   |
     | 4 |   |   |   |   |   |
     | 5 |   |   |   |   |   |
    -```
    -On the first move each player positions 3 pieces of life on the board by typing in the co-ordinates of the pieces. (In the event of the same cell being chosen by both players that cell is left empty.)
    +
    +On the first most each player positions 3 pieces of life on the board by typing in the co-ordinates of the pieces. (In the event of the same cell being chosen by both players that cell is left empty.)
     
     The board is then adjusted to the next generation and printed out.
     
    @@ -44,22 +42,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    -
    -Note: The original program has a bug. The instructions say that if both players
    -enter the same cell that the cell is set to 0 or empty. However, the original
    -Basic program tells the player "ILLEGAL COORDINATES" and makes another cell be entered,
    -giving a slightly unfair advantage to the 2nd player.
    -
    -The Perl verson of the program fixes the bug and follows the instructions.
    -
    -Note: The original code had "GOTO 800" but label 800 didn't exist; it should have gone to label 999.
    -The Basic program has been fixed.
    -
    -Note: The Basic program is written to assume it's being played on a Teletype, i.e. output is printed
    -on paper. To play on a terminal the input must not be echoed, which can be a challenge to do portably
    -and without tying the solution to a specific OS. Some versions may tell you how to do this, others might not.
    diff --git a/56_Life_for_Two/csharp/Board.cs b/56_Life_for_Two/csharp/Board.cs
    deleted file mode 100644
    index f3cb0329c..000000000
    --- a/56_Life_for_Two/csharp/Board.cs
    +++ /dev/null
    @@ -1,74 +0,0 @@
    -using System.Collections;
    -using System.Text;
    -
    -namespace LifeforTwo;
    -
    -internal class Board : IEnumerable
    -{
    -    private readonly Piece[,] _cells = new Piece[7, 7];
    -    private readonly Dictionary _cellCounts = 
    -        new() { [Piece.None] = 0, [Piece.Player1] = 0, [Piece.Player2] = 0 };
    -
    -    public Piece this[Coordinates coordinates]
    -    {
    -        get => this[coordinates.X, coordinates.Y];
    -        set => this[coordinates.X, coordinates.Y] = value;
    -    }
    -
    -    private Piece this[int x, int y]
    -    {
    -        get => _cells[x, y];
    -        set
    -        {
    -            if (!_cells[x, y].IsEmpty) { _cellCounts[_cells[x, y]] -= 1; }
    -            _cells[x, y] = value;
    -            _cellCounts[value] += 1;
    -        }
    -    }
    -
    -    public int Player1Count => _cellCounts[Piece.Player1];
    -    public int Player2Count => _cellCounts[Piece.Player2];
    -
    -    internal bool IsEmptyAt(Coordinates coordinates) => this[coordinates].IsEmpty;
    -
    -    internal void ClearCell(Coordinates coordinates) => this[coordinates] = Piece.NewNone();
    -    internal void AddPlayer1Piece(Coordinates coordinates) => this[coordinates] = Piece.NewPlayer1();
    -    internal void AddPlayer2Piece(Coordinates coordinates) => this[coordinates] = Piece.NewPlayer2();
    -
    -    public override string ToString()
    -    {
    -        var builder = new StringBuilder();
    -
    -        for (var y = 0; y <= 6; y++)
    -        {
    -            builder.AppendLine();
    -            for (var x = 0; x <= 6; x++)
    -            {
    -                builder.Append(GetCellDisplay(x, y));
    -            }
    -        }
    -
    -        return builder.ToString();
    -    }
    -
    -    private string GetCellDisplay(int x, int y) =>
    -        (x, y) switch
    -        {
    -            (0 or 6, _) => $" {y % 6} ",
    -            (_, 0 or 6) => $" {x % 6} ",
    -            _ => $" {this[x, y]} "
    -        };
    -
    -    public IEnumerator GetEnumerator()
    -    {
    -        for (var x = 1; x <= 5; x++)
    -        {
    -            for (var y = 1; y <= 5; y++)
    -            {
    -                yield return new(x, y);
    -            }
    -        }
    -    }
    -
    -    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
    -}
    diff --git a/56_Life_for_Two/csharp/Coordinates.cs b/56_Life_for_Two/csharp/Coordinates.cs
    deleted file mode 100644
    index 09bd3dd4a..000000000
    --- a/56_Life_for_Two/csharp/Coordinates.cs
    +++ /dev/null
    @@ -1,31 +0,0 @@
    -namespace LifeforTwo;
    -
    -internal record Coordinates (int X, int Y)
    -{
    -    public static bool TryCreate((float X, float Y) values, out Coordinates coordinates)
    -    {
    -        if (values.X <= 0 || values.X > 5 || values.Y <= 0 || values.Y > 5)
    -        {
    -            coordinates = new(0, 0);
    -            return false;
    -        }
    -
    -        coordinates = new((int)values.X, (int)values.Y);
    -        return true;
    -    }
    -
    -    public static Coordinates operator +(Coordinates coordinates, int value) =>
    -        new (coordinates.X + value, coordinates.Y + value);
    -
    -    public IEnumerable GetNeighbors()
    -    {
    -        yield return new(X - 1, Y);
    -        yield return new(X + 1, Y);
    -        yield return new(X, Y - 1);
    -        yield return new(X, Y + 1);
    -        yield return new(X - 1, Y - 1);
    -        yield return new(X + 1, Y - 1);
    -        yield return new(X - 1, Y + 1);
    -        yield return new(X + 1, Y + 1);
    -    }
    -}
    diff --git a/56_Life_for_Two/csharp/Game.cs b/56_Life_for_Two/csharp/Game.cs
    deleted file mode 100644
    index de6cb5a5f..000000000
    --- a/56_Life_for_Two/csharp/Game.cs
    +++ /dev/null
    @@ -1,26 +0,0 @@
    -internal class Game
    -{
    -    private readonly IReadWrite _io;
    -
    -    public Game(IReadWrite io)
    -    {
    -        _io = io;
    -    }
    -
    -    public void Play()
    -    {
    -        _io.Write(Streams.Title);
    -
    -        var life = new Life(_io);
    -
    -        _io.Write(life.FirstGeneration);
    -
    -        foreach (var generation in life)
    -        {
    -            _io.WriteLine();
    -            _io.Write(generation);
    -        }
    -
    -        _io.WriteLine(life.Result ?? "No result");
    -    }
    -}
    diff --git a/56_Life_for_Two/csharp/Generation.cs b/56_Life_for_Two/csharp/Generation.cs
    deleted file mode 100644
    index b96ee4786..000000000
    --- a/56_Life_for_Two/csharp/Generation.cs
    +++ /dev/null
    @@ -1,89 +0,0 @@
    -internal class Generation
    -{
    -    private readonly Board _board;
    -
    -    public Generation(Board board)
    -    {
    -        _board = board;
    -        CountNeighbours();
    -    }
    -
    -    public Board Board => _board;
    -
    -    public int Player1Count => _board.Player1Count;
    -    public int Player2Count => _board.Player2Count;
    -
    -    public string? Result => 
    -        (Player1Count, Player2Count) switch
    -        {
    -            (0, 0) => Strings.Draw,
    -            (_, 0) => string.Format(Formats.Winner, 1),
    -            (0, _) => string.Format(Formats.Winner, 2),
    -            _ => null
    -        };
    -
    -    public static Generation Create(IReadWrite io)
    -    {
    -        var board = new Board();
    -
    -        SetInitialPieces(1, coord => board.AddPlayer1Piece(coord));
    -        SetInitialPieces(2, coord => board.AddPlayer2Piece(coord));
    -
    -        return new Generation(board);
    -
    -        void SetInitialPieces(int player, Action setPiece)
    -        {
    -            io.WriteLine(Formats.InitialPieces, player);
    -            for (var i = 1; i <= 3; i++)
    -            {
    -                setPiece(io.ReadCoordinates(board));
    -            }
    -        }
    -    }
    -
    -    public Generation CalculateNextGeneration()
    -    {
    -        var board = new Board();
    -
    -        foreach (var coordinates in _board)
    -        {
    -            board[coordinates] = _board[coordinates].GetNext();
    -        }
    -
    -        return new(board);
    -    }
    -    
    -    public void AddPieces(IReadWrite io)
    -    {
    -        var player1Coordinate = io.ReadCoordinates(1, _board);
    -        var player2Coordinate = io.ReadCoordinates(2, _board);
    -
    -        if (player1Coordinate == player2Coordinate)
    -        {
    -            io.Write(Streams.SameCoords);
    -            // This is a bug existing in the original code. The line should be _board[_coordinates[_player]] = 0;
    -            _board.ClearCell(player1Coordinate + 1);
    -        }
    -        else
    -        {
    -            _board.AddPlayer1Piece(player1Coordinate);
    -            _board.AddPlayer2Piece(player2Coordinate);
    -        }
    -    }
    -
    -    private void CountNeighbours()
    -    {
    -        foreach (var coordinates in _board)
    -        {
    -            var piece = _board[coordinates];
    -            if (piece.IsEmpty) { continue; }
    -
    -            foreach (var neighbour in coordinates.GetNeighbors())
    -            {
    -                _board[neighbour] = _board[neighbour].AddNeighbour(piece);
    -            }
    -        }
    -    }
    -
    -    public override string ToString() => _board.ToString();
    -}
    \ No newline at end of file
    diff --git a/56_Life_for_Two/csharp/IOExtensions.cs b/56_Life_for_Two/csharp/IOExtensions.cs
    deleted file mode 100644
    index d7db9bf49..000000000
    --- a/56_Life_for_Two/csharp/IOExtensions.cs
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -internal static class IOExtensions
    -{
    -    internal static Coordinates ReadCoordinates(this IReadWrite io, int player, Board board)
    -    {
    -        io.Write(Formats.Player, player);
    -        return io.ReadCoordinates(board);
    -    }
    -
    -    internal static Coordinates ReadCoordinates(this IReadWrite io, Board board)
    -    {
    -        while (true)
    -        {
    -            io.WriteLine("X,Y");
    -            var values = io.Read2Numbers("&&&&&&\r");
    -            if (Coordinates.TryCreate(values, out var coordinates) && board.IsEmptyAt(coordinates))
    -            {
    -                return coordinates;
    -            }
    -            io.Write(Streams.IllegalCoords);
    -        }
    -    }
    -}
    \ No newline at end of file
    diff --git a/56_Life_for_Two/csharp/Life.cs b/56_Life_for_Two/csharp/Life.cs
    deleted file mode 100644
    index 7848a3487..000000000
    --- a/56_Life_for_Two/csharp/Life.cs
    +++ /dev/null
    @@ -1,31 +0,0 @@
    -using System.Collections;
    -
    -internal class Life : IEnumerable
    -{
    -    private readonly IReadWrite _io;
    -
    -    public Life(IReadWrite io)
    -    {
    -        _io = io;
    -        FirstGeneration = Generation.Create(io);
    -    }
    -
    -    public Generation FirstGeneration { get; }
    -    public string? Result { get; private set; }
    -    
    -    public IEnumerator GetEnumerator()
    -    {
    -        var current = FirstGeneration;
    -        while (current.Result is null)
    -        {
    -            current = current.CalculateNextGeneration();
    -            yield return current;
    -
    -            if (current.Result is null) { current.AddPieces(_io); }
    -        }
    -
    -        Result = current.Result;
    -    }
    -
    -    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); 
    -}
    \ No newline at end of file
    diff --git a/56_Life_for_Two/csharp/LifeforTwo.csproj b/56_Life_for_Two/csharp/LifeforTwo.csproj
    deleted file mode 100644
    index 3870320c9..000000000
    --- a/56_Life_for_Two/csharp/LifeforTwo.csproj
    +++ /dev/null
    @@ -1,17 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    -  
    -    
    -  
    -
    -  
    -    
    -  
    -
    diff --git a/56_Life_for_Two/csharp/LifeforTwo.sln b/56_Life_for_Two/csharp/LifeforTwo.sln
    deleted file mode 100644
    index 7a5585cb5..000000000
    --- a/56_Life_for_Two/csharp/LifeforTwo.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/csharp/Piece.cs b/56_Life_for_Two/csharp/Piece.cs
    deleted file mode 100644
    index 20e5adba0..000000000
    --- a/56_Life_for_Two/csharp/Piece.cs
    +++ /dev/null
    @@ -1,54 +0,0 @@
    -using System.Collections.Immutable;
    -using System.Diagnostics.CodeAnalysis;
    -
    -namespace LifeforTwo;
    -
    -public struct Piece
    -{
    -    public const int None = 0x0000;
    -    public const int Player1 = 0x0100;
    -    public const int Player2 = 0x1000;
    -    private const int PieceMask = Player1 | Player2;
    -    private const int NeighbourValueOffset = 8;
    -
    -    private static readonly ImmutableHashSet _willBePlayer1 = 
    -        new[] { 0x0003, 0x0102, 0x0103, 0x0120, 0x0130, 0x0121, 0x0112, 0x0111, 0x0012 }.ToImmutableHashSet();
    -    private static readonly ImmutableHashSet _willBePlayer2 = 
    -        new[] { 0x0021, 0x0030, 0x1020, 0x1030, 0x1011, 0x1021, 0x1003, 0x1002, 0x1012 }.ToImmutableHashSet();
    -
    -    private int _value;
    -
    -    private Piece(int value) => _value = value;
    -
    -    public int Value => _value & PieceMask;
    -    public bool IsEmpty => (_value & PieceMask) == None;
    -
    -    public static Piece NewNone() => new(None);
    -    public static Piece NewPlayer1() => new(Player1);
    -    public static Piece NewPlayer2() => new(Player2);
    -
    -    public Piece AddNeighbour(Piece neighbour)
    -    {
    -        _value += neighbour.Value >> NeighbourValueOffset;
    -        return this;
    -    }
    -
    -    public Piece GetNext() => new(
    -        _value switch
    -        {
    -            _ when _willBePlayer1.Contains(_value) => Player1,
    -            _ when _willBePlayer2.Contains(_value) => Player2,
    -            _ => None
    -        });
    -
    -    public override string ToString() =>
    -        (_value & PieceMask) switch
    -        {
    -            Player1 => "*",
    -            Player2 => "#",
    -            _ => " "
    -        };
    -
    -    public static implicit operator Piece(int value) => new(value);
    -    public static implicit operator int(Piece piece) => piece.Value;
    -}
    \ No newline at end of file
    diff --git a/56_Life_for_Two/csharp/Program.cs b/56_Life_for_Two/csharp/Program.cs
    deleted file mode 100644
    index 4c399811c..000000000
    --- a/56_Life_for_Two/csharp/Program.cs
    +++ /dev/null
    @@ -1,5 +0,0 @@
    -global using Games.Common.IO;
    -global using static LifeforTwo.Resources.Resource;
    -global using LifeforTwo;
    -
    -new Game(new ConsoleIO()).Play();
    diff --git a/56_Life_for_Two/csharp/Resources/Draw.txt b/56_Life_for_Two/csharp/Resources/Draw.txt
    deleted file mode 100644
    index 9b9fd8fc8..000000000
    --- a/56_Life_for_Two/csharp/Resources/Draw.txt
    +++ /dev/null
    @@ -1,2 +0,0 @@
    -
    -A draw
    \ No newline at end of file
    diff --git a/56_Life_for_Two/csharp/Resources/IllegalCoords.txt b/56_Life_for_Two/csharp/Resources/IllegalCoords.txt
    deleted file mode 100644
    index ff01dfcbf..000000000
    --- a/56_Life_for_Two/csharp/Resources/IllegalCoords.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Illegal coords. Retype
    diff --git a/56_Life_for_Two/csharp/Resources/InitialPieces.txt b/56_Life_for_Two/csharp/Resources/InitialPieces.txt
    deleted file mode 100644
    index abbadf16e..000000000
    --- a/56_Life_for_Two/csharp/Resources/InitialPieces.txt
    +++ /dev/null
    @@ -1,2 +0,0 @@
    -
    -Player {0}  - 3 live pieces
    \ No newline at end of file
    diff --git a/56_Life_for_Two/csharp/Resources/Player.txt b/56_Life_for_Two/csharp/Resources/Player.txt
    deleted file mode 100644
    index f920e489d..000000000
    --- a/56_Life_for_Two/csharp/Resources/Player.txt
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -
    -
    -Player {0} 
    \ No newline at end of file
    diff --git a/56_Life_for_Two/csharp/Resources/Resource.cs b/56_Life_for_Two/csharp/Resources/Resource.cs
    deleted file mode 100644
    index c6f59d3b9..000000000
    --- a/56_Life_for_Two/csharp/Resources/Resource.cs
    +++ /dev/null
    @@ -1,37 +0,0 @@
    -using System.Reflection;
    -using System.Runtime.CompilerServices;
    -
    -namespace LifeforTwo.Resources;
    -
    -internal static class Resource
    -{
    -    internal static class Streams
    -    {
    -        public static Stream Title => GetStream();
    -        public static Stream IllegalCoords => GetStream();
    -        public static Stream SameCoords => GetStream();
    -    }
    -
    -    internal static class Formats
    -    {
    -        public static string InitialPieces => GetString();
    -        public static string Player => GetString();
    -        public static string Winner => GetString();
    -    }
    -
    -    internal static class Strings
    -    {
    -        public static string Draw => GetString();
    -    }
    -
    -    private static string GetString([CallerMemberName] string? name = null)
    -    {
    -        using var stream = GetStream(name);
    -        using var reader = new StreamReader(stream);
    -        return reader.ReadToEnd();
    -    }
    -
    -    private static Stream GetStream([CallerMemberName] string? name = null) =>
    -        Assembly.GetExecutingAssembly().GetManifestResourceStream($"{typeof(Resource).Namespace}.{name}.txt")
    -            ?? throw new Exception($"Could not find embedded resource stream '{name}'.");
    -}
    \ No newline at end of file
    diff --git a/56_Life_for_Two/csharp/Resources/SameCoords.txt b/56_Life_for_Two/csharp/Resources/SameCoords.txt
    deleted file mode 100644
    index 8af7b066d..000000000
    --- a/56_Life_for_Two/csharp/Resources/SameCoords.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Same coord.  Set to 0
    diff --git a/56_Life_for_Two/csharp/Resources/Title.txt b/56_Life_for_Two/csharp/Resources/Title.txt
    deleted file mode 100644
    index 0e3404a72..000000000
    --- a/56_Life_for_Two/csharp/Resources/Title.txt
    +++ /dev/null
    @@ -1,6 +0,0 @@
    -                                 Life2
    -               Creative Computing  Morristown, New Jersey
    -
    -
    -
    -          U.B. Life Game
    diff --git a/56_Life_for_Two/csharp/Resources/Winner.txt b/56_Life_for_Two/csharp/Resources/Winner.txt
    deleted file mode 100644
    index e35c54407..000000000
    --- a/56_Life_for_Two/csharp/Resources/Winner.txt
    +++ /dev/null
    @@ -1,2 +0,0 @@
    -
    -Player {0} is the winner
    \ No newline at end of file
    diff --git a/56_Life_for_Two/java/LifeForTwo.java b/56_Life_for_Two/java/LifeForTwo.java
    deleted file mode 100644
    index 1f68e7944..000000000
    --- a/56_Life_for_Two/java/LifeForTwo.java
    +++ /dev/null
    @@ -1,305 +0,0 @@
    -import java.util.*;
    -import java.util.stream.IntStream;
    -
    -/**
    - * Life for Two
    - * 

    - * The original BASIC program uses a grid with an extras border of cells all around, - * probably to simplify calculations and manipulations. This java program has the exact - * grid size and instead uses boundary check conditions in the logic. - *

    - * Converted from BASIC to Java by Aldrin Misquitta (@aldrinm) - */ -public class LifeForTwo { - - final static int GRID_SIZE = 5; - - //Pair of offset which when added to the current cell's coordinates, - // give the coordinates of the neighbours - final static int[] neighbourCellOffsets = { - -1, 0, - 1, 0, - 0, -1, - 0, 1, - -1, -1, - 1, -1, - -1, 1, - 1, 1 - }; - - //The best term that I could come with to describe these numbers was 'masks' - //They act like indicators to decide which player won the cell. The value is the score of the cell after all the - // generation calculations. - final static List maskPlayer1 = List.of(3, 102, 103, 120, 130, 121, 112, 111, 12); - final static List maskPlayer2 = List.of(21, 30, 1020, 1030, 1011, 1021, 1003, 1002, 1012); - - public static void main(String[] args) { - printIntro(); - Scanner scan = new Scanner(System.in); - scan.useDelimiter("\\D"); - - int[][] grid = new int[GRID_SIZE][GRID_SIZE]; - - initializeGrid(grid); - - //Read the initial 3 moves for each player - for (int b = 1; b <= 2; b++) { - System.out.printf("\nPLAYER %d - 3 LIVE PIECES.%n", b); - for (int k1 = 1; k1 <= 3; k1++) { - var player1Coordinates = readUntilValidCoordinates(scan, grid); - grid[player1Coordinates.x - 1][player1Coordinates.y - 1] = (b == 1 ? 3 : 30); - } - } - - printGrid(grid); - - calculatePlayersScore(grid); //Convert 3, 30 to 100, 1000 - - resetGridForNextGen(grid); - computeCellScoresForOneGen(grid); - - var playerScores = calculatePlayersScore(grid); - resetGridForNextGen(grid); - - boolean gameOver = false; - while (!gameOver) { - printGrid(grid); - if (playerScores.getPlayer1Score() == 0 && playerScores.getPlayer2Score() == 0) { - System.out.println("\nA DRAW"); - gameOver = true; - } else if (playerScores.getPlayer2Score() == 0) { - System.out.println("\nPLAYER 1 IS THE WINNER"); - gameOver = true; - } else if (playerScores.getPlayer1Score() == 0) { - System.out.println("\nPLAYER 2 IS THE WINNER"); - gameOver = true; - } else { - System.out.print("PLAYER 1 "); - Coordinate player1Move = readCoordinate(scan); - System.out.print("PLAYER 2 "); - Coordinate player2Move = readCoordinate(scan); - if (!player1Move.equals(player2Move)) { - grid[player1Move.x - 1][player1Move.y - 1] = 100; - grid[player2Move.x - 1][player2Move.y - 1] = 1000; - } - //In the original, B is assigned 99 when both players choose the same cell - //and that is used to control the flow - computeCellScoresForOneGen(grid); - playerScores = calculatePlayersScore(grid); - resetGridForNextGen(grid); - } - } - - } - - private static void initializeGrid(int[][] grid) { - for (int[] row : grid) { - Arrays.fill(row, 0); - } - } - - private static void computeCellScoresForOneGen(int[][] grid) { - for (int i = 0; i < GRID_SIZE; i++) { - for (int j = 0; j < GRID_SIZE; j++) { - if (grid[i][j] >= 100) { - calculateScoreForOccupiedCell(grid, i, j); - } - } - } - } - - private static Scores calculatePlayersScore(int[][] grid) { - int m2 = 0; - int m3 = 0; - for (int i = 0; i < GRID_SIZE; i++) { - for (int j = 0; j < GRID_SIZE; j++) { - if (grid[i][j] < 3) { - grid[i][j] = 0; - } else { - if (maskPlayer1.contains(grid[i][j])) { - m2++; - } else if (maskPlayer2.contains(grid[i][j])) { - m3++; - } - } - } - } - return new Scores(m2, m3); - } - - private static void resetGridForNextGen(int[][] grid) { - for (int i = 0; i < GRID_SIZE; i++) { - for (int j = 0; j < GRID_SIZE; j++) { - if (grid[i][j] < 3) { - grid[i][j] = 0; - } else { - if (maskPlayer1.contains(grid[i][j])) { - grid[i][j] = 100; - } else if (maskPlayer2.contains(grid[i][j])) { - grid[i][j] = 1000; - } else { - grid[i][j] = 0; - } - } - } - } - } - - private static void calculateScoreForOccupiedCell(int[][] grid, int i, int j) { - var b = 1; - if (grid[i][j] > 999) { - b = 10; - } - for (int k = 0; k < 15; k += 2) { - //check bounds - var neighbourX = i + neighbourCellOffsets[k]; - var neighbourY = j + neighbourCellOffsets[k + 1]; - if (neighbourX >= 0 && neighbourX < GRID_SIZE && - neighbourY >= 0 && neighbourY < GRID_SIZE) { - grid[neighbourX][neighbourY] = grid[neighbourX][neighbourY] + b; - } - - } - } - - private static void printGrid(int[][] grid) { - System.out.println(); - printRowEdge(); - System.out.println(); - for (int i = 0; i < grid.length; i++) { - System.out.printf("%d ", i + 1); - for (int j = 0; j < grid[i].length; j++) { - System.out.printf(" %c ", mapChar(grid[i][j])); - } - System.out.printf(" %d", i + 1); - System.out.println(); - } - printRowEdge(); - System.out.println(); - } - - private static void printRowEdge() { - System.out.print("0 "); - IntStream.range(1, GRID_SIZE + 1).forEach(i -> System.out.printf(" %s ", i)); - System.out.print(" 0"); - } - - private static char mapChar(int i) { - if (i == 3 || i == 100) { - return '*'; - } - if (i == 30 || i == 1000) { - return '#'; - } - return ' '; - } - - private static Coordinate readUntilValidCoordinates(Scanner scanner, int[][] grid) { - boolean coordinateInRange = false; - Coordinate coordinate = null; - while (!coordinateInRange) { - coordinate = readCoordinate(scanner); - if (coordinate.x <= 0 || coordinate.x > GRID_SIZE - || coordinate.y <= 0 || coordinate.y > GRID_SIZE - || grid[coordinate.x - 1][coordinate.y - 1] != 0) { - System.out.println("ILLEGAL COORDS. RETYPE"); - } else { - coordinateInRange = true; - } - } - return coordinate; - } - - private static Coordinate readCoordinate(Scanner scanner) { - Coordinate coordinate = null; - int x, y; - boolean valid = false; - - System.out.println("X,Y"); - System.out.print("XXXXXX\r"); - System.out.print("$$$$$$\r"); - System.out.print("&&&&&&\r"); - - while (!valid) { - try { - System.out.print("? "); - y = scanner.nextInt(); - x = scanner.nextInt(); - valid = true; - coordinate = new Coordinate(x, y); - } catch (InputMismatchException e) { - System.out.println("!NUMBER EXPECTED - RETRY INPUT LINE"); - valid = false; - } finally { - scanner.nextLine(); - } - } - return coordinate; - } - - private static void printIntro() { - System.out.println(" LIFE2"); - System.out.println(" CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); - System.out.println("\n\n"); - - System.out.println("\tU.B. LIFE GAME"); - } - - private static class Coordinate { - private final int x, y; - - public Coordinate(int x, int y) { - this.x = x; - this.y = y; - } - - public int getX() { - return x; - } - - public int getY() { - return y; - } - - @Override - public String toString() { - return "Coordinate{" + - "x=" + x + - ", y=" + y + - '}'; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Coordinate that = (Coordinate) o; - return x == that.x && y == that.y; - } - - @Override - public int hashCode() { - return Objects.hash(x, y); - } - } - - private static class Scores { - private final int player1Score; - private final int player2Score; - - public Scores(int player1Score, int player2Score) { - this.player1Score = player1Score; - this.player2Score = player2Score; - } - - public int getPlayer1Score() { - return player1Score; - } - - public int getPlayer2Score() { - return player2Score; - } - } - - -} diff --git a/56_Life_for_Two/javascript/lifefortwo.html b/56_Life_for_Two/javascript/lifefortwo.html index c5c490d7a..fbd706364 100644 --- a/56_Life_for_Two/javascript/lifefortwo.html +++ b/56_Life_for_Two/javascript/lifefortwo.html @@ -1,10 +1,9 @@ LIFE FOR TWO - -

    
    +
    
     
     
     
    diff --git a/56_Life_for_Two/javascript/lifefortwo.js b/56_Life_for_Two/javascript/lifefortwo.js
    index a38a0af8d..a8c90e50c 100644
    --- a/56_Life_for_Two/javascript/lifefortwo.js
    +++ b/56_Life_for_Two/javascript/lifefortwo.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/56_Life_for_Two/kotlin/README.md b/56_Life_for_Two/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/56_Life_for_Two/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/56_Life_for_Two/lifefortwo.bas b/56_Life_for_Two/lifefortwo.bas
    index 4faf1f127..e970ef6df 100644
    --- a/56_Life_for_Two/lifefortwo.bas
    +++ b/56_Life_for_Two/lifefortwo.bas
    @@ -60,8 +60,8 @@
     571 IF M3=0 THEN B=1: GOTO 575
     572 IF M2=0 THEN B=2: GOTO 575
     573 GOTO 580
    -574 PRINT: PRINT "A DRAW":GOTO 999
    -575 PRINT: PRINT "PLAYER";B;"IS THE WINNER":GOTO 999
    +574 PRINT: PRINT "A DRAW":GOTO 800
    +575 PRINT: PRINT "PLAYER";B;"IS THE WINNER":GOTO 800
     580 FOR B=1 TO 2: PRINT: PRINT: PRINT "PLAYER";B;: GOSUB 700
     581 IF B=99 THEN 560
     582 NEXT B
    diff --git a/56_Life_for_Two/lua/README.md b/56_Life_for_Two/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/56_Life_for_Two/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/56_Life_for_Two/pascal/README.md b/56_Life_for_Two/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/56_Life_for_Two/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/56_Life_for_Two/perl/README.md b/56_Life_for_Two/perl/README.md
    index 7b3b41a3c..e69c8b819 100644
    --- a/56_Life_for_Two/perl/README.md
    +++ b/56_Life_for_Two/perl/README.md
    @@ -1,21 +1,3 @@
     Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
     
     Conversion to [Perl](https://www.perl.org/)
    -
    -Note: The original program has a bug (see the README in the above dir). This Perl version fixes it.
    -
    -Note: For input, the X value is to the right while the Y value is down.
    -Therefore, the top right cell is "5,1", not "1,5".
    -
    -The original program was made to be played on a Teletype, i.e. a printer on paper.
    -That allowed the program to "black out" the input line to hide a user's input from his/her
    -opponent, assuming the opponent was at least looking away. To do the equivalent on a
    -terminal would require a Perl module that isn't installed by default (i.e. it is not
    -part of CORE and would also require a C compiler to install), nor do I want to issue a
    -shell command to "stty" to hide the input because that would restrict the game to Linux/Unix.
    -This means it would have to be played on the honor system.
    -
    -However, if you want to try it, install the module "Term::ReadKey" ("sudo cpan -i Term::ReadKey"
    -if on Linux/Unix and you have root access). If the code finds that module, it will automatically
    -use it and hide the input ... and restore echoing input again when the games ends. If the module
    -is not found, input will be visible.
    diff --git a/56_Life_for_Two/perl/lifefortwo.pl b/56_Life_for_Two/perl/lifefortwo.pl
    deleted file mode 100644
    index 0c50cdef7..000000000
    --- a/56_Life_for_Two/perl/lifefortwo.pl
    +++ /dev/null
    @@ -1,215 +0,0 @@
    -#!/usr/bin/perl
    -
    -# Life_For_Two program in Perl
    -#   Required extensive restructuring to remove all of the GOTO's.
    -# Translated by Kevin Brannen (kbrannen)
    -
    -use strict;
    -use warnings;
    -
    -# try to load module to hide input, set RKey to true if found
    -my $Rkey = eval { require Term::ReadKey } // 0;
    -END { Term::ReadKey::ReadMode('normal') if ($Rkey); }
    -
    -# globals
    -my @Board;      # 2D board
    -my @X;          # ?
    -my @Y;          # ?
    -my $Player;     # 1 or 2
    -my $M2 = 0;     # ?
    -my $M3 = 0;     # ?
    -
    -# add 0 on front to make data 1 based
    -my @K = (0,3,102,103,120,130,121,112,111,12,21,30,1020,1030,1011,1021,1003,1002,1012);
    -my @A = (0,-1,0,1,0,0,-1,0,1,-1,-1,1,-1,-1,1,1,1);
    -
    -print "\n";
    -print " " x 33, "LIFE2\n";
    -print " " x 15, "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n";
    -print " " x 10, "U.B. LIFE GAME\n";
    -for my $j (1 .. 5) { for my $k (1 .. 5) { $Board[$j][$k] = 0; } }
    -
    -for (1 .. 2)
    -{
    -    $Player = $_; # if we make $Player the loop var, the global isn't set
    -    my $p1 = ($Player == 2) ? 30 : 3;
    -    print "\nPLAYER $Player - 3 LIVE PIECES.\n";
    -    for (1 .. 3)
    -    {
    -        get_input();
    -        $Board[$X[$Player]][$Y[$Player]] = $p1 if ($Player != 99);
    -    }
    -}
    -print_board(); # print board after initial input
    -
    -while (1)
    -{
    -    print "\n";
    -    calc_board();  # calc new positions
    -    print_board(); # print current board after calc
    -
    -    if ($M2 == 0 && $M3 == 0)
    -    {
    -        print "\nA DRAW\n";
    -        last;
    -    }
    -    if ($M3 == 0)
    -    {
    -        win(1);
    -        last;
    -    }
    -    if ($M2 == 0)
    -    {
    -        win(2);
    -        last;
    -    }
    -
    -    for (1 .. 2)
    -    {
    -        $Player = $_; # if we make $Player the loop var, the global isn't set
    -        print "\n\nPLAYER $Player ";
    -        get_input();
    -        last if ($Player == 99);
    -    }
    -    next if ($Player == 99);
    -
    -    $Board[$X[1]][$Y[1]] = 100;
    -    $Board[$X[2]][$Y[2]] = 1000;
    -}
    -exit(0);
    -
    -###########################################################
    -
    -sub win
    -{
    -    my $p = shift;
    -    print "\nPLAYER $p IS THE WINNER\n";
    -}
    -
    -sub calc_board
    -{
    -    for my $j (1 .. 5)
    -    {
    -        for my $k (1 .. 5)
    -        {
    -            if ($Board[$j][$k] > 99)
    -            {
    -                $Player = $Board[$j][$k] > 999 ? 10 : 1;
    -                for (my $c = 1 ; $c <= 15 ; $c += 2)
    -                {
    -                    $Board[$j+$A[$c]][$k+$A[$c+1]] = ($Board[$j+$A[$c]][$k+$A[$c+1]] // 0) + $Player;
    -                }
    -            }
    -        }
    -    }
    -}
    -
    -sub print_board
    -{
    -    $M2 = 0;
    -    $M3 = 0;
    -    for my $j (0 .. 6)
    -    {
    -        print "\n";
    -        for my $k (0 .. 6)
    -        {
    -            if ($j != 0 && $j != 6)
    -            {
    -                if ($k != 0 && $k != 6)
    -                {
    -                    print_row($j, $k);
    -                    next;
    -                }
    -                if ($j == 6)
    -                {
    -                    print "0\n";
    -                    return;
    -                }
    -                print " $j ";
    -            }
    -            else
    -            {
    -                if ($k == 6)
    -                {
    -                    print " 0 ";
    -                    last;
    -                }
    -                print " $k ";
    -            }
    -        }
    -    }
    -}
    -
    -sub print_row
    -{
    -    my ($j, $k) = @_;
    -
    -    if ($Board[$j][$k] >= 3)
    -    {
    -        my $c;
    -        for $c (1 .. 18)
    -        {
    -            if ($Board[$j][$k] == $K[$c])
    -            {
    -                if ($c <= 9)
    -                {
    -                    $Board[$j][$k] = 100;
    -                    $M2++;
    -                    print " * ";
    -                }
    -                else
    -                {
    -                    $Board[$j][$k] = 1000;
    -                    $M3++;
    -                    print " # ";
    -                }
    -                return;
    -            }
    -        }
    -    }
    -    $Board[$j][$k] = 0;
    -    print "   ";
    -}
    -
    -sub get_input
    -{
    -    while (1)
    -    {
    -        print "X,Y\n";
    -        my $ans;
    -
    -        if ($Rkey)
    -        {
    -            # code to hide input
    -            Term::ReadKey::ReadMode('noecho');
    -            $ans = Term::ReadKey::ReadLine(0);
    -            Term::ReadKey::ReadMode('restore');
    -            print "\n"; # do this since the one entered was hidden
    -        }
    -        else
    -        {
    -            # normal, input visible
    -            chomp($ans = <>);
    -        }
    -
    -        ($Y[$Player], $X[$Player]) = split(/[,\s]+/, $ans, 2);
    -        if ($X[$Player] > 5 || $X[$Player] < 1 || $Y[$Player] > 5 || $Y[$Player] < 1)
    -        {
    -            print "ILLEGAL COORDS. RETYPE\n";
    -            next;
    -        }
    -        # this tells you the cell was already taken not zero it out, bug!
    -        #if ($Board[$X[$Player]][$Y[$Player]] != 0)
    -        #{
    -        #    print "ILLEGAL COORDS. RETYPE\n";
    -        #    next;
    -        #}
    -        last;
    -    }
    -
    -    return if ($Player == 1 || $X[1] != $X[2] || $Y[1] != $Y[2]);
    -
    -    print "SAME COORD.  SET TO 0\n";
    -    $Board[$X[$Player]+1][$Y[$Player]+1] = 0;
    -    $Player = 99;
    -}
    diff --git a/56_Life_for_Two/python/life_for_two.py b/56_Life_for_Two/python/life_for_two.py
    deleted file mode 100644
    index c9910f994..000000000
    --- a/56_Life_for_Two/python/life_for_two.py
    +++ /dev/null
    @@ -1,157 +0,0 @@
    -'''
    -LIFE FOR TWO
    -
    -Competitive Game of Life (two or more players).
    -
    -Ported by Sajid Sarker (2022).
    -'''
    -
    -# Global Variable Initialisation
    -# Initialise the board
    -gn = [[0 for _ in range(6)] for _ in range(6)]
    -gx = [0 for _ in range(3)]
    -gy = [0 for _ in range(3)]
    -gk = [0, 3, 102, 103, 120, 130, 121,
    -      112, 111, 12, 21, 30, 1020, 1030,
    -      1011, 1021, 1003, 1002, 1012]
    -ga = [0, -1, 0, 1, 0, 0, -1, 0, 1, -1, -1, 1, -1, -1, 1, 1, 1]
    -m2 = 0
    -m3 = 0
    -
    -
    -# Helper Functions
    -def tab(number) -> str:
    -    t = ""
    -    while len(t) < number:
    -        t += " "
    -    return t
    -
    -
    -def display_header() -> None:
    -    print(f"{tab(33)}LIFE2")
    -    print(f"{tab(15)}CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n")
    -    print(f"{tab(10)}U.B. LIFE GAME")
    -
    -
    -# Board Functions
    -def setup_board() -> None:
    -    # Players add symbols to initially setup the board
    -    for b in range(1, 3):
    -        p1 = 3 if b != 2 else 30
    -        print(f"\nPLAYER {b} - 3 LIVE PIECES.")
    -        for _ in range(1, 4):
    -            query_player(b)
    -            gn[gx[b]][gy[b]] = p1
    -
    -
    -def modify_board() -> None:
    -    # Players take turns to add symbols and modify the board
    -    for b in range(1, 3):
    -        print(f"PLAYER {b} ")
    -        query_player(b)
    -        if b == 99:
    -            break
    -    if b <= 2:
    -        gn[gx[1]][gy[1]] = 100
    -        gn[gx[2]][gy[2]] = 1000
    -
    -
    -def simulate_board() -> None:
    -    # Simulate the board for one step
    -    for j in range(1, 6):
    -        for k in range(1, 6):
    -            if gn[j][k] > 99:
    -                b = 1 if gn[j][k] <= 999 else 10
    -                for o1 in range(1, 16, 2):
    -                    gn[j + ga[o1] - 1][k + ga[o1 + 1] - 1] += b
    -                    # gn[j+ga[o1]][k+ga[o1+1]-1] = gn[j+ga[o1]][k+ga[o1+1]]+b
    -
    -
    -def display_board() -> None:
    -    # Draws the board with all symbols
    -    m2, m3 = 0, 0
    -    for j in range(7):
    -        print("")
    -        for k in range(7):
    -            if j in [0, 6]:
    -                if k != 6:
    -                    print(f" {str(k)} ", end="")
    -                else:
    -                    print(" 0 ", end="")
    -            elif k in [0, 6]:
    -                print(f" {str(j)} ", end="")
    -            elif gn[j][k] < 3:
    -                gn[j][k] = 0
    -                print("   ", end="")
    -            else:
    -                for o1 in range(1, 19):
    -                    if gn[j][k] == gk[o1]:
    -                        break
    -                if o1 <= 18:
    -                    if o1 > 9:
    -                        gn[j][k] = 1000
    -                        m3 += 1
    -                        print(" # ", end="")
    -                    else:
    -                        gn[j][k] = 100
    -                        m2 += 1
    -                        print(" * ", end="")
    -                else:
    -                    gn[j][k] = 0
    -                    print("   ", end="")
    -
    -
    -# Player Functions
    -def query_player(b) -> None:
    -    # Query player for symbol placement coordinates
    -    while True:
    -        print("X,Y\nXXXXXX\n$$$$$$\n&&&&&&")
    -        a_ = input("??")
    -        b_ = input("???")
    -        x_ = [int(num) for num in a_.split() if num.isdigit()]
    -        y_ = [int(num) for num in b_.split() if num.isdigit()]
    -        x_ = [0] if not x_ else x_
    -        y_ = [0] if not y_ else y_
    -        gx[b] = y_[0]
    -        gy[b] = x_[0]
    -        if gx[b] in range(1, 6)\
    -                and gy[b] in range(1, 6)\
    -                and gn[gx[b]][gy[b]] == 0:
    -            break
    -        print("ILLEGAL COORDS. RETYPE")
    -    if b != 1:
    -        if gx[1] == gx[2] and gy[1] == gy[2]:
    -            print("SAME COORD. SET TO 0")
    -            gn[gx[b] + 1][gy[b] + 1] = 0
    -            b = 99
    -
    -
    -# Game Functions
    -def check_winner(m2, m3) -> None:
    -    # Check if the game has been won
    -    if m2 == 0 and m3 == 0:
    -        print("\nA DRAW\n")
    -        return
    -    if m3 == 0:
    -        print("\nPLAYER 1 IS THE WINNER\n")
    -        return
    -    if m2 == 0:
    -        print("\nPLAYER 2 IS THE WINNER\n")
    -        return
    -
    -
    -# Program Flow
    -def main() -> None:
    -    display_header()
    -    setup_board()
    -    display_board()
    -    while True:
    -        print("\n")
    -        simulate_board()
    -        display_board()
    -        check_winner(m2, m3)
    -        modify_board()
    -
    -
    -if __name__ == "__main__":
    -    main()
    diff --git a/56_Life_for_Two/vbnet/LifeforTwo.sln b/56_Life_for_Two/vbnet/LifeforTwo.sln
    deleted file mode 100644
    index 2d5167d34..000000000
    --- a/56_Life_for_Two/vbnet/LifeforTwo.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 31087af1a..000000000
    --- a/56_Life_for_Two/vbnet/LifeforTwo.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    LifeforTwo
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/57_Literature_Quiz/README.md b/57_Literature_Quiz/README.md
    index a0ac6f80f..2e55251ff 100644
    --- a/57_Literature_Quiz/README.md
    +++ b/57_Literature_Quiz/README.md
    @@ -12,7 +12,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/57_Literature_Quiz/csharp/LiteratureQuiz.csproj b/57_Literature_Quiz/csharp/LiteratureQuiz.csproj
    deleted file mode 100644
    index d3fe4757c..000000000
    --- a/57_Literature_Quiz/csharp/LiteratureQuiz.csproj
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    diff --git a/57_Literature_Quiz/csharp/LiteratureQuiz.sln b/57_Literature_Quiz/csharp/LiteratureQuiz.sln
    deleted file mode 100644
    index 8ba67c928..000000000
    --- a/57_Literature_Quiz/csharp/LiteratureQuiz.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/csharp/litquiz.cs b/57_Literature_Quiz/csharp/litquiz.cs
    index c2f07a2ae..0b9a77377 100644
    --- a/57_Literature_Quiz/csharp/litquiz.cs
    +++ b/57_Literature_Quiz/csharp/litquiz.cs
    @@ -5,7 +5,7 @@ namespace litquiz
         class litquiz
         {
             public static int Score = 0;
    -
    +      
     
             public static void Main(string[] args)
             {
    @@ -27,7 +27,7 @@ public static void Main(string[] args)
                 Console.WriteLine();
                 One();
     
    -
    +   
     
             }
     
    @@ -49,7 +49,7 @@ public static void One() {
                     Console.WriteLine("SORRY...FIGARO WAS HIS NAME.");
                     Two();
                 }
    -
    +            
             }
     
             public static void Two()
    @@ -84,7 +84,7 @@ public static void Three()
     
                 string answerThree;
                 answerThree = Console.ReadLine();
    -
    +            
                 if(answerThree == "4")
                 {
                     Console.WriteLine("YEA!  YOU'RE A REAL LITERATURE GIANT.");
    diff --git a/57_Literature_Quiz/java/src/LiteratureQuiz.java b/57_Literature_Quiz/java/src/LiteratureQuiz.java
    index 20331b1ac..d98d58a88 100644
    --- a/57_Literature_Quiz/java/src/LiteratureQuiz.java
    +++ b/57_Literature_Quiz/java/src/LiteratureQuiz.java
    @@ -173,4 +173,4 @@ private String displayTextAndGetInput(String text) {
             System.out.print(text);
             return kbScanner.next();
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/57_Literature_Quiz/javascript/literature-quiz-node.mjs b/57_Literature_Quiz/javascript/literature-quiz-node.mjs
    new file mode 100644
    index 000000000..0d38d5403
    --- /dev/null
    +++ b/57_Literature_Quiz/javascript/literature-quiz-node.mjs
    @@ -0,0 +1,90 @@
    +import * as readline from 'readline'
    +
    +// start reusable code
    +async function input(prompt = "") {
    +    const rl = readline.createInterface({
    +        input: process.stdin,
    +        output: process.stdout
    +    })
    +
    +    return new Promise((resolve, _) => {
    +        rl.setPrompt(prompt)
    +        // show user the question
    +        rl.prompt()
    +        // listen for user answer, 
    +        // callback is triggered as soon as user hits enter key
    +        rl.on('line', answer => {
    +            rl.close()
    +            // resolve the promise, with the input the user entered
    +            resolve(answer)
    +        })
    +    })
    +}
    +
    +function println(message = "", align = "left"){
    +    let padColCount = 0
    +    if(align === "center"){
    +        // calculate the amount of spaces required to center the message
    +        // process.stdout.columns is the number of spaces per line in the terminal
    +        padColCount = Math.round(process.stdout.columns / 2 + message.length / 2)
    +    }
    +    console.log(message.padStart(padColCount, " "))
    +}
    +// end reusable code
    +
    +
    +function equalIgnoreCase(correct, provided){
    +    return correct.toString().toLowerCase() === provided.toString().toLowerCase()
    +}
    +
    +async function evaluateQuestion(question, answerOptions, correctAnswer, correctMessage, wrongMessage){
    +    // ask the user to answer the given question
    +    // this is a blocking wait
    +    const answer = await input(question + "\n" + answerOptions + "\n")
    +    const isCorrect = equalIgnoreCase(correctAnswer, answer)
    +    println(isCorrect ? correctMessage : wrongMessage)
    +    return isCorrect ? 1 : 0
    +}
    +
    +async function main(){
    +    let score = 0
    +    println("LITERATURE QUIZ", "center")
    +    println("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY", "center")
    +    println();println();println()
    +
    +    score += await evaluateQuestion("IN PINOCCHIO, WHAT WAS THE NAME OF THE CAT?", 
    +        "1)TIGGER, 2)CICERO, 3)FIGARO, 4)GUIPETTO", 3,
    +        "VERY GOOD!  HERE'S ANOTHER.", "SORRY...FIGARO WAS HIS NAME.")
    +    println()
    +
    +    score += await evaluateQuestion("FROM WHOSE GARDEN DID BUGS BUNNY STEAL THE CARROTS?", 
    +        "1)MR. NIXON'S, 2)ELMER FUDD'S, 3)CLEM JUDD'S, 4)STROMBOLI'S", 2,
    +        "PRETTY GOOD!", "TOO BAD...IT WAS ELMER FUDD'S GARDEN.")
    +    println()
    +
    +    score += await evaluateQuestion("IN THE WIZARD OF OS, DOROTHY'S DOG WAS NAMED",
    +        "1)CICERO, 2)TRIXIA, 3)KING, 4)TOTO", 4,
    +        "YEA!  YOU'RE A REAL LITERATURE GIANT.",
    +        "BACK TO THE BOOKS,...TOTO WAS HIS NAME.")
    +    println()
    +
    +    score += await evaluateQuestion("WHO WAS THE FAIR MAIDEN WHO ATE THE POISON APPLE",
    +        "1)SLEEPING BEAUTY, 2)CINDERELLA, 3)SNOW WHITE, 4)WENDY", 3,
    +        "GOOD MEMORY!", "OH, COME ON NOW...IT WAS SNOW WHITE.")
    +
    +    println();println()
    +
    +    if(score === 4) {
    +        println("WOW!  THAT'S SUPER!  YOU REALLY KNOW YOUR NURSERY\n"+
    +        "YOUR NEXT QUIZ WILL BE ON 2ND CENTURY CHINESE\n"+
    +        "LITERATURE (HA, HA, HA)")
    +    } else if(score <= 2){
    +        println("UGH.  THAT WAS DEFINITELY NOT TOO SWIFT.  BACK TO\n" +
    +        "NURSERY SCHOOL FOR YOU, MY FRIEND.")
    +    } else {
    +        println("NOT BAD, BUT YOU MIGHT SPEND A LITTLE MORE TIME\n"+
    +        "READING THE NURSERY GREATS.")
    +    }
    +}
    +
    +main()
    \ No newline at end of file
    diff --git a/57_Literature_Quiz/javascript/litquiz.html b/57_Literature_Quiz/javascript/litquiz.html
    index 18510177d..e4aae4c39 100644
    --- a/57_Literature_Quiz/javascript/litquiz.html
    +++ b/57_Literature_Quiz/javascript/litquiz.html
    @@ -1,10 +1,9 @@
     
     
     LITERATURE QUIZ
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/57_Literature_Quiz/javascript/litquiz.js b/57_Literature_Quiz/javascript/litquiz.js
    index f652cdf3b..f4d6a4f6e 100644
    --- a/57_Literature_Quiz/javascript/litquiz.js
    +++ b/57_Literature_Quiz/javascript/litquiz.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/57_Literature_Quiz/javascript/litquiz.mjs b/57_Literature_Quiz/javascript/litquiz.mjs
    deleted file mode 100644
    index 89daef928..000000000
    --- a/57_Literature_Quiz/javascript/litquiz.mjs
    +++ /dev/null
    @@ -1,87 +0,0 @@
    -#!/usr/bin/env node
    -
    -import { println, input } from '../../00_Common/javascript/common.mjs';
    -
    -function printAlign(message = "", align = "left") {
    -    // process.stdout.columns is the number of spaces per line in the terminal
    -    const maxWidth = process.stdout.columns
    -    if (align === "center") {
    -        // calculate the amount of spaces required to center the message
    -        const padColCount = Math.round((process.stdout.columns-message.length)/2);
    -        const padding = padColCount <= 0 ? '' : ' '.repeat(padColCount);
    -        println(padding, message);
    -    } else if (align === "right") {
    -        const padColCount = Math.round(process.stdout.columns-message.length);
    -        const padding = padColCount <= 0 ? '' : ' '.repeat(padColCount);
    -        println(padding, message);
    -    } else {
    -        println(message);
    -    }
    -}
    -
    -function equalIgnoreCase(correct, provided){
    -    return correct.toString().toLowerCase() === provided.toString().toLowerCase()
    -}
    -
    -async function evaluateQuestion(question, answerOptions, correctAnswer, correctMessage, wrongMessage){
    -    // ask the user to answer the given question
    -    println(question);
    -    println(answerOptions.map((answer, index) => `${index+1})${answer}`).join(', '));
    -    // this is a blocking wait
    -    const answer = await input('?')
    -    const isCorrect = equalIgnoreCase(correctAnswer, answer)
    -    println(isCorrect ? correctMessage : wrongMessage)
    -    return isCorrect ? 1 : 0
    -}
    -
    -async function main(){
    -    let score = 0
    -
    -    printAlign("LITERATURE QUIZ", "center")
    -    printAlign("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY", "center")
    -    println("\n\n")
    -
    -    println("TEST YOUR KNOWLEDGE OF CHILDREN'S LITERATURE.");
    -    println();
    -    println("THIS IS A MULTIPLE-CHOICE QUIZ.");
    -    println("TYPE A 1, 2, 3, OR 4 AFTER THE QUESTION MARK.");
    -    println();
    -    println("GOOD LUCK!");
    -    println("\n\n");
    -
    -    score += await evaluateQuestion("IN PINOCCHIO, WHAT WAS THE NAME OF THE CAT?",
    -        [ "TIGGER", "CICERO", "FIGARO", "GUIPETTO"], 3,
    -        "VERY GOOD!  HERE'S ANOTHER.", "SORRY...FIGARO WAS HIS NAME.")
    -    println()
    -
    -    score += await evaluateQuestion("FROM WHOSE GARDEN DID BUGS BUNNY STEAL THE CARROTS?",
    -        [ "MR. NIXON'S", "ELMER FUDD'S", "CLEM JUDD'S", "STROMBOLI'S" ], 2,
    -        "PRETTY GOOD!", "TOO BAD...IT WAS ELMER FUDD'S GARDEN.")
    -    println()
    -
    -    score += await evaluateQuestion("IN THE WIZARD OF OS, DOROTHY'S DOG WAS NAMED",
    -        [ "CICERO", "TRIXIA", "KING", "TOTO" ], 4,
    -        "YEA!  YOU'RE A REAL LITERATURE GIANT.",
    -        "BACK TO THE BOOKS,...TOTO WAS HIS NAME.")
    -    println()
    -
    -    score += await evaluateQuestion("WHO WAS THE FAIR MAIDEN WHO ATE THE POISON APPLE",
    -        [ "SLEEPING BEAUTY", "CINDERELLA", "SNOW WHITE", "WENDY" ], 3,
    -        "GOOD MEMORY!", "OH, COME ON NOW...IT WAS SNOW WHITE.")
    -
    -    println("\n")
    -
    -    if(score === 4) {
    -        println("WOW!  THAT'S SUPER!  YOU REALLY KNOW YOUR NURSERY\n"+
    -        "YOUR NEXT QUIZ WILL BE ON 2ND CENTURY CHINESE\n"+
    -        "LITERATURE (HA, HA, HA)")
    -    } else if(score <= 2){
    -        println("UGH.  THAT WAS DEFINITELY NOT TOO SWIFT.  BACK TO\n" +
    -        "NURSERY SCHOOL FOR YOU, MY FRIEND.")
    -    } else {
    -        println("NOT BAD, BUT YOU MIGHT SPEND A LITTLE MORE TIME\n"+
    -        "READING THE NURSERY GREATS.")
    -    }
    -}
    -
    -main()
    diff --git a/57_Literature_Quiz/kotlin/README.md b/57_Literature_Quiz/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/57_Literature_Quiz/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/57_Literature_Quiz/lua/README.md b/57_Literature_Quiz/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/57_Literature_Quiz/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/57_Literature_Quiz/pascal/README.md b/57_Literature_Quiz/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/57_Literature_Quiz/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/57_Literature_Quiz/perl/litquiz.pl b/57_Literature_Quiz/perl/litquiz.pl
    index eed03506d..f7d410752 100755
    --- a/57_Literature_Quiz/perl/litquiz.pl
    +++ b/57_Literature_Quiz/perl/litquiz.pl
    @@ -78,3 +78,5 @@
     print "NOT BAD, BUT YOU MIGHT SPEND A LITTLE MORE TIME\n";
     print "READING THE NURSERY GREATS.\n";
     exit;
    +
    +
    diff --git a/57_Literature_Quiz/python/litquiz.py b/57_Literature_Quiz/python/litquiz.py
    index 9af123989..b5b9d1c5b 100644
    --- a/57_Literature_Quiz/python/litquiz.py
    +++ b/57_Literature_Quiz/python/litquiz.py
    @@ -6,19 +6,20 @@
     Ported by Dave LeCompte
     """
     
    -from typing import List, NamedTuple
    -
     PAGE_WIDTH = 64
     
     
    -class Question(NamedTuple):
    -    question: str
    -    answer_list: List[str]
    -    correct_number: int
    -    incorrect_message: str
    -    correct_message: str
    +class Question:
    +    def __init__(
    +        self, question, answer_list, correct_number, incorrect_message, correct_message
    +    ):
    +        self.question = question
    +        self.answer_list = answer_list
    +        self.correct_number = correct_number
    +        self.incorrect_message = incorrect_message
    +        self.correct_message = correct_message
     
    -    def ask(self) -> bool:
    +    def ask(self):
             print(self.question)
     
             options = [f"{i+1}){self.answer_list[i]}" for i in range(len(self.answer_list))]
    @@ -66,12 +67,13 @@ def ask(self) -> bool:
     ]
     
     
    -def print_centered(msg: str) -> None:
    +def print_centered(msg):
         spaces = " " * ((64 - len(msg)) // 2)
    +
         print(spaces + msg)
     
     
    -def print_instructions() -> None:
    +def print_instructions():
         print("TEST YOUR KNOWLEDGE OF CHILDREN'S LITERATURE.")
         print()
         print("THIS IS A MULTIPLE-CHOICE QUIZ.")
    @@ -82,7 +84,7 @@ def print_instructions() -> None:
         print()
     
     
    -def main() -> None:
    +def main():
         print_centered("LITERATURE QUIZ")
         print_centered("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
         print()
    diff --git a/57_Literature_Quiz/rust/Cargo.lock b/57_Literature_Quiz/rust/Cargo.lock
    deleted file mode 100644
    index b21cc6a2d..000000000
    --- a/57_Literature_Quiz/rust/Cargo.lock
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    diff --git a/57_Literature_Quiz/rust/Cargo.toml b/57_Literature_Quiz/rust/Cargo.toml
    deleted file mode 100644
    index 1ec696335..000000000
    --- a/57_Literature_Quiz/rust/Cargo.toml
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -[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]
    diff --git a/57_Literature_Quiz/rust/README.md b/57_Literature_Quiz/rust/README.md
    deleted file mode 100644
    index fc6468b9f..000000000
    --- a/57_Literature_Quiz/rust/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Rust](https://www.rust-lang.org/)
    diff --git a/57_Literature_Quiz/rust/src/main.rs b/57_Literature_Quiz/rust/src/main.rs
    deleted file mode 100644
    index a9e3923e5..000000000
    --- a/57_Literature_Quiz/rust/src/main.rs
    +++ /dev/null
    @@ -1,127 +0,0 @@
    -use std::io;
    -
    -
    -fn print_instructions() {
    -    println!("TEST YOUR KNOWLEDGE OF CHILDREN'S LITERATURE.");
    -    println!();
    -    println!("THIS IS A MULTIPLE-CHOICE QUIZ.");
    -    println!("TYPE A 1, 2, 3, OR 4 AFTER THE QUESTION MARK.");
    -    println!();
    -    println!("GOOD LUCK!");
    -    println!();
    -    println!();
    -}
    -
    -
    -fn print_center(text: String, width: usize) {
    -    let pad_size;
    -    if width > text.len() {
    -        pad_size = (width - text.len()) / 2;
    -    } else {
    -        pad_size = 0;
    -    }
    -    println!("{}{}", " ".repeat(pad_size), text);
    -}
    -
    -
    -fn print_results(score: usize, number_of_questions: usize) {
    -    if score == number_of_questions {
    -        println!("WOW!  THAT'S SUPER!  YOU REALLY KNOW YOUR NURSERY");
    -        println!("YOUR NEXT QUIZ WILL BE ON 2ND CENTURY CHINESE");
    -        println!("LITERATURE (HA, HA, HA)");
    -    } else if score < number_of_questions / 2 {
    -        println!("UGH.  THAT WAS DEFINITELY NOT TOO SWIFT.  BACK TO");
    -        println!("NURSERY SCHOOL FOR YOU, MY FRIEND.");
    -    } else {
    -        println!("NOT BAD, BUT YOU MIGHT SPEND A LITTLE MORE TIME");
    -        println!("READING THE NURSERY GREATS.");
    -    }
    -}
    -
    -fn main() {
    -    let page_width: usize = 64;
    -
    -    struct Question<'a> {
    -        question: &'a str,
    -        choices: Vec<&'a str>,
    -        answer: u8,
    -        correct_response: &'a str,
    -        wrong_response: &'a str,
    -    }
    -
    -    impl Question<'_>{
    -        fn ask(&self) -> bool {
    -            println!("{}", self.question);
    -            for i in 0..4 {
    -                print!("{}){}", i+1, self.choices[i]);
    -                if i != 3 { print!(", ")};
    -            }
    -            println!("");
    -            let mut user_input: String = String::new();
    -            io::stdin()
    -                .read_line(&mut user_input)
    -                .expect("Failed to read the line");
    -
    -            if user_input.starts_with(&self.answer.to_string()) {
    -                println!("{}", self.correct_response);
    -                true
    -            } else {
    -                println!("{}", self.wrong_response);
    -                false
    -            }
    -        }
    -    }
    -
    -    let questions: Vec = vec![
    -        Question{
    -            question: "IN PINOCCHIO, WHAT WAS THE NAME OF THE CAT?",
    -            choices: vec!["TIGGER", "CICERO", "FIGARO", "GUIPETTO"],
    -            answer: 3,
    -            wrong_response: "SORRY...FIGARO WAS HIS NAME.",
    -            correct_response: "VERY GOOD!  HERE'S ANOTHER.",
    -        },
    -        Question{
    -            question: "FROM WHOSE GARDEN DID BUGS BUNNY STEAL THE CARROTS?",
    -            choices: vec!["MR. NIXON'S", "ELMER FUDD'S", "CLEM JUDD'S", "STROMBOLI'S"],
    -            answer: 2,
    -            wrong_response: "TOO BAD...IT WAS ELMER FUDD'S GARDEN.",
    -            correct_response: "PRETTY GOOD!",
    -        },
    -        Question{
    -            question: "IN THE WIZARD OF OS, DOROTHY'S DOG WAS NAMED?",
    -            choices: vec!["CICERO", "TRIXIA", "KING", "TOTO"],
    -            answer: 4,
    -            wrong_response: "BACK TO THE BOOKS,...TOTO WAS HIS NAME.",
    -            correct_response: "YEA!  YOU'RE A REAL LITERATURE GIANT.",
    -        },
    -        Question{
    -            question: "WHO WAS THE FAIR MAIDEN WHO ATE THE POISON APPLE?",
    -            choices: vec!["SLEEPING BEAUTY", "CINDERELLA", "SNOW WHITE", "WENDY"],
    -            answer: 3,
    -            wrong_response: "OH, COME ON NOW...IT WAS SNOW WHITE.",
    -            correct_response: "GOOD MEMORY!",
    -        },    
    -    ];
    -    let number_of_questions: usize = questions.len();
    -
    -    print_center("LITERATURE QUIZ".to_string(), page_width);
    -    print_center("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY".to_string(), page_width);
    -    println!();
    -    println!();
    -    println!();
    -    print_instructions();
    -
    -    let mut score = 0;
    -    for question in questions {
    -        if question.ask() {
    -            score += 1;
    -        }
    -        println!();
    -    }
    -
    -    print_results(score, number_of_questions);
    -
    -}
    -
    -
    -
    diff --git a/57_Literature_Quiz/vbnet/LiteratureQuiz.sln b/57_Literature_Quiz/vbnet/LiteratureQuiz.sln
    deleted file mode 100644
    index 67ca803d5..000000000
    --- a/57_Literature_Quiz/vbnet/LiteratureQuiz.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 32c35664e..000000000
    --- a/57_Literature_Quiz/vbnet/LiteratureQuiz.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    LiteratureQuiz
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/58_Love/README.md b/58_Love/README.md
    index 26dc28686..1b2431aa3 100644
    --- a/58_Love/README.md
    +++ b/58_Love/README.md
    @@ -12,7 +12,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/58_Love/csharp/Love.csproj b/58_Love/csharp/Love.csproj
    deleted file mode 100644
    index 523087a3b..000000000
    --- a/58_Love/csharp/Love.csproj
    +++ /dev/null
    @@ -1,16 +0,0 @@
    -
    -
    -  
    -    Exe
    -    net6.0
    -  
    -
    -  
    -    
    -  
    -
    -  
    -    
    -  
    -
    -
    diff --git a/58_Love/csharp/Love.sln b/58_Love/csharp/Love.sln
    index 813af0f28..a89fd1d8a 100644
    --- a/58_Love/csharp/Love.sln
    +++ b/58_Love/csharp/Love.sln
    @@ -1,25 +1,34 @@
     
     Microsoft Visual Studio Solution File, Format Version 12.00
    -# Visual Studio Version 17
    -VisualStudioVersion = 17.0.32014.148
    +# Visual Studio 15
    +VisualStudioVersion = 15.0.26124.0
     MinimumVisualStudioVersion = 15.0.26124.0
    -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Love", "Love.csproj", "{1C02A3CA-615B-42CF-B696-4514770CA67F}"
    +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Love", "Love\Love.csproj", "{FC74E025-A50D-4E19-9337-87F2E4A9F83E}"
     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
    -	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
    +		Release|x64 = Release|x64
    +		Release|x86 = Release|x86
     	EndGlobalSection
     	GlobalSection(SolutionProperties) = preSolution
     		HideSolutionNode = FALSE
     	EndGlobalSection
    -	GlobalSection(ExtensibilityGlobals) = postSolution
    -		SolutionGuid = {F9C55508-108B-4EA1-ADD7-4BA8EC915E68}
    +	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
     	EndGlobalSection
     EndGlobal
    diff --git a/58_Love/csharp/Love/Input.cs b/58_Love/csharp/Love/Input.cs
    new file mode 100644
    index 000000000..030e3ead2
    --- /dev/null
    +++ b/58_Love/csharp/Love/Input.cs
    @@ -0,0 +1,26 @@
    +using System;
    +using System.Collections.Generic;
    +
    +namespace Love
    +{
    +    // Provides input methods which emulate the BASIC interpreter's keyboard input routines
    +    internal static class Input
    +    {
    +        private static void Prompt(string text = "") => Console.Write($"{text}? ");
    +
    +        public static string ReadLine(string prompt)
    +        {
    +            Prompt(prompt);
    +            var values = ReadStrings();
    +
    +            if (values.Length > 1)
    +            {
    +                Console.WriteLine("!Extra input ingored");
    +            }
    +
    +            return values[0];
    +        }
    +
    +        private static string[] ReadStrings() => Console.ReadLine().Split(',', StringSplitOptions.TrimEntries);
    +    }
    +}
    diff --git a/58_Love/csharp/Love/Love.csproj b/58_Love/csharp/Love/Love.csproj
    new file mode 100644
    index 000000000..fc2efa30e
    --- /dev/null
    +++ b/58_Love/csharp/Love/Love.csproj
    @@ -0,0 +1,11 @@
    +
    +
    +  
    +    Exe
    +    net5.0
    +  
    +
    +  
    +    
    +  
    +
    diff --git a/58_Love/csharp/Love/LovePattern.cs b/58_Love/csharp/Love/LovePattern.cs
    new file mode 100644
    index 000000000..4c24ed84a
    --- /dev/null
    +++ b/58_Love/csharp/Love/LovePattern.cs
    @@ -0,0 +1,57 @@
    +using System.IO;
    +
    +namespace Love
    +{
    +    internal class LovePattern
    +    {
    +        private readonly int[] _segmentLengths = new[] {
    +            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
    +        };
    +
    +        public int LineLength => 60;
    +
    +        internal void Write(SourceCharacters source, Stream destination)
    +        {
    +            using var writer = new StreamWriter(destination);
    +
    +            WritePadding(writer);
    +
    +            var lineLength = 0;
    +
    +            foreach (var segmentLength in _segmentLengths)
    +            {
    +                foreach (var character in source.GetCharacters(segmentLength))
    +                {
    +                    writer.Write(character);
    +                }
    +                lineLength += segmentLength;
    +                if (lineLength >= LineLength)
    +                {
    +                    writer.WriteLine();
    +                    lineLength = 0;
    +                }
    +            }
    +
    +            WritePadding(writer);
    +        }
    +
    +        private void WritePadding(StreamWriter writer)
    +        {
    +            for (int i = 0; i < 10; i++)
    +            {
    +                writer.WriteLine();
    +            }
    +        }
    +    }
    +}
    diff --git a/58_Love/csharp/Love/Program.cs b/58_Love/csharp/Love/Program.cs
    new file mode 100644
    index 000000000..a97844660
    --- /dev/null
    +++ b/58_Love/csharp/Love/Program.cs
    @@ -0,0 +1,31 @@
    +using System;
    +using System.Reflection;
    +
    +namespace Love
    +{
    +    internal class Program
    +    {
    +        static void Main(string[] args)
    +        {
    +            DisplayIntro();
    +
    +            var message = Input.ReadLine("Your message, please");
    +            var pattern = new LovePattern();
    +
    +            var source = new SourceCharacters(pattern.LineLength, message);
    +
    +            using var destination = Console.OpenStandardOutput();
    +
    +            pattern.Write(source, destination);
    +        }
    +
    +        private static void DisplayIntro()
    +        {
    +            using var stream = Assembly.GetExecutingAssembly()
    +                .GetManifestResourceStream("Love.Strings.Intro.txt");
    +            using var stdout = Console.OpenStandardOutput();
    +
    +            stream.CopyTo(stdout);
    +        }
    +    }
    +}
    diff --git a/58_Love/csharp/Love/SourceCharacters.cs b/58_Love/csharp/Love/SourceCharacters.cs
    new file mode 100644
    index 000000000..64716f9c8
    --- /dev/null
    +++ b/58_Love/csharp/Love/SourceCharacters.cs
    @@ -0,0 +1,38 @@
    +using System;
    +
    +namespace Love
    +{
    +    internal class SourceCharacters
    +    {
    +        private readonly int _lineLength;
    +        private readonly char[][] _chars;
    +        private int _currentRow;
    +        private int _currentIndex;
    +
    +        public SourceCharacters(int lineLength, string message)
    +        {
    +            _lineLength = lineLength;
    +            _chars = new[] { new char[lineLength], new char[lineLength] };
    +
    +            for (int i = 0; i < lineLength; i++)
    +            {
    +                _chars[0][i] = message[i % message.Length];
    +                _chars[1][i] = ' ';
    +            }
    +        }
    +
    +        public ReadOnlySpan GetCharacters(int count)
    +        {
    +            var span = new ReadOnlySpan(_chars[_currentRow], _currentIndex, count);
    +
    +            _currentRow = 1 - _currentRow;
    +            _currentIndex += count;
    +            if (_currentIndex >= _lineLength)
    +            {
    +                _currentIndex = _currentRow = 0;
    +            }
    +
    +            return span;
    +        }
    +    }
    +}
    diff --git a/58_Love/csharp/Resources/Intro.txt b/58_Love/csharp/Love/Strings/Intro.txt
    similarity index 100%
    rename from 58_Love/csharp/Resources/Intro.txt
    rename to 58_Love/csharp/Love/Strings/Intro.txt
    diff --git a/58_Love/csharp/LovePattern.cs b/58_Love/csharp/LovePattern.cs
    deleted file mode 100644
    index 37e6703cf..000000000
    --- a/58_Love/csharp/LovePattern.cs
    +++ /dev/null
    @@ -1,55 +0,0 @@
    -using System.IO;
    -using System.Text;
    -
    -namespace Love;
    -
    -internal class LovePattern
    -{
    -    private const int _lineLength = 60;
    -    private readonly int[] _segmentLengths = new[] {
    -        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
    -    };
    -    private readonly StringBuilder _pattern = new();
    -
    -    public LovePattern(string message)
    -    {
    -        Fill(new SourceCharacters(_lineLength, message));
    -    }
    -
    -    private void Fill(SourceCharacters source)
    -    {
    -        var lineLength = 0;
    -
    -        foreach (var segmentLength in _segmentLengths)
    -        {
    -            foreach (var character in source.GetCharacters(segmentLength))
    -            {
    -                _pattern.Append(character);
    -            }
    -            lineLength += segmentLength;
    -            if (lineLength >= _lineLength)
    -            {
    -                _pattern.AppendLine();
    -                lineLength = 0;
    -            }
    -        }
    -    }
    -
    -    public override string ToString() =>
    -        new StringBuilder()
    -            .AppendLines(10)
    -            .Append(_pattern)
    -            .AppendLines(10)
    -            .ToString();
    -}
    diff --git a/58_Love/csharp/Program.cs b/58_Love/csharp/Program.cs
    deleted file mode 100644
    index 575bbec20..000000000
    --- a/58_Love/csharp/Program.cs
    +++ /dev/null
    @@ -1,11 +0,0 @@
    -using Games.Common.IO;
    -using Love;
    -using Love.Resources;
    -
    -var io = new ConsoleIO();
    -
    -io.Write(Resource.Streams.Intro);
    -
    -var message = io.ReadString("Your message, please");
    -
    -io.Write(new LovePattern(message));
    diff --git a/58_Love/csharp/Resources/Resource.cs b/58_Love/csharp/Resources/Resource.cs
    deleted file mode 100644
    index fcbe6add4..000000000
    --- a/58_Love/csharp/Resources/Resource.cs
    +++ /dev/null
    @@ -1,16 +0,0 @@
    -using System.IO;
    -using System.Reflection;
    -using System.Runtime.CompilerServices;
    -
    -namespace Love.Resources;
    -
    -internal static class Resource
    -{
    -    internal static class Streams
    -    {
    -        public static Stream Intro => GetStream();
    -    }
    -
    -    private static Stream GetStream([CallerMemberName] string name = null)
    -        => Assembly.GetExecutingAssembly().GetManifestResourceStream($"Love.Resources.{name}.txt");
    -}
    \ No newline at end of file
    diff --git a/58_Love/csharp/SourceCharacters.cs b/58_Love/csharp/SourceCharacters.cs
    deleted file mode 100644
    index f60157540..000000000
    --- a/58_Love/csharp/SourceCharacters.cs
    +++ /dev/null
    @@ -1,37 +0,0 @@
    -using System;
    -
    -namespace Love;
    -
    -internal class SourceCharacters
    -{
    -    private readonly int _lineLength;
    -    private readonly char[][] _chars;
    -    private int _currentRow;
    -    private int _currentIndex;
    -
    -    public SourceCharacters(int lineLength, string message)
    -    {
    -        _lineLength = lineLength;
    -        _chars = new[] { new char[lineLength], new char[lineLength] };
    -
    -        for (int i = 0; i < lineLength; i++)
    -        {
    -            _chars[0][i] = message[i % message.Length];
    -            _chars[1][i] = ' ';
    -        }
    -    }
    -
    -    public ReadOnlySpan GetCharacters(int count)
    -    {
    -        var span = new ReadOnlySpan(_chars[_currentRow], _currentIndex, count);
    -
    -        _currentRow = 1 - _currentRow;
    -        _currentIndex += count;
    -        if (_currentIndex >= _lineLength)
    -        {
    -            _currentIndex = _currentRow = 0;
    -        }
    -
    -        return span;
    -    }
    -}
    diff --git a/58_Love/csharp/StringBuilderExtensions.cs b/58_Love/csharp/StringBuilderExtensions.cs
    deleted file mode 100644
    index 8a985ed91..000000000
    --- a/58_Love/csharp/StringBuilderExtensions.cs
    +++ /dev/null
    @@ -1,16 +0,0 @@
    -using System.Text;
    -
    -namespace Love;
    -
    -internal static class StringBuilderExtensions
    -{
    -    internal static StringBuilder AppendLines(this StringBuilder builder, int count)
    -    {
    -        for (int i = 0; i < count; i++)
    -        {
    -            builder.AppendLine();
    -        }
    -
    -        return builder;
    -    }
    -}
    diff --git a/58_Love/java/src/Love.java b/58_Love/java/src/Love.java
    index da8385aa4..89c1c1de6 100644
    --- a/58_Love/java/src/Love.java
    +++ b/58_Love/java/src/Love.java
    @@ -167,4 +167,4 @@ public static void main(String[] args) {
             Love love = new Love();
             love.process();
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/58_Love/javascript/love.html b/58_Love/javascript/love.html
    index 378883e10..ede593e82 100644
    --- a/58_Love/javascript/love.html
    +++ b/58_Love/javascript/love.html
    @@ -1,10 +1,9 @@
     
     
     LOVE
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/58_Love/javascript/love.js b/58_Love/javascript/love.js
    index 6a99e72fb..d67c6acbc 100644
    --- a/58_Love/javascript/love.js
    +++ b/58_Love/javascript/love.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/58_Love/kotlin/README.md b/58_Love/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/58_Love/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/58_Love/lua/README.md b/58_Love/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/58_Love/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/58_Love/pascal/README.md b/58_Love/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/58_Love/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/58_Love/perl/love.pl b/58_Love/perl/love.pl
    index 31127e050..9e9f95ccd 100755
    --- a/58_Love/perl/love.pl
    +++ b/58_Love/perl/love.pl
    @@ -50,3 +50,5 @@
     
     for (my $I=1; $I<10; $I++) { print "\n"; }
     exit;
    +
    +
    diff --git a/58_Love/python/love.py b/58_Love/python/love.py
    index 2bb93c68c..81c9ae2ff 100644
    --- a/58_Love/python/love.py
    +++ b/58_Love/python/love.py
    @@ -1,116 +1,108 @@
    -"""
    -LOVE
    -
    -From: BASIC Computer Games (1978)
    -      Edited by David H. Ahl
    -
    -"This program is designed to reproduce Robert Indiana's great art
    - work 'Love' with a message of your choice up to 60 characters long.
    -
    -"The [DATA variable is] an alternating count of the number
    - of characters and blanks which form the design.  These data give
    - the correct proportions for a standard 10 character per inch
    - Teletype or line printer.
    -
    -"The LOVE program was created by David Ahl."
    -
    -
    -Python port by Jeff Jetton, 2019
    -"""
    +######################################################################
    +#
    +# LOVE
    +#
    +# From: BASIC Computer Games (1978)
    +#       Edited by David H. Ahl
    +#
    +# "This program is designed to reproduce Robert Indiana's great art
    +#  work 'Love' with a message of your choice up to 60 characters long.
    +#
    +# "The [DATA variable is] an alternating count of the number
    +#  of characters and blanks which form the design.  These data give
    +#  the correct proportions for a standard 10 character per inch
    +#  Teletype or line printer.
    +#
    +# "The LOVE program was created by David Ahl."
    +#
    +#
    +# Python port by Jeff Jetton, 2019
    +#
    +######################################################################
     
     
     # Image data. Each top-level element is a row. Each row element
     # contains alternating character and blank run lengths.
    -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,
    -    ],
    -]
    +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, ] ]
     
     
     # Assume that the total length of the first element
     # is the line length used by every row
     ROW_LEN = sum(DATA[0])
     
    +# Display intro text
    +print("\n                  Love")
    +print("Creative Computing  Morristown, New Jersey")
    +print("\n\n")
    +print("A tribute to the great American artist, Robert Indiana.")
    +print("His great work will be reproduced with a message of")
    +print("your choice up to 60 characters.  If you can't think of")
    +print("a message, simple type the word 'love'\n") # (sic)
    +
    +# Get message from user
    +message = input("Your message, please? ")
    +if message == "":
    +    message = "LOVE"
    +
    +# Repeat the message until we get at least one line's worth
    +while(len(message) < ROW_LEN):
    +    message += message
    +
    +# Display image
    +print("\n" * 9)
    +for row in DATA:
    +    print_message = True
    +    position = 0
    +    line_text = ''
    +    for length in row:
    +        if print_message:
    +            text = message[position:(position + length)]
    +            print_message = False
    +        else:
    +            text = " " * length
    +            print_message = True
    +        line_text += text
    +        position += length
    +    print(line_text)
    +    
    +print("")
     
    -def main() -> None:
    -    # Display intro text
    -    print("\n                  Love")
    -    print("Creative Computing  Morristown, New Jersey")
    -    print("\n\n")
    -    print("A tribute to the great American artist, Robert Indiana.")
    -    print("His great work will be reproduced with a message of")
    -    print("your choice up to 60 characters.  If you can't think of")
    -    print("a message, simple type the word 'love'\n")  # (sic)
    -
    -    # Get message from user
    -    message = input("Your message, please? ")
    -    if message == "":
    -        message = "LOVE"
    -
    -    # Repeat the message until we get at least one line's worth
    -    while len(message) < ROW_LEN:
    -        message += message
    -
    -    # Display image
    -    print("\n" * 9)
    -    for row in DATA:
    -        print_message = True
    -        position = 0
    -        line_text = ""
    -        for length in row:
    -            if print_message:
    -                text = message[position : (position + length)]
    -                print_message = False
    -            else:
    -                text = " " * length
    -                print_message = True
    -            line_text += text
    -            position += length
    -        print(line_text)
    -
    -    print()
    -
    -
    -if __name__ == "__main__":
    -    main()
     
     
     ######################################################################
    @@ -154,3 +146,10 @@ def main() -> None:
     #    ((5, ), (1, 1, 2), (2, 1, 1))
     #
     ######################################################################
    +
    +
    +            
    +        
    +    
    +
    +    
    diff --git a/58_Love/ruby/love.rb b/58_Love/ruby/love.rb
    deleted file mode 100644
    index 3717a14b0..000000000
    --- a/58_Love/ruby/love.rb
    +++ /dev/null
    @@ -1,43 +0,0 @@
    -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
    diff --git a/58_Love/rust/Cargo.lock b/58_Love/rust/Cargo.lock
    deleted file mode 100644
    index b21cc6a2d..000000000
    --- a/58_Love/rust/Cargo.lock
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    diff --git a/58_Love/rust/Cargo.toml b/58_Love/rust/Cargo.toml
    deleted file mode 100644
    index 1ec696335..000000000
    --- a/58_Love/rust/Cargo.toml
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -[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]
    diff --git a/58_Love/rust/README.md b/58_Love/rust/README.md
    deleted file mode 100644
    index 4cd904309..000000000
    --- a/58_Love/rust/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Rust](https://www.rust-lang.org/) by Jadi.
    diff --git a/58_Love/rust/src/main.rs b/58_Love/rust/src/main.rs
    deleted file mode 100644
    index 5e8e18d72..000000000
    --- a/58_Love/rust/src/main.rs
    +++ /dev/null
    @@ -1,92 +0,0 @@
    -use std::io;
    -
    -fn show_intro() {
    -    // Displays the intro text
    -    println!("\n                  Love");
    -    println!("Creative Computing  Morristown, New Jersey");
    -    println!("\n\n");
    -    println!("A tribute to the great American artist, Robert Indiana.");
    -    println!("His great work will be reproduced with a message of");
    -    println!("your choice up to 60 characters.  If you can't think of");
    -    println!("a message, simple type the word 'love'\n"); // (sic)
    -}
    -
    -fn main() {
    -    enum PrintOrPass {
    -        Print,
    -        Pass,
    -    }
    -
    -    let data = [
    -        vec![60],
    -        vec![1, 12, 26, 9, 12],
    -        vec![3, 8, 24, 17, 8],
    -        vec![4, 6, 23, 21, 6],
    -        vec![4, 6, 22, 12, 5, 6, 5],
    -        vec![4, 6, 21, 11, 8, 6, 4],
    -        vec![4, 6, 21, 10, 10, 5, 4],
    -        vec![4, 6, 21, 9, 11, 5, 4],
    -        vec![4, 6, 21, 8, 11, 6, 4],
    -        vec![4, 6, 21, 7, 11, 7, 4],
    -        vec![4, 6, 21, 6, 11, 8, 4],
    -        vec![4, 6, 19, 1, 1, 5, 11, 9, 4],
    -        vec![4, 6, 19, 1, 1, 5, 10, 10, 4],
    -        vec![4, 6, 18, 2, 1, 6, 8, 11, 4],
    -        vec![4, 6, 17, 3, 1, 7, 5, 13, 4],
    -        vec![4, 6, 15, 5, 2, 23, 5],
    -        vec![1, 29, 5, 17, 8],
    -        vec![1, 29, 9, 9, 12],
    -        vec![1, 13, 5, 40, 1],
    -        vec![1, 13, 5, 40, 1],
    -        vec![4, 6, 13, 3, 10, 6, 12, 5, 1],
    -        vec![5, 6, 11, 3, 11, 6, 14, 3, 1],
    -        vec![5, 6, 11, 3, 11, 6, 15, 2, 1],
    -        vec![6, 6, 9, 3, 12, 6, 16, 1, 1],
    -        vec![6, 6, 9, 3, 12, 6, 7, 1, 10],
    -        vec![7, 6, 7, 3, 13, 6, 6, 2, 10],
    -        vec![7, 6, 7, 3, 13, 14, 10],
    -        vec![8, 6, 5, 3, 14, 6, 6, 2, 10],
    -        vec![8, 6, 5, 3, 14, 6, 7, 1, 10],
    -        vec![9, 6, 3, 3, 15, 6, 16, 1, 1],
    -        vec![9, 6, 3, 3, 15, 6, 15, 2, 1],
    -        vec![10, 6, 1, 3, 16, 6, 14, 3, 1],
    -        vec![10, 10, 16, 6, 12, 5, 1],
    -        vec![11, 8, 13, 27, 1],
    -        vec![11, 8, 13, 27, 1],
    -        vec![60],
    -    ];
    -
    -    const ROW_LEN: usize = 60;
    -    show_intro();
    -
    -    let mut input: String = String::new();
    -    io::stdin().read_line(&mut input).expect("No valid input");
    -    let input = if input.len() == 1 {
    -        "LOVE"
    -    } else {
    -        input.trim()
    -    };
    -    // repeat the answer to fill the whole line, we will show chunks of this when needed
    -    let input = input.repeat(ROW_LEN / (input.len()) + 1);
    -
    -    // Now lets display the Love
    -    print!("{}", "\n".repeat(9));
    -    for row in data {
    -        let mut print_or_pass = PrintOrPass::Print;
    -        let mut current_start = 0;
    -        for count in row {
    -            match print_or_pass {
    -                PrintOrPass::Print => {
    -                    print!("{}", &input[current_start..count + current_start]);
    -                    print_or_pass = PrintOrPass::Pass;
    -                }
    -                PrintOrPass::Pass => {
    -                    print!("{}", " ".repeat(count));
    -                    print_or_pass = PrintOrPass::Print;
    -                }
    -            }
    -            current_start += count;
    -        }
    -        println!();
    -    }
    -}
    diff --git a/58_Love/vbnet/Love.sln b/58_Love/vbnet/Love.sln
    deleted file mode 100644
    index 44ae6e7f3..000000000
    --- a/58_Love/vbnet/Love.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 444df2a31..000000000
    --- a/58_Love/vbnet/Love.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Love
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/59_Lunar_LEM_Rocket/README.md b/59_Lunar_LEM_Rocket/README.md
    index 98db7aed6..9d1890ac7 100644
    --- a/59_Lunar_LEM_Rocket/README.md
    +++ b/59_Lunar_LEM_Rocket/README.md
    @@ -22,46 +22,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Known Bugs
    -
    -### lem.bas
    -
    -- The input validation on the thrust value (displayed as P, stored internally as F) appears to be incorrect.  It allows negative values up up to -95, but at -96 or more balks and calls it negative.  I suspect the intent was to disallow any value less than 0 (in keeping with the instructions), *or* nonzero values less than 10.
    -
    -- The physics calculations seem very sus.  If you enter "1000,0,0" (i.e. no thrust at all, integrating 1000 seconds at a time) four times in a row, you first fall, but then mysteriously gain vertical speed, and end up being lost in space.  This makes no sense.  A similar result happened when just periodically applying 10% thrust in an attempt to hover.
    -
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    -
    -### LUNAR
    -
    -Variables:
    -
    -`A`: Altitude in miles.  Up is positive.
    -`V`: Velocity in miles / sec.  Down is positive.
    -
    -`M`: Weight of capsule in pounds, both fuel and machine
    -`N`: Empty weight of capsule in pounds.  So, weight of fuel is M - N.
    -
    -`G`: Gravity in miles / sec^2, down is positive.
    -`Z`: Exhaust velocity in miles / sec
    -
    -`L`: time in seconds since start of simulation.
    -`K`: Burn rate for this 10 second turn, pounds of fuel per sec
    -`T`: Time left in this 10 second turn, in seconds.
    -`S`: Burn time in this 10 second turn, input to subroutine 420.
    -
    -Subroutines:
    -
    -330, Apply updates from one call to subroutine 420.
    -
    -370, If you started descending and ended ascending, figure out whether you hit the surface in between.
    -
    -420, Compute new velocity and altitude using the Tsiolkovsky rocket equation for S seconds:
    -
    -`Q`: Fraction of initial mass that's burnt, i.e. 1 - mf / mo, exactly what we need for the Taylor series of `ln` in the rocket equation. Local to this subroutine.
    -`J`: Final velocity after S seconds, down is positive.  Return value.
    -`I`: Altitude after S seconds, up is positive.  Return value.
    diff --git a/59_Lunar_LEM_Rocket/csharp/LunarLEMRocket.csproj b/59_Lunar_LEM_Rocket/csharp/LunarLEMRocket.csproj
    deleted file mode 100644
    index d3fe4757c..000000000
    --- a/59_Lunar_LEM_Rocket/csharp/LunarLEMRocket.csproj
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    diff --git a/59_Lunar_LEM_Rocket/csharp/LunarLEMRocket.sln b/59_Lunar_LEM_Rocket/csharp/LunarLEMRocket.sln
    deleted file mode 100644
    index 4f74244da..000000000
    --- a/59_Lunar_LEM_Rocket/csharp/LunarLEMRocket.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/javascript/lem.html b/59_Lunar_LEM_Rocket/javascript/lem.html
    index da1785ec0..717ae0054 100644
    --- a/59_Lunar_LEM_Rocket/javascript/lem.html
    +++ b/59_Lunar_LEM_Rocket/javascript/lem.html
    @@ -1,10 +1,9 @@
     
     
     LEM
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/59_Lunar_LEM_Rocket/javascript/lunar.html b/59_Lunar_LEM_Rocket/javascript/lunar.html
    index a94c17c8b..cdcabc2d2 100644
    --- a/59_Lunar_LEM_Rocket/javascript/lunar.html
    +++ b/59_Lunar_LEM_Rocket/javascript/lunar.html
    @@ -1,10 +1,9 @@
     
     
     LUNAR
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/59_Lunar_LEM_Rocket/javascript/lunar.js b/59_Lunar_LEM_Rocket/javascript/lunar.js
    index 43a0e892c..f95d1d16d 100644
    --- a/59_Lunar_LEM_Rocket/javascript/lunar.js
    +++ b/59_Lunar_LEM_Rocket/javascript/lunar.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    @@ -102,7 +102,7 @@ async function main()
             print("0 (FREE FALL) AND 200 (MAXIMUM BURN) POUNDS PER SECOND.\n");
             print("SET NEW BURN RATE EVERY 10 SECONDS.\n");
             print("\n");
    -        print("CAPSULE WEIGHT 32,500 LBS; FUEL WEIGHT 16,000 LBS.\n");
    +        print("CAPSULE WEIGHT 32,500 LBS; FUEL WEIGHT 16,500 LBS.\n");
             print("\n");
             print("\n");
             print("\n");
    diff --git a/59_Lunar_LEM_Rocket/kotlin/README.md b/59_Lunar_LEM_Rocket/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/59_Lunar_LEM_Rocket/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/59_Lunar_LEM_Rocket/lem.bas b/59_Lunar_LEM_Rocket/lem.bas
    index eece9cc1b..aa46895fd 100644
    --- a/59_Lunar_LEM_Rocket/lem.bas
    +++ b/59_Lunar_LEM_Rocket/lem.bas
    @@ -220,7 +220,7 @@
     1085 GOTO 1100
     1090 PRINT
     1095 PRINT "MISSION ABENDED"
    -1100 PRINT
    +1100 PRINT 
     1105 PRINT "DO YOU WANT TO TRY IT AGAIN (YES/NO)?"
     1110 INPUT Z$
     1115 IF Z$="YES" THEN 20
    diff --git a/59_Lunar_LEM_Rocket/lua/README.md b/59_Lunar_LEM_Rocket/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/59_Lunar_LEM_Rocket/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/59_Lunar_LEM_Rocket/lunar.bas b/59_Lunar_LEM_Rocket/lunar.bas
    index 301336150..db07b0a53 100644
    --- a/59_Lunar_LEM_Rocket/lunar.bas
    +++ b/59_Lunar_LEM_Rocket/lunar.bas
    @@ -1,19 +1,19 @@
     10 PRINT TAB(33);"LUNAR"
    -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"
    +20 PRINT TAB(l5);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" 
     25 PRINT:PRINT:PRINT
    -30 PRINT "THIS IS A COMPUTER SIMULATION OF AN APOLLO LUNAR"
    +30 PRINT "THIS IS A COMPUTER SIMULATION OF AN APOLLO LUNAR" 
     40 PRINT "LANDING CAPSULE.": PRINT: PRINT
    -50 PRINT "THE ON-BOARD COMPUTER HAS FAILED (IT WAS MADE BY"
    +50 PRINT "THE ON-BOARD COMPUTER HAS FAILED (IT WAS MADE BY" 
     60 PRINT "XEROX) SO YOU HAVE TO LAND THE CAPSULE MANUALLY."
    -70 PRINT: PRINT "SET BURN RATE OF RETRO ROCKETS TO ANY VALUE BETWEEN"
    -80 PRINT "0 (FREE FALL) AND 200 (MAXIMUM BURN) POUNDS PER SECOND."
    -90 PRINT "SET NEW BURN RATE EVERY 10 SECONDS.": PRINT
    -100 PRINT "CAPSULE WEIGHT 32,500 LBS; FUEL WEIGHT 16,000 LBS."
    +70 PRINT: PRINT "SET BURN RATE OF RETRO ROCKETS TO ANY VALUE BETWEEN" 
    +80 PRINT "0 (FREE FALL) AND 200 (MAXIMUM BURN) POUNDS PER SECOND." 
    +90 PRINT "SET NEW BURN RATE EVERY 10 SECONDS.": PRINT 
    +100 PRINT "CAPSULE WEIGHT 32,500 LBS; FUEL WEIGHT 16,500 LBS."
     110 PRINT: PRINT: PRINT: PRINT "GOOD LUCK"
     120 L=0
    -130 PRINT: PRINT "SEC","MI + FT","MPH","LB FUEL","BURN RATE":PRINT
    +130 PRINT: PRINT "SEC","MI + FT","MPH","LB FUEL","BURN RATE":PRINT 
     140 A=120:V=1:M=33000:N=16500:G=1E-03:Z=1.8
    -150 PRINT L,INT(A);INT(5280*(A-INT(A))),3600*V,M-N,:INPUT K:T=10
    +150 PRINT L,INT(A);INT(5280*(A-INT(A))),3600*V,M-N,:INPUT K:T=10 
     160 IF M-N<1E-03 THEN 240
     170 IF T<1E-03 THEN 150
     180 S=T: IF M>=N+S*K THEN 200
    @@ -24,12 +24,12 @@
     230 GOSUB 330: GOTO 160
     240 PRINT "FUEL OUT AT";L;"SECONDS":S=(-V+SQR(V*V+2*A*G))/G
     250 V=V+G*S: L=L+S
    -260 W=3600*V: PRINT "ON MOON AT";L;"SECONDS - IMPACT VELOCITY";W;"MPH"
    -274 IF W<=1.2 THEN PRINT "PERFECT LANDING!": GOTO 440
    -280 IF W<=10 THEN PRINT "GOOD LANDING (COULD BE BETTER)":GOTO 440
    +260 W=3600*V: PRINT "ON MOON AT";L;"SECONDS - IMPACT VELOCITY";W;"MPH" 
    +274 IF W<=1.2 THEN PRINT "PERFECT LANDING!": GOTO 440 
    +280 IF W<=10 THEN PRINT "GOOD LANDING (COULD BE BETTER)":GOTO 440 
     282 IF W>60 THEN 300
    -284 PRINT "CRAFT DAMAGE... YOU'RE STRANDED HERE UNTIL A RESCUE"
    -286 PRINT "PARTY ARRIVES. HOPE YOU HAVE ENOUGH OXYGEN!"
    +284 PRINT "CRAFT DAMAGE... YOU'RE STRANDED HERE UNTIL A RESCUE" 
    +286 PRINT "PARTY ARRIVES. HOPE YOU HAVE ENOUGH OXYGEN!" 
     288 GOTO 440
     300 PRINT "SORRY THERE WERE NO SURVIVORS. YOU BLEW IT!"
     310 PRINT "IN FACT, YOU BLASTED A NEW LUNAR CRATER";W*.227;"FEET DEEP!"
    diff --git a/59_Lunar_LEM_Rocket/pascal/README.md b/59_Lunar_LEM_Rocket/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/59_Lunar_LEM_Rocket/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/59_Lunar_LEM_Rocket/python/lunar.py b/59_Lunar_LEM_Rocket/python/lunar.py
    index b65e0fa54..b55fc6f2c 100644
    --- a/59_Lunar_LEM_Rocket/python/lunar.py
    +++ b/59_Lunar_LEM_Rocket/python/lunar.py
    @@ -6,9 +6,9 @@
     Ported by Dave LeCompte
     """
     
    +import collections
     import math
    -from dataclasses import dataclass
    -from typing import Any, NamedTuple
    +
     
     PAGE_WIDTH = 64
     
    @@ -33,38 +33,41 @@
     BURN_LEFT = FUEL_RIGHT + COLUMN_WIDTH
     BURN_RIGHT = BURN_LEFT + BURN_WIDTH
     
    -
    -class PhysicalState(NamedTuple):
    -    velocity: float
    -    altitude: float
    +PhysicalState = collections.namedtuple("PhysicalState", ["velocity", "altitude"])
     
     
    -def print_centered(msg: str) -> None:
    +def print_centered(msg):
         spaces = " " * ((PAGE_WIDTH - len(msg)) // 2)
         print(spaces + msg)
     
     
    -def print_header(title: str) -> None:
    +def print_header(title):
         print_centered(title)
    -    print_centered("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n")
    +    print_centered("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
    +    print()
    +    print()
    +    print()
    +
     
    +def add_rjust(line, s, pos):
    +    # adds a new field to a line right justified to end at pos
     
    -def add_rjust(line: str, s: Any, pos: int) -> str:
    -    """Add a new field to a line right justified to end at pos"""
    -    s_str = str(s)
    -    slen = len(s_str)
    +    s = str(s)
    +    slen = len(s)
         if len(line) + slen > pos:
             new_len = pos - slen
             line = line[:new_len]
         if len(line) + slen < pos:
             spaces = " " * (pos - slen - len(line))
             line = line + spaces
    -    return line + s_str
    +    return line + s
    +
     
    +def add_ljust(line, s, pos):
    +    # adds a new field to a line left justified starting at pos
     
    -def add_ljust(line: str, s: str, pos: int) -> str:
    -    """Add a new field to a line left justified starting at pos"""
    -    s = s
    +    s = str(s)
    +    slen = len(s)
         if len(line) > pos:
             line = line[:pos]
         if len(line) < pos:
    @@ -73,31 +76,60 @@ def add_ljust(line: str, s: str, pos: int) -> str:
         return line + s
     
     
    -def print_instructions() -> None:
    -    """Somebody had a bad experience with Xerox."""
    +def print_instructions():
    +    # Somebody had a bad experience with Xerox.
    +
         print("THIS IS A COMPUTER SIMULATION OF AN APOLLO LUNAR")
    -    print("LANDING CAPSULE.\n\n")
    +    print("LANDING CAPSULE.")
    +    print()
    +    print()
         print("THE ON-BOARD COMPUTER HAS FAILED (IT WAS MADE BY")
    -    print("XEROX) SO YOU HAVE TO LAND THE CAPSULE MANUALLY.\n")
    +    print("XEROX) SO YOU HAVE TO LAND THE CAPSULE MANUALLY.")
    +    print()
     
     
    -def print_intro() -> None:
    +def print_intro():
         print("SET BURN RATE OF RETRO ROCKETS TO ANY VALUE BETWEEN")
         print("0 (FREE FALL) AND 200 (MAXIMUM BURN) POUNDS PER SECOND.")
    -    print("SET NEW BURN RATE EVERY 10 SECONDS.\n")
    -    print("CAPSULE WEIGHT 32,500 LBS; FUEL WEIGHT 16,000 LBS.\n\n\n")
    -    print("GOOD LUCK\n")
    -
    -
    -def format_line_for_report(
    -    t: Any,
    -    miles: Any,
    -    feet: Any,
    -    velocity: Any,
    -    fuel: Any,
    -    burn_rate: str,
    -    is_header: bool,
    -) -> str:
    +    print("SET NEW BURN RATE EVERY 10 SECONDS.")
    +    print()
    +    print("CAPSULE WEIGHT 32,500 LBS; FUEL WEIGHT 16,500 LBS.")
    +    print()
    +    print()
    +    print()
    +    print("GOOD LUCK")
    +    print()
    +
    +
    +def show_landing(sim_clock, capsule):
    +    w = 3600 * capsule.v
    +    print(
    +        f"ON MOON AT {sim_clock.elapsed_time:.2f} SECONDS - IMPACT VELOCITY {w:.2f} MPH"
    +    )
    +    if w < 1.2:
    +        print("PERFECT LANDING!")
    +    elif w < 10:
    +        print("GOOD LANDING (COULD BE BETTER)")
    +    elif w <= 60:
    +        print("CRAFT DAMAGE... YOU'RE STRANDED HERE UNTIL A RESCUE")
    +        print("PARTY ARRIVES. HOPE YOU HAVE ENOUGH OXYGEN!")
    +    else:
    +        print("SORRY THERE WERE NO SURVIVORS. YOU BLEW IT!")
    +        print(f"IN FACT, YOU BLASTED A NEW LUNAR CRATER {w*.227:.2f} FEET DEEP!")
    +    end_sim()
    +
    +
    +def show_out_of_fuel(sim_clock, capsule):
    +    print(f"FUEL OUT AT {sim_clock.elapsed_time} SECONDS")
    +    delta_t = (
    +        -capsule.v + math.sqrt(capsule.v ** 2 + 2 * capsule.a * capsule.g)
    +    ) / capsule.g
    +    capsule.v += capsule.g * delta_t
    +    sim_clock.advance(delta_t)
    +    show_landing(sim_clock, capsule)
    +
    +
    +def format_line_for_report(t, miles, feet, velocity, fuel, burn_rate, is_header):
         line = add_rjust("", t, SECONDS_RIGHT)
         line = add_rjust(line, miles, ALT_MI_RIGHT)
         line = add_rjust(line, feet, ALT_FT_RIGHT)
    @@ -110,77 +142,70 @@ def format_line_for_report(
         return line
     
     
    -class SimulationClock:
    -    def __init__(self, elapsed_time: float, time_until_next_prompt: float) -> None:
    -        self.elapsed_time = elapsed_time
    -        self.time_until_next_prompt = time_until_next_prompt
    -
    -    def time_for_prompt(self) -> bool:
    -        return self.time_until_next_prompt < 1e-3
    -
    -    def advance(self, delta_t: float) -> None:
    -        self.elapsed_time += delta_t
    -        self.time_until_next_prompt -= delta_t
    -
    -
    -@dataclass
     class Capsule:
    -    altitude: float = 120  # in miles above the surface
    -    velocity: float = 1  # downward
    -    m: float = 33000  # mass_with_fuel
    -    n: float = 16500  # mass_without_fuel
    -    g: float = 1e-3
    -    z: float = 1.8
    -    fuel_per_second: float = 0
    -
    -    def remaining_fuel(self) -> float:
    +    def __init__(
    +        self,
    +        altitude=120,
    +        velocity=1,
    +        mass_with_fuel=33000,
    +        mass_without_fuel=16500,
    +        g=1e-3,
    +        z=1.8,
    +    ):
    +        self.a = altitude  # in miles above the surface
    +        self.v = velocity  # downward
    +        self.m = mass_with_fuel
    +        self.n = mass_without_fuel
    +        self.g = g
    +        self.z = z
    +        self.fuel_per_second = 0
    +
    +    def remaining_fuel(self):
             return self.m - self.n
     
    -    def is_out_of_fuel(self) -> bool:
    +    def is_out_of_fuel(self):
             return self.remaining_fuel() < 1e-3
     
    -    def update_state(
    -        self, sim_clock: SimulationClock, delta_t: float, new_state: PhysicalState
    -    ) -> None:
    +    def update_state(self, sim_clock, delta_t, new_state):
             sim_clock.advance(delta_t)
             self.m = self.m - delta_t * self.fuel_per_second
    -        self.altitude = new_state.altitude
    -        self.velocity = new_state.velocity
    +        self.a = new_state.altitude
    +        self.v = new_state.velocity
     
    -    def fuel_time_remaining(self) -> float:
    +    def fuel_time_remaining(self):
             # extrapolates out how many seconds we have at the current fuel burn rate
             assert self.fuel_per_second > 0
             return self.remaining_fuel() / self.fuel_per_second
     
    -    def predict_motion(self, delta_t: float) -> PhysicalState:
    +    def predict_motion(self, delta_t):
             # Perform an Euler's Method numerical integration of the equations of motion.
     
             q = delta_t * self.fuel_per_second / self.m
     
             # new velocity
             new_velocity = (
    -            self.velocity
    +            self.v
                 + self.g * delta_t
    -            + self.z * (-q - q**2 / 2 - q**3 / 3 - q**4 / 4 - q**5 / 5)
    +            + self.z * (-q - q ** 2 / 2 - q ** 3 / 3 - q ** 4 / 4 - q ** 5 / 5)
             )
     
             # new altitude
             new_altitude = (
    -            self.altitude
    -            - self.g * delta_t**2 / 2
    -            - self.velocity * delta_t
    +            self.a
    +            - self.g * delta_t ** 2 / 2
    +            - self.v * delta_t
                 + self.z
                 * delta_t
    -            * (q / 2 + q**2 / 6 + q**3 / 12 + q**4 / 20 + q**5 / 30)
    +            * (q / 2 + q ** 2 / 6 + q ** 3 / 12 + q ** 4 / 20 + q ** 5 / 30)
             )
     
             return PhysicalState(altitude=new_altitude, velocity=new_velocity)
     
    -    def make_state_display_string(self, sim_clock: SimulationClock) -> str:
    +    def make_state_display_string(self, sim_clock):
             seconds = sim_clock.elapsed_time
    -        miles = int(self.altitude)
    -        feet = int(5280 * (self.altitude - miles))
    -        velocity = int(3600 * self.velocity)
    +        miles = int(self.a)
    +        feet = int(5280 * (self.a - miles))
    +        velocity = int(3600 * self.v)
             fuel = int(self.remaining_fuel())
             burn_rate = " ? "
     
    @@ -188,45 +213,27 @@ def make_state_display_string(self, sim_clock: SimulationClock) -> str:
                 seconds, miles, feet, velocity, fuel, burn_rate, False
             )
     
    -    def prompt_for_burn(self, sim_clock: SimulationClock) -> None:
    +    def prompt_for_burn(self, sim_clock):
             msg = self.make_state_display_string(sim_clock)
     
             self.fuel_per_second = float(input(msg))
             sim_clock.time_until_next_prompt = 10
     
     
    -def show_landing(sim_clock: SimulationClock, capsule: Capsule) -> None:
    -    w = 3600 * capsule.velocity
    -    print(
    -        f"ON MOON AT {sim_clock.elapsed_time:.2f} SECONDS - IMPACT VELOCITY {w:.2f} MPH"
    -    )
    -    if w < 1.2:
    -        print("PERFECT LANDING!")
    -    elif w < 10:
    -        print("GOOD LANDING (COULD BE BETTER)")
    -    elif w <= 60:
    -        print("CRAFT DAMAGE... YOU'RE STRANDED HERE UNTIL A RESCUE")
    -        print("PARTY ARRIVES. HOPE YOU HAVE ENOUGH OXYGEN!")
    -    else:
    -        print("SORRY THERE WERE NO SURVIVORS. YOU BLEW IT!")
    -        print(f"IN FACT, YOU BLASTED A NEW LUNAR CRATER {w*.227:.2f} FEET DEEP!")
    -    end_sim()
    +class SimulationClock:
    +    def __init__(self, elapsed_time, time_until_next_prompt):
    +        self.elapsed_time = elapsed_time
    +        self.time_until_next_prompt = time_until_next_prompt
     
    +    def time_for_prompt(self):
    +        return self.time_until_next_prompt < 1e-3
     
    -def show_out_of_fuel(sim_clock: SimulationClock, capsule: Capsule) -> None:
    -    print(f"FUEL OUT AT {sim_clock.elapsed_time} SECONDS")
    -    delta_t = (
    -        -capsule.velocity
    -        + math.sqrt(capsule.velocity**2 + 2 * capsule.altitude * capsule.g)
    -    ) / capsule.g
    -    capsule.velocity += capsule.g * delta_t
    -    sim_clock.advance(delta_t)
    -    show_landing(sim_clock, capsule)
    +    def advance(self, delta_t):
    +        self.elapsed_time += delta_t
    +        self.time_until_next_prompt -= delta_t
     
     
    -def process_final_tick(
    -    delta_t: float, sim_clock: SimulationClock, capsule: Capsule
    -) -> None:
    +def process_final_tick(delta_t, sim_clock, capsule):
         # When we extrapolated our position based on our velocity
         # and delta_t, we overshot the surface. For better
         # accuracy, we will back up and do shorter time advances.
    @@ -237,20 +244,20 @@ def process_final_tick(
                 return
             # line 35
             average_vel = (
    -            capsule.velocity
    +            capsule.v
                 + math.sqrt(
    -                capsule.velocity**2
    +                capsule.v ** 2
                     + 2
    -                * capsule.altitude
    +                * capsule.a
                     * (capsule.g - capsule.z * capsule.fuel_per_second / capsule.m)
                 )
             ) / 2
    -        delta_t = capsule.altitude / average_vel
    +        delta_t = capsule.a / average_vel
             new_state = capsule.predict_motion(delta_t)
             capsule.update_state(sim_clock, delta_t, new_state)
     
     
    -def handle_flyaway(sim_clock: SimulationClock, capsule: Capsule) -> bool:
    +def handle_flyaway(sim_clock, capsule):
         """
         The user has started flying away from the moon. Since this is a
         lunar LANDING simulation, we wait until the capsule's velocity is
    @@ -263,11 +270,11 @@ def handle_flyaway(sim_clock: SimulationClock, capsule: Capsule) -> bool:
             w = (1 - capsule.m * capsule.g / (capsule.z * capsule.fuel_per_second)) / 2
             delta_t = (
                 capsule.m
    -            * capsule.velocity
    +            * capsule.v
                 / (
                     capsule.z
                     * capsule.fuel_per_second
    -                * math.sqrt(w**2 + capsule.velocity / capsule.z)
    +                * math.sqrt(w ** 2 + capsule.v / capsule.z)
                 )
             ) + 0.05
     
    @@ -279,16 +286,22 @@ def handle_flyaway(sim_clock: SimulationClock, capsule: Capsule) -> bool:
     
             capsule.update_state(sim_clock, delta_t, new_state)
     
    -        if (new_state.velocity > 0) or (capsule.velocity <= 0):
    +        if (new_state.velocity > 0) or (capsule.v <= 0):
                 # return to normal sim
                 return False
     
     
    -def end_sim() -> None:
    -    print("\n\n\nTRY AGAIN??\n\n\n")
    +def end_sim():
    +    print()
    +    print()
    +    print()
    +    print("TRY AGAIN??")
    +    print()
    +    print()
    +    print()
     
     
    -def run_simulation() -> None:
    +def run_simulation():
         print()
         print(
             format_line_for_report("SEC", "MI", "FT", "MPH", "LB FUEL", "BURN RATE", True)
    @@ -323,8 +336,11 @@ def run_simulation() -> None:
                 process_final_tick(delta_t, sim_clock, capsule)
                 return
     
    -        if capsule.velocity > 0 and new_state.velocity < 0:
    -            if handle_flyaway(sim_clock, capsule):
    +        if capsule.v > 0 and new_state.velocity < 0:
    +            # moving away from the moon
    +
    +            landed = handle_flyaway(sim_clock, capsule)
    +            if landed:
                     process_final_tick(delta_t, sim_clock, capsule)
                     return
     
    @@ -332,7 +348,7 @@ def run_simulation() -> None:
                 capsule.update_state(sim_clock, delta_t, new_state)
     
     
    -def main() -> None:
    +def main():
         print_header("LUNAR")
         print_instructions()
         while True:
    diff --git a/59_Lunar_LEM_Rocket/rust/README.md b/59_Lunar_LEM_Rocket/rust/README.md
    deleted file mode 100644
    index 158d6cb1a..000000000
    --- a/59_Lunar_LEM_Rocket/rust/README.md
    +++ /dev/null
    @@ -1,11 +0,0 @@
    -README.md
    -
    -Original source downloaded from Vintage Basic
    -
    -This folder for chapter #59 contains three different games.  Three folders here contain the three games:
    -
    - - Rocket
    - - LEM
    - - lunar
    -
    -Conversion to [Rust](https://www.rust-lang.org)
    diff --git a/59_Lunar_LEM_Rocket/rust/rocket/Cargo.toml b/59_Lunar_LEM_Rocket/rust/rocket/Cargo.toml
    deleted file mode 100644
    index e22d3e143..000000000
    --- a/59_Lunar_LEM_Rocket/rust/rocket/Cargo.toml
    +++ /dev/null
    @@ -1,10 +0,0 @@
    -[package]
    -name = "rocket"
    -version = "1.0.0"
    -edition = "2021"
    -
    -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
    -
    -[dependencies]
    -text_io = "0.1.10"
    -num-integer = "0.1"
    diff --git a/59_Lunar_LEM_Rocket/rust/rocket/src/main.rs b/59_Lunar_LEM_Rocket/rust/rocket/src/main.rs
    deleted file mode 100644
    index bd4685c61..000000000
    --- a/59_Lunar_LEM_Rocket/rust/rocket/src/main.rs
    +++ /dev/null
    @@ -1,107 +0,0 @@
    -//Goal of this port is to keep Basic lang idioms where possible. Gotta have those single letter capital variables!
    -use num_integer::{sqrt};
    -use std::io::{self, Write};
    -use text_io::{read, try_read};
    -#[allow(non_snake_case)]
    -fn main() {
    -    println!("{:>30}", "ROCKET");
    -    println!("{:>15}", "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY");
    -    println!();println!();println!();
    -    println!("LUNAR LANDING SIMULATION");
    -    println!("----- ------- ----------");println!();
    -    let A= input("DO YOU WANT INSTRUCTIONS (YES OR NO) ");
    -    if !(A=="NO") {
    -        println!();
    -        println!("YOU ARE LANDING ON THE MOON AND AND HAVE TAKEN OVER MANUAL");
    -        println!("CONTROL 1000 FEET ABOVE A GOOD LANDING SPOT. YOU HAVE A DOWN-");
    -        println!("WARD VELOCITY OF 50 FEET/SEC. 150 UNITS OF FUEL REMAIN.");
    -        println!();
    -        println!("HERE ARE THE RULES THAT GOVERN YOUR APOLLO SPACE-CRAFT:"); println!();
    -        println!("(1) AFTER EACH SECOND THE HEIGHT, VELOCITY, AND REMAINING FUEL");
    -        println!("    WILL BE REPORTED VIA DIGBY YOUR ON-BOARD COMPUTER.");
    -        println!("(2) AFTER THE REPORT A '?' WILL APPEAR. ENTER THE NUMBER");
    -        println!("    OF UNITS OF FUEL YOU WISH TO BURN DURING THE NEXT");
    -        println!("    SECOND. EACH UNIT OF FUEL WILL SLOW YOUR DESCENT BY");
    -        println!("    1 FOOT/SEC.");
    -        println!("(3) THE MAXIMUM THRUST OF YOUR ENGINE IS 30 FEET/SEC/SEC");
    -        println!("    OR 30 UNITS OF FUEL PER SECOND.");
    -        println!("(4) WHEN YOU CONTACT THE LUNAR SURFACE. YOUR DESCENT ENGINE");
    -        println!("    WILL AUTOMATICALLY SHUT DOWN AND YOU WILL BE GIVEN A");
    -        println!("    REPORT OF YOUR LANDING SPEED AND REMAINING FUEL.");
    -        println!("(5) IF YOU RUN OUT OF FUEL THE '?' WILL NO LONGER APPEAR");
    -        println!("    BUT YOUR SECOND BY SECOND REPORT WILL CONTINUE UNTIL");
    -        println!("    YOU CONTACT THE LUNAR SURFACE.");println!();
    -    }
    -    loop {
    -        println!("BEGINNING LANDING PROCEDURE..........");println!();
    -        println!("G O O D  L U C K ! ! !");
    -        println!();println!();
    -        println!("SEC  FEET      SPEED     FUEL     PLOT OF DISTANCE");
    -        println!();
    -        let mut T=0;let mut H:i32=1000;let mut V=50;let mut F=150;
    -        let D:i32; let mut V1:i32; let mut B:i32;
    -        'falling: loop {
    -            println!(" {:<4}{:<11}{:<10}{:<8}I{capsule:>high$}", T,H,V,F,high=(H/15) as usize,capsule="*");
    -            B = input_int("");
    -            if B<0 { B=0 }
    -            else { if B>30 { B=30 } }
    -            if B>F { B=F }
    -            'nofuel: loop {
    -                V1=V-B+5;
    -                F=F-B;
    -                H=H- (V+V1)/2;
    -                if  H<=0 { break 'falling}
    -                T=T+1;
    -                V=V1;
    -                if F>0 { break 'nofuel }
    -                if B!=0 {
    -                    println!("**** OUT OF FUEL ****");
    -                }
    -                println!(" {:<4}{:<11}{:<10}{:<8}I{capsule:>high$}", T,H,V,F,high=(H/12+29) as usize,capsule="*");
    -                B=0;
    -            }
    -        }
    -        H=H+ (V1+V)/2;
    -        if B==5 {
    -            D=H/V;
    -        } else {
    -            D=(-V+sqrt(V*V+H*(10-2*B)))/(5-B);
    -            V1=V+(5-B)*D;
    -        }
    -        println!("***** CONTACT *****");
    -        println!("TOUCHDOWN AT {} SECONDS.",T+D);
    -        println!("LANDING VELOCITY={} FEET/SEC.",V1);
    -        println!("{} UNITS OF FUEL REMAINING.", F);
    -        if V1==0 {
    -            println!("CONGRATULATIONS! A PERFECT LANDING!!");
    -            println!("YOUR LICENSE WILL BE RENEWED.......LATER.");
    -        }
    -        if V1.abs()>=2 {
    -            println!("***** SORRY, BUT YOU BLEW IT!!!!");
    -            println!("APPROPRIATE CONDOLENCES WILL BE SENT TO YOUR NEXT OF KIN.");
    -        }
    -        println!();println!();println!();
    -        let A = input("ANOTHER MISSION");
    -        if !(A=="YES") { break };
    -    }
    -    println!();println!( "CONTROL OUT.");println!();
    -}
    -
    -
    -fn input(prompt:&str) -> String {
    -    loop {
    -        print!("{} ? ",prompt);io::stdout().flush().unwrap();
    -        let innn:String=read!("{}\n");
    -        let out:String = innn.trim().to_string();
    -        if out!="" {return out}
    -    }
    -}
    -fn input_int(prompt:&str) -> i32 {
    -    loop {
    -        print!("{} ? ",prompt);io::stdout().flush().unwrap();
    -        match try_read!() {
    -            Ok(n) => return n,
    -            Err(_) => println!("Enter a number 0-30"),
    -        }
    -    }
    -}
    diff --git a/59_Lunar_LEM_Rocket/vbnet/LunarLEMRocket.sln b/59_Lunar_LEM_Rocket/vbnet/LunarLEMRocket.sln
    deleted file mode 100644
    index a77348e6e..000000000
    --- a/59_Lunar_LEM_Rocket/vbnet/LunarLEMRocket.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 553bdcd54..000000000
    --- a/59_Lunar_LEM_Rocket/vbnet/LunarLEMRocket.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    LunarLEMRocket
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/60_Mastermind/README.md b/60_Mastermind/README.md
    index 05383f106..e9bf1c3ce 100644
    --- a/60_Mastermind/README.md
    +++ b/60_Mastermind/README.md
    @@ -27,131 +27,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -### How the computer deduces your guess.
    -
    -The computer takes the number of black pegs and white pegs that the user reports
    -and uses that information as a target. It then assumes its guess is the answer
    -and proceeds to compare the black and white pegs against all remaining possible
    -answers. For each set of black and white pegs it gets in these comparisons, if 
    -they don't match what the user reported, then they can not be part of the solution.
    -This can be a non-intuitive assumption, so we'll walk through it with a three color,
    -three position example (27 possible solutions.)
    -
    -Let's just suppose our secret code we're hiding from the computer is `BWB`
    -
    -First let's point out the commutative property of comparing two codes for their
    -black and white pegs. A black peg meaning correct color and correct position, and
    -a white peg meaning correct color and wrong position.  If the computer guesses
    -`RBW` then the black/white peg report is 0 black, 2 white.  But if `RBW` is the 
    -secret code and the computer guesses `BWB` the reporting for `BWB` is going to be
    -the same, 0 black, 2 white. 
    -
    -Now lets look at a table with the reporting for every possible guess the computer 
    -can make while our secret code is `BWB`.
    -                                                         
    -| Guess | Black | White |     | Guess | Black | White |     | Guess | Black | White |
    -|-------|-------|-------|-----|-------|-------|-------|-----|-------|-------|-------|
    -| BBB   | 2     | 0     |     | WBB   | 1     | 2     |     | RBB   | 1     | 1     |   
    -| BBW   | 1     | 2     |     | WBW   | 0     | 2     |     | RBW   | 0     | 2     |   
    -| BBR   | 1     | 1     |     | WBR   | 0     | 2     |     | RBR   | 0     | 1     |    
    -| BWB   | 3     | 0     |     | WWB   | 2     | 0     |     | RWB   | 2     | 0     |    
    -| BWW   | 2     | 0     |     | WWW   | 1     | 0     |     | RWW   | 1     | 0     |    
    -| BWR   | 2     | 0     |     | WWR   | 1     | 0     |     | RWR   | 1     | 0     |    
    -| BRB   | 2     | 0     |     | WRB   | 1     | 1     |     | RRB   | 1     | 0     |    
    -| BRW   | 1     | 1     |     | WRW   | 0     | 1     |     | RRW   | 0     | 1     |    
    -| BRR   | 1     | 0     |     | WRR   | 0     | 1     |     | RRR   | 0     | 0     | 
    -
    -The computer has guessed `RBW` and the report on it is 0 black, 2 white. The code
    -used to eliminate other solutions looks like this:
    -
    -`1060 IF B1<>B OR W1<>W THEN I(X)=0`
    -
    -which says set `RBW` as the secret and compare it to all remaining solutions and 
    -get rid of any that don't match the same black and white report, 0 black and 2 white. 
    -So let's do that.
    -
    -Remember, `RBW` is pretending to be the secret code here. These are the remaining
    -solutions reporting their black and white pegs against `RBW`.
    -
    -| Guess | Black | White |     | Guess | Black | White |     | Guess | Black | White |
    -|-------|-------|-------|-----|-------|-------|-------|-----|-------|-------|-------|
    -| BBB   | 1     | 0     |     | WBB   | 1     | 1     |     | RBB   | 2     | 0     |   
    -| BBW   | 2     | 0     |     | WBW   | 2     | 0     |     | RBW   | 3     | 0     |   
    -| BBR   | 1     | 1     |     | WBR   | 1     | 2     |     | RBR   | 2     | 0     |    
    -| BWB   | 0     | 2     |     | WWB   | 0     | 2     |     | RWB   | 1     | 2     |    
    -| BWW   | 1     | 1     |     | WWW   | 1     | 0     |     | RWW   | 2     | 0     |    
    -| BWR   | 0     | 3     |     | WWR   | 1     | 1     |     | RWR   | 1     | 1     |    
    -| BRB   | 0     | 2     |     | WRB   | 0     | 3     |     | RRB   | 1     | 1     |    
    -| BRW   | 1     | 2     |     | WRW   | 1     | 1     |     | RRW   | 2     | 0     |    
    -| BRR   | 0     | 2     |     | WRR   | 0     | 2     |     | RRR   | 1     | 0     | 
    -
    -Now we are going to eliminate every solution that **DOESN'T** match 0 black and 2 white.
    -
    -| Guess    | Black | White |     | Guess    | Black | White |     | Guess    | Black | White |
    -|----------|-------|-------|-----|----------|-------|-------|-----|----------|-------|-------|
    -| ~~~BBB~~ | 1     | 0     |     | ~~~WBB~~ | 1     | 1     |     | ~~~RBB~~ | 2     | 0     |   
    -| ~~~BBW~~ | 2     | 0     |     | ~~~WBW~~ | 2     | 0     |     | ~~~RBW~~ | 3     | 0     |   
    -| ~~~BBR~~ | 1     | 1     |     | ~~~WBR~~ | 1     | 2     |     | ~~~RBR~~ | 2     | 0     |    
    -| BWB      | 0     | 2     |     | WWB      | 0     | 2     |     | ~~~RWB~~ | 1     | 2     |    
    -| ~~~BWW~~ | 1     | 1     |     | ~~~WWW~~ | 1     | 0     |     | ~~~RWW~~ | 2     | 0     |    
    -| ~~~BWR~~ | 0     | 3     |     | ~~~WWR~~ | 1     | 1     |     | ~~~RWR~~ | 1     | 1     |    
    -| BRB      | 0     | 2     |     | ~~~WRB~~ | 0     | 3     |     | ~~~RRB~~ | 1     | 1     |    
    -| ~~~BRW~~ | 1     | 2     |     | ~~~WRW~~ | 1     | 1     |     | ~~~RRW~~ | 2     | 0     |    
    -| BRR      | 0     | 2     |     | WRR      | 0     | 2     |     | ~~~RRR~~ | 1     | 0     |          
    -                                   
    - That wipes out all but five solutions. Notice how the entire right column of solutions 
    - is eliminated, including our original guess of `RBW`, therefore eliminating any 
    - special case to specifically eliminate this guess from the solution set when we first find out
    - its not the answer.
    - 
    - Continuing on, we have the following solutions left of which our secret code, `BWB` 
    - is one of them. Remember our commutative property explained previously. 
    -
    -| Guess | Black | White |
    -|-------|-------|-------|
    -| BWB   | 0     | 2     |
    -| BRB   | 0     | 2     |
    -| BRR   | 0     | 2     |
    -| WWB   | 0     | 2     |
    -| WRR   | 0     | 2     |
    -
    -So for its second pick, the computer will randomly pick one of these remaining solutions. Let's pick
    -the middle one, `BRR`, and perform the same ritual. Our user reports to the computer 
    -that it now has 1 black, 0 whites when comparing to our secret code `BWB`. Let's 
    -now compare `BRR` to the remaining five solutions and eliminate any that **DON'T**
    -report 1 black and 0 whites.
    -
    -| Guess    | Black | White |
    -|----------|-------|-------|
    -| BWB      | 1     | 0     |
    -| ~~~BRB~~ | 2     | 0     |
    -| ~~~BRR~~ | 3     | 0     |
    -| ~~~WWB~~ | 0     | 1     |
    -| ~~~WRR~~ | 2     | 0     | 
    -
    -Only one solution matches and it's our secret code! The computer will guess this
    -one next as it's the only choice left, for a total of three moves. 
    -Coincidentally, I believe the expected maximum number of moves the computer will 
    -make is the number of positions plus one for the initial guess with no information.
    -This is because it is winnowing down the solutions 
    -logarithmically on average. You noticed on the first pass, it wiped out 22 
    -solutions. If it was doing this logarithmically the worst case guess would 
    -still eliminate 18 of the solutions leaving 9 (32).  So we have as
    -a guideline:
    -
    - Log(# of Colors)TotalPossibilities
    - 
    -but TotalPossibilities = (# of Colors)# of Positions
    -
    -so you end up with the number of positions as a guess limit. If you consider the
    -simplest non-trivial puzzle, two colors with two positions, and you guess BW or 
    -WB first, the most you can logically deduce if you get 1 black and 1 white is 
    -that it is either WW, or BB which could bring your total guesses up to three 
    -which is the number of positions plus one.  So if your computer's turn is taking
    -longer than the number of positions plus one to find the answer then something 
    -is wrong with your code. 
    -
    -#### Known Bugs
    -
    -- Line 622 is unreachable, as the previous line ends in a GOTO and that line number is not referenced anywhere.  It appears that the intent was to tell the user the correct combination after they fail to guess it in 10 tries, which would be a very nice feature, but does not actually work.  (In the MiniScript port, I have made this feature work.)
    diff --git a/60_Mastermind/csharp/Mastermind.csproj b/60_Mastermind/csharp/Game/Game.csproj
    similarity index 100%
    rename from 60_Mastermind/csharp/Mastermind.csproj
    rename to 60_Mastermind/csharp/Game/Game.csproj
    diff --git a/60_Mastermind/csharp/Code.cs b/60_Mastermind/csharp/Game/src/Code.cs
    similarity index 100%
    rename from 60_Mastermind/csharp/Code.cs
    rename to 60_Mastermind/csharp/Game/src/Code.cs
    diff --git a/60_Mastermind/csharp/CodeFactory.cs b/60_Mastermind/csharp/Game/src/CodeFactory.cs
    similarity index 100%
    rename from 60_Mastermind/csharp/CodeFactory.cs
    rename to 60_Mastermind/csharp/Game/src/CodeFactory.cs
    diff --git a/60_Mastermind/csharp/ColorInfo.cs b/60_Mastermind/csharp/Game/src/ColorInfo.cs
    similarity index 100%
    rename from 60_Mastermind/csharp/ColorInfo.cs
    rename to 60_Mastermind/csharp/Game/src/ColorInfo.cs
    diff --git a/60_Mastermind/csharp/Colors.cs b/60_Mastermind/csharp/Game/src/Colors.cs
    similarity index 100%
    rename from 60_Mastermind/csharp/Colors.cs
    rename to 60_Mastermind/csharp/Game/src/Colors.cs
    diff --git a/60_Mastermind/csharp/Command.cs b/60_Mastermind/csharp/Game/src/Command.cs
    similarity index 100%
    rename from 60_Mastermind/csharp/Command.cs
    rename to 60_Mastermind/csharp/Game/src/Command.cs
    diff --git a/60_Mastermind/csharp/Controller.cs b/60_Mastermind/csharp/Game/src/Controller.cs
    similarity index 100%
    rename from 60_Mastermind/csharp/Controller.cs
    rename to 60_Mastermind/csharp/Game/src/Controller.cs
    diff --git a/60_Mastermind/csharp/EnumerableExtensions.cs b/60_Mastermind/csharp/Game/src/EnumerableExtensions.cs
    similarity index 100%
    rename from 60_Mastermind/csharp/EnumerableExtensions.cs
    rename to 60_Mastermind/csharp/Game/src/EnumerableExtensions.cs
    diff --git a/60_Mastermind/csharp/Program.cs b/60_Mastermind/csharp/Game/src/Program.cs
    similarity index 100%
    rename from 60_Mastermind/csharp/Program.cs
    rename to 60_Mastermind/csharp/Game/src/Program.cs
    diff --git a/60_Mastermind/csharp/TurnResult.cs b/60_Mastermind/csharp/Game/src/TurnResult.cs
    similarity index 100%
    rename from 60_Mastermind/csharp/TurnResult.cs
    rename to 60_Mastermind/csharp/Game/src/TurnResult.cs
    diff --git a/60_Mastermind/csharp/View.cs b/60_Mastermind/csharp/Game/src/View.cs
    similarity index 100%
    rename from 60_Mastermind/csharp/View.cs
    rename to 60_Mastermind/csharp/Game/src/View.cs
    diff --git a/60_Mastermind/csharp/Mastermind.sln b/60_Mastermind/csharp/Mastermind.sln
    index 0da53b6d5..c3827fb7d 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 17
    -VisualStudioVersion = 17.0.32014.148
    +# Visual Studio Version 16
    +VisualStudioVersion = 16.0.31321.278
     MinimumVisualStudioVersion = 10.0.40219.1
    -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mastermind", "Mastermind.csproj", "{AEC839CD-C6D3-4476-AA85-79B160AF78BE}"
    +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Game", "Game\Game.csproj", "{E8D63140-971D-4FBF-8138-964E54CCB7DD}"
     EndProject
     Global
     	GlobalSection(SolutionConfigurationPlatforms) = preSolution
    @@ -11,10 +11,10 @@ Global
     		Release|Any CPU = Release|Any CPU
     	EndGlobalSection
     	GlobalSection(ProjectConfigurationPlatforms) = postSolution
    -		{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
    +		{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
     	EndGlobalSection
     	GlobalSection(SolutionProperties) = preSolution
     		HideSolutionNode = FALSE
    diff --git a/60_Mastermind/java/Mastermind.java b/60_Mastermind/java/Mastermind.java
    deleted file mode 100644
    index a8b7d4223..000000000
    --- a/60_Mastermind/java/Mastermind.java
    +++ /dev/null
    @@ -1,423 +0,0 @@
    -import java.util.ArrayList;
    -import java.util.Arrays;
    -import java.util.BitSet;
    -import java.util.List;
    -import java.util.Objects;
    -import java.util.Random;
    -import java.util.Scanner;
    -import java.util.function.Function;
    -import java.util.function.Predicate;
    -import java.util.stream.Collectors;
    -import java.util.stream.IntStream;
    -
    -/**
    - * A port of the BASIC Mastermind game in java.
    - *
    - * Differences between this and the original BASIC:
    - *    Uses a number base conversion approach to converting solution ids to
    - *    color code strings. The original performs an inefficient add by 1
    - *    with carry technique where every carry increments the next positions
    - *    color id.
    - *
    - *    Implements a ceiling check on the number of positions in a secret code
    - *    to not run out of memory. Because of the algorithm that the computer
    - *    uses to deduce the players secret code, it searches through the entire
    - *    possible spectrum of solutions. This can be a very large number because
    - *    it's (number of colors) ^ (number of positions). The original will
    - *    happily try to allocate all the memory on the system if this number is
    - *    too large. If it did successfully allocate the memory on a large solution
    - *    set then it would also take too long to compute code strings via its
    - *    technique mentioned in the previous note.
    - *
    - *    An extra message is given at the start to alert the player to the
    - *    BOARD and QUIT commands.
    - */
    -public class Mastermind {
    -  final Random random = new Random();
    -  // some less verbose printing methods
    -  static private void pf(String s, Object... o){ System.out.printf(s, o);}
    -  static private void pl(String s){System.out.println(s);}
    -  static private void pl(){System.out.println();}
    -
    -  public static void main(String[] args) {
    -    title();
    -    Mastermind game = setup();
    -    game.play();
    -  }
    -
    -  /**
    -   * The eight possible color codes.
    -   */
    -  private enum Color {
    -    B("BLACK"), W("WHITE"), R("RED"), G("GREEN"),
    -    O("ORANGE"), Y("YELLOW"), P("PURPLE"), T("TAN");
    -    public final String name;
    -
    -    Color(String name) {
    -      this.name = name;
    -    }
    -  }
    -
    -  /**
    -   * Represents a guess and the subsequent number of colors in the correct
    -   * position (blacks), and the number of colors present but not in the correct
    -   * position (whites.)
    -   */
    -  private record Guess(int guessNum, String guess, int blacks, int whites){}
    -
    -
    -  private void play() {
    -    IntStream.rangeClosed(1,rounds).forEach(this::playRound);
    -    pl("GAME OVER");
    -    pl("FINAL SCORE: ");
    -    pl(getScore());
    -  }
    -
    -  /**
    -   * Builder-ish pattern for creating Mastermind game
    -   * @return Mastermind game object
    -   */
    -  private static Mastermind setup() {
    -    int numOfColors;
    -    pf("NUMBER OF COLORS? > ");
    -    numOfColors = getPositiveNumberUpTo(Color.values().length);
    -    int maxPositions = getMaxPositions(numOfColors);
    -    pf("NUMBER OF POSITIONS (MAX %d)? > ", maxPositions);
    -    int positions = getPositiveNumberUpTo(maxPositions);
    -    pf("NUMBER OF ROUNDS? > ");
    -    int rounds = getPositiveNumber();
    -    pl("ON YOUR TURN YOU CAN ENTER 'BOARD' TO DISPLAY YOUR PREVIOUS GUESSES,");
    -    pl("OR 'QUIT' TO GIVE UP.");
    -    return new Mastermind(numOfColors, positions, rounds, 10);
    -  }
    -
    -  /**
    -   * Computes the number of allowable positions to prevent the total possible
    -   * solution set that the computer has to check to a reasonable number, and
    -   * to prevent out of memory errors.
    -   *
    -   * The computer guessing algorithm uses a BitSet which has a limit of 2^31
    -   * bits (Integer.MAX_VALUE bits). Since the number of possible solutions to
    -   * any mastermind game is (numColors) ^ (numPositions) we need find the
    -   * maximum number of positions by finding the Log|base-NumOfColors|(2^31)
    -   *
    -   * @param numOfColors  number of different colors
    -   * @return             max number of positions in the secret code.
    -   */
    -  private static int getMaxPositions(int numOfColors){
    -    return (int)(Math.log(Integer.MAX_VALUE)/Math.log(numOfColors));
    -  }
    -
    -  final int numOfColors, positions, rounds, possibilities;
    -  int humanMoves, computerMoves;
    -  final BitSet solutionSet;
    -  final Color[] colors;
    -  final int maxTries;
    -
    -  // A recording of human guesses made during the round for the BOARD command.
    -  final List guesses = new ArrayList<>();
    -
    -  // A regular expression to validate user guess strings
    -  final String guessValidatorRegex;
    -
    -  public Mastermind(int numOfColors, int positions, int rounds, int maxTries) {
    -    this.numOfColors = numOfColors;
    -    this.positions = positions;
    -    this.rounds = rounds;
    -    this.maxTries = maxTries;
    -    this.humanMoves = 0;
    -    this.computerMoves = 0;
    -    String colorCodes = Arrays.stream(Color.values())
    -                              .limit(numOfColors)
    -                              .map(Color::toString)
    -                              .collect(Collectors.joining());
    -    // regex that limits the number of color codes and quantity for a guess.
    -    this.guessValidatorRegex = "^[" + colorCodes + "]{" + positions + "}$";
    -    this.colors = Color.values();
    -    this.possibilities = (int) Math.round(Math.pow(numOfColors, positions));
    -    pf("TOTAL POSSIBILITIES =% d%n", possibilities);
    -    this.solutionSet = new BitSet(possibilities);
    -    displayColorCodes(numOfColors);
    -  }
    -
    -  private void playRound(int round) {
    -    pf("ROUND NUMBER % d ----%n%n",round);
    -    humanTurn();
    -    computerTurn();
    -    pl(getScore());
    -  }
    -
    -  private void humanTurn() {
    -    guesses.clear();
    -    String secretCode = generateColorCode();
    -    pl("GUESS MY COMBINATION. \n");
    -    int guessNumber = 1;
    -    while (true) {   // User input loop
    -      pf("MOVE #%d GUESS ?", guessNumber);
    -      final String guess = getWord();
    -      if (guess.equals(secretCode)) {
    -        guesses.add(new Guess(guessNumber, guess, positions, 0));
    -        pf("YOU GUESSED IT IN %d MOVES!%n", guessNumber);
    -        humanMoves++;
    -        pl(getScore());
    -        return;
    -      } else if ("BOARD".equals(guess)) {  displayBoard();
    -      } else if ("QUIT".equals(guess))  {  quit(secretCode);
    -      } else if (!validateGuess(guess)) {  pl(guess + " IS UNRECOGNIZED.");
    -      } else {
    -        Guess g = evaluateGuess(guessNumber, guess, secretCode);
    -        pf("YOU HAVE %d BLACKS AND %d WHITES.%n", g.blacks(), g.whites());
    -        guesses.add(g);
    -        humanMoves++;
    -        guessNumber++;
    -      }
    -      if (guessNumber > maxTries) {
    -        pl("YOU RAN OUT OF MOVES!  THAT'S ALL YOU GET!");
    -        pl("THE ACTUAL COMBINATION WAS: " + secretCode);
    -        return;
    -      }
    -    }
    -  }
    -
    -  private void computerTurn(){
    -    while (true) {
    -      pl("NOW I GUESS.  THINK OF A COMBINATION.");
    -      pl("HIT RETURN WHEN READY:");
    -      solutionSet.set(0, possibilities);  // set all bits to true
    -      getInput("RETURN KEY", Scanner::nextLine, Objects::nonNull);
    -      int guessNumber = 1;
    -      while(true){
    -        if (solutionSet.cardinality() == 0) {
    -          // user has given wrong information, thus we have cancelled out
    -          // any remaining possible valid solution.
    -          pl("YOU HAVE GIVEN ME INCONSISTENT INFORMATION.");
    -          pl("TRY AGAIN, AND THIS TIME PLEASE BE MORE CAREFUL.");
    -          break;
    -        }
    -        // Randomly pick an untried solution.
    -        int solution = solutionSet.nextSetBit(generateSolutionID());
    -        if (solution == -1) {
    -          solution = solutionSet.nextSetBit(0);
    -        }
    -        String guess = solutionIdToColorCode(solution);
    -        pf("MY GUESS IS: %s  BLACKS, WHITES ? ",guess);
    -        int[] bAndWPegs = getPegCount(positions);
    -        if (bAndWPegs[0] == positions) {
    -          pf("I GOT IT IN % d MOVES!%n", guessNumber);
    -          computerMoves+=guessNumber;
    -          return;
    -        }
    -        // wrong guess, first remove this guess from solution set
    -        solutionSet.clear(solution);
    -        int index = 0;
    -        // Cycle through remaining solution set, marking any solutions as invalid
    -        // that don't exactly match what the user said about our guess.
    -        while ((index = solutionSet.nextSetBit(index)) != -1) {
    -          String solutionStr = solutionIdToColorCode(index);
    -          Guess possibleSolution = evaluateGuess(0, solutionStr, guess);
    -          if (possibleSolution.blacks() != bAndWPegs[0] ||
    -              possibleSolution.whites() != bAndWPegs[1]) {
    -            solutionSet.clear(index);
    -          }
    -          index++;
    -        }
    -        guessNumber++;
    -      }
    -    }
    -  }
    -
    -  // tally black and white pegs
    -  private Guess evaluateGuess(int guessNum, String guess, String secretCode) {
    -    int blacks = 0, whites = 0;
    -    char[] g = guess.toCharArray();
    -    char[] sc = secretCode.toCharArray();
    -    // An incremented number that marks this position as having been counted
    -    // as a black or white peg already.
    -    char visited = 0x8000;
    -    // Cycle through guess letters and check for color and position match
    -    // with the secretCode. If both match, mark it black.
    -    // Else cycle through remaining secretCode letters and check if color
    -    // matches. If this matches, a preventative check must be made against
    -    // the guess letter matching the secretCode letter at this position in
    -    // case it would be counted as a black in one of the next passes.
    -    for (int j = 0; j < positions; j++) {
    -      if (g[j] == sc[j]) {
    -        blacks++;
    -        g[j] = visited++;
    -        sc[j] = visited++;
    -      }
    -      for (int k = 0; k < positions; k++) {
    -        if (g[j] == sc[k] && g[k] != sc[k]) {
    -          whites++;
    -          g[j] = visited++;
    -          sc[k] = visited++;
    -        }
    -      }
    -    }
    -    return new Guess(guessNum, guess, blacks, whites);
    -  }
    -
    -  private boolean validateGuess(String guess) {
    -    return guess.length() == positions && guess.matches(guessValidatorRegex);
    -  }
    -
    -  private String getScore() {
    -    return "SCORE:%n\tCOMPUTER \t%d%n\tHUMAN \t%d%n"
    -        .formatted(computerMoves, humanMoves);
    -  }
    -
    -  private void printGuess(Guess g){
    -    pf("% 3d%9s% 15d% 10d%n",g.guessNum(),g.guess(),g.blacks(),g.whites());
    -  }
    -  
    -  private void displayBoard() {
    -    pl();
    -    pl("BOARD");
    -    pl("MOVE     GUESS          BLACK     WHITE");
    -    guesses.forEach(this::printGuess);
    -    pl();
    -  }
    -
    -  private void quit(String secretCode) {
    -    pl("QUITTER!  MY COMBINATION WAS: " + secretCode);
    -    pl("GOOD BYE");
    -    System.exit(0);
    -  }
    -
    -  /**
    -   * Generates a set of color codes randomly.
    -   */
    -  private String generateColorCode() {
    -    int solution = generateSolutionID();
    -    return solutionIdToColorCode(solution);
    -  }
    -
    -  /**
    -   * From the total possible number of solutions created at construction, choose
    -   * one randomly.
    -   *
    -   * @return one of many possible solutions
    -   */
    -  private int generateSolutionID() {
    -    return random.nextInt(0, this.possibilities);
    -  }
    -
    -  /**
    -   * Given the number of colors and positions in a secret code, decode one of
    -   * those permutations, a solution number, into a string of letters
    -   * representing colored pegs.
    -   *
    -   * The pattern can be decoded easily as a number with base `numOfColors` and
    -   * `positions` representing the digits. For example if numOfColors is 5 and
    -   * positions is 3 then the pattern is converted to a number that is base 5
    -   * with three digits. Each digit then maps to a particular color.
    -   *
    -   * @param solution one of many possible solutions
    -   * @return String representing this solution's color combination.
    -   */
    -  private String solutionIdToColorCode(final int solution) {
    -    StringBuilder secretCode = new StringBuilder();
    -    int pos = possibilities;
    -    int remainder = solution;
    -    for (int i = positions - 1; i > 0; i--) {
    -      pos = pos / numOfColors;
    -      secretCode.append(colors[remainder / pos].toString());
    -      remainder = remainder % pos;
    -    }
    -    secretCode.append(colors[remainder].toString());
    -    return secretCode.toString();
    -  }
    -
    -  private static void displayColorCodes(int numOfColors) {
    -    pl("\n\nCOLOR     LETTER\n=====     ======");
    -    Arrays.stream(Color.values())
    -          .limit(numOfColors)
    -          .map(c -> c.name + " ".repeat(13 - c.name.length()) + c)
    -          .forEach(Mastermind::pl);
    -    pl();pl();
    -  }
    -
    -  private static void title() {
    -    pl("""    
    -                                  MASTERMIND
    -                   CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY%n%n%n
    -    """);
    -  }
    -
    -  /////////////////////////////////////////////////////////
    -  // User input functions from here on
    -
    -  /**
    -   * Base input function to be called from a specific input function.
    -   * Re-prompts upon unexpected or invalid user input.
    -   * Discards any remaining input in the line of user entered input once
    -   * it gets what it wants.
    -   * @param descriptor  Describes explicit type of input expected
    -   * @param extractor   The method performed against a Scanner object to parse
    -   *                    the type of input.
    -   * @param conditional A test that the input meets a minimum validation.
    -   * @param          Input type returned.
    -   * @return            input type for this line of user input.
    -   */
    -  private static  T getInput(String descriptor,
    -                                Function extractor,
    -                                Predicate conditional) {
    -
    -    Scanner scanner = new Scanner(System.in);
    -    while (true) {
    -      try {
    -        T input = extractor.apply(scanner);
    -        if (conditional.test(input)) {
    -          return input;
    -        }
    -      } catch (Exception ex) {
    -        try {
    -          // If we are here then a call on the scanner was most likely unable to
    -          // parse the input. We need to flush whatever is leftover from this
    -          // line of interactive user input so that we can re-prompt for new input.
    -          scanner.nextLine();
    -        } catch (Exception ns_ex) {
    -          // if we are here then the input has been closed, or we received an
    -          // EOF (end of file) signal, usually in the form of a ctrl-d or
    -          // in the case of Windows, a ctrl-z.
    -          pl("END OF INPUT, STOPPING PROGRAM.");
    -          System.exit(1);
    -        }
    -      }
    -      pf("!%s EXPECTED - RETRY INPUT LINE%n? ", descriptor);
    -    }
    -  }
    -
    -  private static int getPositiveNumber() {
    -    return getInput("NUMBER", Scanner::nextInt, num -> num > 0);
    -  }
    -
    -  private static int getPositiveNumberUpTo(long to) {
    -    return getInput(
    -        "NUMBER FROM 1 TO " + to,
    -        Scanner::nextInt,
    -        num -> num > 0 && num <= to);
    -  }
    -
    -  private static int[] getPegCount(int upperBound) {
    -    int[] nums = {Integer.MAX_VALUE, Integer.MAX_VALUE};
    -    while (true) {
    -      String input = getInput(
    -          "NUMBER, NUMBER",
    -          Scanner::nextLine,
    -          s -> s.matches("\\d+[\\s,]+\\d+$"));
    -      String[] numbers = input.split("[\\s,]+");
    -      nums[0] = Integer.parseInt(numbers[0].trim());
    -      nums[1] = Integer.parseInt(numbers[1].trim());
    -      if (nums[0] <= upperBound && nums[1] <= upperBound &&
    -          nums[0] >= 0 && nums[1] >= 0) {
    -        return nums;
    -      }
    -      pf("NUMBERS MUST BE FROM 0 TO %d.%n? ", upperBound);
    -    }
    -  }
    -
    -  private static String getWord() {
    -    return getInput("WORD", Scanner::next, word -> !"".equals(word));
    -  }
    -}
    diff --git a/60_Mastermind/javascript/mastermind.html b/60_Mastermind/javascript/mastermind.html
    index 74e7f593f..e1835c05a 100644
    --- a/60_Mastermind/javascript/mastermind.html
    +++ b/60_Mastermind/javascript/mastermind.html
    @@ -1,10 +1,9 @@
     
     
     MASTERMIND
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/60_Mastermind/javascript/mastermind.js b/60_Mastermind/javascript/mastermind.js
    index 1fbd13ec2..40d8139e3 100644
    --- a/60_Mastermind/javascript/mastermind.js
    +++ b/60_Mastermind/javascript/mastermind.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    @@ -269,8 +269,6 @@ async function main()
                     print("YOU GUESSED IT IN " + m + " MOVES!\n");
                     break;
                 }
    -            //tell human results
    -            print("YOU HAVE " + b + " BLACKS AND " + w + " WHITES.")
                 // Save all this stuff for board printout later
                 ss[m] = str;
                 sa[m] = [];
    @@ -282,7 +280,7 @@ async function main()
             }
             h += m;
             show_score();
    -
    +        
             //
             // Now computer guesses
             //
    diff --git a/60_Mastermind/kotlin/README.md b/60_Mastermind/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/60_Mastermind/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/60_Mastermind/lua/README.md b/60_Mastermind/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/60_Mastermind/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/60_Mastermind/mastermind.bas b/60_Mastermind/mastermind.bas
    index e6d548935..774c062c2 100644
    --- a/60_Mastermind/mastermind.bas
    +++ b/60_Mastermind/mastermind.bas
    @@ -27,7 +27,7 @@
     240 NEXT X
     250 PRINT
     260 FOR R=1 TO R9
    -270 PRINT
    +270 PRINT 
     280 PRINT "ROUND NUMBER";R;"----"
     290 PRINT
     300 PRINT "GUESS MY COMBINATION.":PRINT
    diff --git a/60_Mastermind/pascal/README.md b/60_Mastermind/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/60_Mastermind/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/60_Mastermind/perl/README.md b/60_Mastermind/perl/README.md
    index 67786f328..e69c8b819 100644
    --- a/60_Mastermind/perl/README.md
    +++ b/60_Mastermind/perl/README.md
    @@ -1,7 +1,3 @@
     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
    deleted file mode 100755
    index 873648529..000000000
    --- a/60_Mastermind/perl/mastermind.pl
    +++ /dev/null
    @@ -1,419 +0,0 @@
    -#!/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 :
    diff --git a/60_Mastermind/python/mastermind.py b/60_Mastermind/python/mastermind.py
    index 8fcecc624..ccc2ae9c2 100644
    --- a/60_Mastermind/python/mastermind.py
    +++ b/60_Mastermind/python/mastermind.py
    @@ -1,226 +1,230 @@
    -import random
    -import sys
    -from typing import List, Union, Tuple
    -
    -
    -#  define some parameters for the game which should not be modified.
    -def setup_game() -> Tuple[int, int, int, int]:
    -    print("""
    -                                  MASTERMIND
    -                   CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY
    -
    -
    -
    -    """)
    -    # get user inputs for game conditions
    -    num_colors: int = len(COLOR_LETTERS) + 1
    -    while num_colors > len(COLOR_LETTERS):
    -        num_colors = int(input("Number of colors (max 8): "))  # C9 in BASIC
    -    num_positions = int(input("Number of positions: "))  # P9 in BASIC
    -    num_rounds = int(input("Number of rounds: "))  # R9 in BASIC
    -    possibilities = num_colors**num_positions
    -
    -    print(f"Number of possibilities {possibilities}")
    -    print("Color\tLetter")
    -    print("=====\t======")
    -    for element in range(0, num_colors):
    -        print(f"{COLORS[element]}\t{COLORS[element][0]}")
    -    return num_colors, num_positions, num_rounds, possibilities
    -
    -
    -# Global variables
    -COLORS = ["BLACK", "WHITE", "RED", "GREEN", "ORANGE", "YELLOW", "PURPLE", "TAN"]
    -COLOR_LETTERS = "BWRGOYPT"
    -NUM_COLORS, NUM_POSITIONS, NUM_ROUNDS, POSSIBILITIES = setup_game()
    -human_score = 0
    -computer_score = 0
    -
    -
    -def main() -> None:
    -    current_round = 1
    -    while current_round <= NUM_ROUNDS:
    -        print(f"Round number {current_round}")
    -        human_turn()
    -        computer_turn()
    -        current_round += 1
    -    print_score(is_final_score=True)
    -    sys.exit()
    -
    -
    -def human_turn() -> None:
    -    global human_score
    -    num_moves = 1
    -    guesses: List[List[Union[str, int]]] = []
    -    print("Guess my combination ...")
    -    secret_combination = int(POSSIBILITIES * random.random())
    -    answer = possibility_to_color_code(secret_combination)
    -    while True:
    -        print(f"Move # {num_moves} Guess : ")
    -        user_command = input("Guess ")
    -        if user_command == "BOARD":
    -            print_board(guesses)  # 2000
    -        elif user_command == "QUIT":  # 2500
    -            print(f"QUITTER! MY COMBINATION WAS: {answer}")
    -            print("GOOD BYE")
    -            quit()
    -        elif len(user_command) != NUM_POSITIONS:  # 410
    -            print("BAD NUMBER OF POSITIONS")
    -        else:
    -            invalid_letters = get_invalid_letters(user_command)
    -            if invalid_letters > "":
    -                print(f"INVALID GUESS: {invalid_letters}")
    -            else:
    -                guess_results = compare_two_positions(user_command, answer)
    -                if guess_results[1] == NUM_POSITIONS:  # correct guess
    -                    print(f"You guessed it in {num_moves} moves!")
    -                    human_score = human_score + num_moves
    -                    print_score()
    -                    return  # from human turn, triumphant
    -                else:
    -                    print(f"You have {guess_results[1]} blacks and {guess_results[2]} whites")
    -                    guesses.append(guess_results)
    -                    num_moves += 1
    -
    -        if num_moves > 10:  # RAN OUT OF MOVES
    -            print("YOU RAN OUT OF MOVES! THAT'S ALL YOU GET!")
    -            print(f"THE ACTUAL COMBINATION WAS: {answer}")
    -            human_score = human_score + num_moves
    -            print_score()
    -            return  # from human turn, defeated
    -
    -
    -def computer_turn() -> None:
    -    global computer_score
    -    while True:
    -        all_possibilities = [1] * POSSIBILITIES
    -        num_moves = 1
    -        print("NOW I GUESS. THINK OF A COMBINATION.")
    -        input("HIT RETURN WHEN READY: ")
    -        while True:
    -            possible_guess = find_first_solution_of(all_possibilities)
    -            if possible_guess < 0:  # no solutions left :(
    -                print("YOU HAVE GIVEN ME INCONSISTENT INFORMATION.")
    -                print("TRY AGAIN, AND THIS TIME PLEASE BE MORE CAREFUL.")
    -                break  # out of inner while loop, restart computer turn
    -
    -            computer_guess = possibility_to_color_code(possible_guess)
    -            print(f"My guess is: {computer_guess}")
    -            blacks_str, whites_str = input(
    -                "ENTER BLACKS, WHITES (e.g. 1,2): "
    -            ).split(",")
    -            blacks = int(blacks_str)
    -            whites = int(whites_str)
    -            if blacks == NUM_POSITIONS:  # Correct guess
    -                print(f"I GOT IT IN {num_moves} MOVES")
    -                computer_score = computer_score + num_moves
    -                print_score()
    -                return  # from computer turn
    -
    -            # computer guessed wrong, deduce which solutions to eliminate.
    -            for i in range(0, POSSIBILITIES):
    -                if all_possibilities[i] == 0:  # already ruled out
    -                    continue
    -                possible_answer = possibility_to_color_code(i)
    -                comparison = compare_two_positions(
    -                    possible_answer, computer_guess
    -                )
    -                if (blacks != comparison[1]) or (whites != comparison[2]):
    -                    all_possibilities[i] = 0
    -
    -            if num_moves == 10:
    -                print("I USED UP ALL MY MOVES!")
    -                print("I GUESS MY CPU IS JUST HAVING AN OFF DAY.")
    -                computer_score = computer_score + num_moves
    -                print_score()
    -                return  # from computer turn, defeated.
    -            num_moves += 1
    -
    -
    -def find_first_solution_of(all_possibilities: List[int]) -> int:
    -    """Scan through all_possibilities for first remaining non-zero marker,
    -    starting from some random position and wrapping around if needed.
    -    If not found return -1."""
    -    start = int(POSSIBILITIES * random.random())
    -    for i in range(0, POSSIBILITIES):
    -        solution = (i + start) % POSSIBILITIES
    -        if all_possibilities[solution]:
    -            return solution
    -    return -1
    -
    -
    -# 470
    -def get_invalid_letters(user_command) -> str:
    -    """Makes sure player input consists of valid colors for selected game configuration."""
    -    valid_colors = COLOR_LETTERS[:NUM_COLORS]
    -    invalid_letters = ""
    -    for letter in user_command:
    -        if letter not in valid_colors:
    -            invalid_letters = invalid_letters + letter
    -    return invalid_letters
    -
    -
    -# 2000
    -def print_board(guesses) -> None:
    -    """Print previous guesses within the round."""
    -    print("Board")
    -    print("Move\tGuess\tBlack White")
    -    for idx, guess in enumerate(guesses):
    -        print(f"{idx + 1}\t{guess[0]}\t{guess[1]}     {guess[2]}")
    -
    -
    -def possibility_to_color_code(possibility: int) -> str:
    -    """Accepts a (decimal) number representing one permutation in the realm of
    -    possible secret codes and returns the color code mapped to that permutation.
    -    This algorithm is essentially converting a decimal  number to a number with
    -    a base of #num_colors, where each color code letter represents a digit in
    -    that #num_colors base."""
    -    color_code: str = ""
    -    pos: int = NUM_COLORS ** NUM_POSITIONS  # start with total possibilities
    -    remainder = possibility
    -    for _ in range(NUM_POSITIONS - 1, 0, -1):  # process all but the last digit
    -        pos = pos // NUM_COLORS
    -        color_code += COLOR_LETTERS[remainder // pos]
    -        remainder = remainder % pos
    -    color_code += COLOR_LETTERS[remainder]  # last digit is what remains
    -    return color_code
    -
    -
    -# 4500
    -def compare_two_positions(guess: str, answer: str) -> List[Union[str, int]]:
    -    """Returns blacks (correct color and position) and whites (correct color
    -    only) for candidate position (guess) versus reference position (answer)."""
    -    blacks = 0
    -    whites = 0
    -    initial_guess = guess
    -    increment = 0
    -    for pos in range(0, NUM_POSITIONS):
    -        if guess[pos] != answer[pos]:
    -            for pos2 in range(0, NUM_POSITIONS):
    -                if guess[pos] == answer[pos2] and guess[pos2] != answer[pos2]:  # correct color but not correct place
    -                    whites = whites + 1
    -                    answer = answer[:pos2] + chr(increment) + answer[pos2 + 1:]
    -                    guess = guess[:pos] + chr(increment + 1) + guess[pos + 1:]
    -                    increment = increment + 2
    -        else:  # correct color and placement
    -            blacks = blacks + 1
    -            # THIS IS DEVIOUSLY CLEVER
    -            guess = guess[:pos] + chr(increment + 1) + guess[pos + 1:]
    -            answer = answer[:pos] + chr(increment) + answer[pos + 1:]
    -            increment = increment + 2
    -    return [initial_guess, blacks, whites]
    -
    -
    -# 5000 + logic from 1160
    -def print_score(is_final_score: bool = False) -> None:
    -    """Print score after each turn ends, including final score at end of game."""
    -    if is_final_score:
    -        print("GAME OVER")
    -        print("FINAL SCORE:")
    -    else:
    -        print("SCORE:")
    -    print(f"     COMPUTER {computer_score}")
    -    print(f"     HUMAN    {human_score}")
    -
    -
    -if __name__ == "__main__":
    -    main()
    +import random, sys
    +
    +
    +
    +def main():
    +
    +    global colors, color_letters, num_positions, num_colors, human_score, computer_score
    +    colors = ["BLACK", "WHITE", "RED", "GREEN", "ORANGE", "YELLOW", "PURPLE", "TAN"]
    +    color_letters = "BWRGOYPT"
    +
    +    num_colors = 100
    +    human_score = 0
    +    computer_score = 0
    +
    +    # get user inputs for game conditions
    +    print("Mastermind")
    +    print('Creative Computing Morristown, New Jersey')
    +    while num_colors > 8:
    +        num_colors = int(input("Number of colors (max 8): ")) # C9 in BASIC
    +    num_positions = int(input("Number of positions: ")) # P9 in BASIC
    +    num_rounds = int(input("Number of rounds: ")) # R9 in BASIC
    +    possibilities = num_colors**num_positions
    +    all_possibilities = [1] * possibilities
    +
    +    print("Number of possibilities {}".format(possibilities))
    +    print('Color\tLetter')
    +    print('=====\t======')
    +    for element in range(0, num_colors):
    +        print("{}\t{}".format(colors[element], colors[element][0]))
    +
    +    current_round = 1
    +
    +    while current_round <= num_rounds:
    +        print('Round number {}'.format(current_round))
    +        num_moves = 1
    +        guesses = []
    +        turn_over = False
    +        print('Guess my combination ...')
    +        answer = int(possibilities * random.random()) 
    +        numeric_answer = [-1] * num_positions
    +        for i in range(0, answer):
    +            numeric_answer = get_possibility(numeric_answer)
    +        #human_readable_answer = make_human_readable(numeric_answer)
    +        while (num_moves < 10 and not turn_over ):
    +            print('Move # {} Guess : '.format(num_moves))
    +            user_command = input('Guess ')
    +            if user_command == "BOARD":
    +                print_board(guesses) #2000
    +            elif user_command == "QUIT": #2500
    +                human_readable_answer = make_human_readable(numeric_answer)
    +                print('QUITTER! MY COMBINATION WAS: {}'.format(human_readable_answer))
    +                print('GOOD BYE')
    +                quit()
    +            elif len(user_command) != num_positions: #410
    +                print("BAD NUMBER OF POSITIONS")
    +            else:
    +                invalid_letters = get_invalid_letters(user_command)
    +                if invalid_letters > "":
    +                    print("INVALID GUESS: {}".format(invalid_letters))
    +                else:
    +                    guess_results = compare_two_positions(user_command, make_human_readable(numeric_answer))
    +                    print("Results: {}".format(guess_results))
    +                    if guess_results[1] == num_positions: # correct guess
    +                        turn_over = True
    +                        print("You guessed it in {} moves!".format(num_moves))
    +                        human_score = human_score + num_moves
    +                        print_score()
    +                    else:
    +                        print("You have {} blacks and {} whites".format(guess_results[1], guess_results[2]))
    +                        num_moves = num_moves + 1
    +                        guesses.append(guess_results)
    +        if not turn_over: # RAN OUT OF MOVES
    +            print ("YOU RAN OUT OF MOVES! THAT'S ALL YOU GET!")
    +            print("THE ACTUAL COMBINATION WAS: {}".format(make_human_readable(numeric_answer)))
    +            human_score = human_score + num_moves
    +            print_score()
    +
    +        # COMPUTER TURN
    +        guesses = []
    +        turn_over = False
    +        inconsistent_information = False
    +        while(not turn_over  and not inconsistent_information ):
    +            all_possibilities = [1] * possibilities
    +            num_moves = 1
    +            inconsistent_information = False
    +            print ("NOW I GUESS. THINK OF A COMBINATION.")
    +            player_ready = input("HIT RETURN WHEN READY: ")
    +            while (num_moves < 10 and not turn_over  and not inconsistent_information):
    +                found_guess = False
    +                computer_guess = int(possibilities * random.random())
    +                if all_possibilities[computer_guess] == 1: # random guess is possible, use it
    +                    found_guess = True
    +                    guess = computer_guess
    +                else:
    +                    for i in range (computer_guess, possibilities):
    +                        if all_possibilities[i] == 1:
    +                            found_guess = True
    +                            guess = i
    +                            break
    +                    if not found_guess:
    +                        for i in range (0, computer_guess):
    +                            if all_possibilities[i] == 1:
    +                                found_guess = True
    +                                guess = i
    +                                break
    +                if not found_guess: # inconsistent info from user
    +                    print('YOU HAVE GIVEN ME INCONSISTENT INFORMATION.')
    +                    print('TRY AGAIN, AND THIS TIME PLEASE BE MORE CAREFUL.')
    +                    turn_over = True
    +                    inconsistent_information = True
    +                else:
    +                    numeric_guess = [-1] * num_positions
    +                    for i in range(0, guess):
    +                        numeric_guess = get_possibility(numeric_guess)
    +                    human_readable_guess = make_human_readable(numeric_guess)
    +                    print('My guess is: {}'.format(human_readable_guess))
    +                    blacks, whites = input("ENTER BLACKS, WHITES (e.g. 1,2): ").split(",")
    +                    blacks = int(blacks)
    +                    whites = int(whites)
    +                    if blacks == num_positions: #Correct guess
    +                        print('I GOT IT IN {} MOVES'.format(num_moves))
    +                        turn_over = True
    +                        computer_score = computer_score + num_moves
    +                        print_score()
    +                    else:
    +                        num_moves += 1
    +                        for i in range (0, possibilities):   
    +                            if all_possibilities[i] == 0: #already ruled out
    +                                continue
    +                            numeric_possibility = [-1] * num_positions
    +                            for j in range (0, i):
    +                                numeric_possibility = get_possibility(numeric_possibility)
    +                            human_readable_possibility = make_human_readable(numeric_possibility) #4000
    +                            comparison = compare_two_positions(human_readable_possibility, human_readable_guess)
    +                            print(comparison)
    +                            if ((blacks != comparison[1]) or (whites != comparison[2])):
    +                                all_possibilities[i] = 0
    +            if not turn_over: # COMPUTER DID NOT GUESS
    +                print("I USED UP ALL MY MOVES!")
    +                print("I GUESS MY CPU IS JUST HAVING AN OFF DAY.")
    +                computer_score = computer_score + num_moves
    +                print_score()
    +        current_round += 1
    +    print_score(is_final_score=True)
    +    sys.exit()
    +
    +#470
    +def get_invalid_letters(user_command):
    +    """Makes sure player input consists of valid colors for selected game configuration."""
    +    valid_colors = color_letters[:num_colors]
    +    invalid_letters = ""
    +    for letter in user_command:
    +        if letter not in valid_colors:
    +            invalid_letters = invalid_letters + letter
    +    return invalid_letters
    +
    +#2000
    +def print_board(guesses):
    +    """Prints previous guesses within the round."""
    +    print("Board")
    +    print("Move\tGuess\tBlack White")
    +    for idx, guess in enumerate(guesses):
    +        print('{}\t{}\t{}     {}'.format(idx+1, guess[0], guess[1], guess[2]))
    +
    +#3500
    +# Easily the place for most optimization, since they generate every possibility 
    +# every time when checking for potential solutions
    +# From the original article: 
    +#    "We did try a version that kept an actual list of all possible combinations
    +#    (as a string array), which was significantly faster than this versionn but
    +#    which ate tremendous amounts of memory."
    +def get_possibility(possibility):
    +    #print(possibility)
    +    if possibility[0] > -1: #3530
    +        current_position = 0 # Python arrays are zero-indexed
    +        while True:
    +            if possibility[current_position] < num_colors-1: # zero-index again
    +                possibility[current_position] += 1
    +                return possibility
    +            else:
    +                possibility[current_position] = 0
    +                current_position += 1
    +    else: #3524
    +        possibility = [0] * num_positions
    +    return possibility
    +
    +#4500
    +def compare_two_positions(guess, answer):
    +    """Returns blacks (correct color and position) and whites (correct color only) for candidate position (guess) versus reference position (answer)."""
    +    increment = 0
    +    blacks = 0
    +    whites = 0
    +    initial_guess = guess
    +    for pos in range(0, num_positions):
    +        if guess[pos] != answer[pos]:
    +            for pos2 in range(0, num_positions):
    +                if not(guess[pos] != answer[pos2] or guess[pos2] == answer[pos2]): # correct color but not correct place
    +                    whites = whites + 1
    +                    answer = answer[:pos2] + chr(increment) + answer[pos2+1:]
    +                    guess = guess[:pos] + chr(increment+1) + guess[pos+1:]
    +                    increment = increment + 2
    +        else: #correct color and placement
    +            blacks = blacks + 1
    +            # THIS IS DEVIOUSLY CLEVER
    +            guess = guess[:pos] + chr(increment+1) + guess[pos+1:]
    +            answer = answer[:pos] + chr(increment) + answer[pos+1:]
    +            increment = increment + 2
    +    return [initial_guess, blacks, whites]
    + 
    +#5000 + logic from 1160
    +def print_score(is_final_score=False):
    +    """Prints score after each turn ends, including final score at end of game."""
    +    if is_final_score:
    +        print("GAME OVER")
    +        print("FINAL SCORE:")
    +    else:
    +        print("SCORE:")
    +    print("     COMPUTER {}".format(computer_score))
    +    print("     HUMAN    {}".format(human_score))
    +
    +#4000, 5500, 6000 subroutines are all identical
    +def make_human_readable(num):
    +    """Make the numeric representation of a position human readable."""
    +    retval = ''
    +    for i in range(0, len(num)):
    +        retval = retval + color_letters[int(num[i])]
    +    return retval
    +
    +if __name__ == "__main__":
    +    main()
    diff --git a/60_Mastermind/rust/Mastermind/Cargo.toml b/60_Mastermind/rust/Mastermind/Cargo.toml
    deleted file mode 100644
    index 83729722a..000000000
    --- a/60_Mastermind/rust/Mastermind/Cargo.toml
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -[package]
    -name = "mastermind"
    -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/60_Mastermind/rust/Mastermind/README.md b/60_Mastermind/rust/Mastermind/README.md
    deleted file mode 100644
    index 7e85f9a15..000000000
    --- a/60_Mastermind/rust/Mastermind/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Rust](https://www.rust-lang.org/) by Anthony Rubick [AnthonyMichaelTDM](https://github.com/AnthonyMichaelTDM)
    diff --git a/60_Mastermind/rust/Mastermind/src/main.rs b/60_Mastermind/rust/Mastermind/src/main.rs
    deleted file mode 100644
    index 92fc852a5..000000000
    --- a/60_Mastermind/rust/Mastermind/src/main.rs
    +++ /dev/null
    @@ -1,420 +0,0 @@
    -use rand::{Rng, prelude::{thread_rng, ThreadRng}};
    -use std::{io, fmt::Display, str::FromStr};
    -
    -//DATA
    -const COLORS: [&str;8] = ["Black ", "White ","Red ","Green ","Orange ","Yellow ", "Purple ", "Tan "]; //all available colors
    -const LETTERS: &str = "BWRGOYPT"; //letters representing the above colors
    -
    -struct CODE {
    -    code: Vec, //maybe use a char array later, idk
    -
    -}
    -impl CODE {
    -    /**
    -     * create generic, empty code
    -     */
    -    fn new() -> CODE {
    -        return CODE{code: Vec::new()};
    -    }
    -    /**
    -     * generates and returns a random CODE with the given parameters
    -     */
    -    fn new_random(rng: &mut ThreadRng, num_colors: usize, num_positions: usize) -> CODE {
    -        //data
    -        let mut code = CODE{code: Vec::new()};
    -        //generate random combination of colors
    -        for _i in 0..num_positions {
    -            code.code.push(rng.gen_range(0..num_colors));
    -        }
    -        return code;
    -    }
    -    /**
    -     * converts input_int from base 10 to base num_colors to generate the code
    -     * input_int must be between 0 and num_colors.pow(num_positions)
    -     */
    -    fn new_from_int(mut input_int: usize, num_colors: usize, num_positions: usize) -> CODE {
    -        //DATA
    -        let mut converted_number:Vec<_> = Vec::new();
    -        assert!(2 <= num_colors && num_colors <= 36); //if num_colors is outside of this range, things break later on
    -
    -        //convert input_int into a code by effectively converting input_int from base 10 to base n where n is num_colors, uses some fancy stuff to do this
    -        loop {
    -            converted_number.push(std::char::from_digit((input_int % num_colors) as u32, num_colors as u32).unwrap()); //
    -            input_int /= num_colors;
    -            if input_int == 0 {break}
    -        }
    -
    -        while converted_number.len() < num_positions {converted_number.push('0');} // fill remaining space with zero's
    -        let converted_number: Vec<_> = converted_number.iter().rev().map(|e| e.to_digit(num_colors as u32).unwrap() as usize).collect(); //reverse the vector and convert it to integers
    -        return CODE{code: converted_number};
    -    }
    -    /**
    -     * returns a code parsed from the passed string
    -     */
    -    fn new_from_string(input_string: String, num_colors: usize) -> Option {
    -        let valid_chars = &LETTERS[0..num_colors];
    -        //DATA
    -        let new_code = CODE{
    -            code:
    -            input_string.to_ascii_uppercase().chars() //get an iterator with all the chars in input string converted to uppercase
    -            .filter( |c| { valid_chars.contains(*c)}) //remove chars that aren't in LETTERS
    -            .map( |x| -> usize {valid_chars.find(x).expect("invalid character")})//convert all the chars into usizes representing their index in LETTERS
    -            .collect() //wrap this iterator up into a vector
    -        };
    -        //if code is empty, return None, otherwise return Some(code)
    -        if new_code.code.is_empty() {return None;}
    -        else {return Some(new_code);}
    -    }
    -
    -    /**
    -     * returns a string containing the code represented as characters
    -     */
    -    fn _as_human_readible_chars(&self) -> String {
    -        return self.code.iter().map(|i|->char{LETTERS.chars().nth(*i).expect("index out of bounds")}).collect();
    -    }
    -    /**
    -     * returns a string containing the code represented as words
    -     */
    -    fn _as_human_readible_words(&self) -> String {
    -        return self.code.iter().map(|i|->&str{COLORS.iter().nth(*i).expect("index out of bounds")}).collect();
    -    }
    -}
    -struct GUESS {
    -    code: CODE,
    -    blacks: usize,
    -    whites: usize,
    -}
    -impl GUESS {
    -    /**
    -     * create a new guess, and evaluate it
    -     */
    -    fn new(code: CODE) -> GUESS {
    -        return GUESS{code:code, blacks:0,whites:0 };
    -    }
    -
    -    /**
    -     * evaulates itself for the number of black and white pegs it should have for a given answer
    -     */
    -    fn evaluate(&mut self, answer:&CODE) {
    -        //data
    -        let mut consumed = vec![false;answer.code.len()];
    -
    -        if self.code.code.len() != answer.code.len() {
    -            panic!("only codes of the same length can be compared");
    -        }
    -
    -        for i in 0..answer.code.len() {
    -            if self.code.code[i] == answer.code[i] { //correct value correct place
    -                self.blacks += 1;
    -                consumed[i] = true;
    -            }
    -            else {
    -                //check for correct value incorrect place, don't count positions that are already exact matches
    -                for j in 0..answer.code.len() {
    -                    if !consumed[j] && self.code.code[i] == answer.code[j] && self.code.code[j] != answer.code[j] {
    -                        self.whites += 1;
    -                        consumed[j] = true;
    -                        break;
    -                    }
    -                }
    -            }
    -        }
    -    }
    -}
    -
    -fn main() {
    -    //DATA
    -    let mut rng = thread_rng();
    -    let num_colors: usize;
    -    let num_positions: usize;
    -    let num_rounds: usize;
    -    let num_guesses: usize;
    -    let total_posibilities: usize;
    -
    -    let mut human_score: usize = 0;
    -    let mut computer_score: usize = 0;
    -
    -    //print welcome message
    -    welcome();
    -
    -    //ask user for a number of colors, positions, and rounds
    -    num_colors = get_number_from_user_input("NUMBER OF COLORS", "", 1, COLORS.len());
    -    num_positions = get_number_from_user_input("NUMBER OF POSITIONS", "", 2, 10);
    -    num_rounds = get_number_from_user_input("NUMBER OF ROUNDS", "", 1, 10);
    -    num_guesses = get_number_from_user_input("NUMBER OF GUESSES", "", 10, 0);
    -
    -
    -    //print number of posibilities
    -    total_posibilities = num_colors.pow(num_positions as u32);
    -    println!("\nTOTAL POSSIBILITIES = {}\n", total_posibilities);
    -
    -    //print color letter table
    -    print_color_letter_table(num_colors);
    -
    -    //game loop
    -    for round_num in 1..=num_rounds {
    -        //data
    -        let mut num_moves: usize = 1;
    -        let mut answer: CODE;
    -        let mut guess: GUESS;
    -        let mut guesses: Vec = Vec::new();
    -        let mut all_possibilities = vec![true; total_posibilities];
    -
    -
    -        //print round number
    -        println!("\n\nROUND NUMBER: {}", round_num);
    -
    -        //human player is code-breaker, computer is code-maker
    -        //generate a combination
    -        answer = CODE::new_random(&mut rng, num_colors, num_positions);
    -        //println!("CODE: {:?}", answer._as_human_readible_chars()); //this is for troubleshooting, prints the code converted back into characters
    -
    -        //round loop
    -        loop {
    -            //loop condition
    -            if num_moves > num_guesses {
    -                println!("YOU RAN OUT OF MOVES!  THAT'S ALL YOU GET!");
    -                println!("THE ACTUAL COMBINATION WAS: {}", answer._as_human_readible_chars());
    -                human_score += num_moves;
    -                print_scores(human_score,computer_score);
    -                break;
    -            }
    -
    -            //input loop
    -            guess = GUESS::new(loop {
    -                println!("\nMOVE # {} GUESS: ", num_moves);
    -
    -                //get player move
    -                let mut raw_input = String::new(); //temp variable to store user input
    -                io::stdin().read_line(&mut raw_input).expect("CANNOT READ INPUT!"); //read user input from standard input and store it to raw_input
    -
    -                //attempt to parse input
    -                if raw_input.trim().eq_ignore_ascii_case("board") {
    -                    //print the board state
    -                    print_board(&guesses);
    -                    continue; //run loop again
    -                }
    -                else if raw_input.trim().eq_ignore_ascii_case("quit") {
    -                    //quit the game
    -                    println!("QUITTER!  MY COMBINATION WAS: {}\nGOOD BYE", answer._as_human_readible_words());
    -                    return; //exit the game
    -                }
    -                else {
    -                    //parse input for a code
    -                    match CODE::new_from_string(raw_input, num_colors) {
    -                        Some(code) => {
    -                            //ensure code is correct length
    -                            if code.code.len() != num_positions { // if not
    -                                println!("BAD NUMBER OF POSITIONS.");
    -                                continue; //run loop again
    -                            }
    -                            else {break code;}//break with the code
    -                        },
    -                        None => continue, //run loop again
    -                    }
    -                }
    -            });
    -
    -            //evaluate guess
    -            guess.evaluate(&answer);
    -            let blacks = guess.blacks;
    -            let whites = guess.whites;
    -            //add guess to the list of guesses
    -            guesses.push(guess);
    -
    -            //tell human the results
    -            if blacks >= num_positions { //guessed it correctly
    -                println!("YOU GUESSED IT IN {} MOVES!", num_moves);
    -                human_score += num_moves;
    -                print_scores(human_score,computer_score);
    -                break; //break from loop
    -            } else { //didn't
    -                println!("YOU HAVE {} BLACKS AND {} WHITES.", blacks, whites);
    -                //increment moves
    -                num_moves += 1;
    -            }
    -        }
    -
    -        //computer is code-breaker, human player is code-maker
    -        println!("\nNOW I GUESS.  THINK OF A COMBINATION.\nHIT RETURN WHEN READY: ");
    -        //prompt user to give a valid combination #730
    -        //input loop
    -        answer = loop {
    -            let mut raw_input = String::new(); //temp variable to store user input
    -            io::stdin().read_line(&mut raw_input).expect("CANNOT READ INPUT!"); //read user input from standard input and store it to raw_input
    -
    -            //attempt to create a code from the user input, if successful break the loop returning the code
    -            if let Some(code) = CODE::new_from_string(raw_input, num_colors) {
    -                if code.code.len() == num_positions {break code;} //exit loop with code
    -                else {println!("CODE MUST HAVE {} POSITIONS", num_positions);continue;} //tell them to try again
    -            }
    -
    -            println!("INVALID CODE.  TRY AGAIN"); //if unsuccessful, this is printed and the loop runs again
    -        };
    -
    -        //reset some things in preparation for computer play
    -        guesses.clear();
    -        num_moves = 0;
    -        //let num_colors = *answer.code.iter().max().unwrap(); //figure out the number of colors from the code | Commented bc we're enforcing that the computer cracks the same size code as the human
    -        //let num_positions = answer.code.len(); //figure out the number of positions from the code | Commented bc we're enforcing that the computer cracks the same size code as the human
    -
    -        //round loop
    -        loop {
    -            //loop condition
    -            if num_moves > num_guesses {
    -                println!("I USED UP ALL MY MOVES!");
    -                println!("I GUESS MY CPU IS JUST HAVING AN OFF DAY.");
    -                computer_score += num_moves;
    -                print_scores(human_score,computer_score);
    -                break;
    -            }
    -
    -            //randomly generate a guess //770
    -            let mut guess_int = rng.gen_range(0..total_posibilities);
    -            guess = GUESS::new(CODE::new());
    -            //if it's possible, use it //780
    -            if all_possibilities[guess_int] {
    -                guess = GUESS::new(CODE::new_from_int(guess_int, num_colors, num_positions)); //create guess
    -            }
    -            else {//if it's not possible:
    -                //  search all possibilities after guess, use first valid one //790
    -                for g in guess_int..total_posibilities {
    -                    if all_possibilities[g] {
    -                        guess_int=g;
    -                        guess = GUESS::new(CODE::new_from_int(guess_int, num_colors, num_positions)); //create guess
    -                        break;
    -                    }
    -                }
    -                //if none was found
    -                //  search all possibilities before guess, use first valid one //820
    -                if guess.code.code.is_empty() {
    -                    for g in (0..guess_int).rev() {
    -                        if all_possibilities[g] {
    -                            guess_int=g;
    -                            guess = GUESS::new(CODE::new_from_int(guess_int, num_colors, num_positions)); //create guess
    -                            break;
    -                        }
    -                    }
    -                }
    -                // if none where found, tell the user and start over #850
    -                if guess.code.code.is_empty() {
    -                    println!("YOU HAVE GIVEN ME INCONSISTENT INFORMATION.");
    -                    println!("PLAY AGAIN, AND THIS TIME PLEASE BE MORE CAREFUL.");
    -                    return; //exit game
    -                };
    -            }
    -
    -            //convert guess into something readible #890
    -            //print it #940
    -            println!("MY GUESS IS: {}", guess.code._as_human_readible_chars());
    -            //ask user for feedback, #980
    -            let blacks=get_number_from_user_input("BLACKS: ", "", 0, num_positions);
    -            let whites=get_number_from_user_input("WHITES: ", "", 0, num_positions);
    -
    -            //if we got it, end #990
    -            if blacks >= num_positions { //guessed it correctly
    -                println!("I GOT IT IN {} MOVES!", num_moves);
    -                computer_score += num_moves;
    -                print_scores(human_score,computer_score);
    -                break; //break from loop
    -            } else { //didn't
    -                all_possibilities[guess_int] = false;
    -                //if we didn't, eliminate the combinations that don't work
    -                //we know the number of black and white pegs for a valid answer, so eleminate all that get different amounts
    -                all_possibilities.iter_mut().enumerate().for_each(|b| {
    -                    if *b.1 { //filter out ones we already know aren't possible
    -                        let mut tmp_guess = GUESS::new(CODE::new_from_int(b.0, num_colors, num_positions));
    -                        tmp_guess.evaluate(&guess.code); //compare with computer guess
    -                        if blacks != tmp_guess.blacks || whites != tmp_guess.whites { //if number of blacks/whites is different, set it to false
    -                            *b.1 = false;
    -                        }
    -                    }
    -                });
    -
    -                //increment moves
    -                num_moves += 1;
    -            }
    -
    -
    -        }
    -
    -    }
    -}
    -
    -/**
    - * print the welcome message
    - */
    -fn welcome() {
    -    println!("
    -                             MASTERMIND
    -              CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY
    -
    -
    -    ");
    -}
    -
    -/**
    - * print scores
    - */
    -fn print_scores(human_score:usize, computer_score:usize) {
    -    println!("SCORE\n\tCOMPUTER: {}\n\tHUMAN: {}", computer_score, human_score);
    -}
    -
    -/**
    - * print the color - letter table
    - * only prints the first num_colors pairs
    - */
    -fn print_color_letter_table(num_colors: usize) {
    -    println!("COLOR\tLETTER");
    -    println!("=====\t======");
    -    for i in 0..num_colors {
    -        println!("{}\t{}", COLORS[i], &LETTERS[i..i+1]);
    -    }
    -}
    -
    -fn print_board(guesses: &Vec) {
    -    println!("BOARD");
    -    println!("MOVE\tGUESS\t\tBLACK\tWhite");
    -    for guess in guesses.iter().enumerate() {
    -        println!("{}\t{}\t\t{}\t{}", guess.0,guess.1.code._as_human_readible_chars(),guess.1.blacks,guess.1.whites);
    -    }
    -}
    -
    -/**
    - * gets a number from user input
    - * pass an empty &str for error_message if you don't want one printed
    - * pass a min lower  than the max to have minimun and maximun bounds
    - * pass a min higher than the max to only have a minumum bound
    - * pass a min equal   to  the max to only have a maximun bound
    - */
    -fn get_number_from_user_input(prompt: &str, error_message: &str, min:T, max:T) -> T {
    -    //DATA
    -    let mut raw_input = String::new(); // temporary variable for user input that can be parsed later
    -
    -    //input loop
    -    return loop {
    -
    -        //print prompt
    -        println!("{}", prompt);
    -        //read user input from standard input, and store it to raw_input
    -        raw_input.clear(); //clear input
    -        io::stdin().read_line(&mut raw_input).expect( "CANNOT READ INPUT!");
    -
    -        //from input, try to read a number
    -        if let Ok(i) = raw_input.trim().parse() {
    -            //what bounds must the input fall into
    -            if min < max {  //have a min and max bound: [min,max]
    -                if i >= min && i <= max {//is input valid, within bounds
    -                    break i; //exit the loop with the value i, returning it
    -                } else {println!("ONLY BETWEEN {} AND {}, PLEASE!", min, max);} //print error message specific to this case
    -            } else if min > max { //only a min bound: [min, infinity)
    -                if i >= min {break i;} else {println!("NO LESS THAN {}, PLEASE!", min);}
    -            } else { //only a max bound: (-infinity, max]
    -                if i <= max {break i;} else {println!("NO MORE THAN {}, PLEASE!", max);}
    -            }
    -            continue; //continue to the next loop iteration
    -        };
    -        //this is only reached if a number couldn't be parsed from the input
    -        if !error_message.is_empty() {println!("{}",error_message);} //if they gave an error message to use, print it
    -    };
    -}
    diff --git a/60_Mastermind/rust/Mastermind_refactored_for_conventions/Cargo.toml b/60_Mastermind/rust/Mastermind_refactored_for_conventions/Cargo.toml
    deleted file mode 100644
    index 14762c87e..000000000
    --- a/60_Mastermind/rust/Mastermind_refactored_for_conventions/Cargo.toml
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -[package]
    -name = "mastermind_refactored_for_conventions"
    -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"
    \ No newline at end of file
    diff --git a/60_Mastermind/rust/Mastermind_refactored_for_conventions/README.md b/60_Mastermind/rust/Mastermind_refactored_for_conventions/README.md
    deleted file mode 100644
    index 7e85f9a15..000000000
    --- a/60_Mastermind/rust/Mastermind_refactored_for_conventions/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Rust](https://www.rust-lang.org/) by Anthony Rubick [AnthonyMichaelTDM](https://github.com/AnthonyMichaelTDM)
    diff --git a/60_Mastermind/rust/Mastermind_refactored_for_conventions/src/lib.rs b/60_Mastermind/rust/Mastermind_refactored_for_conventions/src/lib.rs
    deleted file mode 100644
    index 1fd92d62a..000000000
    --- a/60_Mastermind/rust/Mastermind_refactored_for_conventions/src/lib.rs
    +++ /dev/null
    @@ -1,463 +0,0 @@
    -/*
    - lib.rs contains all the logic of the program
    -*/
    -use rand::{Rng, prelude::thread_rng}; //rng
    -use std::error::Error; //better errors
    -use std::io::{self, Write}; //io interactions
    -use std::{str::FromStr, fmt::Display}; //traits
    -
    -//DATA
    -const COLORS: [&str;8] = ["Black ", "White ","Red ","Green ","Orange ","Yellow ", "Purple ", "Tan "]; //all available colors
    -const LETTERS: &str = "BWRGOYPT"; //letters representing the above colors
    -
    -/// handles setup for the game
    -pub struct Config {
    -    num_colors: usize,
    -    num_positions: usize,
    -    num_rounds: usize,
    -    num_guesses: usize,
    -    total_possibilities: usize,
    -}
    -impl Config {
    -    /// creates and returns a new Config from user input
    -    pub fn new() -> Result> {
    -        //DATA
    -        let mut config: Config = Config { 
    -            num_colors: 0,
    -            num_positions: 0,
    -            num_rounds: 0,
    -            num_guesses: 0,
    -            total_possibilities: 0,
    -        };
    -
    -        //get data from user input
    -        //input loop
    -        loop {match get_number_from_input("NUMBER OF COLORS: ", 2, COLORS.len()) {
    -            Ok(num) => {
    -                config.num_colors = num;
    -                break;
    -            },
    -            Err(e) => eprintln!("{}",e),
    -        }}
    -        //input loop
    -        loop {match get_number_from_input("NUMBER OF POSITIONS: ", 2, 10) {
    -            Ok(num) => {
    -                config.num_positions = num;
    -                break;
    -            },
    -            Err(e) => eprintln!("{}",e),
    -        }}
    -        //input loop
    -        loop {match get_number_from_input("NUMBER OF ROUNDS: ", 1, 10) {
    -            Ok(num) => {
    -                config.num_rounds = num;
    -                break;
    -            },
    -            Err(e) => eprintln!("{}",e),
    -        }}
    -        //input loop
    -        loop {match get_number_from_input("NUMBER OF GUESSES: ", 10, 0) {
    -            Ok(num) => {
    -                config.num_guesses = num;
    -                break;
    -            },
    -            Err(e) => eprintln!("{}",e),
    -        }}
    -        //calc total posibilities
    -        config.total_possibilities = config.num_colors.pow(config.num_positions as u32);
    -
    -        //return new config
    -        return Ok(config);
    -    }
    -}
    -
    -/// run the program
    -pub fn run(config: &Config) -> Result<(), Box> {
    -    //DATA
    -    let mut human_score: usize = 0;
    -    let mut computer_score: usize = 0;
    -
    -    //print number of possibilities
    -    println!("\nTOTAL POSSIBILITIES = {}\n", config.total_possibilities);
    -
    -    //print color letter table
    -    print_color_letter_table(config.num_colors);
    -
    -    //for every round
    -    for round in 1..=config.num_rounds {
    -        //print round number
    -        println!("\n\nROUND NUMBER: {}", round);
    -
    -        //computer as code-maker
    -        if let Some(score) = play_round_computer_codemaker(config) {
    -            human_score += score;
    -        } else {break;}
    -
    -        //human as code-maker
    -        if let Some(score) = play_round_human_codemaker(config) {
    -            computer_score += score;
    -        } else {break;}
    -
    -        //print scores
    -        print_scores(human_score,computer_score);
    -    }
    -
    -    //return to main
    -    Ok(())
    -}
    -
    -/// run a round with computer as code-maker
    -/// returns the number of turns it takes the human to guess the secret code
    -fn play_round_computer_codemaker(config: &Config) -> Option {
    -    //DATA
    -    let mut rng = thread_rng();
    -    let mut guesses: Vec = Vec::new();
    -    let secret: Code;
    -
    -    //generate secret
    -    secret = Code::new_from_int(rng.gen_range(0..config.num_colors.pow(config.num_positions.try_into().unwrap())), config);
    -
    -    //round loop
    -    for human_moves in 1..=config.num_guesses {
    -        //get guess from user input
    -        //input loop
    -        let mut guess = loop {
    -            //get input
    -            let user_input = get_string_from_user_input(format!("\nMOVE # {} GUESS: ", human_moves).as_str()).expect("something went wrong getting user guess");
    -
    -            //parse input
    -            if user_input.trim().eq_ignore_ascii_case("board") { //print the board state
    -                print_board(&guesses);
    -                continue; //run input loop again
    -            } else if user_input.trim().eq_ignore_ascii_case("quit") { //quit the game
    -                println!("QUITTER!  MY COMBINATION WAS: {}\nGOOD BYE", secret.as_human_readible_chars());
    -                return None; //exit the game
    -            } else {
    -                //parse input for a code
    -                match Code::new_from_string(&user_input, &config) {
    -                    Ok(code) => {
    -                        //ensure code is correct length
    -                        if code.code.len() != config.num_positions { // if not
    -                            println!("BAD NUMBER OF POSITIONS.");
    -                            continue; //run loop again
    -                        }
    -                        else {break code;}//break with the code
    -                    },
    -                    Err(e) => {eprintln!("{}",e); continue;}, //run loop again
    -                }
    -            }
    -        };
    -        
    -        //evaluate guess
    -        guess.evaluate(&secret).expect("something went wrong evaluating user guess");
    -
    -        //tell user the results
    -        if guess.black_pins >= config.num_positions { //guessed it correctly
    -            println!("YOU GUESSED IT IN {} MOVES!", human_moves);
    -            return Some(human_moves); //exit function
    -        } else { //didn't
    -            println!("YOU HAVE {} BLACKS AND {} WHITES.", guess.black_pins, guess.white_pins);
    -        }
    -
    -        //add guess to the list of guesses
    -        guesses.push(guess);
    -    }
    -
    -    //only runs if user doesn't guess the code
    -    println!("YOU RAN OUT OF MOVES!  THAT'S ALL YOU GET!");
    -    println!("THE ACTUAL COMBINATION WAS: {}", secret.as_human_readible_chars());
    -    return Some(config.num_guesses); //max score gain per round
    -}
    -
    -/// run a round with human as code-maker
    -/// returns the number of turns it takes the computer to guess the secret code
    -fn play_round_human_codemaker(config: &Config) -> Option{
    -    //DATA
    -    let mut rng = thread_rng();
    -    let mut all_possibilities = vec![true; config.total_possibilities];
    -    let _secret: Code;
    -
    -
    -    //get a secret code from user input
    -    println!("\nNOW I GUESS.  THINK OF A COMBINATION.\nHIT RETURN WHEN READY: ");
    -    // input loop
    -    _secret = loop {
    -        //get input
    -        let user_input = get_string_from_user_input("").expect("something went wrong getting secret from user");
    -
    -        //parse input
    -        if let Ok(code) = Code::new_from_string(&user_input, config) {
    -            if code.code.len() == config.num_positions {break code;} //exit loop with code
    -            else {println!("CODE MUST HAVE {} POSITIONS", config.num_positions);continue;} //tell them to try again
    -        }
    -        println!("INVALID CODE.  TRY AGAIN"); //if unsuccessful, this is printed and the loop runs again
    -    };
    -
    -    //round loop
    -    for computer_moves in 1..=config.num_guesses {
    -        let mut guess: Code = Code::new();
    -
    -        //randomly generate a guess //770
    -        let mut guess_int = rng.gen_range(0..config.total_possibilities);
    -        // if possible, use it //780
    -        if all_possibilities[guess_int] {
    -            guess = Code::new_from_int(guess_int, &config); //create guess
    -        }
    -        else {// if not possible:
    -            // search all possibilities after guess, use first valid one //790
    -            for g in guess_int..config.total_possibilities {
    -                if all_possibilities[g] {
    -                    guess_int=g;
    -                    guess = Code::new_from_int(guess_int, &config); //create guess
    -                    break;
    -                }
    -            }
    -            // if none was found
    -            //  search all possibilities before guess, use first valid one //820
    -            if guess.code.is_empty() {
    -                for g in (0..guess_int).rev() {
    -                    if all_possibilities[g] {
    -                        guess_int=g;
    -                        guess = Code::new_from_int(guess_int, &config); //create guess
    -                        break;
    -                    }
    -                }
    -            }
    -
    -            // if none where found, tell the user and start over #850
    -            if guess.code.is_empty() {
    -                println!("YOU HAVE GIVEN ME INCONSISTENT INFORMATION.");
    -                println!("PLAY AGAIN, AND THIS TIME PLEASE BE MORE CAREFUL.");
    -                return None; //exit game
    -            };
    -        }
    -
    -        //convert guess into something readible #890
    -        //print it #940
    -        println!("MY GUESS IS: {}", guess.as_human_readible_chars());
    -
    -        //ask user for feedback, #980
    -        // input loop for black pegs
    -        loop {match get_number_from_input("BLACKS: ", 0, config.num_positions) {
    -            Ok(num) => {
    -                guess.black_pins = num;
    -                break;
    -            },
    -            Err(e) => eprintln!("{}",e),
    -        }}
    -        // input loop for white pegs
    -        loop {match get_number_from_input("WHITES: ", 0, config.num_positions) {
    -            Ok(num) => {
    -                guess.white_pins = num;
    -                break;
    -            },
    -            Err(e) => eprintln!("{}",e),
    -        }}
    -
    -        //if computer guessed it, end #990
    -        if guess.black_pins >= config.num_positions { //guessed it correctly
    -            println!("I GOT IT IN {} MOVES!", computer_moves);
    -            return Some(computer_moves); //exit function
    -        } else { //didn't
    -            all_possibilities[guess_int] = false;
    -            //if we didn't, eliminate the combinations that don't work
    -            //we know the number of black and white pegs for a valid answer, so eleminate all that get different amounts
    -            all_possibilities.iter_mut().enumerate().for_each(|b| {
    -                if *b.1 { //filter out ones we already know aren't possible
    -                    let mut tmp_guess = Code::new_from_int(b.0, &config);
    -                    tmp_guess.evaluate(&guess).expect("something went wrong evaluation the computer's guess"); //compare with computer guess
    -                    if (guess.black_pins != tmp_guess.black_pins) || (guess.white_pins != tmp_guess.white_pins) { //if number of blacks/whites is different, set it to false
    -                        *b.1 = false;
    -                    }
    -                }
    -            });
    -        }
    -    }
    -
    -    //only runs if computer doesn't guess the code
    -    println!("I USED UP ALL MY MOVES!");
    -    println!("I GUESS MY CPU IS JUST HAVING AN OFF DAY.");
    -    return Some(config.num_guesses); //max moves the computer could've taken
    -}
    -
    -struct Code {
    -    code: Vec,
    -    black_pins: usize,
    -    white_pins: usize,
    -}
    -impl Code {
    -    /// create generic, empty code
    -    fn new() -> Code {
    -        return Code{code: Vec::new(), black_pins:0, white_pins:0};
    -    }
    -    /// converts input_int from base 10 to base num_colors to generate the code
    -    /// input_int must be between 0 and num_colors.pow(num_positions)
    -    fn new_from_int(mut input_int: usize, config: &Config) -> Code {
    -        //DATA
    -        let mut converted_number:Vec<_> = Vec::new();
    -        assert!(2 <= config.num_colors && config.num_colors <= 36); //if num_colors is outside of this range, things break later on
    -
    -        //convert input_int into a code by effectively converting input_int from base 10 to base n where n is num_colors, uses some fancy stuff to do this
    -        loop {
    -            converted_number.push(std::char::from_digit((input_int % config.num_colors).try_into().unwrap(), config.num_colors.try_into().unwrap()).unwrap()); //
    -            input_int /= config.num_colors;
    -            if input_int == 0 {break}
    -        }
    -        
    -        while converted_number.len() < config.num_positions {converted_number.push('0');} // fill remaining space with zero's
    -        let converted_number: Vec<_> = converted_number.iter().rev().map(|e| e.to_digit(config.num_colors.try_into().unwrap()).unwrap() .try_into().unwrap()).collect(); //reverse the vector and convert it to integers
    -        return Code{code: converted_number, black_pins:0, white_pins:0};
    -    }
    -    /// returns a code parsed from the passed string
    -    fn new_from_string(input_string: &str, config: &Config) -> Result> {
    -        let valid_chars = &LETTERS[0..config.num_colors];
    -        //DATA
    -        let new_code = Code{
    -            code: {
    -                input_string.to_ascii_uppercase().chars() //get an iterator with all the chars in input string converted to uppercase
    -                .filter( |c| { valid_chars.contains(*c)}) //remove chars that aren't in LETTERS
    -                .map( |x| -> usize {valid_chars.find(x).expect("invalid character")})//convert all the chars into usizes representing their index in LETTERS
    -                .collect() //wrap this iterator up into a vector
    -            },
    -            black_pins: 0,
    -            white_pins: 0,
    -        };
    -        //if code is empty, return None, otherwise return Some(code)
    -        if new_code.code.is_empty() {return Err(String::from("Input String did not contain enough valid characters").into());}
    -        else {return Ok(new_code);}
    -    }
    -
    -    /// returns a string containing the code represented as characters
    -    fn as_human_readible_chars(&self) -> String {
    -        return self.code.iter().map(|i|->char{LETTERS.chars().nth(*i).expect("index out of bounds")}).collect();
    -    }
    -
    -    /**
    -     * evaulates itself for the number of black and white pegs it should have when compared to a given secret
    -     */
    -    fn evaluate(&mut self, secret:&Code) -> Result<(),Box> {
    -        //data
    -        let mut consumed = vec![false;secret.code.len()];
    -
    -        if self.code.len() != secret.code.len() {
    -            return Err(String::from("only codes of the same length can be compared").into());
    -        }
    -
    -        for i in 0..secret.code.len() {
    -            if self.code[i] == secret.code[i] { //correct value correct place
    -                self.black_pins += 1;
    -                consumed[i] = true;
    -            }
    -            else {
    -                //check for correct value incorrect place, don't count positions that are already exact matches
    -                for j in 0..secret.code.len() {
    -                    if !consumed[j] && self.code[i] == secret.code[j] && self.code[j] != secret.code[j] {
    -                        self.white_pins += 1;
    -                        consumed[j] = true;
    -                        break;
    -                    }
    -                }
    -            }
    -        }
    -
    -        return Ok(())
    -    }
    -}
    -
    -
    -
    -/// print scores
    -fn print_scores(human_score:usize, computer_score:usize) {
    -    println!("SCORE\n\tCOMPUTER: {}\n\tHUMAN: {}", computer_score, human_score);
    -}
    -/// print the color - letter table
    -/// only prints the first num_colors pairs
    -fn print_color_letter_table(num_colors:usize) {
    -    println!("COLOR\tLETTER");
    -    println!("=====\t======");
    -    for i in 0..num_colors {
    -        println!("{}\t{}", COLORS[i], &LETTERS[i..i+1]);
    -    }
    -}
    -/// prints the board state, previous guesses and the number of black/white pins for each
    -fn print_board(guesses: &[Code]) {
    -    println!("BOARD");
    -    println!("MOVE\tGUESS\t\tBLACK\tWhite");
    -    for guess in guesses.iter().enumerate() {
    -        println!("{}\t{}\t\t{}\t{}", guess.0,guess.1.as_human_readible_chars(),guess.1.black_pins,guess.1.white_pins);
    -    }
    -}
    -
    -
    -
    -/// gets a string from user input
    -fn get_string_from_user_input(prompt: &str) -> Result> {
    -    //DATA
    -    let mut raw_input = String::new();
    -
    -    //print prompt
    -    print!("{}", prompt);
    -    //make sure it's printed before getting input
    -    io::stdout().flush().expect("couldn't flush stdout");
    -
    -    //read user input from standard input, and store it to raw_input, then return it or an error as needed
    -    raw_input.clear(); //clear input
    -    match io::stdin().read_line(&mut raw_input) {
    -        Ok(_num_bytes_read) => return Ok(String::from(raw_input.trim())),
    -        Err(err) => return Err(format!("ERROR: CANNOT READ INPUT!: {}", err).into()),
    -    }
    -}
    -/// generic function to get a number from the passed string (user input)
    -/// pass a min lower  than the max to have minimun and maximun bounds
    -/// pass a min higher than the max to only have a minumum bound
    -/// pass a min equal   to  the max to only have a maximun bound
    -/// 
    -/// Errors:
    -/// no number on user input
    -fn get_number_from_input(prompt: &str, min:T, max:T) -> Result> {
    -    //DATA
    -    let raw_input: String;
    -    let processed_input: String;
    -
    -    
    -    //input looop
    -    raw_input = loop {
    -        match get_string_from_user_input(prompt) {
    -            Ok(input) => break input,
    -            Err(e) => {
    -                eprintln!("{}",e);
    -                continue;
    -            },
    -        }
    -    };
    -
    -    //filter out num-numeric characters from user input
    -    processed_input = raw_input.chars().filter(|c| c.is_numeric()).collect();
    -
    -    //from input, try to read a number
    -    match processed_input.trim().parse() {
    -        Ok(i) => {
    -            //what bounds must the input fall into
    -            if min < max {  //have a min and max bound: [min,max]
    -                if i >= min && i <= max {//is input valid, within bounds
    -                    return Ok(i); //exit the loop with the value i, returning it
    -                } else { //print error message specific to this case
    -                    return Err(format!("ONLY BETWEEN {} AND {}, PLEASE!", min, max).into());
    -                } 
    -            } else if min > max { //only a min bound: [min, infinity)
    -                if i >= min {
    -                    return Ok(i);
    -                } else {
    -                    return Err(format!("NO LESS THAN {}, PLEASE!", min).into());
    -                }
    -            } else { //only a max bound: (-infinity, max]
    -                if i <= max {
    -                    return Ok(i);
    -                } else {
    -                    return Err(format!("NO MORE THAN {}, PLEASE!", max).into());
    -                }
    -            }
    -        },
    -        Err(_e) => return Err(format!("Error: couldn't find a valid number in {}",raw_input).into()),
    -    }
    -}
    diff --git a/60_Mastermind/rust/Mastermind_refactored_for_conventions/src/main.rs b/60_Mastermind/rust/Mastermind_refactored_for_conventions/src/main.rs
    deleted file mode 100644
    index 5a5d01295..000000000
    --- a/60_Mastermind/rust/Mastermind_refactored_for_conventions/src/main.rs
    +++ /dev/null
    @@ -1,40 +0,0 @@
    -use std::process;//allows for some better error handling
    -
    -mod lib; //allows access to lib.rs
    -use lib::Config;
    -
    -/// main function
    -/// responsibilities:
    -/// - Calling the command line logic with the argument values
    -/// - Setting up any other configuration
    -/// - Calling a run function in lib.rs
    -/// - Handling the error if run returns an error
    -fn main() {
    -    //greet user
    -    welcome();
    -
    -    // set up other configuration
    -    let mut config = Config::new().unwrap_or_else(|err| {
    -        eprintln!("Problem configuring program: {}", err);
    -        process::exit(1);
    -    });
    -
    -    // run the program
    -    if let Err(e) = lib::run(&mut config) {
    -        eprintln!("Application Error: {}", e); //use the eprintln! macro to output to standard error
    -        process::exit(1); //exit the program with an error code
    -    }
    -
    -    //end of program
    -    println!("THANKS FOR PLAYING!");
    -}
    -
    -/// print the welcome message
    -fn welcome() {
    -    println!("
    -                             MASTERMIND
    -              CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY
    -
    -
    -    ");
    -}
    diff --git a/60_Mastermind/vbnet/Mastermind.sln b/60_Mastermind/vbnet/Mastermind.sln
    deleted file mode 100644
    index 5ea0a3694..000000000
    --- a/60_Mastermind/vbnet/Mastermind.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index dc0b78900..000000000
    --- a/60_Mastermind/vbnet/Mastermind.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Mastermind
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/61_Math_Dice/README.md b/61_Math_Dice/README.md
    index 7955b94e5..a24c9dbe6 100644
    --- a/61_Math_Dice/README.md
    +++ b/61_Math_Dice/README.md
    @@ -12,7 +12,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/61_Math_Dice/csharp/README.md b/61_Math_Dice/csharp/README.md
    index e0863abd2..7017b45ae 100644
    --- a/61_Math_Dice/csharp/README.md
    +++ b/61_Math_Dice/csharp/README.md
    @@ -7,4 +7,4 @@ Conversion Notes
     - There are minor spacing issues which have been preserved in this port.
     - This implementation uses switch expressions to concisely place the dice pips in the right place.
     - Random() is only pseudo-random but perfectly adequate for the purposes of simulating dice rolls.
    -- Console width is assumed to be 120 chars for the purposes of centrally aligned the intro text.
    +- Console width is assumed to be 120 chars for the purposes of centrally aligned the intro text.
    \ No newline at end of file
    diff --git a/61_Math_Dice/java/Die.java b/61_Math_Dice/java/Die.java
    index a1c8bbade..1a6162132 100644
    --- a/61_Math_Dice/java/Die.java
    +++ b/61_Math_Dice/java/Die.java
    @@ -21,15 +21,15 @@ private void throwDie() {
             this.faceValue = 1 + generator.nextInt(sides);
         }
     
    -
    -    /**
    +    
    +    /** 
          * @return the faceValue
          */
         public int getFaceValue() {
             return faceValue;
         }
     
    -
    +    
         public void printDie() {
             throwDie();
             int x = this.getFaceValue();
    @@ -70,4 +70,4 @@ private void printZero() {
         private void printTwo() {
             System.out.println("| * * |");
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/61_Math_Dice/java/MathDice.java b/61_Math_Dice/java/MathDice.java
    index 51494151b..bd2ecd705 100644
    --- a/61_Math_Dice/java/MathDice.java
    +++ b/61_Math_Dice/java/MathDice.java
    @@ -35,9 +35,9 @@ public static void main(String[] args) {
                         in.nextLine();
                     }
     
    -                if(guess == 0)
    +                if(guess == 0) 
                         System.exit(0);
    -
    +                
                     tries++;
                 }
     
    @@ -50,4 +50,4 @@ public static void main(String[] args) {
             }
         }
     
    -}
    +}
    \ No newline at end of file
    diff --git a/61_Math_Dice/javascript/mathdice.html b/61_Math_Dice/javascript/mathdice.html
    index 095d7a9be..dfdf3f5f4 100644
    --- a/61_Math_Dice/javascript/mathdice.html
    +++ b/61_Math_Dice/javascript/mathdice.html
    @@ -1,10 +1,9 @@
     
     
     MATH DICE
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/61_Math_Dice/javascript/mathdice.js b/61_Math_Dice/javascript/mathdice.js
    index 60cfb8a7c..f6ccda814 100644
    --- a/61_Math_Dice/javascript/mathdice.js
    +++ b/61_Math_Dice/javascript/mathdice.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/61_Math_Dice/kotlin/README.md b/61_Math_Dice/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/61_Math_Dice/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/61_Math_Dice/lua/README.md b/61_Math_Dice/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/61_Math_Dice/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/61_Math_Dice/pascal/README.md b/61_Math_Dice/pascal/README.md
    new file mode 100644
    index 000000000..0e40aa9fb
    --- /dev/null
    +++ b/61_Math_Dice/pascal/README.md
    @@ -0,0 +1,15 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    +
    +##### Translator Notes:
    +I tried to preserve as much of the original layout and flow of the code
    +as possible.  I added a procedure for the printing of the die-face; and
    +another to read an integer from the player, as I was unhappy with the runtime 
    +error message spat out when a non-number is given to readln().
    +
    +I was torn between using the correct singular term "die" instead of "dice".  
    +In the end I used a (poor?) combination of both.
    +
    +krt@krt.com.au 2020-10-12
    +
    diff --git a/00_Alternate_Languages/61_Math_Dice/pascal/mathdice.pas b/61_Math_Dice/pascal/mathdice.pas
    similarity index 97%
    rename from 00_Alternate_Languages/61_Math_Dice/pascal/mathdice.pas
    rename to 61_Math_Dice/pascal/mathdice.pas
    index 3c9c85aab..617f898f6 100644
    --- a/00_Alternate_Languages/61_Math_Dice/pascal/mathdice.pas
    +++ b/61_Math_Dice/pascal/mathdice.pas
    @@ -20,7 +20,7 @@ procedure printDice( face_value: integer );
         else
             writeln( 'I * * I' );
     
    -    if ( ( face_value = 2 ) or ( face_value = 4 ) ) then
    +    if ( ( face_value = 2 ) or ( face_value = 4 ) ) then 
             writeln( 'I     I' )
         else if ( face_value = 6 ) then
             writeln( 'I * * I' )
    @@ -33,7 +33,7 @@ procedure printDice( face_value: integer );
             writeln( 'I   * I' )
         else
             writeln( 'I * * I' );
    -
    +        
         writeln( ' ----- ' );
     end;
     
    @@ -61,7 +61,7 @@ function inputNumber(): integer;
         input_error := 1;
         while ( input_error <> 0 ) do
         begin
    -        readln( player_input );
    +        readln( player_input ); 
     
             val( player_input, player_answer, input_error );
     
    @@ -126,3 +126,4 @@ function inputNumber(): integer;
             writeln( 'THE DICE ROLL AGAIN...' );
         end;
     end.
    +
    diff --git a/61_Math_Dice/perl/mathdice.pl b/61_Math_Dice/perl/mathdice.pl
    index 47a0a4a00..4a2b6f6ee 100644
    --- a/61_Math_Dice/perl/mathdice.pl
    +++ b/61_Math_Dice/perl/mathdice.pl
    @@ -48,7 +48,7 @@ sub game_play {
     			    else {
     					print "N0, THE ANSWER IS $sum\n";
     				}
    -
    +				
     			}
     		}
     	}
    diff --git a/61_Math_Dice/python/mathdice.py b/61_Math_Dice/python/mathdice.py
    index 4081e0cca..ca84555cf 100644
    --- a/61_Math_Dice/python/mathdice.py
    +++ b/61_Math_Dice/python/mathdice.py
    @@ -1,56 +1,51 @@
     from random import randint
    -
     print("Math Dice")
     print("https://github.com/coding-horror/basic-computer-games")
     print()
    -print(
    -    """This program generates images of two dice.
    +print("""This program generates images of two dice.
     When two dice and an equals sign followed by a question
     mark have been printed, type your answer, and hit the ENTER
     key.
     To conclude the program, type 0.
    -"""
    -)
    -
    +""")
     
    -def print_dice(n: int) -> None:
    -    def print_0() -> None:
    +def print_dice(n):
    +    
    +    def print_0():
             print("|     |")
    -
    -    def print_2() -> None:
    +    def print_2():
             print("| * * |")
     
         print(" ----- ")
     
    -    if n in {4, 5, 6}:
    +    if n in [4,5,6]:
             print_2()
    -    elif n in {2, 3}:
    +    elif n in [2,3]:
             print("| *   |")
         else:
             print_0()
     
    -    if n in {1, 3, 5}:
    +    if n in [1,3,5]:
             print("|  *  |")
    -    elif n in {2, 4}:
    +    elif n in [2,4]:
             print_0()
         else:
             print_2()
     
    -    if n in {4, 5, 6}:
    +    if n in [4,5,6]:
             print_2()
    -    elif n in {2, 3}:
    +    elif n in [2,3]:
             print("|   * |")
         else:
             print_0()
     
         print(" ----- ")
     
    -
    -def main() -> None:
    +def main():
     
         while True:
    -        d1 = randint(1, 6)
    -        d2 = randint(1, 6)
    +        d1 = randint(1,6)
    +        d2 = randint(1,6)
             guess = 13
     
             print_dice(d1)
    @@ -75,8 +70,10 @@ def main() -> None:
             else:
                 print("Correct!")
     
    +
             print("The dice roll again....")
     
     
    +
     if __name__ == "__main__":
    -    main()
    +    main()
    \ No newline at end of file
    diff --git a/61_Math_Dice/ruby/mathdice.rb b/61_Math_Dice/ruby/mathdice.rb
    deleted file mode 100644
    index c265e9cf9..000000000
    --- a/61_Math_Dice/ruby/mathdice.rb
    +++ /dev/null
    @@ -1,115 +0,0 @@
    -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
    diff --git a/61_Math_Dice/rust/Cargo.lock b/61_Math_Dice/rust/Cargo.lock
    deleted file mode 100644
    index 4fe2abbea..000000000
    --- a/61_Math_Dice/rust/Cargo.lock
    +++ /dev/null
    @@ -1,75 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.10"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.147"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/61_Math_Dice/rust/Cargo.toml b/61_Math_Dice/rust/Cargo.toml
    deleted file mode 100644
    index 3b1d02f52..000000000
    --- a/61_Math_Dice/rust/Cargo.toml
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -[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/61_Math_Dice/rust/README.md b/61_Math_Dice/rust/README.md
    deleted file mode 100644
    index 375601ae5..000000000
    --- a/61_Math_Dice/rust/README.md
    +++ /dev/null
    @@ -1,5 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Rust](https://www.rust-lang.org/) by Anthony Rubick [AnthonyMichaelTDM](https://github.com/AnthonyMichaelTDM)
    -
    -If you wish to give the user more than 2 attempts to get the number, change value assigned to the num_tries variable at the start of the main function
    diff --git a/61_Math_Dice/rust/src/main.rs b/61_Math_Dice/rust/src/main.rs
    deleted file mode 100644
    index fc92dc16e..000000000
    --- a/61_Math_Dice/rust/src/main.rs
    +++ /dev/null
    @@ -1,134 +0,0 @@
    -use rand::{Rng, prelude::{thread_rng}};
    -use std::io;
    -
    -fn main() {
    -    //DATA
    -    let num_tries:u8 = 2; //number of tries the player gets each round, must be at least 1
    -    let mut rng = thread_rng();
    -    let mut user_guess: u8;
    -    let mut dice_1:u8;
    -    let mut dice_2:u8;
    -
    -    //print welcome message
    -    welcome();
    -
    -    //game loop
    -    loop {
    -        //roll dice
    -        dice_1 = rng.gen_range(1..=6);
    -        dice_2 = rng.gen_range(1..=6);
    -
    -        //print dice
    -        print_dice(dice_1);
    -        println!("   +");
    -        print_dice(dice_2);
    -        println!("   =");
    -
    -        //get user guess, they have 2 tries
    -        for t in 0..num_tries {
    -            //get guess
    -            user_guess = get_number_from_user_input("", "That's not a valid number!", 1, 12);
    -
    -            //if they get it wrong
    -            if user_guess != (dice_1+dice_2) {
    -                //print different message depending on what try they're on
    -                if t < num_tries-1 { // user has tries left
    -                    println!("NO, COUNT THE SPOTS AND GIVE ANOTHER ANSWER.");
    -                    println!("   =");
    -                }
    -                else { //this is their last try
    -                    println!("NO, THE ANSWER IS {}", dice_1+dice_2);
    -                }
    -            }
    -            else {
    -                println!("RIGHT!");
    -                break;
    -            }
    -        }
    -
    -        //play again
    -        println!("\nThe dice roll again....");
    -    }
    -
    -}
    -
    -/**
    - * prints the welcome message to the console
    - */
    -fn welcome() {
    -    println!("
    -                              MATH DICE
    -              CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY
    -    \n\n
    -    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, PRESS Ctrl+C AS YOUR ANSWER.\n
    -    ");
    -}
    -
    -/**
    - * print the dice,
    - */
    -fn print_dice(dice_value:u8) {
    -    //data
    -
    -    //top
    -    println!(" ----- ");
    -    //first layer
    -    match dice_value {
    -        4|5|6 => println!("| * * |"),
    -        2|3 => println!("| *   |"),
    -        _=>println!("|     |"),
    -    }
    -
    -    //second layer
    -    match dice_value {
    -        1|3|5 => println!("|  *  |"),
    -        2|4 => println!("|     |"),
    -        _=>println!("| * * |"),
    -    }
    -
    -    //third layer
    -    match dice_value {
    -        4|5|6 => println!("| * * |"),
    -        2|3 => println!("|   * |"),
    -        _=>println!("|     |"),
    -    }
    -
    -    //bottom
    -    println!(" ----- ");
    -}
    -
    -/**
    - * gets a integer from user input
    - */
    -fn get_number_from_user_input(prompt: &str, error_message: &str, min:u8, max:u8) -> u8 {
    -    //input loop
    -    return loop {
    -        let mut raw_input = String::new(); // temporary variable for user input that can be parsed later
    -
    -        //print prompt
    -        println!("{}", prompt);
    -        //read user input from standard input, and store it to raw_input
    -        //raw_input.clear(); //clear input
    -        io::stdin().read_line(&mut raw_input).expect( "CANNOT READ INPUT!");
    -
    -        //from input, try to read a number
    -        match raw_input.trim().parse::() {
    -            Ok(i) => {
    -                if i < min || i > max { //input out of desired range
    -                    println!("{}  ({}-{})", error_message, min,max);
    -                    continue; // run the loop again
    -                }
    -                else {
    -                    break i;// this escapes the loop, returning i
    -                }
    -            },
    -            Err(e) => {
    -                println!("{}  {}", error_message, e.to_string().to_uppercase());
    -                continue; // run the loop again
    -            }
    -        };
    -    };
    -}
    diff --git a/61_Math_Dice/vbnet/MathDice.sln b/61_Math_Dice/vbnet/MathDice.sln
    deleted file mode 100644
    index 4fe58a59b..000000000
    --- a/61_Math_Dice/vbnet/MathDice.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index dd19501b2..000000000
    --- a/61_Math_Dice/vbnet/MathDice.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    MathDice
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/62_Mugwump/README.md b/62_Mugwump/README.md
    index 9fb09d618..c67037f20 100644
    --- a/62_Mugwump/README.md
    +++ b/62_Mugwump/README.md
    @@ -16,7 +16,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/62_Mugwump/csharp/Distance.cs b/62_Mugwump/csharp/Distance.cs
    deleted file mode 100644
    index 301851578..000000000
    --- a/62_Mugwump/csharp/Distance.cs
    +++ /dev/null
    @@ -1,13 +0,0 @@
    -namespace Mugwump;
    -
    -internal struct Distance
    -{
    -    private readonly float _value;
    -
    -    public Distance(float deltaX, float deltaY)
    -    {
    -        _value = (float)Math.Sqrt(deltaX * deltaX + deltaY * deltaY);
    -    }
    -
    -    public override string ToString() => _value.ToString("0.0");
    -}
    diff --git a/62_Mugwump/csharp/Game.cs b/62_Mugwump/csharp/Game.cs
    deleted file mode 100644
    index 2f790c0de..000000000
    --- a/62_Mugwump/csharp/Game.cs
    +++ /dev/null
    @@ -1,55 +0,0 @@
    -using System.Reflection;
    -
    -namespace Mugwump;
    -
    -internal class Game
    -{
    -    private readonly TextIO _io;
    -    private readonly IRandom _random;
    -
    -    internal Game(TextIO io, IRandom random)
    -    {
    -        _io = io;
    -        _random = random;
    -    }
    -
    -    internal void Play(Func playAgain = null)
    -    {
    -        DisplayIntro();
    -
    -        while (playAgain?.Invoke() ?? true)
    -        {
    -            Play(new Grid(_io, _random));
    -
    -            _io.WriteLine();
    -            _io.WriteLine("That was fun! Let's play again.......");
    -            _io.WriteLine("Four more mugwumps are now in hiding.");
    -        }
    -    }
    -
    -    private void DisplayIntro()
    -    {
    -        using var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Mugwump.Strings.Intro.txt");
    -
    -        _io.Write(stream);
    -    }
    -
    -    private void Play(Grid grid)
    -    {
    -        for (int turn = 1; turn <= 10; turn++)
    -        {
    -            var guess = _io.ReadGuess($"Turn no. {turn} -- what is your guess");
    -
    -            if (grid.Check(guess))
    -            {
    -                _io.WriteLine();
    -                _io.WriteLine($"You got them all in {turn} turns!");
    -                return;
    -            }
    -        }
    -
    -        _io.WriteLine();
    -        _io.WriteLine("Sorry, that's 10 tries.  Here is where they're hiding:");
    -        grid.Reveal();
    -    }
    -}
    diff --git a/62_Mugwump/csharp/Grid.cs b/62_Mugwump/csharp/Grid.cs
    deleted file mode 100644
    index 8fb63ddcb..000000000
    --- a/62_Mugwump/csharp/Grid.cs
    +++ /dev/null
    @@ -1,40 +0,0 @@
    -using System.Collections.Generic;
    -using System.Linq;
    -
    -namespace Mugwump;
    -
    -internal class Grid
    -{
    -    private readonly TextIO _io;
    -    private readonly List _mugwumps;
    -
    -    public Grid(TextIO io, IRandom random)
    -    {
    -        _io = io;
    -        _mugwumps = Enumerable.Range(1, 4).Select(id => new Mugwump(id, random.NextPosition(10, 10))).ToList();
    -    }
    -
    -    public bool Check(Position guess)
    -    {
    -        foreach (var mugwump in _mugwumps.ToList())
    -        {
    -            var (found, distance) = mugwump.FindFrom(guess);
    -
    -            _io.WriteLine(found ? $"You have found {mugwump}" : $"You are {distance} units from {mugwump}");
    -            if (found)
    -            {
    -                _mugwumps.Remove(mugwump);
    -            }
    -        }
    -
    -        return _mugwumps.Count == 0;
    -    }
    -
    -    public void Reveal()
    -    {
    -        foreach (var mugwump in _mugwumps)
    -        {
    -            _io.WriteLine(mugwump.Reveal());
    -        }
    -    }
    -}
    diff --git a/62_Mugwump/csharp/IRandomExtensions.cs b/62_Mugwump/csharp/IRandomExtensions.cs
    deleted file mode 100644
    index 7ef7a55b0..000000000
    --- a/62_Mugwump/csharp/IRandomExtensions.cs
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -namespace Mugwump;
    -
    -internal static class IRandomExtensions
    -{
    -    internal static Position NextPosition(this IRandom random, int maxX, int maxY) =>
    -        new(random.Next(maxX), random.Next(maxY));
    -}
    diff --git a/62_Mugwump/csharp/Mugwump.cs b/62_Mugwump/csharp/Mugwump.cs
    deleted file mode 100644
    index 6b5a398fb..000000000
    --- a/62_Mugwump/csharp/Mugwump.cs
    +++ /dev/null
    @@ -1,19 +0,0 @@
    -namespace Mugwump;
    -
    -internal class Mugwump
    -{
    -    private readonly int _id;
    -    private readonly Position _position;
    -
    -    public Mugwump(int id, Position position)
    -    {
    -        _id = id;
    -        _position = position;
    -    }
    -
    -    public (bool, Distance) FindFrom(Position guess) => (guess == _position, guess - _position);
    -
    -    public string Reveal() => $"{this} is at {_position}";
    -
    -    public override string ToString() => $"Mugwump {_id}";
    -}
    diff --git a/62_Mugwump/csharp/Mugwump.csproj b/62_Mugwump/csharp/Mugwump.csproj
    deleted file mode 100644
    index c6c4a891c..000000000
    --- a/62_Mugwump/csharp/Mugwump.csproj
    +++ /dev/null
    @@ -1,16 +0,0 @@
    -
    -
    -  
    -    Exe
    -    net6.0
    -  
    -
    -  
    -    
    -  
    -
    -  
    -    
    -  
    -
    -
    diff --git a/62_Mugwump/csharp/Mugwump.sln b/62_Mugwump/csharp/Mugwump.sln
    index ab99858ae..bc3cfbfff 100644
    --- a/62_Mugwump/csharp/Mugwump.sln
    +++ b/62_Mugwump/csharp/Mugwump.sln
    @@ -1,25 +1,34 @@
     
     Microsoft Visual Studio Solution File, Format Version 12.00
    -# Visual Studio Version 17
    -VisualStudioVersion = 17.0.32014.148
    +# Visual Studio 15
    +VisualStudioVersion = 15.0.26124.0
     MinimumVisualStudioVersion = 15.0.26124.0
    -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mugwump", "Mugwump.csproj", "{DB23BDB0-10A4-4771-B942-E646A1A5C416}"
    +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mugwump", "Mugwump\Mugwump.csproj", "{83F42802-4E7C-49B5-A022-DB9B6A65F2C6}"
     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
    -	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
    +		Release|x64 = Release|x64
    +		Release|x86 = Release|x86
     	EndGlobalSection
     	GlobalSection(SolutionProperties) = preSolution
     		HideSolutionNode = FALSE
     	EndGlobalSection
    -	GlobalSection(ExtensibilityGlobals) = postSolution
    -		SolutionGuid = {1FE34948-9066-4F57-A4C1-423293A430C5}
    +	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
     	EndGlobalSection
     EndGlobal
    diff --git a/62_Mugwump/csharp/Mugwump/Game.cs b/62_Mugwump/csharp/Mugwump/Game.cs
    new file mode 100644
    index 000000000..bf72d44eb
    --- /dev/null
    +++ b/62_Mugwump/csharp/Mugwump/Game.cs
    @@ -0,0 +1,36 @@
    +using System;
    +using System.Linq;
    +
    +namespace Mugwump
    +{
    +    internal class Game
    +    {
    +        private readonly Grid _grid;
    +
    +        private Game(Random random)
    +        {
    +            _grid = new Grid(Enumerable.Range(1, 4).Select(id => new Mugwump(id, random.Next(10), random.Next(10))));
    +        }
    +
    +        public static void Play(Random random) => new Game(random).Play();
    +
    +        private void Play()
    +        {
    +            for (int turn = 1; turn <= 10; turn++)
    +            {
    +                var guess = Input.ReadGuess($"Turn no. {turn} -- what is your guess");
    +
    +                if (_grid.Check(guess))
    +                {
    +                    Console.WriteLine();
    +                    Console.WriteLine($"You got them all in {turn} turns!");
    +                    return;
    +                }
    +            }
    +
    +            Console.WriteLine();
    +            Console.WriteLine("Sorry, that's 10 tries.  Here is where they're hiding:");
    +            _grid.Reveal();
    +        }
    +    }
    +}
    diff --git a/62_Mugwump/csharp/Mugwump/Grid.cs b/62_Mugwump/csharp/Mugwump/Grid.cs
    new file mode 100644
    index 000000000..dd89c638e
    --- /dev/null
    +++ b/62_Mugwump/csharp/Mugwump/Grid.cs
    @@ -0,0 +1,40 @@
    +using System;
    +using System.Collections.Generic;
    +using System.Linq;
    +
    +namespace Mugwump
    +{
    +    internal class Grid
    +    {
    +        private readonly List _mugwumps;
    +
    +        public Grid(IEnumerable mugwumps)
    +        {
    +            _mugwumps = mugwumps.ToList();
    +        }
    +
    +        public bool Check(Position guess)
    +        {
    +            foreach (var mugwump in _mugwumps.ToList())
    +            {
    +                var (found, distance) = mugwump.FindFrom(guess);
    +
    +                Console.WriteLine(found ? $"You have found {mugwump}" : $"You are {distance} units from {mugwump}");
    +                if (found)
    +                {
    +                    _mugwumps.Remove(mugwump);
    +                }
    +            }
    +
    +            return _mugwumps.Count == 0;
    +        }
    +
    +        public void Reveal()
    +        {
    +            foreach (var mugwump in _mugwumps.ToList())
    +            {
    +                Console.WriteLine(mugwump.Reveal());
    +            }
    +        }
    +    }
    +}
    diff --git a/62_Mugwump/csharp/Mugwump/Input.cs b/62_Mugwump/csharp/Mugwump/Input.cs
    new file mode 100644
    index 000000000..97222c3e8
    --- /dev/null
    +++ b/62_Mugwump/csharp/Mugwump/Input.cs
    @@ -0,0 +1,66 @@
    +using System;
    +using System.Collections.Generic;
    +
    +namespace Mugwump
    +{
    +    // Provides input methods which emulate the BASIC interpreter's keyboard input routines
    +    internal static class Input
    +    {
    +        internal static Position ReadGuess(string prompt)
    +        {
    +            Console.WriteLine();
    +            Console.WriteLine();
    +            var input = ReadNumbers(prompt, 2);
    +            return new Position(input[0], input[1]);
    +        }
    +
    +        private static void Prompt(string text = "") => Console.Write($"{text}? ");
    +
    +        private static List ReadNumbers(string prompt, int requiredCount)
    +        {
    +            var numbers = new List();
    +
    +            while (!TryReadNumbers(prompt, requiredCount, numbers))
    +            {
    +                prompt = "";
    +            }
    +
    +            return numbers;
    +        }
    +
    +        private static bool TryReadNumbers(string prompt, int requiredCount, List numbers)
    +        {
    +            Prompt(prompt);
    +            var inputValues = ReadStrings();
    +
    +            foreach (var value in inputValues)
    +            {
    +                if (numbers.Count == requiredCount)
    +                {
    +                    Console.WriteLine("!Extra input ingored");
    +                    return true;
    +                }
    +
    +                if (!TryParseNumber(value, out var number))
    +                {
    +                    return false;
    +                }
    +
    +                numbers.Add(number);
    +            }
    +
    +            return numbers.Count == requiredCount || TryReadNumbers("?", requiredCount, numbers);
    +        }
    +
    +        private static string[] ReadStrings() => Console.ReadLine().Split(',', StringSplitOptions.TrimEntries);
    +
    +        private static bool TryParseNumber(string text, out float number)
    +        {
    +            if (float.TryParse(text, out number)) { return true; }
    +
    +            Console.WriteLine("!Number expected - retry input line");
    +            number = default;
    +            return false;
    +        }
    +    }
    +}
    diff --git a/62_Mugwump/csharp/Mugwump/Mugwump.cs b/62_Mugwump/csharp/Mugwump/Mugwump.cs
    new file mode 100644
    index 000000000..bd117c63e
    --- /dev/null
    +++ b/62_Mugwump/csharp/Mugwump/Mugwump.cs
    @@ -0,0 +1,20 @@
    +namespace Mugwump
    +{
    +    internal class Mugwump
    +    {
    +        private readonly int _id;
    +        private readonly Position _position;
    +
    +        public Mugwump(int id, int x, int y)
    +        {
    +            _id = id;
    +            _position = new Position(x, y);
    +        }
    +
    +        public (bool, Distance) FindFrom(Position guess) => (guess == _position, guess - _position);
    +
    +        public string Reveal() => $"{this} is at {_position}";
    +
    +        public override string ToString() => $"Mugwump {_id}";
    +    }
    +}
    diff --git a/62_Mugwump/csharp/Mugwump/Mugwump.csproj b/62_Mugwump/csharp/Mugwump/Mugwump.csproj
    new file mode 100644
    index 000000000..fc2efa30e
    --- /dev/null
    +++ b/62_Mugwump/csharp/Mugwump/Mugwump.csproj
    @@ -0,0 +1,11 @@
    +
    +
    +  
    +    Exe
    +    net5.0
    +  
    +
    +  
    +    
    +  
    +
    diff --git a/62_Mugwump/csharp/Mugwump/Offset.cs b/62_Mugwump/csharp/Mugwump/Offset.cs
    new file mode 100644
    index 000000000..c62e38626
    --- /dev/null
    +++ b/62_Mugwump/csharp/Mugwump/Offset.cs
    @@ -0,0 +1,16 @@
    +using System;
    +
    +namespace Mugwump
    +{
    +    internal class Distance
    +    {
    +        private readonly float _value;
    +
    +        public Distance(float deltaX, float deltaY)
    +        {
    +            _value = (float)Math.Sqrt(deltaX * deltaX + deltaY * deltaY);
    +        }
    +
    +        public override string ToString() => $"{_value:0.0}";
    +    }
    +}
    diff --git a/62_Mugwump/csharp/Mugwump/Position.cs b/62_Mugwump/csharp/Mugwump/Position.cs
    new file mode 100644
    index 000000000..6005ae8b7
    --- /dev/null
    +++ b/62_Mugwump/csharp/Mugwump/Position.cs
    @@ -0,0 +1,9 @@
    +namespace Mugwump
    +{
    +    internal record Position(float X, float Y)
    +    {
    +        public override string ToString() => $"( {X} , {Y} )";
    +
    +        public static Distance operator -(Position p1, Position p2) => new(p1.X - p2.X, p1.Y - p2.Y);
    +    }
    +}
    diff --git a/62_Mugwump/csharp/Mugwump/Program.cs b/62_Mugwump/csharp/Mugwump/Program.cs
    new file mode 100644
    index 000000000..6121b81dd
    --- /dev/null
    +++ b/62_Mugwump/csharp/Mugwump/Program.cs
    @@ -0,0 +1,33 @@
    +using System;
    +using System.Reflection;
    +
    +namespace Mugwump
    +{
    +    class Program
    +    {
    +        static void Main(string[] args)
    +        {
    +            DisplayIntro();
    +
    +            var random = new Random();
    +
    +            while (true)
    +            {
    +                Game.Play(random);
    +
    +                Console.WriteLine();
    +                Console.WriteLine("That was fun! Let's play again.......");
    +                Console.WriteLine("Four more mugwumps are now in hiding.");
    +            }
    +        }
    +
    +        private static void DisplayIntro()
    +        {
    +            using var stream = Assembly.GetExecutingAssembly()
    +                .GetManifestResourceStream("Mugwump.Strings.Intro.txt");
    +            using var stdout = Console.OpenStandardOutput();
    +
    +            stream.CopyTo(stdout);
    +        }
    +    }
    +}
    diff --git a/62_Mugwump/csharp/Mugwump/Strings/Intro.txt b/62_Mugwump/csharp/Mugwump/Strings/Intro.txt
    new file mode 100644
    index 000000000..30ede4d68
    --- /dev/null
    +++ b/62_Mugwump/csharp/Mugwump/Strings/Intro.txt
    @@ -0,0 +1,15 @@
    +                                 Mugwump
    +               Creative Computing  Morristown, New Jersey
    +
    +
    +
    +The object of this game is to find four mugwumps
    +hidden on a 10 by 10 grid.  Homebase is position 0,0.
    +Any guess you make must be two numbers with each
    +number between 0 and 9, inclusive.  First number
    +is distance to right of homebase and second number
    +is distance above homebase.
    +
    +You get 10 tries.  After each try, I will tell
    +you how far you are from each wugwump.
    +
    diff --git a/62_Mugwump/csharp/Position.cs b/62_Mugwump/csharp/Position.cs
    deleted file mode 100644
    index 5f808cc34..000000000
    --- a/62_Mugwump/csharp/Position.cs
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -namespace Mugwump;
    -
    -internal record struct Position(float X, float Y)
    -{
    -    public override string ToString() => $"( {X} , {Y} )";
    -
    -    public static Distance operator -(Position p1, Position p2) => new(p1.X - p2.X, p1.Y - p2.Y);
    -}
    diff --git a/62_Mugwump/csharp/Program.cs b/62_Mugwump/csharp/Program.cs
    deleted file mode 100644
    index f5031b88d..000000000
    --- a/62_Mugwump/csharp/Program.cs
    +++ /dev/null
    @@ -1,12 +0,0 @@
    -global using System;
    -global using Games.Common.IO;
    -global using Games.Common.Randomness;
    -
    -using Mugwump;
    -
    -var random = new RandomNumberGenerator();
    -var io = new ConsoleIO();
    -
    -var game = new Game(io, random);
    -
    -game.Play();
    diff --git a/62_Mugwump/csharp/Strings/Intro.txt b/62_Mugwump/csharp/Strings/Intro.txt
    deleted file mode 100644
    index ea46087a0..000000000
    --- a/62_Mugwump/csharp/Strings/Intro.txt
    +++ /dev/null
    @@ -1,14 +0,0 @@
    -                                 Mugwump
    -               Creative Computing  Morristown, New Jersey
    -
    -
    -
    -The object of this game is to find four mugwumps
    -hidden on a 10 by 10 grid.  Homebase is position 0,0.
    -Any guess you make must be two numbers with each
    -number between 0 and 9, inclusive.  First number
    -is distance to right of homebase and second number
    -is distance above homebase.
    -
    -You get 10 tries.  After each try, I will tell
    -you how far you are from each wugwump.
    diff --git a/62_Mugwump/csharp/TextIOExtensions.cs b/62_Mugwump/csharp/TextIOExtensions.cs
    deleted file mode 100644
    index a21039e4b..000000000
    --- a/62_Mugwump/csharp/TextIOExtensions.cs
    +++ /dev/null
    @@ -1,13 +0,0 @@
    -namespace Mugwump;
    -
    -// Provides input methods which emulate the BASIC interpreter's keyboard input routines
    -internal static class TextIOExtensions
    -{
    -    internal static Position ReadGuess(this TextIO io, string prompt)
    -    {
    -        io.WriteLine();
    -        io.WriteLine();
    -        var (x, y) = io.Read2Numbers(prompt);
    -        return new Position(x, y);
    -    }
    -}
    diff --git a/62_Mugwump/java/src/Mugwump.java b/62_Mugwump/java/src/Mugwump.java
    index a35ce8456..6dbefef1a 100644
    --- a/62_Mugwump/java/src/Mugwump.java
    +++ b/62_Mugwump/java/src/Mugwump.java
    @@ -183,4 +183,4 @@ public static void main(String[] args) {
             Mugwump mugwump = new Mugwump();
             mugwump.play();
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/62_Mugwump/javascript/mugwump.html b/62_Mugwump/javascript/mugwump.html
    index 3a7a9161e..1d5904872 100644
    --- a/62_Mugwump/javascript/mugwump.html
    +++ b/62_Mugwump/javascript/mugwump.html
    @@ -1,10 +1,9 @@
     
     
     MUGWUMP
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/62_Mugwump/javascript/mugwump.js b/62_Mugwump/javascript/mugwump.js
    index 6ae35a87e..06f0adb9c 100644
    --- a/62_Mugwump/javascript/mugwump.js
    +++ b/62_Mugwump/javascript/mugwump.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/62_Mugwump/kotlin/README.md b/62_Mugwump/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/62_Mugwump/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/62_Mugwump/lua/README.md b/62_Mugwump/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/62_Mugwump/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/62_Mugwump/pascal/README.md b/62_Mugwump/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/62_Mugwump/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/62_Mugwump/perl/mugwump.pl b/62_Mugwump/perl/mugwump.pl
    index 13a50bff9..33835b773 100755
    --- a/62_Mugwump/perl/mugwump.pl
    +++ b/62_Mugwump/perl/mugwump.pl
    @@ -10,7 +10,7 @@
     
     # init_mugwump: pick the random places for the Mugwumps
     sub init_mugwump() {
    -    @MUGWUMP = ();
    +    @MUGWUMP = (); 
         for (1 .. 4) {
             push @MUGWUMP, [ int(rand 10), int(rand 10) ];
         }
    @@ -44,7 +44,7 @@ ()
     PLAY: while (1) {
     
         init_mugwump();
    -    TURN: for my $turn (1 .. 10) {
    +    TURN: for my $turn (1 .. 10) { 
     
             printf("\nTurn no %d -- what is your guess ? ", $turn);
     
    @@ -88,8 +88,9 @@ ()
             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";
     }
    +
    diff --git a/62_Mugwump/python/mugwump.py b/62_Mugwump/python/mugwump.py
    index cc719c172..fdcc29450 100644
    --- a/62_Mugwump/python/mugwump.py
    +++ b/62_Mugwump/python/mugwump.py
    @@ -1,13 +1,12 @@
     from math import sqrt
     from random import randint
    -from typing import List, Tuple
     
     
    -def introduction() -> None:
    +def introduction():
         print(
             """The object of this game is to find 4 mugwumps
     hidden on a 10*10 grid.  Homebase is position 0,0.
    -Any guess you make must be two numbers with each
    +Any guess you make must be two numbers with each 
     number between 0 and 9 inclusive.  First number
     is distance to right of homebase, and second number
     is the distance above homebase."""
    @@ -19,7 +18,7 @@ def introduction() -> None:
         )
     
     
    -def generate_mugwumps(n: int = 4) -> List[List[int]]:
    +def generate_mugwumps(n=4):
         mugwumps = []
         for _ in range(n):
             current = [randint(0, 9), randint(0, 9)]
    @@ -27,18 +26,18 @@ def generate_mugwumps(n: int = 4) -> List[List[int]]:
         return mugwumps
     
     
    -def reveal_mugwumps(mugwumps: List[List[int]]) -> None:
    +def reveal_mugwumps(mugwumps):
         print("Sorry, that's 10 tries.  Here's where they're hiding.")
         for idx, mugwump in enumerate(mugwumps, 1):
             if mugwump[0] != -1:
                 print(f"Mugwump {idx} is at {mugwump[0]},{mugwump[1]}")
     
     
    -def calculate_distance(guess: Tuple[int, int], mugwump: List[int]) -> float:
    -    return sqrt(((mugwump[0] - guess[0]) ** 2) + ((mugwump[1] - guess[1]) ** 2))
    +def calculate_distance(guess, mugwump):
    +    d = sqrt(((mugwump[0] - guess[0]) ** 2) + ((mugwump[1] - guess[1]) ** 2))
    +    return d
     
    -
    -def play_again() -> None:
    +def play_again():
         print("THAT WAS FUN! LET'S PLAY AGAIN.......")
         choice = input("Press Enter to play again, any other key then Enter to quit.")
         if choice == "":
    @@ -46,8 +45,7 @@ def play_again() -> None:
         else:
             exit()
     
    -
    -def play_round() -> None:
    +def play_round():
         mugwumps = generate_mugwumps()
         turns = 1
         score = 0
    diff --git a/62_Mugwump/rust/Cargo.lock b/62_Mugwump/rust/Cargo.lock
    deleted file mode 100644
    index 4fe2abbea..000000000
    --- a/62_Mugwump/rust/Cargo.lock
    +++ /dev/null
    @@ -1,75 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.10"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.147"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/62_Mugwump/rust/Cargo.toml b/62_Mugwump/rust/Cargo.toml
    deleted file mode 100644
    index 3b1d02f52..000000000
    --- a/62_Mugwump/rust/Cargo.toml
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -[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/62_Mugwump/rust/src/coordinate.rs b/62_Mugwump/rust/src/coordinate.rs
    deleted file mode 100644
    index f13eb2406..000000000
    --- a/62_Mugwump/rust/src/coordinate.rs
    +++ /dev/null
    @@ -1,41 +0,0 @@
    -#![allow(dead_code)]
    -
    -#[derive(Debug)]
    -pub struct Coordinate {
    -    x: u8,
    -    y: u8,
    -    pub state: CoordState,
    -    pub mugwump_number: u8,
    -}
    -
    -impl Coordinate {
    -    pub fn new(pos: (u8, u8), has_mugwump: bool, mugwump_number: i32) -> Self {
    -        let mut mug_no = 0;
    -
    -        let state = if has_mugwump {
    -            mug_no = mugwump_number;
    -            CoordState::HasMugwump
    -        } else {
    -            CoordState::Normal
    -        };
    -
    -        Coordinate {
    -            x: pos.0,
    -            y: pos.1,
    -            state,
    -            mugwump_number: mug_no as u8,
    -        }
    -    }
    -
    -    pub fn get_pos(&self) -> (u8, u8) {
    -        (self.x, self.y)
    -    }
    -}
    -
    -#[derive(Debug, PartialEq)]
    -pub enum CoordState {
    -    Normal,
    -    HasMugwump,
    -    Checked,
    -    FoundMugwump,
    -}
    diff --git a/62_Mugwump/rust/src/draw.rs b/62_Mugwump/rust/src/draw.rs
    deleted file mode 100644
    index d7fac325e..000000000
    --- a/62_Mugwump/rust/src/draw.rs
    +++ /dev/null
    @@ -1,67 +0,0 @@
    -use crate::coordinate::{CoordState, Coordinate};
    -
    -pub fn draw_board(coords: &Vec, show_mugwumps: bool) {
    -    let draw_top_bottom = |is_top: bool| {
    -        let (mut left, mut right) = ("╔", "╗");
    -
    -        if !is_top {
    -            (left, right) = ("╚", "╝");
    -        }
    -
    -        for i in 0..11 {
    -            if i == 0 {
    -                print!("{}══", left);
    -            } else if i == 10 {
    -                print!("═══{}", right)
    -            } else {
    -                print!("══");
    -            }
    -        }
    -        println!("");
    -    };
    -
    -    draw_top_bottom(true);
    -
    -    let mut y: i8 = 9;
    -
    -    print!("║ {} ", y);
    -    for (i, c) in coords.iter().enumerate() {
    -        {
    -            use CoordState::*;
    -
    -            let mut _char = ' ';
    -
    -            match c.state {
    -                Normal => _char = '-',
    -                HasMugwump => _char = if show_mugwumps { 'M' } else { '-' },
    -                Checked => _char = '*',
    -                FoundMugwump => _char = '𑗌',
    -            }
    -
    -            print!("{} ", _char);
    -        }
    -
    -        if ((i + 1) % 10) == 0 {
    -            y -= 1;
    -
    -            print!("║");
    -            println!("");
    -
    -            if i != 99 {
    -                print!("║ {} ", y);
    -            }
    -        }
    -    }
    -
    -    print!("║ ♥︎ ");
    -    for i in 0..10 {
    -        print!("{} ", i);
    -
    -        if i == 9 {
    -            print!("║");
    -        }
    -    }
    -    println!("");
    -
    -    draw_top_bottom(false);
    -}
    diff --git a/62_Mugwump/rust/src/game.rs b/62_Mugwump/rust/src/game.rs
    deleted file mode 100644
    index f556dfac1..000000000
    --- a/62_Mugwump/rust/src/game.rs
    +++ /dev/null
    @@ -1,162 +0,0 @@
    -use rand::Rng;
    -
    -use crate::{
    -    coordinate::{CoordState, Coordinate},
    -    draw::draw_board,
    -    util,
    -};
    -
    -pub struct Game {
    -    pub coords: Vec,
    -    tries: u8,
    -    show_board: bool,
    -}
    -
    -impl Game {
    -    pub fn new(show_board: bool) -> Self {
    -        let mut coords = Vec::new();
    -        let mut random_indexes = Vec::new();
    -        let get_random_index = || -> i32 { rand::thread_rng().gen_range(0..100) };
    -
    -        for _ in 0..4 {
    -            let mut i = get_random_index();
    -            while random_indexes.contains(&i) {
    -                i = get_random_index();
    -            }
    -            random_indexes.push(i);
    -        }
    -
    -        let mut x = 0;
    -        let mut y: i8 = 9;
    -
    -        let mut mugwump_number = 0;
    -
    -        for i in 0..100 {
    -            let mut has_mugwump = false;
    -
    -            if random_indexes.contains(&i) {
    -                has_mugwump = true;
    -                mugwump_number += 1;
    -            }
    -
    -            coords.push(Coordinate::new((x, y as u8), has_mugwump, mugwump_number));
    -
    -            x += 1;
    -
    -            if ((i + 1) % 10) == 0 {
    -                x = 0;
    -                y -= 1;
    -            }
    -        }
    -
    -        Game {
    -            coords,
    -            tries: 0,
    -            show_board,
    -        }
    -    }
    -
    -    pub fn tick(&mut self) -> Option {
    -        let mut game_over = false;
    -
    -        if self.tries >= 10 {
    -            println!("SORRY THAT'S 10 TRIES. HERE IS WHERE THEY ARE HIDING");
    -
    -            for m in self.get_mugwumps() {
    -                println!("MUGWUMP {} IS AT {:?}", m.mugwump_number, m.get_pos());
    -            }
    -
    -            if self.show_board {
    -                draw_board(&self.coords, true);
    -            }
    -
    -            game_over = true;
    -        }
    -
    -        if self.get_mugwumps().len() == 0 {
    -            println!("YOU HAVE FOUND ALL MUGWUMPS!");
    -
    -            game_over = true;
    -        }
    -
    -        if game_over {
    -            return util::prompt_bool("THAT WAS FUN! PLAY AGAIN (Y/n)?");
    -        }
    -
    -        self.tries += 1;
    -
    -        if self.show_board {
    -            draw_board(&self.coords, true);
    -        }
    -
    -        let entered_position = self.input_coordinate();
    -        self.check_position(entered_position);
    -
    -        None
    -    }
    -
    -    fn check_position(&mut self, pos: (u8, u8)) {
    -        if let Some(coord) = self.coords.iter_mut().find(|c| c.get_pos() == pos) {
    -            use CoordState::*;
    -
    -            match coord.state {
    -                Normal => {
    -                    coord.state = Checked;
    -                    self.print_distances(pos);
    -                }
    -                HasMugwump => {
    -                    coord.state = FoundMugwump;
    -                    println!("YOU FOUND MUGWUMP {}", coord.mugwump_number);
    -                    self.print_distances(pos);
    -                }
    -                Checked | FoundMugwump => println!("YOU ALREADY LOOKED HERE!"),
    -            }
    -        }
    -    }
    -
    -    fn print_distances(&self, (x, y): (u8, u8)) {
    -        let print = |m: &Coordinate| {
    -            let (mx, my) = m.get_pos();
    -            let (x, y, mx, my) = (x as i32, y as i32, mx as i32, my as i32);
    -            let distance = (((x - mx).pow(2) + (y - my).pow(2)) as f32).sqrt();
    -
    -            println!(
    -                "YOU ARE {} UNITS FROM MUGWUMP {}",
    -                distance, m.mugwump_number
    -            );
    -        };
    -
    -        for m in self.get_mugwumps() {
    -            print(m);
    -        }
    -    }
    -
    -    fn input_coordinate(&self) -> (u8, u8) {
    -        let msg = format!("TURN NO. {} WHAT IS YOUR GUESS?", self.tries);
    -        let input = util::prompt(msg.as_str());
    -
    -        if !input.contains(",") {
    -            println!("YOU MUST ENTER A COORDINATE: #,#");
    -            return (0, 0);
    -        }
    -
    -        let axes: Vec<&str> = input.split(",").collect();
    -        let mut pos = [0; 2];
    -
    -        for (i, a) in axes.iter().enumerate() {
    -            match a.parse::() {
    -                Ok(p) => pos[i] = p as u8,
    -                Err(_) => println!("YOU MUST ENTER A COORDINATE: #,#"),
    -            }
    -        }
    -
    -        (pos[0], pos[1])
    -    }
    -
    -    fn get_mugwumps(&self) -> Vec<&Coordinate> {
    -        self.coords
    -            .iter()
    -            .filter(|c| c.state == CoordState::HasMugwump)
    -            .collect()
    -    }
    -}
    diff --git a/62_Mugwump/rust/src/main.rs b/62_Mugwump/rust/src/main.rs
    deleted file mode 100644
    index fbd4479de..000000000
    --- a/62_Mugwump/rust/src/main.rs
    +++ /dev/null
    @@ -1,44 +0,0 @@
    -mod coordinate;
    -mod draw;
    -mod game;
    -pub mod util;
    -
    -use crate::game::Game;
    -
    -fn main() {
    -    println!("\n\nMUGWUMP");
    -    println!("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n");
    -
    -    println!("THE OBJECT OF THIS GAME IS TO FIND FOUR MUGWUMPS");
    -    println!("HIDDEN ON A 10 BY 10 GRID.  HOMEBASE IS POSITION 0,0.");
    -    println!("ANY GUESS YOU MAKE MUST BE TWO NUMBERS WITH EACH");
    -    println!("NUMBER BETWEEN 0 AND 9, INCLUSIVE.  FIRST NUMBER");
    -    println!("IS DISTANCE TO RIGHT OF HOMEBASE AND SECOND NUMBER");
    -    println!("IS DISTANCE ABOVE HOMEBASE!\n");
    -
    -    println!("YOU GET 10 TRIES.  AFTER EACH TRY, I WILL TELL");
    -    println!("YOU HOW FAR YOU ARE FROM EACH MUGWUMP.\n");
    -
    -    let mut _quit = false;
    -
    -    while !_quit {
    -        let mut show_board = true;
    -
    -        if let Some(r) = util::prompt_bool("WOULD YOU LIKE TO SEE THE BOARD?") {
    -            show_board = r;
    -        }
    -
    -        let mut game = Game::new(show_board);
    -
    -        loop {
    -            if let Some(again) = game.tick() {
    -                if !again {
    -                    _quit = true;
    -                } else {
    -                    println!("FOUR MORE MUGWUMPS ARE NOW IN HIDING")
    -                }
    -                break;
    -            }
    -        }
    -    }
    -}
    diff --git a/62_Mugwump/rust/src/util.rs b/62_Mugwump/rust/src/util.rs
    deleted file mode 100644
    index ff4e9ecb8..000000000
    --- a/62_Mugwump/rust/src/util.rs
    +++ /dev/null
    @@ -1,25 +0,0 @@
    -use std::io;
    -
    -pub fn prompt(msg: &str) -> String {
    -    println!("\n{}", msg);
    -
    -    let mut input = String::new();
    -
    -    io::stdin()
    -        .read_line(&mut input)
    -        .expect("Failed to read line.");
    -
    -    input.trim().to_string()
    -}
    -
    -pub fn prompt_bool(msg: &str) -> Option {
    -    loop {
    -        let response = prompt(msg);
    -
    -        match response.to_uppercase().as_str() {
    -            "Y" | "YES" => return Some(true),
    -            "N" | "NO" => return Some(false),
    -            _ => println!("PLEASE ENTER (Y)ES or (N)O."),
    -        }
    -    }
    -}
    diff --git a/62_Mugwump/vbnet/Mugwump.sln b/62_Mugwump/vbnet/Mugwump.sln
    deleted file mode 100644
    index 49f0dd09c..000000000
    --- a/62_Mugwump/vbnet/Mugwump.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 50f8a0a18..000000000
    --- a/62_Mugwump/vbnet/Mugwump.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Mugwump
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/63_Name/README.md b/63_Name/README.md
    index f8b610e94..45bf4e9a8 100644
    --- a/63_Name/README.md
    +++ b/63_Name/README.md
    @@ -12,7 +12,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/63_Name/java/Name.java b/63_Name/java/Name.java
    deleted file mode 100644
    index 7b67f4899..000000000
    --- a/63_Name/java/Name.java
    +++ /dev/null
    @@ -1,55 +0,0 @@
    -import java.util.Arrays;
    -import java.util.Scanner;
    -
    -public class Name {
    -
    -    public static void printempty() { System.out.println(" "); }
    -
    -    public static void print(String toprint) { System.out.println(toprint); }
    -
    -    public static void main(String[] args) {
    -        print("                                          NAME");
    -        print("                         CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY");
    -        printempty();
    -        printempty();
    -        print("HELLO.");
    -        print("MY NAME iS CREATIVE COMPUTER.");
    -        print("WHATS YOUR NAME? (FIRST AND LAST)");
    -
    -        Scanner namesc = new Scanner(System.in);
    -        String name = namesc.nextLine();
    -
    -        String namereversed = new StringBuilder(name).reverse().toString();
    -
    -        char namesorted[] = name.toCharArray();
    -        Arrays.sort(namesorted);
    -
    -        printempty();
    -        print("THANK YOU, " + namereversed);
    -        printempty();
    -        print("OOPS!  I GUESS I GOT IT BACKWARDS.  A SMART");
    -        print("COMPUTER LIKE ME SHOULDN'T MAKE A MISTAKE LIKE THAT!");
    -        printempty();
    -        printempty();
    -        print("BUT I JUST NOTICED YOUR LETTERS ARE OUT OF ORDER.");
    -
    -        print("LET'S PUT THEM IN ORDER LIKE THIS: " + new String(namesorted));
    -        printempty();
    -        printempty();
    -
    -        print("DON'T YOU LIKE THAT BETTER?");
    -        printempty();
    -
    -        Scanner agreementsc = new Scanner(System.in);
    -        String agreement = agreementsc.nextLine();
    -
    -        if (agreement.equalsIgnoreCase("yes")) {
    -            print("I KNEW YOU'D AGREE!!");
    -        } else {
    -            print("I'M SORRY YOU DON'T LIKE IT THAT WAY.");
    -            printempty();
    -            print("I REALLY ENJOYED MEETING YOU, " + name);
    -            print("HAVE A NICE DAY!");
    -        }
    -    }
    -}
    diff --git a/63_Name/java/main.class b/63_Name/java/main.class
    new file mode 100644
    index 000000000..db01b014a
    --- /dev/null
    +++ b/63_Name/java/main.class
    @@ -0,0 +1,55 @@
    +import java.util.Arrays;
    +import java.util.Scanner;
    +
    +public class main {
    +
    +    public static void printempty() { System.out.println(" "); }
    +
    +    public static void print(String toprint) { System.out.println(toprint); }
    +
    +    public static void main(String[] args) {
    +        print("                                          NAME");
    +        print("                         CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY");
    +        printempty();
    +        printempty();
    +        print("HELLO.");
    +        print("MY NAME iS CREATIVE COMPUTER.");
    +        print("WHATS YOUR NAME? (FIRST AND LAST)");
    +
    +        Scanner namesc = new Scanner(System.in);
    +        String name = namesc.nextLine();
    +
    +        String namereversed = new StringBuilder(name).reverse().toString();
    +
    +        char namesorted[] = name.toCharArray();
    +        Arrays.sort(namesorted);
    +
    +        printempty();
    +        print("THANK YOU, " + namereversed);
    +        printempty();
    +        print("OOPS!  I GUESS I GOT IT BACKWARDS.  A SMART");
    +        print("COMPUTER LIKE ME SHOULDN'T MAKE A MISTAKE LIKE THAT!");
    +        printempty();
    +        printempty();
    +        print("BUT I JUST NOTICED YOUR LETTERS ARE OUT OF ORDER.");
    +
    +        print("LET'S PUT THEM IN ORDER LIKE THIS: " + new String(namesorted));
    +        printempty();
    +        printempty();
    +
    +        print("DON'T YOU LIKE THAT BETTER?");
    +        printempty();
    +
    +        Scanner agreementsc = new Scanner(System.in);
    +        String agreement = agreementsc.nextLine();
    +
    +        if (agreement.equalsIgnoreCase("yes")) {
    +            print("I KNEW YOU'D AGREE!!");
    +        } else {
    +            print("I'M SORRY YOU DON'T LIKE IT THAT WAY.");
    +            printempty();
    +            print("I REALLY ENJOYED MEETING YOU, " + name);
    +            print("HAVE A NICE DAY!");
    +        }
    +    }
    +}
    diff --git a/63_Name/javascript/name.html b/63_Name/javascript/name.html
    index 94f58551f..bed003f4d 100644
    --- a/63_Name/javascript/name.html
    +++ b/63_Name/javascript/name.html
    @@ -1,10 +1,9 @@
     
     
     NAME
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/63_Name/javascript/name.js b/63_Name/javascript/name.js
    index 3c376f599..cfa33cf44 100644
    --- a/63_Name/javascript/name.js
    +++ b/63_Name/javascript/name.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/63_Name/kotlin/README.md b/63_Name/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/63_Name/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/63_Name/lua/README.md b/63_Name/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/63_Name/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/63_Name/lua/name.lua b/63_Name/lua/name.lua
    deleted file mode 100644
    index 32d51c93e..000000000
    --- a/63_Name/lua/name.lua
    +++ /dev/null
    @@ -1,85 +0,0 @@
    --- HELLO
    ---
    --- Converted from BASIC to Lua by Recanman
    -
    -local function tab(space)
    -    local str = ""
    -
    -    for _ = space, 1, -1 do
    -        str = str .. " "
    -    end
    -
    -    return str
    -end
    -
    --- reused from Bagels.lua
    -function getInput(prompt)
    -    io.write(prompt)
    -    io.flush()
    -    local input = io.read("l")
    -    if not input then  --- test for EOF
    -        print("GOODBYE")
    -        os.exit(0)
    -    end
    -    return input
    -end
    -
    -print(tab(33) .. "HELLO\n")
    -print(tab(15) .. "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n")
    -print("\n")
    -print("\n")
    -print("\n")
    -
    -print("HELLO.  MY NAME IS CREATIVE COMPUTER.\n")
    -print("\n")
    -print("\n")
    -
    -print("WHAT'S YOUR NAME (FIRST AND LAST)")
    -
    -local ns = getInput("? ")
    -local l = string.len(ns)
    -print("\n")
    -
    -local function main()
    -    print("THANK YOU, " .. string.reverse(ns) .. ".\n")
    -
    -    print("OOPS!  I GUESS I GOT IT BACKWARDS.  A SMART")
    -    print("COMPUTER LIKE ME SHOULDN'T MAKE A MISTAKE LIKE THAT!\n")
    -    print("BUT I JUST NOTICED YOUR LETTERS ARE OUT OF ORDER.\n")
    -    print("LET'S PUT THEM IN ORDER LIKE THIS: ")
    -    
    -    local b = {}
    -    
    -    for i = 1, l, 1 do
    -        local letter = string.sub(ns, i, i)
    -        b[i] = string.byte(letter)
    -    end
    -    
    -    table.sort(b, function(v1, v2)
    -        return v1 < v2
    -    end)
    -    
    -    local str = ""
    -    for _, letter in ipairs(b) do
    -        str = str .. string.char(letter)
    -    end
    -    
    -    str = string.reverse(str)
    -    print(str)
    -    
    -    print("\n\n")
    -    print("DON'T YOU LIKE THAT BETTER")
    -    
    -    local ds = getInput("? ")
    -        
    -    if ds == "YES" then
    -        print("I KNEW YOU'D AGREE!!\n")
    -    else
    -        print("I'M SORRY YOU DON'T LIKE IT THAT WAY.\n")
    -    end
    -    
    -    print("I REALLY ENJOYED MEETING YOU " ..  ns .. ".\n")
    -    print("HAVE A NICE DAY!\n")
    -end
    -
    -main()
    diff --git a/63_Name/pascal/README.md b/63_Name/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/63_Name/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/63_Name/perl/name.pl b/63_Name/perl/name.pl
    index 512ffbb7e..d25bcfe0a 100755
    --- a/63_Name/perl/name.pl
    +++ b/63_Name/perl/name.pl
    @@ -31,3 +31,5 @@
     print "\n"; print "I REALLY ENJOYED MEETING YOU $A.\n";
     print "HAVE A NICE DAY!\n";
     exit;
    +
    +
    diff --git a/63_Name/python/name.py b/63_Name/python/name.py
    index 94b8170d6..5c567d5a5 100644
    --- a/63_Name/python/name.py
    +++ b/63_Name/python/name.py
    @@ -7,27 +7,45 @@
     """
     
     
    -def is_yes_ish(answer: str) -> bool:
    +def print_with_tab(space_count, msg):
    +    if space_count > 0:
    +        spaces = " " * space_count
    +    else:
    +        spaces = ""
    +    print(spaces + msg)
    +
    +
    +def is_yes_ish(answer):
         cleaned = answer.strip().upper()
    -    return cleaned in {"Y", "YES"}
    +    if cleaned == "Y" or cleaned == "YES":
    +        return True
    +    return False
     
     
    -def main() -> None:
    -    print(" " * 34 + "NAME")
    -    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n")
    +def main():
    +    print_with_tab(34, "NAME")
    +    print_with_tab(15, "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
    +    print()
    +    print()
    +    print()
         print("HELLO.")
         print("MY NAME iS CREATIVE COMPUTER.")
         name = input("WHAT'S YOUR NAME (FIRST AND LAST)?")
         print()
         name_as_list = list(name)
         reversed_name = "".join(name_as_list[::-1])
    -    print(f"THANK YOU, {reversed_name}.\n")
    +    print(f"THANK YOU, {reversed_name}.")
    +    print()
         print("OOPS!  I GUESS I GOT IT BACKWARDS.  A SMART")
    -    print("COMPUTER LIKE ME SHOULDN'T MAKE A MISTAKE LIKE THAT!\n\n")
    +    print("COMPUTER LIKE ME SHOULDN'T MAKE A MISTAKE LIKE THAT!")
    +    print()
    +    print()
         print("BUT I JUST NOTICED YOUR LETTERS ARE OUT OF ORDER.")
     
         sorted_name = "".join(sorted(name_as_list))
    -    print(f"LET'S PUT THEM IN ORDER LIKE THIS: {sorted_name}\n\n")
    +    print(f"LET'S PUT THEM IN ORDER LIKE THIS: {sorted_name}")
    +    print()
    +    print()
     
         print("DON'T YOU LIKE THAT BETTER?")
         like_answer = input()
    @@ -41,5 +59,4 @@ def main() -> None:
         print("HAVE A NICE DAY!")
     
     
    -if __name__ == "__main__":
    -    main()
    +main()
    diff --git a/63_Name/ruby/name.rb b/63_Name/ruby/name.rb
    deleted file mode 100644
    index 522c7af01..000000000
    --- a/63_Name/ruby/name.rb
    +++ /dev/null
    @@ -1,42 +0,0 @@
    -def is_yes_ish answer
    -    cleaned = answer.upcase
    -    return true if ["Y", "YES"].include? cleaned
    -    return false
    -end
    -
    -def main
    -    puts " " * 34 + "NAME"
    -
    -    puts "HELLO."
    -    puts "MY NAME iS COMPUTER."
    -    print "WHAT'S YOUR NAME (FIRST AND LAST)? "
    -    name = gets.chomp!
    -    puts ""
    -    name_as_list = name.split("")
    -    reversed_name = name_as_list.reverse.join("")
    -
    -    puts "THANK YOU, #{reversed_name}.\n"
    -    puts "OOPS!  I GUESS I GOT IT BACKWARDS.  A SMART"
    -    puts "COMPUTER LIKE ME SHOULDN'T MAKE A MISTAKE LIKE THAT!\n\n"
    -    puts "BUT I JUST NOTICED YOUR LETTERS ARE OUT OF ORDER."
    -
    -    sorted_name = name_as_list.sort.join("")
    -    puts "LET'S PUT THEM IN ORDER LIKE THIS: #{sorted_name}\n\n"
    -    print "DON'T YOU LIKE THAT BETTER? "
    -    like_answer = gets.chomp!
    -    puts
    -    if is_yes_ish(like_answer)
    -        puts "I KNEW YOU'D AGREE!!"
    -    else
    -        puts "I'M SORRY YOU DON'T LIKE IT THAT WAY."
    -    end
    -
    -    puts ""
    -    puts "I REALLY ENJOYED MEETING YOU, #{name}."
    -    puts "HAVE A NICE DAY!"
    -end
    -
    -
    -if __FILE__ == $0
    -    main
    -end
    \ No newline at end of file
    diff --git a/63_Name/rust/Cargo.toml b/63_Name/rust/Cargo.toml
    deleted file mode 100644
    index 7d75412a6..000000000
    --- a/63_Name/rust/Cargo.toml
    +++ /dev/null
    @@ -1,6 +0,0 @@
    -[package]
    -name = "rust"
    -version = "0.1.0"
    -edition = "2021"
    -
    -[dependencies]
    diff --git a/63_Name/rust/src/main.rs b/63_Name/rust/src/main.rs
    deleted file mode 100644
    index 1a1f631a7..000000000
    --- a/63_Name/rust/src/main.rs
    +++ /dev/null
    @@ -1,116 +0,0 @@
    -/** NAME GAME BY GEOFFREY CHASE
    - * https://github.com/coding-horror/basic-computer-games/blob/main/63_Name/name.bas
    - * Direct conversion from BASIC to Rust by Pablo Marques (marquesrs).
    - * No additional features or improvements were added. As a faithful translation, 
    - * many of the code here are done in an unrecommended way by today's standards.
    - * 17/02/25
    -*/
    -
    -use std::io::Write;
    -
    -fn main() {
    -    let mut input = String::new();
    -    
    -    //1 PRINT TAB(34);"NAME"
    -    //2 PRINT TAB(15);"CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY"
    -    //3 PRINT: PRINT: PRINT
    -    print!("{}{}\n{}{}\n\n\n\n",
    -        " ".repeat(34),
    -        "NAME",
    -        " ".repeat(15),
    -        "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY"
    -    );
    -    
    -    //5 DIM B$(40)
    -    let mut b = [0; 40];
    -    
    -    //10 PRINT "HELLO.": PRINT "MY NAME IS CREATIVE COMPUTER."
    -    //20 PRINT "WHAT'S YOUR NAME (FIRST AND LAST";: INPUT A$: L=LEN(A$)
    -    print!("{}\n{}\n{}",
    -        "HELLO.",
    -        "MY NAME IS CREATIVE COMPUTER.",
    -        "WHAT'S YOUR NAME (FIRST AND LAST)? "
    -    );
    -    
    -    let _ = std::io::stdout().flush().unwrap();
    -    std::io::stdin().read_line(&mut input).unwrap();
    -    let a = input.trim().to_uppercase();
    -    let l = a.len();
    -    
    -    //30 PRINT: PRINT "THANK YOU, ";
    -    print!("\nTHANK YOU, ");
    -    
    -    //40 FOR I=1 TO L: B$(I)=MID$(A$,I,1): NEXT I
    -    for i in 1..=l {
    -        b[i-1] = a.chars().nth(i-1).unwrap() as u8;
    -    }
    -    
    -    //50 FOR I=L TO 1 STEP -1: PRINT B$(I);: NEXT I
    -    for i in (1..=l).rev() {
    -        print!("{}", b[i-1] as char);
    -    }
    -    
    -    //60 PRINT ".": PRINT "OOPS!  I GUESS I GOT IT BACKWARDS.  A SMART"
    -    //70 PRINT "COMPUTER LIKE ME SHOULDN'T MAKE A MISTAKE LIKE THAT!": PRINT
    -    //80 PRINT "BUT I JUST NOTICED YOUR LETTERS ARE OUT OF ORDER."
    -    //90 PRINT "LET'S PUT THEM IN ORDER LIKE THIS: ";
    -    print!("{}\n{}\n{}\n\n{}\n{}",
    -        ".",
    -        "OOPS! I GUESS I GOT IT BACKWARDS. A SMART",
    -        "COMPUTER LIKE ME SHOULDN'T MAKE A MISTAKE LIKE THAT!",
    -        "BUT I JUST NOTICED YOUR LETTERS ARE OUT OF ORDER.",
    -        "LET'S PUT THEM IN ORDER LIKE THIS: "
    -    );
    -
    -    //100 FOR J=2 TO L: I=J-1: T$=B$(J)
    -    let mut i;
    -    let mut t;
    -    for j in 2..=l { 
    -        i = j - 1;
    -        t = b[j-1];
    -        loop {
    -            //110 IF T$>B$(I) THEN 130
    -            if i == 0 || t > b[i-1] {
    -                //130 B$(I+1)=T$: NEXT J
    -                b[i] = t;
    -                break;
    -            } else {
    -                //120 B$(I+1)=B$(I): I=I-1: IF I>0 THEN 110
    -                b[i] = b[i-1];
    -                i = i - 1;
    -            }
    -        } 
    -    }
    -    
    -    //140 FOR I=1 TO L: PRINT B$(I);: NEXT I: PRINT: PRINT
    -    for i in 1..=l {
    -        print!("{}", b[i-1] as char);
    -    }
    -    print!("\n\n");
    -    
    -    //150 PRINT "DON'T YOU LIKE THAT BETTER";: INPUT D$
    -    print!("DON'T YOU LIKE THAT BETTER? ");
    -    
    -    let _ = std::io::stdout().flush().unwrap();
    -    input.clear();
    -    std::io::stdin().read_line(&mut input).unwrap();
    -    let d = input.trim().to_uppercase();
    -    
    -    //160 IF D$="YES" THEN 180
    -    if d == "YES" || d == "Y" {
    -        //180 PRINT: PRINT "I KNEW YOU'D AGREE!!"
    -        print!("\nI KNEW YOU'D AGREE!!");
    -    }
    -    else {
    -        //170 PRINT: PRINT "I'M SORRY YOU DON'T LIKE IT THAT WAY.": GOTO 200
    -        print!("\nI'M SORRY YOU DON'T LIKE IT THAT WAY.");
    -    }
    -    
    -    print!("\n\n{}{}.\n{}\n",
    -        "I REALLY ENJOYED MEETING YOU ",
    -        a,
    -        "HAVE A NICE DAY!"
    -    );
    -    
    -    //999 END
    -}
    diff --git a/63_Name/vbnet/Name.sln b/63_Name/vbnet/Name.sln
    deleted file mode 100644
    index 29b923562..000000000
    --- a/63_Name/vbnet/Name.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index a06d78f33..000000000
    --- a/63_Name/vbnet/Name.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Name
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/64_Nicomachus/README.md b/64_Nicomachus/README.md
    index bec9c7821..bbe911fc3 100644
    --- a/64_Nicomachus/README.md
    +++ b/64_Nicomachus/README.md
    @@ -16,7 +16,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/64_Nicomachus/csharp/Nicomachus.csproj b/64_Nicomachus/csharp/Nicomachus.csproj
    deleted file mode 100644
    index d3fe4757c..000000000
    --- a/64_Nicomachus/csharp/Nicomachus.csproj
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    diff --git a/64_Nicomachus/csharp/Nicomachus.sln b/64_Nicomachus/csharp/Nicomachus.sln
    deleted file mode 100644
    index 5287cabf6..000000000
    --- a/64_Nicomachus/csharp/Nicomachus.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/csharp/program.cs b/64_Nicomachus/csharp/program.cs
    deleted file mode 100644
    index c8ba4184d..000000000
    --- a/64_Nicomachus/csharp/program.cs
    +++ /dev/null
    @@ -1,122 +0,0 @@
    -using System.Text;
    -using System.Threading;
    -
    -namespace Nicomachus
    -{
    -    class Nicomachus
    -    {
    -        private void DisplayIntro()
    -        {
    -            Console.WriteLine();
    -            Console.WriteLine("NICOMA".PadLeft(23));
    -            Console.WriteLine("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY");
    -            Console.WriteLine();
    -            Console.WriteLine();
    -            Console.WriteLine();
    -            Console.WriteLine("Boomerang puzzle from Arithmetica of Nicomachus -- A.D. 90!");
    -       }
    -
    -        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("Eh?  I don't understand '{0}'  Try 'Yes' or 'No'.", LineInput);
    -            }
    -
    -            return false;
    -        }
    -
    -        private int PromptForNumber(string Prompt)
    -        {
    -            bool InputSuccess = false;
    -            int ReturnResult = 0;
    -
    -            while (!InputSuccess)
    -            {
    -                Console.Write(Prompt);
    -                string Input = Console.ReadLine().Trim();
    -                InputSuccess = int.TryParse(Input, out ReturnResult);
    -                if (!InputSuccess)
    -                    Console.WriteLine("*** Please enter a valid number ***");
    -            }   
    -
    -            return ReturnResult;
    -        }
    -
    -        private void PlayOneRound()
    -        {
    -            Random rand = new Random();
    -            int A_Number = 0;
    -            int B_Number = 0;
    -            int C_Number = 0;
    -            int D_Number = 0;
    -
    -            Console.WriteLine();
    -            Console.WriteLine("Please think of a number between 1 and 100.");
    -
    -            A_Number = PromptForNumber("Your number divided by 3 has a remainder of? ");
    -            B_Number = PromptForNumber("Your number divided by 5 has a remainder of? ");
    -            C_Number = PromptForNumber("Your number divided by 7 has a remainder of? ");
    -
    -            Console.WriteLine();
    -            Console.WriteLine("Let me think a moment...");
    -
    -            Thread.Sleep(2000);
    -
    -            D_Number = 70 * A_Number + 21 * B_Number + 15 * C_Number;
    -
    -            while (D_Number > 105)
    -            {
    -                D_Number -= 105;
    -            }
    -
    -            if (PromptYesNo("Your number was " + D_Number.ToString() + ", right? "))
    -            {
    -                Console.WriteLine();
    -                Console.WriteLine("How about that!!");
    -            }
    -            else
    -            {
    -                Console.WriteLine();
    -                Console.WriteLine("I feel your arithmetic is in error.");
    -            }
    -
    -            Console.WriteLine();
    -
    -       }
    -
    -        public void Play()
    -        {
    -            bool ContinuePlay = true;
    -
    -            DisplayIntro();
    -
    -            do 
    -            {
    -                PlayOneRound();
    -
    -                ContinuePlay = PromptYesNo("Let's try another? ");
    -            }
    -            while (ContinuePlay);
    -        }
    -    }
    -    class Program
    -    {
    -        static void Main(string[] args)
    -        {
    -
    -            new Nicomachus().Play();
    -
    -        }
    -    }
    -}
    \ No newline at end of file
    diff --git a/64_Nicomachus/java/src/Nicomachus.java b/64_Nicomachus/java/src/Nicomachus.java
    index 9996ecd24..53bbbedd7 100644
    --- a/64_Nicomachus/java/src/Nicomachus.java
    +++ b/64_Nicomachus/java/src/Nicomachus.java
    @@ -182,4 +182,4 @@ public static void main(String[] args) throws Exception {
             Nicomachus nicomachus = new Nicomachus();
             nicomachus.play();
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/64_Nicomachus/javascript/nicomachus.html b/64_Nicomachus/javascript/nicomachus.html
    index 757aaaf51..2fe069f8b 100644
    --- a/64_Nicomachus/javascript/nicomachus.html
    +++ b/64_Nicomachus/javascript/nicomachus.html
    @@ -1,10 +1,9 @@
     
     
     NICOMACHUS
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/64_Nicomachus/javascript/nicomachus.js b/64_Nicomachus/javascript/nicomachus.js
    index 93083d781..7abe1d513 100644
    --- a/64_Nicomachus/javascript/nicomachus.js
    +++ b/64_Nicomachus/javascript/nicomachus.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/64_Nicomachus/kotlin/README.md b/64_Nicomachus/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/64_Nicomachus/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/64_Nicomachus/lua/README.md b/64_Nicomachus/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/64_Nicomachus/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/64_Nicomachus/pascal/README.md b/64_Nicomachus/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/64_Nicomachus/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/64_Nicomachus/perl/nicomachus.pl b/64_Nicomachus/perl/nicomachus.pl
    index 254859303..4ed2018ff 100755
    --- a/64_Nicomachus/perl/nicomachus.pl
    +++ b/64_Nicomachus/perl/nicomachus.pl
    @@ -42,3 +42,5 @@
     	print "LET'S TRY ANOTHER.\n";
     	} #goto Line20;
     exit;
    +
    +
    diff --git a/64_Nicomachus/python/nicomachus.py b/64_Nicomachus/python/nicomachus.py
    index 1485d4a1c..33c5ab580 100644
    --- a/64_Nicomachus/python/nicomachus.py
    +++ b/64_Nicomachus/python/nicomachus.py
    @@ -6,16 +6,24 @@
     Ported by Dave LeCompte
     """
     
    -# PORTING NOTE
    -#
    -# The title, as printed ingame, is "NICOMA", hinting at a time when
    -# filesystems weren't even 8.3, but could only support 6 character
    -# filenames.
    +"""
    +PORTING NOTE
    +
    +The title, as printed ingame, is "NICOMA", hinting at a time when
    +filesystems weren't even 8.3, but could only support 6 character
    +filenames.
    +"""
     
     import time
     
    +def print_with_tab(spaces_count, msg):
    +    if spaces_count > 0:
    +        spaces = " " * spaces_count
    +    else:
    +        spaces = ""
    +    print(spaces + msg)
     
    -def get_yes_or_no() -> bool:
    +def get_yes_or_no():
         while True:
             response = input().upper()
             if response == "YES":
    @@ -25,7 +33,7 @@ def get_yes_or_no() -> bool:
             print(f"EH?  I DON'T UNDERSTAND '{response}'  TRY 'YES' OR 'NO'.")
     
     
    -def play_game() -> None:
    +def play_game():
         print("PLEASE THINK OF A NUMBER BETWEEN 1 AND 100.")
         print("YOUR NUMBER DIVIDED BY 3 HAS A REMAINDER OF")
         a = int(input())
    @@ -43,23 +51,28 @@ def play_game() -> None:
     
         print(f"YOUR NUMBER WAS {d}, RIGHT?")
     
    -    if get_yes_or_no():
    +    response = get_yes_or_no()
    +
    +    if response:
             print("HOW ABOUT THAT!!")
         else:
             print("I FEEL YOUR ARITHMETIC IS IN ERROR.")
         print()
         print("LET'S TRY ANOTHER")
    +    
     
    -
    -def main() -> None:
    -    print(" " * 33 + "NICOMA")
    -    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n")
    -
    +def main():
    +    print_with_tab(33, "NICOMA")
    +    print_with_tab(15, "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
    +    print()
    +    print()
    +    print()
    +    
         print("BOOMERANG PUZZLE FROM ARITHMETICA OF NICOMACHUS -- A.D. 90!")
         print()
         while True:
             play_game()
    -
    +        
     
     if __name__ == "__main__":
         main()
    diff --git a/64_Nicomachus/rust/Cargo.lock b/64_Nicomachus/rust/Cargo.lock
    deleted file mode 100644
    index b21cc6a2d..000000000
    --- a/64_Nicomachus/rust/Cargo.lock
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    diff --git a/64_Nicomachus/rust/Cargo.toml b/64_Nicomachus/rust/Cargo.toml
    deleted file mode 100644
    index 1ec696335..000000000
    --- a/64_Nicomachus/rust/Cargo.toml
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -[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]
    diff --git a/64_Nicomachus/rust/src/main.rs b/64_Nicomachus/rust/src/main.rs
    deleted file mode 100644
    index 40a8aa51b..000000000
    --- a/64_Nicomachus/rust/src/main.rs
    +++ /dev/null
    @@ -1,71 +0,0 @@
    -use std::io;
    -
    -fn main() {
    -    println!("\n\n~~Nicomachus~~");
    -    println!("Creative Computing Morristown, New Jersey\n");
    -
    -    println!("Boomerang Puzzle from Arithmetica of Nicomachus -- A.D. 90!\n");
    -
    -    loop {
    -        println!("Please think of a number between 1 and 100.\n");
    -
    -        let a = question("3");
    -        let b = question("5");
    -        let c = question("7");
    -
    -        println!("\nLet me think a moment...");
    -        std::thread::sleep(std::time::Duration::from_secs(2));
    -
    -        let d: i32 = (70 * a + 21 * b + 15 * c) % 105;
    -
    -        if prompt(format!("Your number was {}, right?", d)) {
    -            println!("\nHow about that!!");
    -        } else {
    -            println!("\nI feel your arithmetic is in error.");
    -        }
    -
    -        if !prompt("\nTry another?".to_string()) {
    -            break;
    -        }
    -    }
    -}
    -
    -fn question(n: &str) -> i32 {
    -    loop {
    -        println!("Your number divided by {} has a remainder of?", n);
    -
    -        let input = read_line().trim().parse::();
    -
    -        match input {
    -            Ok(r) => return r,
    -            Err(_) => println!("Input must be a number."),
    -        }
    -    }
    -}
    -
    -fn prompt(msg: String) -> bool {
    -    println!("{}", msg);
    -
    -    loop {
    -        let input = read_line().trim().to_uppercase();
    -        let input = input.as_str();
    -
    -        if input == "Y" || input == "YES" {
    -            return true;
    -        } else if input == "N" || input == "NO" {
    -            return false;
    -        } else {
    -            println!("Please input either (Y)es or (N)o.")
    -        }
    -    }
    -}
    -
    -fn read_line() -> String {
    -    let mut input = String::new();
    -
    -    io::stdin()
    -        .read_line(&mut input)
    -        .expect("Failed to read line.");
    -
    -    input
    -}
    diff --git a/64_Nicomachus/vbnet/Nicomachus.sln b/64_Nicomachus/vbnet/Nicomachus.sln
    deleted file mode 100644
    index bea341c45..000000000
    --- a/64_Nicomachus/vbnet/Nicomachus.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 404fd9d9c..000000000
    --- a/64_Nicomachus/vbnet/Nicomachus.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Nicomachus
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/65_Nim/README.md b/65_Nim/README.md
    index fae886395..867f641d4 100644
    --- a/65_Nim/README.md
    +++ b/65_Nim/README.md
    @@ -22,13 +22,6 @@ As published in Basic Computer Games (1978):
     - [Atari Archives](https://www.atariarchives.org/basicgames/showpage.php?page=118)
     - [Annarchive](https://annarchive.com/files/Basic_Computer_Games_Microcomputer_Edition.pdf#page=133)
     
    +
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -This can be a real challenge to port because of all the `GOTO`s going out of loops down to code. You may need breaks and continues, or other techniques.
    -
    -#### Known Bugs
    -
    -- If, after the player moves, all piles are gone, the code prints "MACHINE LOSES" regardless of the win condition (when line 1550 jumps to line 800).  This should instead jump to line 800 ("machine loses") if W=1, but jump to 820 ("machine wins") if W=2.
    diff --git a/65_Nim/csharp/Nim.csproj b/65_Nim/csharp/Nim.csproj
    deleted file mode 100644
    index d3fe4757c..000000000
    --- a/65_Nim/csharp/Nim.csproj
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    diff --git a/65_Nim/csharp/Nim.sln b/65_Nim/csharp/Nim.sln
    deleted file mode 100644
    index dd324894e..000000000
    --- a/65_Nim/csharp/Nim.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/javascript/nim.html b/65_Nim/javascript/nim.html
    index 1d6efd233..db914b252 100644
    --- a/65_Nim/javascript/nim.html
    +++ b/65_Nim/javascript/nim.html
    @@ -1,10 +1,9 @@
     
     
     NIM
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/65_Nim/javascript/nim.js b/65_Nim/javascript/nim.js
    index ddd09d98d..847c049a0 100644
    --- a/65_Nim/javascript/nim.js
    +++ b/65_Nim/javascript/nim.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    @@ -146,7 +146,7 @@ async function main()
                                     print("MACHINE LOSES\n");
                                 break;
                             }
    -
    +                        
                         } else {
                             c = 0;
                             for (i = 1; i <= n; i++) {
    diff --git a/65_Nim/kotlin/README.md b/65_Nim/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/65_Nim/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/65_Nim/lua/README.md b/65_Nim/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/65_Nim/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/65_Nim/nim.bas b/65_Nim/nim.bas
    index d078a0c6a..cda67e30c 100644
    --- a/65_Nim/nim.bas
    +++ b/65_Nim/nim.bas
    @@ -151,6 +151,6 @@
     1680 IF Q9$="NO" THEN 1730
     1690 IF Q9$="no" THEN 1730
     1700 PRINT "PLEASE.  YES OR NO."
    -1710 GOTO 1650
    +1710 GOTO 1650 
     1720 GOTO 440
     1730 END
    diff --git a/65_Nim/pascal/README.md b/65_Nim/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/65_Nim/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/65_Nim/python/Traditional_NIM.py b/65_Nim/python/Traditional_NIM.py
    index 655e5d85c..3507ecc26 100644
    --- a/65_Nim/python/Traditional_NIM.py
    +++ b/65_Nim/python/Traditional_NIM.py
    @@ -1,106 +1,126 @@
     import random
    -from typing import Tuple
    -
     
    +#Class of the Game
     class NIM:
    -    def __init__(self) -> None:
    -        self.piles = {1: 7, 2: 5, 3: 3, 4: 1}
    -
    -    def remove_pegs(self, command) -> None:
    -        try:
    -
    -            pile, num = command.split(",")
    -            num = int(num)
    -            pile = int(pile)
     
    -        except Exception as e:
    +  def __init__(self):
     
    -            if "not enough values" in str(e):
    -                print(
    -                    '\nNot a valid command. Your command should be in the form of "1,3", Try Again\n'
    -                )
    +    self.Piles = {
    +        1 : 7,
    +        2 : 5,
    +        3 : 3,
    +        4 : 1
    +        }
     
    -            else:
    -                print("\nError, Try again\n")
    -            return None
    +  def Remove_pegs(self, command):
     
    -        if self._command_integrity(num, pile):
    -            self.piles[pile] -= num
    -        else:
    -            print("\nInvalid value of either Peg or Pile\n")
    +    try:
     
    -    def get_ai_move(self) -> Tuple[int, int]:
    -        possible_pile = [k for k, v in self.piles.items() if v != 0]
    -        pile = random.choice(possible_pile)
    +      pile, num = command.split(',')
    +      num = int(num)
    +      pile = int(pile)
     
    -        num = random.randint(1, self.piles[pile])
    +    except Exception as e:
     
    -        return pile, num
    +      if 'not enough values' in str(e):
    +        print('\nNot a valid command. Your command should be in the form of "1,3", Try Again\n')
     
    -    def _command_integrity(self, num, pile) -> bool:
    -        return pile <= 4 and pile >= 1 and num <= self.piles[pile]
    +      else:
    +        print('\nError, Try again\n')
    +      return None
     
    -    def print_pegs(self) -> None:
    -        for pile, peg in self.piles.items():
    -            print(f'Pile {pile} : {"O " * peg}')
    +    if self._command_integrity(num, pile) == True:
    +      self.Piles[pile] -= num
    +    else:
    +      print('\nInvalid value of either Peg or Pile\n')
     
    -    def help(self) -> None:
    -        print("-" * 10)
    -        print('\nThe Game is player with a number of Piles of Objects("O" == one peg)')
    -        print("\nThe Piles are arranged as given below(Tradional NIM)\n")
    -        self.print_pegs()
    -        print(
    -            '\nAny Number of of Objects are removed one pile by "YOU" and the machine alternatively'
    -        )
    -        print("\nOn your turn, you may take all the objects that remain in any pile")
    -        print("but you must take ATLEAST one object")
    -        print("\nAnd you may take objects from only one pile on a single turn.")
    -        print("\nThe winner is defined as the one that picks the last remaning object")
    -        print("-" * 10)
    +  def get_AI_move(self):
    +    
    +    possible_pile = []
    +    for k,v in self.Piles.items():
    +      if v != 0:
    +        possible_pile.append(k)
     
    -    def check_for_win(self) -> bool:
    -        sum = 0
    -        for v in self.piles.values():
    -            sum += v
    +    pile = random.choice(possible_pile)
     
    -        return sum == 0
    +    num = random.randint(1,self.Piles[pile])
     
    +    return pile, num
     
    -def main() -> None:
    -    # Game initialization
    -    game = NIM()
    +  def _command_integrity(self, num, pile):
     
    -    print("Hello, This is a game of NIM")
    -    help = input("Do You Need Instruction (YES or NO): ")
    +    if pile <= 4 and pile >= 1:
    +      if num <= self.Piles[pile]:
    +        return True
    +    
    +    return False
     
    -    if help.lower() == "yes":
    -        game.help()
    +  def print_pegs(self):
     
    -    # Start game loop
    -    input("\nPress Enter to start the Game:\n")
    +    for pile, peg in self.Piles.items():
    +      print('Pile {} : {}'.format(pile, 'O '*peg))
    +    
    +  def Help(self):
     
    -    while True:
    -        game.print_pegs()
    +    print('-'*10)
    +    print('\nThe Game is player with a number of Piles of Objects("O" == one peg)')
    +    print('\nThe Piles are arranged as given below(Tradional NIM)\n')
    +    self.print_pegs()
    +    print('\nAny Number of of Objects are removed one pile by "YOU" and the machine alternatively')
    +    print('\nOn your turn, you may take all the objects that remain in any pile')
    +    print('but you must take ATLEAST one object')
    +    print('\nAnd you may take objects from only one pile on a single turn.')
    +    print('\nThe winner is defined as the one that picks the last remaning object')
    +    print('-'*10)
     
    -        # Players Move
    -        command = input("\nYOUR MOVE - Number of PILE, Number of Object? ")
    -        game.remove_pegs(command)
    -        if game.check_for_win():
    -            print("\nPlayer Wins the Game, Congratulations!!")
    -            input("\nPress any key to exit")
    -            break
    -
    -        # Computers Move
    -        ai_command = game.get_ai_move()
    -        print(
    -            f"\nA.I MOVE - A.I Removed {ai_command[1]} pegs from Pile {ai_command[0]}"
    -        )
    -        game.remove_pegs(f"{str(ai_command[0])},{str(ai_command[1])}")
    -        if game.check_for_win():
    -            print("\nComputer Wins the Game, Better Luck Next Time\n")
    -            input("Press any key to exit")
    -            break
    +  def Checkforwin(self):
     
    +    sum = 0
    +    for k,v in self.Piles.items():
    +      sum += v
    +    
    +    if sum == 0:
    +      return True
    +    
    +    else:
    +      return False
     
    +#main program
     if __name__ == "__main__":
    -    main()
    +
    +  #Game initialization
    +  game = NIM()
    +
    +  print('Hello, This is a game of NIM')
    +  help = input('Do You Need Instruction (YES or NO): ')
    +
    +  if help == 'yes' or help == 'YES' or help == 'Yes':
    +
    +    #Printing Game Instruction
    +    game.Help()
    +
    +  #Start game loop
    +  input('\nPress Enter to start the Game:\n')
    +  End = False
    +  while True:
    +
    +    game.print_pegs()
    +
    +    #Players Move
    +    command = input('\nYOUR MOVE - Number of PILE, Number of Object? ')
    +    game.Remove_pegs(command)
    +    End = game.Checkforwin()
    +    if End == True: 
    +      print('\nPlayer Wins the Game, Congratulations!!')
    +      input('\nPress any key to exit')
    +      break
    +    
    +    #Computers Move
    +    command = game.get_AI_move()
    +    print('\nA.I MOVE - A.I Removed {} pegs from Pile {}'.format(command[1],command[0]))
    +    game.Remove_pegs(str(command[0]) +',' + str(command[1]))
    +    End = game.Checkforwin()
    +    if End == True: 
    +      print('\nComputer Wins the Game, Better Luck Next Time\n')
    +      input('Press any key to exit')
    +      break
    diff --git a/65_Nim/ruby/nim.rb b/65_Nim/ruby/nim.rb
    index d6b157b3a..a326695fc 100644
    --- a/65_Nim/ruby/nim.rb
    +++ b/65_Nim/ruby/nim.rb
    @@ -278,3 +278,5 @@ def yourMove
     end
     end
     end
    +
    +
    diff --git a/65_Nim/rust/Cargo.lock b/65_Nim/rust/Cargo.lock
    deleted file mode 100644
    index fc74a49e2..000000000
    --- a/65_Nim/rust/Cargo.lock
    +++ /dev/null
    @@ -1,23 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "nanorand"
    -version = "0.6.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "729eb334247daa1803e0a094d0a5c55711b85571179f5ec6e53eccfdf7008958"
    -
    -[[package]]
    -name = "nim"
    -version = "1.0.0"
    -dependencies = [
    - "nanorand",
    - "text_io",
    -]
    -
    -[[package]]
    -name = "text_io"
    -version = "0.1.12"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "d5f0c8eb2ad70c12a6a69508f499b3051c924f4b1cfeae85bfad96e6bc5bba46"
    diff --git a/65_Nim/rust/Cargo.toml b/65_Nim/rust/Cargo.toml
    deleted file mode 100644
    index 4032c3647..000000000
    --- a/65_Nim/rust/Cargo.toml
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -[package]
    -name = "nim"
    -version = "1.0.0"
    -edition = "2021"
    -
    -[dependencies]
    -text_io = "0.1.10"
    -nanorand = "0.6.1"
    \ No newline at end of file
    diff --git a/65_Nim/rust/src/main.rs b/65_Nim/rust/src/main.rs
    deleted file mode 100644
    index beeba85cb..000000000
    --- a/65_Nim/rust/src/main.rs
    +++ /dev/null
    @@ -1,409 +0,0 @@
    -/*
    - * Nim
    - * Originally from the wonderful book: _Basic Computer Games_
    - * Port to Rust By David Lotts
    -*/
    -use nanorand::{tls::TlsWyRand, Rng};
    -use std::io::{self, Write};
    -use text_io::{read, try_read};
    -
    -/// Play Nim
    -// line numbers from the orginal Basic program are in the end of line comments. 
    -// If you see two number comments: the first one is a 
    -// GOTO or THEN destination, second is the current line. Example: // 800 //210
    -fn main() {
    -    let mut rng = nanorand::tls_rng();
    -    println!("{:>37}", "NIM"); //100
    -    println!("{:>15}{}", "", "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY"); //110
    -    println!();
    -    println!();
    -    println!(); //120
    -    let mut piles = [0.0; 100];
    -    let mut b_piles = [[0.0; 100]; 11];
    -    let mut ix_do = [0usize; 3]; //210
    -    println!("THIS IS THE GAME OF NIM."); //220
    -                                          //230
    -    loop {
    -        let instuct_me = input("DO YOU WANT INSTRUCTIONS"); //240
    -        if instuct_me == "NO" || instuct_me == "no" {
    -            break;
    -        } //440   //260
    -        if instuct_me == "YES" || instuct_me == "yes" {
    -            instructions();
    -            break;
    -        } //310   //280
    -        println!("PLEASE ANSWER YES OR NO"); //290
    -    } //300
    -    'play_again: loop {
    -        println!(); //440
    -        let winner_take_last: bool = loop {
    -            let choice = input_int("ENTER WIN OPTION - 1 TO TAKE LAST, 2 TO AVOID LAST"); //460
    -            if (1..=2).contains(&choice) {
    -                break choice == 1;
    -            } //490  //470
    -        };
    -        let np = loop {
    -            //490
    -            let choice = input_int("ENTER NUMBER OF PILES"); //500
    -            if choice <= 100 && choice >= 1 {
    -                break choice;
    -            } //490   //510
    -              //490   //520
    -              //490   //530
    -        };
    -        println!("ENTER PILE SIZES"); //540
    -        for ix in 0..np as usize {
    -            //550
    -            piles[ix] = loop {
    -                let choice = input_int(&(ix + 1).to_string()); //570
    -                if choice <= 2000 && choice >= 1 && choice >= 1 {
    -                    break choice as f64;
    -                } //560   //580
    -                  //560   //600
    -            }
    -        } //610
    -        let human_first = loop {
    -            //620
    -            let choice = input("DO YOU WANT TO MOVE FIRST"); //630
    -            let choice = choice.to_lowercase();
    -            if choice == "yes" {
    -                break true;
    -            } //1450   //650
    -            if choice == "no" {
    -                break false;
    -            } //700   //670
    -            println!("PLEASE ANSWER YES OR NO."); //680
    -        }; //690
    -
    -        let mut winner = WinState::GameOn;
    -        if human_first {
    -            winner = human_turn(winner_take_last, np, &mut piles);
    -        };
    -        //### main game loop
    -        if winner.is_game_on() {
    -            winner = loop {
    -                // break on winner returning from here:
    -                let win = machines_turn(
    -                    &mut rng,
    -                    winner_take_last,
    -                    np,
    -                    &mut piles,
    -                    &mut ix_do,
    -                    &mut b_piles,
    -                );
    -                if !win.is_game_on() {
    -                    break win;
    -                }; //starts at 700
    -
    -                println!("PILE  SIZE"); //1380
    -                for ix in 0..np as usize {
    -                    //1390
    -                    println!("{} {}", ix + 1, piles[ix]); //1400
    -                } //  NEXT ix   //1410
    -
    -                // break on winner returning from here:
    -                let win = human_turn(winner_take_last, np, &mut piles);
    -                if !win.is_game_on() {
    -                    break win;
    -                };
    -                //  GOTO 700   //1560
    -            };
    -        }
    -        println!(
    -            "MACHINE {}",
    -            if winner == WinState::ComputerWins {
    -                "WINS"
    -            } else {
    -                "LOSES"
    -            }
    -        );
    -        loop {
    -            // Game over //1640
    -            let choice = input("do you want to play another game"); //1650
    -            match choice.to_ascii_lowercase().as_str() {
    -                "yes" => break,                       //1720   //1660
    -                "no" => break 'play_again,            //1730   //1680
    -                _ => println!("PLEASE.  YES OR NO."), //1700
    -            } //  GOTO 1650    //1710
    -        } //  GOTO 440   //1720
    -    } //  END   //1730
    -}
    -
    -#[derive(PartialEq)]
    -enum WinState {
    -    GameOn,
    -    ComputerWins,
    -    HumanWins,
    -}
    -
    -impl WinState {
    -    /// Returns `true` if the win state is [`GameOn`].
    -    ///
    -    /// [`GameOn`]: WinState::GameOn
    -    fn is_game_on(&self) -> bool {
    -        matches!(self, Self::GameOn)
    -    }
    -}
    -
    -/// Computer's turn
    -fn machines_turn(
    -    rng: &mut TlsWyRand,
    -    winner_take_last: bool,
    -    np: i32,
    -    piles: &mut [f64; 100],
    -    ix_do: &mut [usize; 3],
    -    b_piles: &mut [[f64; 100]; 11],
    -) -> WinState {
    -    if !winner_take_last {
    -        //940   //700
    -        //### Loser takes last, check for winner
    -        let mut count = 0; //710
    -        'wayout: loop {
    -            'outer: loop {
    -                for ix in 0..np as usize {
    -                    //720
    -                    if piles[ix] == 0.0 {
    -                        continue;
    -                    } //730
    -                    count += 1; //740
    -                    if count == 3 {
    -                        break 'outer;
    -                    } //840   //750
    -                    ix_do[count] = ix; //760
    -                } //770
    -                  // exactly two piles remain
    -                if count == 2 {
    -                    // println!("Only two piles remain : unused0={} pile1={} pile2={}",ix_do[0]+1,ix_do[1]+1,ix_do[2]+1); //diagnostic
    -                    if piles[ix_do[1]] == 1.0 || piles[ix_do[2]] == 1.0 {
    -                        //920
    -                        return WinState::ComputerWins;
    -                    } //820   //930
    -                    break 'wayout;
    -                } //920   //780
    -                  // exactly one pile remains, loser takes last, and before machine's turn
    -                  // println!("Only one pile remains : pile={}",ix_do[1]); //diagnostic
    -                assert!(piles[ix_do[1]] > 0.0);
    -                if piles[ix_do[1]] == 1.0 {
    -                    //820    //790
    -                    return WinState::HumanWins; //800
    -                                                // GOTO 1640   //810
    -                } else {
    -                    return WinState::ComputerWins; //820
    -                                                   // GOTO 1640   //830
    -                }
    -            }
    -            count = 0; //840
    -            let mut is_all_ones = true;
    -            for ix in 0..np as usize {
    -                // FOR ix=1 TO N   //850
    -                if piles[ix] > 1.0 {
    -                    is_all_ones = false;
    -                    break;
    -                } //940   //860
    -                if piles[ix] != 0.0 {
    -                    //890   //870
    -                    count = count + 1; //880
    -                }
    -            } // NEXT ix   //890
    -            if is_all_ones && count % 2 != 0 {
    -                //800   //900
    -                return WinState::HumanWins;
    -            }
    -            break; // GOTO 940   //910
    -        }
    -    }
    -    //### winner take last (or first?) -- check for winner
    -    for ix in 0..np as usize {
    -        //940
    -        let mut sticks = piles[ix]; //950
    -        for jx in 0..=10 {
    -            //960
    -            let half = sticks / 2.0; //970
    -            b_piles[ix][jx] = 2.0 * (half - half.trunc()); //980
    -            sticks = half.trunc(); //990
    -        } //  NEXT J   //1000
    -    } //  NEXT I   //1010
    -
    -    let mut is_odd = false;
    -    let mut ix_max_pile = usize::MAX; // make sure this fails if ever used.
    -    for jx in (0..=10).rev() {
    -        //1020
    -        let mut count = 0; //1030
    -        let mut highest = 0.0; //1040
    -        for ix in 0..np as usize {
    -            //1050
    -            if b_piles[ix][jx] == 0.0 {
    -                continue;
    -            }; //1110   //1060
    -            count = count + 1; //1070
    -            if piles[ix] <= highest as f64 {
    -                continue;
    -            }; //1110   //1080
    -            highest = piles[ix]; //1090
    -            ix_max_pile = ix; //1100
    -        } //NEXT I   //1110
    -          // println!("if none are odd, use random: count={} odd={}", count,count%2!=0); //diagnostic
    -        if count % 2 != 0 {
    -            is_odd = true;
    -            break;
    -        } // C/2<>INT(C/2) //1190   //1120
    -    } //  NEXT J   //1130
    -    if !is_odd {
    -        let mut ix_random;
    -        loop {
    -            ix_random = rng.generate_range(0..np as usize); //(N*RND(1)+1).trunc();   //1140
    -            if piles[ix_random] != 0.0 {
    -                break;
    -            } //1140   //1150
    -        }
    -        let remove_random = rng.generate_range(1..=piles[ix_random] as i32); // INT(A[E]*RND(1)+1)   //1160
    -        piles[ix_random] = piles[ix_random] - remove_random as f64; //1170
    -        // println!("I choose random: pile={} removed={}",ix_random+1,remove_random) //diagnostic
    -        // GOTO 1380   //1180
    -    } else {
    -        // println!("max pile: pile={}, was={} setting to 0. Expect add back.",ix_max_pile+1,piles[ix_max_pile]); //diagnostic
    -        piles[ix_max_pile] = 0.0; //1190
    -        for jx in 0..=10 {
    -            //1200
    -            b_piles[ix_max_pile][jx] = 0.0; //1210
    -            let mut countum = 0; //1220
    -            for ix in 0..np as usize {
    -                //1230
    -                if b_piles[ix][jx] == 0.0 {
    -                    continue;
    -                } //1260   //1240
    -                countum += 1; // count non-empty  //1250
    -            } //  NEXT ix   //1260
    -            piles[ix_max_pile] =
    -                piles[ix_max_pile] + ((countum % 2) * 2usize.pow(jx as u32)) as f64;
    -            //1270
    -            // println!("I choose max pile : pile={}, add back=odd?2^{}:0={}",ix_max_pile+1,jx,((countum%2)*2usize.pow(jx as u32))); //diagnostic
    -        } //  NEXT J   //1280
    -
    -        'done: loop {
    -            if !winner_take_last {
    -                //1380   //1290
    -                let mut counter = 0; //1300
    -                for ix in 0..np as usize {
    -                    //1310
    -                    if piles[ix] > 1.0 {
    -                        break 'done;
    -                    } //1380   //1320
    -                    if piles[ix] != 0.0 {
    -                        //1350  //1330
    -                        counter += 1; //1340
    -                    }
    -                } //  NEXT ix   //1350
    -                  // done if C is odd
    -                if counter % 2 != 0 {
    -                    break;
    -                } //1380   //1360
    -                  // println!("max pile if even: 1 - pile : pile={}, before 1-p = {}",ix_max_pile+1,piles[ix_max_pile]); //diagnostic
    -                piles[ix_max_pile] = 1.0 - piles[ix_max_pile]; //1370
    -            }
    -            break;
    -        }
    -    }
    -    return WinState::GameOn; //1380 is after this
    -}
    -
    -/// Human decide what you want to do and see if there is a winner
    -fn human_turn(winner_take_last: bool, np: i32, piles: &mut [f64; 100]) -> WinState {
    -    if winner_take_last {
    -        //1450   //1420
    -        let is_all_empty = one_if_all_zero(np, &piles); //  GOSUB 1570   //1430
    -        if is_all_empty == 1 {
    -            return WinState::ComputerWins;
    -        } //820   //1440  //### machine wins
    -    }
    -    //### many things go here
    -    loop {
    -        //1450
    -        let (pile_choice, remove_choice) = input_2int("YOUR MOVE - PILE, NUMBER TO BE REMOVED"); //1460
    -        if pile_choice > np || pile_choice < 1 {
    -            continue;
    -        } //1450   //1480
    -        let ix_choice = (pile_choice - 1) as usize;
    -        if remove_choice < 1 || remove_choice as f64 > piles[ix_choice] {
    -            continue;
    -        }; //1450   //1500
    -           // remove the humans choice:
    -        piles[ix_choice] = piles[ix_choice] - remove_choice as f64; //1530
    -        break;
    -    }
    -    if one_if_all_zero(np, &piles) == 1
    -    //  GOSUB 1570   //1540
    -    {
    -        return WinState::HumanWins;
    -    } //800   //1550  //### machine loses!
    -    return WinState::GameOn;
    -}
    -
    -/// returns 0 if all A are 0, otherwise 1
    -fn one_if_all_zero(np: i32, piles: &[f64; 100]) -> i32 {
    -    // sets Z to the return value
    -    //1570
    -    for ix in 0..np as usize {
    -        //1580
    -        if piles[ix] != 0.0 {
    -            return 0;
    -        } //1610   //1590
    -          //1600
    -    } //1610
    -    return 1; //1620
    -} //1630
    -
    -fn instructions() {
    -    println!("THE GAME IS PLAYED WITH A NUMBER OF PILES OF OBJECTS.");
    -    println!("ANY NUMBER OF OBJECTS ARE REMOVED FROM ONE PILE BY YOU AND");
    -    println!("THE MACHINE ALTERNATELY.  ON YOUR TURN, YOU MAY TAKE");
    -    println!("ALL THE OBJECTS THAT REMAIN IN ANY PILE, BUT YOU MUST");
    -    println!("TAKE AT LEAST ONE OBJECT, AND YOU MAY TAKE OBJECTS FROM");
    -    println!("ONLY ONE PILE ON A SINGLE TURN.  YOU MUST SPECIFY WHETHER");
    -    println!("WINNING IS DEFINED AS TAKING OR NOT TAKING THE LAST OBJECT,");
    -    println!("THE NUMBER OF PILES IN THE GAME, AND HOW MANY OBJECTS ARE");
    -    println!("ORIGINALLY IN EACH PILE.  EACH PILE MAY CONTAIN A");
    -    println!("DIFFERENT NUMBER OF OBJECTS.");
    -    println!("THE MACHINE WILL SHOW ITS MOVE BY LISTING EACH PILE AND THE");
    -    println!("NUMBER OF OBJECTS REMAINING IN THE PILES AFTER  EACH OF ITS");
    -    println!("MOVES.");
    -}
    -
    -/// print the prompt, wait for a number and newline.  Loop if invalid.
    -fn input(prompt: &str) -> String {
    -    loop {
    -        print!("{} ? ", prompt);
    -        io::stdout().flush().unwrap();
    -        // TODO:  asks twice on win10, not linux.  \r vs \n?
    -        let innn: String = read!("{}\n");
    -        let out: String = innn.trim().to_string();
    -        if out != "" {
    -            return out;
    -        }
    -    }
    -}
    -fn input_int(prompt: &str) -> i32 {
    -    loop {
    -        print!("{} ? ", prompt);
    -        io::stdout().flush().unwrap();
    -        match try_read!() {
    -            Ok(n) => return n,
    -            Err(_) => {}
    -        }
    -    }
    -}
    -
    -fn input_2int(prompt: &str) -> (i32, i32) {
    -    loop {
    -        let inp = input(prompt);
    -        let nums: Vec = inp
    -            .split(",")
    -            .filter_map(|c| c.parse::().ok())
    -            .collect();
    -        if nums.len() != 2 {
    -            println!("Enter two numbers like: 9,9",);
    -            continue;
    -        }
    -        return (nums[0], nums[1]);
    -    }
    -}
    diff --git a/65_Nim/vbnet/Nim.sln b/65_Nim/vbnet/Nim.sln
    deleted file mode 100644
    index 17c6bf866..000000000
    --- a/65_Nim/vbnet/Nim.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index f551edd08..000000000
    --- a/65_Nim/vbnet/Nim.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Nim
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/66_Number/README.md b/66_Number/README.md
    index 2df37b6b7..47a9b5cba 100644
    --- a/66_Number/README.md
    +++ b/66_Number/README.md
    @@ -12,7 +12,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -Contrary to the description, the computer picks *five* random numbers per turn, not one.  You are not rewarded based on how close your guess is to one number, but rather to which of these five random numbers (if any) it happens to match exactly.
    diff --git a/66_Number/csharp/Number.csproj b/66_Number/csharp/Number.csproj
    deleted file mode 100644
    index d3fe4757c..000000000
    --- a/66_Number/csharp/Number.csproj
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    diff --git a/66_Number/csharp/Number.sln b/66_Number/csharp/Number.sln
    deleted file mode 100644
    index f42e7e2a2..000000000
    --- a/66_Number/csharp/Number.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/csharp/program.cs b/66_Number/csharp/program.cs
    deleted file mode 100644
    index b73c9c7b5..000000000
    --- a/66_Number/csharp/program.cs
    +++ /dev/null
    @@ -1,126 +0,0 @@
    -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();
    -
    -        }
    -    }
    -}
    diff --git a/66_Number/java/2/Number.java b/66_Number/java/Number.java
    similarity index 100%
    rename from 66_Number/java/2/Number.java
    rename to 66_Number/java/Number.java
    diff --git a/66_Number/java/1/Number.java b/66_Number/java/main.class
    similarity index 100%
    rename from 66_Number/java/1/Number.java
    rename to 66_Number/java/main.class
    diff --git a/66_Number/javascript/number.html b/66_Number/javascript/number.html
    index c462a2373..5e3841862 100644
    --- a/66_Number/javascript/number.html
    +++ b/66_Number/javascript/number.html
    @@ -1,10 +1,9 @@
     
     
     NUMBER
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/66_Number/javascript/number.js b/66_Number/javascript/number.js
    index 06e236d5d..5bda2ae67 100644
    --- a/66_Number/javascript/number.js
    +++ b/66_Number/javascript/number.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/66_Number/kotlin/README.md b/66_Number/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/66_Number/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/66_Number/lua/README.md b/66_Number/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/66_Number/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/66_Number/pascal/README.md b/66_Number/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/66_Number/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/66_Number/perl/number.pl b/66_Number/perl/number.pl
    index a5a5889b6..b76dc6e5b 100755
    --- a/66_Number/perl/number.pl
    +++ b/66_Number/perl/number.pl
    @@ -35,3 +35,5 @@ sub FNR {
     	my ($X)= @_; #Useless...
     	return int(5*rand(1)+1);
     	}
    +
    +
    diff --git a/66_Number/python/number.py b/66_Number/python/number.py
    index e6840d92a..7746ff6af 100644
    --- a/66_Number/python/number.py
    +++ b/66_Number/python/number.py
    @@ -9,7 +9,16 @@
     import random
     
     
    -def print_instructions() -> None:
    +def print_with_tab(num_spaces, msg):
    +    if num_spaces > 0:
    +        spaces = " " * num_spaces
    +    else:
    +        spaces = ""
    +
    +    print(spaces + msg)
    +
    +
    +def print_instructions():
         print("YOU HAVE 100 POINTS.  BY GUESSING NUMBERS FROM 1 TO 5, YOU")
         print("CAN GAIN OR LOSE POINTS DEPENDING UPON HOW CLOSE YOU GET TO")
         print("A RANDOM NUMBER SELECTED BY THE COMPUTER.")
    @@ -19,17 +28,20 @@ def print_instructions() -> None:
         print()
     
     
    -def fnr() -> int:
    +def fnr():
         return random.randint(1, 5)
     
     
    -def main() -> None:
    -    print(" " * 33 + "NUMBER")
    -    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
    +def main():
    +    print_with_tab(33, "NUMBER")
    +    print_with_tab(15, "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
    +    print()
    +    print()
    +    print()
     
         print_instructions()
     
    -    points: float = 100
    +    points = 100
     
         while points <= 500:
             print("GUESS A NUMBER FROM 1 TO 5")
    diff --git a/66_Number/rust/Cargo.lock b/66_Number/rust/Cargo.lock
    deleted file mode 100644
    index 4fe2abbea..000000000
    --- a/66_Number/rust/Cargo.lock
    +++ /dev/null
    @@ -1,75 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.10"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.147"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/66_Number/rust/Cargo.toml b/66_Number/rust/Cargo.toml
    deleted file mode 100644
    index 22ab0ba84..000000000
    --- a/66_Number/rust/Cargo.toml
    +++ /dev/null
    @@ -1,10 +0,0 @@
    -[package]
    -name = "rust"
    -version = "0.1.0"
    -authors = ["AnthonyMichaelTDM <68485672+AnthonyMichaelTDM@users.noreply.github.com>"]
    -edition = "2018"
    -
    -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
    -
    -[dependencies]
    -rand = "0.8.5"
    diff --git a/66_Number/rust/README.md b/66_Number/rust/README.md
    deleted file mode 100644
    index 7e85f9a15..000000000
    --- a/66_Number/rust/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Rust](https://www.rust-lang.org/) by Anthony Rubick [AnthonyMichaelTDM](https://github.com/AnthonyMichaelTDM)
    diff --git a/66_Number/rust/src/main.rs b/66_Number/rust/src/main.rs
    deleted file mode 100644
    index 70dfbfbf4..000000000
    --- a/66_Number/rust/src/main.rs
    +++ /dev/null
    @@ -1,62 +0,0 @@
    -use rand::{Rng, prelude::thread_rng};
    -use std::io;
    -
    -fn main() {
    -    //DATA
    -    let mut points: usize = 100;
    -    let mut rng = thread_rng();
    -    let mut number:u8;
    -
    -    //print welcome message
    -    welcome();
    -
    -    //game loop
    -    while points <= 500 {
    -        //generate number
    -        number = rng.gen_range(1..=5);
    -        //NOTE: while looking at the original basic, I realized that the outcome of your guess is effectively random
    -        //so instead of generating 5 variables with random values between 1-5 and doing something depedning which one has the value they guess...
    -        //why not just let them "guess" and do a random action without using uneeded variables? .. so that's what I did.
    -
    -        //let them "guess"
    -        println!("GUESS A NUMBER FROM 1 TO 5");//print prompt
    -        if let Ok(_i) = io::stdin().read_line(&mut String::new()) {} // get input from standard in, and do nothing with it even if an error is thrown
    -
    -        //do something depending on the previously generated random number
    -        match number {
    -            1 => if points>=5{points -= 5},//the if statement here prevents overflow, points is stored as an unsigned integer, so we can't let it be negative
    -            2 => points += 5,
    -            3 => {//jackpot
    -                points *= 2;
    -                println!("YOU HIT THE JACKPOT!!!");
    -            },
    -            4 => points += 1,
    -            5 => points /= 2,
    -            _ => {},
    -        };
    -
    -        //tell then how many points they have
    -        println!("YOU HAVE {} POINTS.", points);
    -    }
    -
    -    //print
    -}
    -
    -/**
    - * print the welcome message
    - */
    -fn welcome() {
    -    println!("
    -              CREATIVE COMPUTING MORRISTOWN, NEW JERSEY
    -
    -
    -
    -    YOU HAVE 100 POINTS.  BY GUESSING NUMBERS FROM 1 TO 5, YOU
    -    CAN GAIN OR LOSE POINTS DEPENDING UPON HOW CLOSE YOU GET TO
    -    A RANDOM NUMBER SELECTED BY THE COMPUTER.
    -
    -    YOU OCCASIONALLY WILL GET A JACKPOT WHICH WILL DOUBLE(!)
    -    YOUR POINT COUNT.  YOU WIN WHEN YOU GET 500 POINTS
    -
    -    ");
    -}
    diff --git a/66_Number/vbnet/Number.sln b/66_Number/vbnet/Number.sln
    deleted file mode 100644
    index d0838e1ad..000000000
    --- a/66_Number/vbnet/Number.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index ad922daf4..000000000
    --- a/66_Number/vbnet/Number.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Number
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/67_One_Check/README.md b/67_One_Check/README.md
    index 63161d82e..b3522e15c 100644
    --- a/67_One_Check/README.md
    +++ b/67_One_Check/README.md
    @@ -27,7 +27,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/67_One_Check/csharp/Board.cs b/67_One_Check/csharp/Board.cs
    deleted file mode 100644
    index 2e68072dc..000000000
    --- a/67_One_Check/csharp/Board.cs
    +++ /dev/null
    @@ -1,64 +0,0 @@
    -namespace OneCheck;
    -
    -internal class Board
    -{
    -    private readonly bool[][] _checkers;
    -    private int _pieceCount;
    -    private int _moveCount;
    -
    -    public Board()
    -    {
    -        _checkers = 
    -            Enumerable.Range(0, 8)
    -                .Select(r => Enumerable.Range(0, 8)
    -                    .Select(c => r <= 1 || r >= 6 || c <= 1 || c >= 6).ToArray())
    -                .ToArray();
    -        _pieceCount = 48;
    -    }
    -
    -    private bool this[int index]
    -    {
    -        get => _checkers[index / 8][index % 8];
    -        set => _checkers[index / 8][index % 8] = value;
    -    }
    -
    -    public bool PlayMove(IReadWrite io)
    -    {
    -        while (true)
    -        {
    -            var from = (int)io.ReadNumber(Prompts.From);
    -            if (from == 0) { return false; }
    -
    -            var move = new Move { From = from - 1, To = (int)io.ReadNumber(Prompts.To) - 1 };
    -
    -            if (TryMove(move)) 
    -            { 
    -                _moveCount++;
    -                return true; 
    -            }
    -
    -            io.Write(Streams.IllegalMove);
    -        }
    -    }
    -
    -    public bool TryMove(Move move)
    -    {
    -        if (move.IsInRange && move.IsTwoSpacesDiagonally && IsPieceJumpingPieceToEmptySpace(move))
    -        {
    -            this[move.From] = false;
    -            this[move.Jumped] = false;
    -            this[move.To] = true;
    -            _pieceCount--;
    -            return true;
    -        }
    -
    -        return false;
    -    }
    -
    -    private bool IsPieceJumpingPieceToEmptySpace(Move move) => this[move.From] && this[move.Jumped] && !this[move.To];
    -
    -    public string GetReport() => string.Format(Formats.Results, _moveCount, _pieceCount);
    -
    -    public override string ToString() => 
    -        string.Join(Environment.NewLine, _checkers.Select(r => string.Join(" ", r.Select(c => c ? " 1" : " 0"))));
    -}
    diff --git a/67_One_Check/csharp/Game.cs b/67_One_Check/csharp/Game.cs
    deleted file mode 100644
    index d9e64e265..000000000
    --- a/67_One_Check/csharp/Game.cs
    +++ /dev/null
    @@ -1,45 +0,0 @@
    -namespace OneCheck;
    -
    -internal class Game
    -{
    -    private readonly IReadWrite _io;
    -
    -    public Game(IReadWrite io)
    -    {
    -        _io = io;
    -    }
    -
    -    public void Play()
    -    {
    -        _io.Write(Streams.Introduction);
    -        
    -        do
    -        {
    -            var board = new Board();
    -            do
    -            {
    -                _io.WriteLine(board);
    -                _io.WriteLine();
    -            } while (board.PlayMove(_io));
    -
    -            _io.WriteLine(board.GetReport());
    -        } while (_io.ReadYesNo(Prompts.TryAgain) == "yes");
    -
    -        _io.Write(Streams.Bye);
    -    }
    -}
    -
    -internal static class IOExtensions
    -{
    -    internal static string ReadYesNo(this IReadWrite io, string prompt)
    -    {
    -        while (true)
    -        {
    -            var response = io.ReadString(prompt).ToLower();
    -
    -            if (response == "yes" || response == "no") { return response; }
    -
    -            io.Write(Streams.YesOrNo);
    -        }
    -    }
    -}
    diff --git a/67_One_Check/csharp/Move.cs b/67_One_Check/csharp/Move.cs
    deleted file mode 100644
    index 0b48659e4..000000000
    --- a/67_One_Check/csharp/Move.cs
    +++ /dev/null
    @@ -1,13 +0,0 @@
    -namespace OneCheck;
    -
    -internal class Move
    -{
    -    public int From { get; init; }
    -    public int To { get; init; }
    -    public int Jumped => (From + To) / 2;
    -
    -    public bool IsInRange => From >= 0 && From <= 63 && To >= 0 && To <= 63;
    -    public bool IsTwoSpacesDiagonally => RowDelta == 2 && ColumnDelta == 2;
    -    private int RowDelta => Math.Abs(From / 8 - To / 8);
    -    private int ColumnDelta => Math.Abs(From % 8 - To % 8);
    -}
    \ No newline at end of file
    diff --git a/67_One_Check/csharp/OneCheck.csproj b/67_One_Check/csharp/OneCheck.csproj
    deleted file mode 100644
    index 3870320c9..000000000
    --- a/67_One_Check/csharp/OneCheck.csproj
    +++ /dev/null
    @@ -1,17 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    -  
    -    
    -  
    -
    -  
    -    
    -  
    -
    diff --git a/67_One_Check/csharp/OneCheck.sln b/67_One_Check/csharp/OneCheck.sln
    deleted file mode 100644
    index f6a550c75..000000000
    --- a/67_One_Check/csharp/OneCheck.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/csharp/Program.cs b/67_One_Check/csharp/Program.cs
    deleted file mode 100644
    index 4a3ab83b6..000000000
    --- a/67_One_Check/csharp/Program.cs
    +++ /dev/null
    @@ -1,5 +0,0 @@
    -global using Games.Common.IO;
    -global using static OneCheck.Resources.Resource;
    -using OneCheck;
    -
    -new Game(new ConsoleIO()).Play();
    diff --git a/67_One_Check/csharp/Resources/Bye.txt b/67_One_Check/csharp/Resources/Bye.txt
    deleted file mode 100644
    index ee4ddab11..000000000
    --- a/67_One_Check/csharp/Resources/Bye.txt
    +++ /dev/null
    @@ -1,2 +0,0 @@
    -
    -O.K.  Hope you had fun!!
    \ No newline at end of file
    diff --git a/67_One_Check/csharp/Resources/From.txt b/67_One_Check/csharp/Resources/From.txt
    deleted file mode 100644
    index bb4c7a2d3..000000000
    --- a/67_One_Check/csharp/Resources/From.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Jump from
    \ No newline at end of file
    diff --git a/67_One_Check/csharp/Resources/IllegalMove.txt b/67_One_Check/csharp/Resources/IllegalMove.txt
    deleted file mode 100644
    index a96b6e81e..000000000
    --- a/67_One_Check/csharp/Resources/IllegalMove.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Illegal move.  Try again...
    \ No newline at end of file
    diff --git a/67_One_Check/csharp/Resources/Introduction.txt b/67_One_Check/csharp/Resources/Introduction.txt
    deleted file mode 100644
    index 409f6b37f..000000000
    --- a/67_One_Check/csharp/Resources/Introduction.txt
    +++ /dev/null
    @@ -1,30 +0,0 @@
    -                              One Check
    -               Creative Computing  Morristown, New Jersey
    -
    -
    -
    -Solitaire checker puzzle by David Ahl
    -
    -48 checkers and placed on the 2 outside spaces of a
    -standard 64-square checkerboard.  The object is to
    -remove as many checkers as possible by diagonal jumps
    -(as in standard checkers).  Use the numbered board to
    -indicate the square you wish to jump from and to.  On
    -the board printed out on each turn '1' indicates a
    -checker and '0' an empty square.  When you have no
    -possible jumps remaining, input a '0' in response to
    -question 'Jump from ?'
    -
    -Here is the numerical board:
    -
    - 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  37  38  39  40
    - 41  42  43  44  45  46  47  48
    - 49  50  51  52  53  54  55  56
    - 57  58  59  60  61  62  63  64
    -
    -And here is the opening position of the checkers.
    -
    diff --git a/67_One_Check/csharp/Resources/Resource.cs b/67_One_Check/csharp/Resources/Resource.cs
    deleted file mode 100644
    index 7095d7ec0..000000000
    --- a/67_One_Check/csharp/Resources/Resource.cs
    +++ /dev/null
    @@ -1,45 +0,0 @@
    -using System.Reflection;
    -using System.Runtime.CompilerServices;
    -
    -namespace OneCheck.Resources;
    -
    -internal static class Resource
    -{
    -    internal static class Streams
    -    {
    -        public static Stream Introduction => GetStream();
    -        public static Stream IllegalMove => GetStream();
    -        public static Stream YesOrNo => GetStream();
    -        public static Stream Bye => GetStream();
    -    }
    -
    -    internal static class Formats
    -    {
    -        public static string Results => GetString();
    -    }
    -
    -    internal static class Prompts
    -    {
    -        public static string From => GetString();
    -        public static string To => GetString();
    -        public static string TryAgain => GetString();
    -    }
    -
    -    internal static class Strings
    -    {
    -        public static string TooManyColumns => GetString();
    -        public static string TooManyRows => GetString();
    -    }
    -
    -    private static string GetString([CallerMemberName] string? name = null)
    -    {
    -        using var stream = GetStream(name);
    -        using var reader = new StreamReader(stream);
    -        return reader.ReadToEnd();
    -    }
    -
    -
    -    private static Stream GetStream([CallerMemberName] string? name = null) =>
    -        Assembly.GetExecutingAssembly().GetManifestResourceStream($"{typeof(Resource).Namespace}.{name}.txt")
    -            ?? throw new Exception($"Could not find embedded resource stream '{name}'.");
    -}
    \ No newline at end of file
    diff --git a/67_One_Check/csharp/Resources/Results.txt b/67_One_Check/csharp/Resources/Results.txt
    deleted file mode 100644
    index a8771b6b0..000000000
    --- a/67_One_Check/csharp/Resources/Results.txt
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -
    -You made {0} jumps and had {1} pieces
    -remaining on the board.
    diff --git a/67_One_Check/csharp/Resources/To.txt b/67_One_Check/csharp/Resources/To.txt
    deleted file mode 100644
    index 788636ffb..000000000
    --- a/67_One_Check/csharp/Resources/To.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -to
    \ No newline at end of file
    diff --git a/67_One_Check/csharp/Resources/TryAgain.txt b/67_One_Check/csharp/Resources/TryAgain.txt
    deleted file mode 100644
    index c65e51fc8..000000000
    --- a/67_One_Check/csharp/Resources/TryAgain.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Try again
    \ No newline at end of file
    diff --git a/67_One_Check/csharp/Resources/YesOrNo.txt b/67_One_Check/csharp/Resources/YesOrNo.txt
    deleted file mode 100644
    index 703d4ad6c..000000000
    --- a/67_One_Check/csharp/Resources/YesOrNo.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Please answer 'Yes' or 'No'.
    \ No newline at end of file
    diff --git a/67_One_Check/java/OneCheck.java b/67_One_Check/java/OneCheck.java
    index 88194b299..0e69fc304 100644
    --- a/67_One_Check/java/OneCheck.java
    +++ b/67_One_Check/java/OneCheck.java
    @@ -9,39 +9,39 @@
      * 

    * Note: The idea was to create a version of the 1970's BASIC game in Java, without introducing * new features - no additional text, error checking, etc has been added. - * + * * Converted from BASIC to Java by Darren Cardenas. */ - -public class OneCheck { + +public class OneCheck { private final Scanner scan; // For user input - + private enum Step { SHOW_INSTRUCTIONS, SHOW_BOARD, GET_MOVE, GET_SUMMARY, QUERY_RETRY - } - + } + public OneCheck() { - + scan = new Scanner(System.in); - - } // End of constructor OneCheck - + + } // End of constructor OneCheck + public void play() { - + showIntro(); startGame(); - - } // End of method play - + + } // End of method play + private static void showIntro() { - + System.out.println(" ".repeat(29) + "ONE CHECK"); System.out.println(" ".repeat(14) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); System.out.println("\n\n"); - - } // End of method showIntro - + + } // End of method showIntro + private void startGame() { int fromSquare = 0; @@ -50,26 +50,26 @@ private void startGame() { int square = 0; int startPosition = 0; int toSquare = 0; - + // Move legality test variables int fromTest1 = 0; int fromTest2 = 0; int toTest1 = 0; int toTest2 = 0; - + int[] positions = new int[65]; - + Step nextStep = Step.SHOW_INSTRUCTIONS; - + String lineContent = ""; - String userResponse = ""; + String userResponse = ""; // Begin outer while loop while (true) { - + // Begin switch switch (nextStep) { - + case SHOW_INSTRUCTIONS: System.out.println("SOLITAIRE CHECKER PUZZLE BY DAVID AHL\n"); @@ -82,68 +82,68 @@ private void startGame() { System.out.println("CHECKER AND '0' AN EMPTY SQUARE. WHEN YOU HAVE NO"); System.out.println("POSSIBLE JUMPS REMAINING, INPUT A '0' IN RESPONSE TO"); System.out.println("QUESTION 'JUMP FROM ?'\n"); - System.out.println("HERE IS THE NUMERICAL BOARD:\n"); - + System.out.println("HERE IS THE NUMERICAL BOARD:\n"); + nextStep = Step.SHOW_BOARD; break; - + case SHOW_BOARD: - + // Begin loop through all squares for (square = 1; square <= 57; square += 8) { - + lineContent = String.format("% -4d%-4d%-4d%-4d%-4d%-4d%-4d%-4d", square, square + 1, square + 2, square + 3, square + 4, square + 5, square + 6, square + 7); System.out.println(lineContent); - + } // End loop through all squares - + System.out.println(""); System.out.println("AND HERE IS THE OPENING POSITION OF THE CHECKERS."); - System.out.println(""); - + System.out.println(""); + Arrays.fill(positions, 1); - + // Begin generating start positions for (square = 19; square <= 43; square += 8) { - + for (startPosition = square; startPosition <= square + 3; startPosition++) { - + positions[startPosition] = 0; - - } + + } } // End generating start positions - + numJumps = 0; - - printBoard(positions); - + + printBoard(positions); + nextStep = Step.GET_MOVE; break; - + case GET_MOVE: - + System.out.print("JUMP FROM? "); fromSquare = scan.nextInt(); scan.nextLine(); // Discard newline - + // User requested summary - if (fromSquare == 0) { + if (fromSquare == 0) { nextStep = Step.GET_SUMMARY; - break; + break; } - + System.out.print("TO? "); toSquare = scan.nextInt(); scan.nextLine(); // Discard newline - System.out.println(""); + System.out.println(""); // Check legality of move fromTest1 = (int) Math.floor((fromSquare - 1.0) / 8.0); fromTest2 = fromSquare - 8 * fromTest1; toTest1 = (int) Math.floor((toSquare - 1.0) / 8.0); toTest2 = toSquare - 8 * toTest1; - + if ((fromTest1 > 7) || (toTest1 > 7) || (fromTest2 > 8) || @@ -153,49 +153,49 @@ private void startGame() { (positions[(toSquare + fromSquare) / 2] == 0) || (positions[fromSquare] == 0) || (positions[toSquare] == 1)) { - + System.out.println("ILLEGAL MOVE. TRY AGAIN..."); nextStep = Step.GET_MOVE; - break; + break; } positions[toSquare] = 1; positions[fromSquare] = 0; positions[(toSquare + fromSquare) / 2] = 0; numJumps++; - - printBoard(positions); - + + printBoard(positions); + nextStep = Step.GET_MOVE; break; - + case GET_SUMMARY: - + numPieces = 0; - + // Count remaining pieces - for (square = 1; square <= 64; square++) { - numPieces += positions[square]; + for (square = 1; square <= 64; square++) { + numPieces += positions[square]; } - + System.out.println(""); System.out.println("YOU MADE " + numJumps + " JUMPS AND HAD " + numPieces + " PIECES"); - System.out.println("REMAINING ON THE BOARD.\n"); - - nextStep = Step.QUERY_RETRY; + System.out.println("REMAINING ON THE BOARD.\n"); + + nextStep = Step.QUERY_RETRY; break; - + case QUERY_RETRY: while (true) { System.out.print("TRY AGAIN? "); userResponse = scan.nextLine(); System.out.println(""); - + if (userResponse.toUpperCase().equals("YES")) { nextStep = Step.SHOW_BOARD; break; - } + } else if (userResponse.toUpperCase().equals("NO")) { System.out.println("O.K. HOPE YOU HAD FUN!!"); return; @@ -203,50 +203,50 @@ else if (userResponse.toUpperCase().equals("NO")) { else { System.out.println("PLEASE ANSWER 'YES' OR 'NO'."); } - } + } break; - + default: System.out.println("INVALID STEP"); nextStep = Step.QUERY_RETRY; - break; + break; } // End of switch - - } // End outer while loop - - } // End of method startGame - + + } // End outer while loop + + } // End of method startGame + public void printBoard(int[] positions) { - + int column = 0; - int row = 0; + int row = 0; String lineContent = ""; - + // Begin loop through all rows for (row = 1; row <= 57; row += 8) { - + // Begin loop through all columns for (column = row; column <= row + 7; column++) { - - lineContent += " " + positions[column]; - + + lineContent += " " + positions[column]; + } // End loop through all columns - + System.out.println(lineContent); - lineContent = ""; - + lineContent = ""; + } // End loop through all rows - System.out.println(""); - + System.out.println(""); + } // End of method printBoard - + public static void main(String[] args) { - + OneCheck game = new OneCheck(); game.play(); - + } // End of method main - + } // End of class OneCheck diff --git a/67_One_Check/javascript/onecheck.html b/67_One_Check/javascript/onecheck.html index e95bbf6b8..ffdb77e5c 100644 --- a/67_One_Check/javascript/onecheck.html +++ b/67_One_Check/javascript/onecheck.html @@ -1,10 +1,9 @@ ONE CHECK - -

    
    +
    
     
     
     
    diff --git a/67_One_Check/javascript/onecheck.js b/67_One_Check/javascript/onecheck.js
    index 36876809f..a9633b466 100644
    --- a/67_One_Check/javascript/onecheck.js
    +++ b/67_One_Check/javascript/onecheck.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/67_One_Check/kotlin/README.md b/67_One_Check/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/67_One_Check/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/67_One_Check/lua/README.md b/67_One_Check/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/67_One_Check/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/67_One_Check/pascal/README.md b/67_One_Check/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/67_One_Check/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/67_One_Check/python/onecheck.py b/67_One_Check/python/onecheck.py
    index 21ffbd6e1..b3d828b19 100644
    --- a/67_One_Check/python/onecheck.py
    +++ b/67_One_Check/python/onecheck.py
    @@ -1,117 +1,115 @@
    -"""
    -ONE CHECK
    +# ONE CHECK
     
    -Port to Python by imiro
    -"""
    +# Port to python by imiro
     
    -from typing import Tuple
    +def tab(x):
    +    return ' '*x
     
    -
    -def main() -> None:
    +def main():
    +    
         # Initial instructions
    -    print(" " * 30 + "ONE CHECK")
    -    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n")
    -    print("SOLITAIRE CHECKER PUZZLE BY DAVID AHL\n")
    -    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 ?'\n")
    -    print("HERE IS THE NUMERICAL BOARD:\n")
    -
    -    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("\nAND HERE IS THE OPENING POSITION OF THE CHECKERS.\n")
    -
    +    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(f"YOU MADE {jumps} JUMPS AND HAD {left} PIECES")
    -        print("REMAINING ON THE BOARD.\n")
    +        print("YOU MADE " + jumps + " JUMPS AND HAD " + left + " PIECES")
    +        print("REMAINING ON THE BOARD.")
    +        print()
     
    -        if not (try_again()):
    +        if not(try_again()):
                 break
     
    -    print("\nO.K.  HOPE YOU HAD FUN!!")
    -
    +    print()
    +    print("O.K.  HOPE YOU HAD FUN!!")
     
    -def play_game() -> Tuple[str, str]:
    +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 = [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])
    +        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_str = input()
    -            f = int(f_str)
    +            print("JUMP FROM", end=' ')
    +            f = input()
    +            f = int(f)
                 if f == 0:
                     break
    -            print("TO", end=" ")
    -            t_str = input()
    -            t = int(t_str)
    +            print("TO", end=' ')
    +            t = input()
    +            t = int(t)
                 print()
     
                 # Check legality of move
    -            f1 = (f - 1) // 8
    +            f1 = ((f-1) // 8)
                 f2 = f - 8 * f1
    -            t1 = (t - 1) // 8
    +            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
    -            ):
    +            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:
    +        
    +        if(f == 0):
                 break
             board[t] = 1
             board[f] = 0
    -        board[(t + f) // 2] = 0
    +        board[(t+f) // 2] = 0
             jumps = jumps + 1
     
         left = 0
    -    for i in range(1, 64 + 1):
    +    for i in range(1,64+1):
             left = left + board[i]
         return (str(jumps), str(left))
     
    -
    -def try_again() -> bool:
    -    print("TRY AGAIN", end=" ")
    -    answer = input().upper()
    -    if answer == "YES":
    +def try_again():
    +    print("TRY AGAIN", end=' ')
    +    answer = input()
    +    if (answer.upper() == "YES"):
             return True
    -    elif answer == "NO":
    +    elif (answer.upper() == "NO"):
             return False
         print("PLEASE ANSWER 'YES' OR 'NO'.")
    -    return try_again()
    -
    +    try_again()
     
    -if __name__ == "__main__":
    +if __name__ == '__main__':
         main()
    diff --git a/67_One_Check/vbnet/OneCheck.sln b/67_One_Check/vbnet/OneCheck.sln
    deleted file mode 100644
    index d641e964c..000000000
    --- a/67_One_Check/vbnet/OneCheck.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 2b36f16f6..000000000
    --- a/67_One_Check/vbnet/OneCheck.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    OneCheck
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/68_Orbit/README.md b/68_Orbit/README.md
    index be765b557..df49852b1 100644
    --- a/68_Orbit/README.md
    +++ b/68_Orbit/README.md
    @@ -20,10 +20,10 @@ of orbit    <       ^ ship
     
     ```
     
    -The distance of the bomb from the ship is computed using the law of cosines. The law of cosines states:
    +The distance of the bomb from the ship is computed using the law of consines. The law of cosines states:
     
     ```
    -D = SQUAREROOT( R**2 + D1**2 - 2*R*D1*COS(A-A1) )
    +D = SQUAREROOT( R**2+D1**2+R*D1*COS(A-A1) )
     ```
     
     Where D is the distance between the ship and the bomb, R is the altitude of the ship, D1 is the altitude of the bomb, and A-A1 is the angle between the ship and the bomb.
    @@ -55,7 +55,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/68_Orbit/csharp/Orbit.csproj b/68_Orbit/csharp/Orbit.csproj
    deleted file mode 100644
    index d3fe4757c..000000000
    --- a/68_Orbit/csharp/Orbit.csproj
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    diff --git a/68_Orbit/csharp/Orbit.sln b/68_Orbit/csharp/Orbit.sln
    deleted file mode 100644
    index 0ca7e270c..000000000
    --- a/68_Orbit/csharp/Orbit.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/csharp/program.cs b/68_Orbit/csharp/program.cs
    deleted file mode 100644
    index 6dac9131f..000000000
    --- a/68_Orbit/csharp/program.cs
    +++ /dev/null
    @@ -1,199 +0,0 @@
    -using System.Text;
    -
    -namespace Orbit
    -{
    -    class Orbit
    -    {
    -        private void DisplayIntro()
    -        {
    -            Console.WriteLine();
    -            Console.WriteLine("ORBIT".PadLeft(23));
    -            Console.WriteLine("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY");
    -            Console.WriteLine();
    -            Console.WriteLine();
    -            Console.WriteLine();
    -            Console.WriteLine("");
    -            Console.WriteLine("SOMEWHERE ABOVE YOUR PLANET IS A ROMULAN SHIP.");
    -            Console.WriteLine();
    -            Console.WriteLine("THE SHIP IS IN A CONSTANT POLAR ORBIT.  ITS");
    -            Console.WriteLine("DISTANCE FROM THE CENTER OF YOUR PLANET IS FROM");
    -            Console.WriteLine("10,000 TO 30,000 MILES AND AT ITS PRESENT VELOCITY CAN");
    -            Console.WriteLine("CIRCLE YOUR PLANET ONCE EVERY 12 TO 36 HOURS.");
    -            Console.WriteLine();
    -            Console.WriteLine("UNFORTUNATELY, THEY ARE USING A CLOAKING DEVICE SO");
    -            Console.WriteLine("YOU ARE UNABLE TO SEE THEM, BUT WITH A SPECIAL");
    -            Console.WriteLine("INSTRUMENT YOU CAN TELL HOW NEAR THEIR SHIP YOUR");
    -            Console.WriteLine("PHOTON BOMB EXPLODED.  YOU HAVE SEVEN HOURS UNTIL THEY");
    -            Console.WriteLine("HAVE BUILT UP SUFFICIENT POWER IN ORDER TO ESCAPE");
    -            Console.WriteLine("YOUR PLANET'S GRAVITY.");
    -            Console.WriteLine();
    -            Console.WriteLine("YOUR PLANET HAS ENOUGH POWER TO FIRE ONE BOMB AN HOUR.");
    -            Console.WriteLine();
    -            Console.WriteLine("AT THE BEGINNING OF EACH HOUR YOU WILL BE ASKED TO GIVE AN");
    -            Console.WriteLine("ANGLE (BETWEEN 0 AND 360) AND A DISTANCE IN UNITS OF");
    -            Console.WriteLine("100 MILES (BETWEEN 100 AND 300), AFTER WHICH YOUR BOMB'S");
    -            Console.WriteLine("DISTANCE FROM THE ENEMY SHIP WILL BE GIVEN.");
    -            Console.WriteLine();
    -            Console.WriteLine("AN EXPLOSION WITHIN 5,000 MILES OF THE ROMULAN SHIP");
    -            Console.WriteLine("WILL DESTROY IT.");
    -            Console.WriteLine();
    -            Console.WriteLine("BELOW IS A DIAGRAM TO HELP YOU VISUALIZE YOUR PLIGHT.");
    -            Console.WriteLine();
    -            Console.WriteLine();
    -            Console.WriteLine("                          90");
    -            Console.WriteLine("                    0000000000000");
    -            Console.WriteLine("                 0000000000000000000");
    -            Console.WriteLine("               000000           000000");
    -            Console.WriteLine("             00000                 00000");
    -            Console.WriteLine("            00000    XXXXXXXXXXX    00000");
    -            Console.WriteLine("           00000    XXXXXXXXXXXXX    00000");
    -            Console.WriteLine("          0000     XXXXXXXXXXXXXXX     0000");
    -            Console.WriteLine("         0000     XXXXXXXXXXXXXXXXX     0000");
    -            Console.WriteLine("        0000     XXXXXXXXXXXXXXXXXXX     0000");
    -            Console.WriteLine("180<== 00000     XXXXXXXXXXXXXXXXXXX     00000 ==>0");
    -            Console.WriteLine("        0000     XXXXXXXXXXXXXXXXXXX     0000");
    -            Console.WriteLine("         0000     XXXXXXXXXXXXXXXXX     0000");
    -            Console.WriteLine("          0000     XXXXXXXXXXXXXXX     0000");
    -            Console.WriteLine("           00000    XXXXXXXXXXXXX    00000");
    -            Console.WriteLine("            00000    XXXXXXXXXXX    00000");
    -            Console.WriteLine("             00000                 00000");
    -            Console.WriteLine("               000000           000000");
    -            Console.WriteLine("                 0000000000000000000");
    -            Console.WriteLine("                    0000000000000");
    -            Console.WriteLine("                         270");
    -            Console.WriteLine();
    -            Console.WriteLine("X - YOUR PLANET");
    -            Console.WriteLine("O - THE ORBIT OF THE ROMULAN SHIP");
    -            Console.WriteLine();
    -            Console.WriteLine("ON THE ABOVE DIAGRAM, THE ROMULAN SHIP IS CIRCLING");
    -            Console.WriteLine("COUNTERCLOCKWISE AROUND YOUR PLANET.  DON'T FORGET THAT");
    -            Console.WriteLine("WITHOUT SUFFICIENT POWER THE ROMULAN SHIP'S ALTITUDE");
    -            Console.WriteLine("AND ORBITAL RATE WILL REMAIN CONSTANT.");
    -            Console.WriteLine();
    -            Console.WriteLine("GOOD LUCK.  THE FEDERATION IS COUNTING ON YOU.");
    -       }
    -
    -        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 int PromptForNumber(string Prompt)
    -        {
    -            bool InputSuccess = false;
    -            int ReturnResult = 0;
    -
    -            while (!InputSuccess)
    -            {
    -                Console.Write(Prompt);
    -                string Input = Console.ReadLine().Trim();
    -                InputSuccess = int.TryParse(Input, out ReturnResult);
    -                if (!InputSuccess)
    -                    Console.WriteLine("*** Please enter a valid number ***");
    -            }   
    -
    -            return ReturnResult;
    -        }
    -
    -        private void PlayOneRound()
    -        {
    -            Random rand = new Random();
    -            string Prompt = "";
    -
    -            int A_AngleToShip = 0;
    -            int D_DistanceFromBombToShip = 0;
    -            int R_DistanceToShip = 0;
    -            int H_Hour = 0;
    -            int A1_Angle = 0;
    -            int D1_DistanceForDetonation = 0;
    -            int T = 0;
    -            double C_ExplosionDistance = 0;
    -
    -            A_AngleToShip = Convert.ToInt32(360 * rand.NextDouble());
    -            D_DistanceFromBombToShip = Convert.ToInt32(200 * rand.NextDouble()) + 200;
    -            R_DistanceToShip = Convert.ToInt32(20 * rand.NextDouble()) + 10;
    -
    -            while (H_Hour < 7)
    -            {
    -                H_Hour++;
    -
    -                Console.WriteLine();
    -                Console.WriteLine();
    -                Prompt = "This is hour " + H_Hour.ToString() + ", at what angle do you wish to send\nyour photon bomb? ";
    -                A1_Angle = PromptForNumber(Prompt);
    -
    -                D1_DistanceForDetonation = PromptForNumber("How far out do you wish to detonate it? ");
    -
    -                Console.WriteLine();
    -                Console.WriteLine();
    -
    -                A_AngleToShip += R_DistanceToShip;
    -                if (A_AngleToShip >= 360)
    -                    A_AngleToShip -= 360;
    -
    -                T = Math.Abs(A_AngleToShip = A1_Angle);
    -                if (T >= 180)
    -                    T = 360 - T;
    -
    -                C_ExplosionDistance = Math.Sqrt(D_DistanceFromBombToShip * D_DistanceFromBombToShip + D1_DistanceForDetonation * 
    -                                                D1_DistanceForDetonation - 2 * D_DistanceFromBombToShip * D1_DistanceForDetonation * 
    -                                                Math.Cos(T * 3.14159 / 180));
    -                
    -                Console.WriteLine("Your photon bomb exploded {0:N3}*10^2 miles from the", C_ExplosionDistance);
    -                Console.WriteLine("Romulan ship.");
    -
    -                if (C_ExplosionDistance <= 50)
    -                {
    -                    Console.WriteLine("You have successfully completed your mission.");
    -                    return;
    -                }
    -            }
    -
    -            Console.WriteLine("You allowed the Romulans to escape.");
    -            return;
    - 
    -        }
    -
    -        public void Play()
    -        {
    -            bool ContinuePlay = true;
    -
    -            DisplayIntro();
    -
    -            do 
    -            {
    -                PlayOneRound();
    -
    -                Console.WriteLine("Another Romulan ship has gone in to orbit.");
    -                ContinuePlay = PromptYesNo("Do you wish to try to destroy it? ");
    -            }
    -            while (ContinuePlay);
    -            
    -            Console.WriteLine("Good bye.");
    -        }
    -    }
    -    class Program
    -    {
    -        static void Main(string[] args)
    -        {
    -
    -            new Orbit().Play();
    -
    -        }
    -    }
    -}
    \ No newline at end of file
    diff --git a/68_Orbit/java/Orbit.java b/68_Orbit/java/Orbit.java
    index 5ecdb770e..13a8026bc 100644
    --- a/68_Orbit/java/Orbit.java
    +++ b/68_Orbit/java/Orbit.java
    @@ -10,29 +10,29 @@
      * 

    * Note: The idea was to create a version of the 1970's BASIC game in Java, without introducing * new features - no additional text, error checking, etc has been added. - * + * * Converted from BASIC to Java by Darren Cardenas. */ - -public class Orbit { + +public class Orbit { private final Scanner scan; // For user input - + public Orbit() { - + scan = new Scanner(System.in); - - } // End of constructor Orbit + + } // End of constructor Orbit public void play() { - + showIntro(); startGame(); - - } // End of method play - + + } // End of method play + private static void showIntro() { - + System.out.println(" ".repeat(32) + "ORBIT"); System.out.println(" ".repeat(14) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); System.out.println("\n\n"); @@ -57,13 +57,13 @@ private static void showIntro() { System.out.println("ANGLE (BETWEEN 0 AND 360) AND A DISTANCE IN UNITS OF"); System.out.println("100 MILES (BETWEEN 100 AND 300), AFTER WHICH YOUR BOMB'S"); System.out.println("DISTANCE FROM THE ENEMY SHIP WILL BE GIVEN."); - System.out.println(""); + System.out.println(""); System.out.println("AN EXPLOSION WITHIN 5,000 MILES OF THE ROMULAN SHIP"); System.out.println("WILL DESTROY IT."); System.out.println(""); System.out.println("BELOW IS A DIAGRAM TO HELP YOU VISUALIZE YOUR PLIGHT."); System.out.println(""); - System.out.println(""); + System.out.println(""); System.out.println(" 90"); System.out.println(" 0000000000000"); System.out.println(" 0000000000000000000"); @@ -94,58 +94,58 @@ private static void showIntro() { System.out.println("WITHOUT SUFFICIENT POWER THE ROMULAN SHIP'S ALTITUDE"); System.out.println("AND ORBITAL RATE WILL REMAIN CONSTANT."); System.out.println(""); - System.out.println("GOOD LUCK. THE FEDERATION IS COUNTING ON YOU."); - - } // End of method showIntro - + System.out.println("GOOD LUCK. THE FEDERATION IS COUNTING ON YOU."); + + } // End of method showIntro + private void startGame() { - double bombDistance = 0; + double bombDistance = 0; int bombAltitude = 0; int bombAngle = 0; int deltaAngle = 0; int hour = 0; int shipAltitude = 0; int shipAngle = 0; - int shipRate = 0; - String userResponse = ""; + int shipRate = 0; + String userResponse = ""; // Begin outer while loop - while (true) { + while (true) { shipAngle = (int) (361 * Math.random()); shipAltitude = (int) (201 * Math.random() + 200); shipRate = (int) (21 * Math.random() + 10); hour = 0; - + // Begin time limit loop while (hour < 7) { System.out.println(""); System.out.println(""); System.out.println("THIS IS HOUR " + (hour + 1) + ", AT WHAT ANGLE DO YOU WISH TO SEND"); - System.out.print("YOUR PHOTON BOMB? "); + System.out.print("YOUR PHOTON BOMB? "); bombAngle = Integer.parseInt(scan.nextLine()); - + System.out.print("HOW FAR OUT DO YOU WISH TO DETONATE IT? "); bombAltitude = Integer.parseInt(scan.nextLine()); - + System.out.println(""); System.out.println(""); - + // Update ship position shipAngle += shipRate; // Handle full revolutions - if (shipAngle >= 360) { + if (shipAngle >= 360) { shipAngle -= 360; } - + deltaAngle = Math.abs(shipAngle - bombAngle); // Keep angle in upper quadrants - if (deltaAngle >= 180) { - deltaAngle = 360 - deltaAngle; + if (deltaAngle >= 180) { + deltaAngle = 360 - deltaAngle; } bombDistance = Math.sqrt(shipAltitude * shipAltitude + bombAltitude * bombAltitude - 2 * shipAltitude @@ -153,22 +153,22 @@ private void startGame() { System.out.format("YOUR PHOTON BOMB EXPLODED " + "%.5f" + "*10^2 MILES FROM THE\n", bombDistance); System.out.println("ROMULAN SHIP."); - + // Win condition - if (bombDistance <= 50) { + if (bombDistance <= 50) { System.out.println("YOU HAVE SUCCESSFULLY COMPLETED YOUR MISSION."); - break; - } - + break; + } + hour++; - + } // End time limit loop // Lose condition - if (hour == 7) { - System.out.println("YOU HAVE ALLOWED THE ROMULANS TO ESCAPE."); - } - + if (hour == 7) { + System.out.println("YOU HAVE ALLOWED THE ROMULANS TO ESCAPE."); + } + System.out.println("ANOTHER ROMULAN SHIP HAS GONE INTO ORBIT."); System.out.print("DO YOU WISH TO TRY TO DESTROY IT? "); userResponse = scan.nextLine(); @@ -176,17 +176,17 @@ private void startGame() { if (!userResponse.toUpperCase().equals("YES")) { System.out.println("GOOD BYE."); break; - } - - } // End outer while loop - - } // End of method startGame + } + + } // End outer while loop + + } // End of method startGame public static void main(String[] args) { - + Orbit game = new Orbit(); game.play(); - + } // End of method main - + } // End of class Orbit diff --git a/68_Orbit/javascript/orbit.html b/68_Orbit/javascript/orbit.html index 65e75c291..b5ea39821 100644 --- a/68_Orbit/javascript/orbit.html +++ b/68_Orbit/javascript/orbit.html @@ -1,10 +1,9 @@ ORBIT - -

    
    +
    
     
     
     
    diff --git a/68_Orbit/javascript/orbit.js b/68_Orbit/javascript/orbit.js
    index ed20fe0f1..fc505bdf6 100644
    --- a/68_Orbit/javascript/orbit.js
    +++ b/68_Orbit/javascript/orbit.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/68_Orbit/kotlin/README.md b/68_Orbit/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/68_Orbit/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/68_Orbit/lua/README.md b/68_Orbit/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/68_Orbit/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/68_Orbit/orbit.bas b/68_Orbit/orbit.bas
    index f290eee47..123028871 100644
    --- a/68_Orbit/orbit.bas
    +++ b/68_Orbit/orbit.bas
    @@ -57,7 +57,7 @@
     199 PRINT "COUNTERCLOCKWISE AROUND YOUR PLANET.  DON'T FORGET THAT"
     200 PRINT "WITHOUT SUFFICIENT POWER THE ROMULAN SHIP'S ALTITUDE"
     210 PRINT "AND ORBITAL RATE WILL REMAIN CONSTANT."
    -220 PRINT
    +220 PRINT 
     230 PRINT "GOOD LUCK.  THE FEDERATION IS COUNTING ON YOU."
     270 A=INT(360*RND(1))
     280 D=INT(200*RND(1)+200)
    diff --git a/68_Orbit/pascal/README.md b/68_Orbit/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/68_Orbit/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/68_Orbit/python/orbit.py b/68_Orbit/python/orbit.py
    index cfca3c93b..66fb6c560 100644
    --- a/68_Orbit/python/orbit.py
    +++ b/68_Orbit/python/orbit.py
    @@ -12,12 +12,12 @@
     PAGE_WIDTH = 64
     
     
    -def print_centered(msg: str) -> None:
    +def print_centered(msg):
         spaces = " " * ((PAGE_WIDTH - len(msg)) // 2)
         print(spaces + msg)
     
     
    -def print_instructions() -> None:
    +def print_instructions():
         print(
             """SOMEWHERE ABOVE YOUR PLANET IS A ROMULAN SHIP.
     
    @@ -81,7 +81,7 @@ def print_instructions() -> None:
         )
     
     
    -def get_yes_or_no() -> bool:
    +def get_yes_or_no():
         while True:
             response = input().upper()
             if response == "YES":
    @@ -92,7 +92,7 @@ def get_yes_or_no() -> bool:
                 print("PLEASE TYPE 'YES' OR 'NO'")
     
     
    -def game_over(is_success: bool) -> bool:
    +def game_over(is_success):
         if is_success:
             print("YOU HAVE SUCCESSFULLY COMPLETED YOUR MISSION.")
         else:
    @@ -103,11 +103,13 @@ def game_over(is_success: bool) -> bool:
         return get_yes_or_no()
     
     
    -def play_game() -> bool:
    +def play_game():
         rom_angle = random.randint(0, 359)
         rom_distance = random.randint(100, 300)
         rom_angular_velocity = random.randint(10, 30)
    -    for hour in range(1, 8):
    +    hour = 0
    +    while hour < 7:
    +        hour += 1
             print()
             print()
             print(f"THIS IS HOUR {hour}, AT WHAT ANGLE DO YOU WISH TO SEND")
    @@ -122,8 +124,8 @@ def play_game() -> bool:
             rom_angle = (rom_angle + rom_angular_velocity) % 360
             angular_difference = rom_angle - bomb_angle
             c = math.sqrt(
    -            rom_distance**2
    -            + bomb_distance**2
    +            rom_distance ** 2
    +            + bomb_distance ** 2
                 - 2
                 * rom_distance
                 * bomb_distance
    @@ -141,9 +143,12 @@ def play_game() -> bool:
         return False
     
     
    -def main() -> None:
    +def main():
         print_centered("ORBIT")
    -    print_centered("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n")
    +    print_centered("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
    +    print()
    +    print()
    +    print()
     
         print_instructions()
     
    diff --git a/68_Orbit/ruby/orbit.rb b/68_Orbit/ruby/orbit.rb
    deleted file mode 100644
    index cbf86b4d1..000000000
    --- a/68_Orbit/ruby/orbit.rb
    +++ /dev/null
    @@ -1,132 +0,0 @@
    -PAGE_WIDTH = 64
    -
    -def print_centered(msg)
    -	spaces = " " * ((PAGE_WIDTH / msg.length).fdiv(2))
    -	puts "#{spaces}#{msg}"
    -end
    -
    -def print_instructions
    -	puts "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.
    -"
    -end
    -
    -
    -def get_yes_or_no()
    -	while true
    -		response = gets.chomp!.upcase
    -		if response == "YES"
    -			return true
    -		elsif response == "NO"
    -			return false
    -		else
    -			print("PLEASE TYPE 'YES' OR 'NO'")
    -		end
    -	end
    -end
    -
    -def game_over(is_success)
    -	if is_success
    -		puts "YOU HAVE SUCCESSFULLY COMPLETED YOUR MISSION."
    -	else
    -		puts "YOU HAVE ALLOWED THE ROMULANS TO ESCAPE."
    -		puts "ANOTHER ROMULAN SHIP HAS GONE INTO ORBIT."
    -		puts "DO YOU WISH TO TRY TO DESTROY IT?"
    -		return get_yes_or_no()
    -	end
    -end
    -
    -def play_game
    -	rom_angle = rand(1...360)
    -	rom_distance = rand(100...301)
    -	rom_angular_velocity = rand(10...31)
    -	hour = 0
    -	while hour < 7
    -		hour += 1
    -		puts "\n\n"
    -		puts "THIS IS HOUR #{hour}, AT WHAT ANGLE DO YOU WISH TO SEND"
    -		puts "YOUR PHOTON BOMB?"
    -
    -		bomb_angle = gets.chomp!.to_f
    -		puts "HOW FAR OUT DO YOU WISH TO DETONATE IT?"
    -		bomb_distance = gets.chomp!.to_f
    -		puts "\n\n"
    -
    -		rom_angle = (rom_angle + rom_angular_velocity) % 360
    -		angular_difference = rom_angle - bomb_angle
    -		c = Math.sqrt(rom_distance**2 + bomb_distance**2 - 2 * rom_distance * bomb_distance * Math.cos(angular_difference * Math::PI / 180))
    -
    -		puts "YOUR PHOTON BOMB EXPLODED #{sprintf('%.4f', 5)}*10^2 MILES FROM THE"
    -		puts "ROMULAN SHIP."
    -
    -		if c <= 50
    -			# Destroyed the Romulan
    -			return true
    -		end
    -	end
    -	return false
    -end
    -
    -def main
    -    print_centered "ORBIT"
    -
    -    print_instructions()
    -
    -    while true
    -        success = play_game()
    -        again = game_over(success)
    -        if !again
    -            return
    -        end
    -    end
    -end
    -
    -if __FILE__ == $0
    -  main
    -end
    -    
    \ No newline at end of file
    diff --git a/68_Orbit/rust/Cargo.lock b/68_Orbit/rust/Cargo.lock
    deleted file mode 100644
    index 4fe2abbea..000000000
    --- a/68_Orbit/rust/Cargo.lock
    +++ /dev/null
    @@ -1,75 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.10"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.147"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/68_Orbit/rust/Cargo.toml b/68_Orbit/rust/Cargo.toml
    deleted file mode 100644
    index 1c2935d47..000000000
    --- a/68_Orbit/rust/Cargo.toml
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -[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"
    \ No newline at end of file
    diff --git a/68_Orbit/rust/README.md b/68_Orbit/rust/README.md
    deleted file mode 100644
    index 7e85f9a15..000000000
    --- a/68_Orbit/rust/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Rust](https://www.rust-lang.org/) by Anthony Rubick [AnthonyMichaelTDM](https://github.com/AnthonyMichaelTDM)
    diff --git a/68_Orbit/rust/src/lib.rs b/68_Orbit/rust/src/lib.rs
    deleted file mode 100644
    index 2075d7843..000000000
    --- a/68_Orbit/rust/src/lib.rs
    +++ /dev/null
    @@ -1,215 +0,0 @@
    -/*
    - lib.rs contains all the logic of the program
    -*/
    -
    -use std::{error::Error, fmt::Display, str::FromStr, io::{self, Write}, f64::consts::PI};
    -
    -use rand::{thread_rng, Rng};
    -
    -/// handles setup for the game
    -pub struct Config {
    -}
    -impl Config {
    -    /// creates and returns a new Config from user input
    -    pub fn new() -> Result> {
    -        //DATA
    -        let config: Config = Config {};
    -
    -        //this game doesn't actually need a config
    -
    -        //return new config
    -        return Ok(config);
    -    }
    -}
    -
    -/// run the program
    -pub fn run(_config: &Config) -> Result<(), Box> {
    -    
    -    //play game as long as user wants to play it
    -    while play_game() {}
    -    
    -    //return to main
    -    Ok(())
    -}
    -
    -/// handles playing the game one time
    -/// after playing, asks the user if they want to play again and ...
    -/// returns true if user wants to play again, false otherwise
    -fn play_game() -> bool {
    -    //DATA
    -    let mut rng = thread_rng();
    -    let mut ship_destroyed:bool = false;
    -    //generate position of the ship
    -    let mut ship:Polar =  Polar::new(rng.gen_range(0.0..2.0*PI), rng.gen_range(100.0_f64..300.0_f64).floor());
    -    let ship_speed:f64 = rng.gen_range((PI/36.0)..(PI/12.0)); //10deg - 30deg, but radians
    -
    -    //game
    -    // round loop
    -    for hour in 0..7 {
    -        //DATA
    -        let photon_bomb:Polar;
    -        let two_pi = 2.0*PI;
    -        let distance;
    -        
    -        //tell user the hour
    -        println!("THIS IS HOUR {},", hour);
    -
    -        //get input for angle and distance to send the bomb
    -        photon_bomb = get_bomb_from_user_input();
    -
    -        //move ship
    -        ship.angle += ship_speed;
    -        if ship.angle > two_pi { ship.angle -= two_pi}
    -
    -        //calculate distance of bomb from ship
    -        distance = photon_bomb.distance_from(&ship);
    -        //tell user how far away they were from the target
    -        println!("YOUR PHOTON BOMB EXPLODED {}*10^2 MILES FROM THE ROMULAN SHIP\n\n", distance);
    -
    -        //did the bomb destroy the ship?
    -        ship_destroyed = distance <= 50.0;
    -        if ship_destroyed {break;}
    -        //otherwise user didn't destroy the ship, run loop again
    -    }
    -    
    -    //print results message depending on whether or not the user destroyed the ship in time
    -    if ship_destroyed {
    -        println!("YOU HAVE SUCCESFULLY COMPLETED YOUR MISSION.");
    -    } else {
    -        println!("YOU HAVE ALLOWED THE ROMULANS TO ESCAPE.")
    -    }
    -
    -    //prompt user to play again
    -    //do they want to play yes? if they do return true, otherwise false
    -    return match get_string_from_user_input("ANOTHER ROMULAN SHIP HAS GONE INTO ORBIT.\nDO YOU WISH TO TRY TO DESTROY IT?\n(y/n) ") {
    -        Ok(string) => string.chars().any(|c| c.eq_ignore_ascii_case(&'y')),
    -        Err(_e) => false,
    -    };
    -}
    -
    -/// structure to handle polar coordinates
    -struct Polar {
    -    angle: f64,
    -    radius: f64,
    -}
    -impl Polar {
    -    /// create new polar cordinate with the given angle (in degrees) and radiurd from the origin
    -    fn new(angle:f64, radius:f64) -> Polar {
    -        //if radius is negative, correct it
    -        if radius < 0.0 {
    -            return Polar{ angle: angle + PI/2.0, radius: -radius };
    -        }
    -        Polar { angle, radius}
    -    }
    -    ///create new polar cordinate with the given angle (in degrees, converted to radians) and radius from the origin
    -    fn new_from_degrees(angle:usize, radius:f64) -> Polar {
    -        let angle_to_rads: f64 = f64::from( (angle % 360) as u16) * PI/180.0;
    -        
    -        Polar::new(angle_to_rads, radius)
    -    }
    -    ///calculates the distance between 2 coordinates using the law of cosines
    -    fn distance_from(&self,other:&Polar) -> f64 {
    -        (other.radius*other.radius + self.radius*self.radius - 2.0*other.radius*self.radius*((other.angle-self.angle).abs().cos())).sqrt().floor()
    -    }
    -}
    -
    -/// gets a Polar with bomb angle and detonation range from user
    -fn get_bomb_from_user_input() -> Polar {
    -    return loop {//input loop
    -        //DATA
    -        let bomb_angle:usize;
    -        let bomb_altitude:f64;
    -        //get angle
    -        match get_number_from_input("AT WHAT ANGLE DO YOU WISH TO SEND YOUR PHOTON BOMB (0-360): ", 0_usize, 360_usize) {
    -            Ok(angle) => bomb_angle = angle,
    -            Err(err) => {
    -                println!("{}",err);
    -                continue;
    -            },
    -        }
    -        //get radius
    -        match get_number_from_input("HOW FAR OUT DO YOU WISH TO DETONATE IT (100.0-300.0): ", 100.0, 300.0) {
    -            Ok(radius) => bomb_altitude = radius,
    -            Err(err) => {
    -                println!("{}",err);
    -                continue;
    -            },
    -        }
    -        println!("");
    -        //create coordinates from input
    -        break Polar::new_from_degrees( bomb_angle, bomb_altitude);
    -    };
    -}
    -
    -/// gets a string from user input
    -fn get_string_from_user_input(prompt: &str) -> Result> {
    -    //DATA
    -    let mut raw_input = String::new();
    -
    -    //print prompt
    -    print!("{}", prompt);
    -    //make sure it's printed before getting input
    -    io::stdout().flush().unwrap();
    -
    -    //read user input from standard input, and store it to raw_input, then return it or an error as needed
    -    raw_input.clear(); //clear input
    -    match io::stdin().read_line(&mut raw_input) {
    -        Ok(_num_bytes_read) => return Ok(String::from(raw_input.trim())),
    -        Err(err) => return Err(format!("ERROR: CANNOT READ INPUT!: {}", err).into()),
    -    }
    -}
    -
    -/// generic function to get a number from the passed string (user input)
    -/// pass a min lower  than the max to have minimun and maximun bounds
    -/// pass a min higher than the max to only have a minumum bound
    -/// pass a min equal   to  the max to only have a maximun bound
    -/// 
    -/// Errors:
    -/// no number on user input
    -fn get_number_from_input(prompt: &str, min:T, max:T) -> Result> {
    -    //DATA
    -    let raw_input: String;
    -    let processed_input: String;
    -
    -    
    -    //input looop
    -    raw_input = loop {
    -        match get_string_from_user_input(prompt) {
    -            Ok(input) => break input,
    -            Err(e) => {
    -                eprintln!("{}",e);
    -                continue;
    -            },
    -        }
    -    };
    -
    -    //filter out num-numeric characters from user input
    -    processed_input = raw_input.chars().filter(|c| c.is_numeric() || c.eq_ignore_ascii_case(&'.')).collect();
    -
    -    //from input, try to read a number
    -    match processed_input.trim().parse() {
    -        Ok(i) => {
    -            //what bounds must the input fall into
    -            if min < max {  //have a min and max bound: [min,max]
    -                if i >= min && i <= max {//is input valid, within bounds
    -                    return Ok(i); //exit the loop with the value i, returning it
    -                } else { //print error message specific to this case
    -                    return Err(format!("ONLY BETWEEN {} AND {}, PLEASE!", min, max).into());
    -                } 
    -            } else if min > max { //only a min bound: [min, infinity)
    -                if i >= min {
    -                    return Ok(i);
    -                } else {
    -                    return Err(format!("NO LESS THAN {}, PLEASE!", min).into());
    -                }
    -            } else { //only a max bound: (-infinity, max]
    -                if i <= max {
    -                    return Ok(i);
    -                } else {
    -                    return Err(format!("NO MORE THAN {}, PLEASE!", max).into());
    -                }
    -            }
    -        },
    -        Err(_e) => return Err(format!("Error: couldn't find a valid number in {}",raw_input).into()),
    -    }
    -}
    \ No newline at end of file
    diff --git a/68_Orbit/rust/src/main.rs b/68_Orbit/rust/src/main.rs
    deleted file mode 100644
    index 18d61a762..000000000
    --- a/68_Orbit/rust/src/main.rs
    +++ /dev/null
    @@ -1,103 +0,0 @@
    -/*
    -    The responsibilities that remain in the main function after separating concerns
    -    should be limited to the following:
    - - Setting up any configuration
    - - Calling a run function in lib.rs
    - - Handling the error if run returns an error
    -*/
    -
    -use std::process;       //allows for some better error handling
    -
    -mod lib;
    -use lib::Config;
    -
    -/// main function
    -fn main() {
    -    //greet user
    -    welcome();
    -
    -    // set up other configuration
    -    let mut config = Config::new().unwrap_or_else(|err| {
    -        eprintln!("Problem configuring program: {}", err);
    -        process::exit(1);
    -    });
    -
    -    // run the program
    -    if let Err(e) = lib::run(&mut config) {
    -        eprintln!("Application Error: {}", e); //use the eprintln! macro to output to standard error
    -        process::exit(1); //exit the program with an error code
    -    }
    -
    -    //end of program
    -    println!("THANKS FOR PLAYING!");
    -}
    -
    -/// prints the welcome/start message
    -fn welcome() {
    -    println!("
    -                                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.
    -    ");
    -}
    -
    diff --git a/68_Orbit/vbnet/Orbit.sln b/68_Orbit/vbnet/Orbit.sln
    deleted file mode 100644
    index b2b021d10..000000000
    --- a/68_Orbit/vbnet/Orbit.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 29be1358c..000000000
    --- a/68_Orbit/vbnet/Orbit.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Orbit
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/69_Pizza/README.md b/69_Pizza/README.md
    index 7f9e3fcf2..671e72377 100644
    --- a/69_Pizza/README.md
    +++ b/69_Pizza/README.md
    @@ -14,11 +14,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Known Bugs
    -
    -- The program does no validation of its input, and crashes if you enter coordinates outside the valid range.  (Ports may choose to improve on this, for example by repeating the prompt until valid coordinates are given.)
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/69_Pizza/csharp/CustomerMap.cs b/69_Pizza/csharp/Pizza/CustomerMap.cs
    similarity index 98%
    rename from 69_Pizza/csharp/CustomerMap.cs
    rename to 69_Pizza/csharp/Pizza/CustomerMap.cs
    index d2214c269..ee991de31 100644
    --- a/69_Pizza/csharp/CustomerMap.cs
    +++ b/69_Pizza/csharp/Pizza/CustomerMap.cs
    @@ -25,7 +25,7 @@ public string GetCustomerOnPosition(int x, int y)
                 {
                     return string.Empty;
                 }
    -
    +                        
                 return _customerMap[y, x];
             }
     
    @@ -74,8 +74,8 @@ public override string ToString()
             /// True if position is out of range otherwise false.
             private bool IsPositionOutOfRange(int x, int y)
             {
    -            return
    -                x < 0 || x > _mapSize - 1 ||
    +            return 
    +                x < 0 || x > _mapSize - 1 || 
                     y < 0 || y > _mapSize - 1;
             }
     
    @@ -128,4 +128,4 @@ private void AppendXLine(StringBuilder mapToDisplay, int horizontalSpace)
                 mapToDisplay.Append(Environment.NewLine);
             }
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/69_Pizza/csharp/Pizza.csproj b/69_Pizza/csharp/Pizza/Pizza.csproj
    similarity index 100%
    rename from 69_Pizza/csharp/Pizza.csproj
    rename to 69_Pizza/csharp/Pizza/Pizza.csproj
    diff --git a/69_Pizza/csharp/Pizza.sln b/69_Pizza/csharp/Pizza/Pizza.sln
    similarity index 100%
    rename from 69_Pizza/csharp/Pizza.sln
    rename to 69_Pizza/csharp/Pizza/Pizza.sln
    diff --git a/69_Pizza/csharp/PizzaGame.cs b/69_Pizza/csharp/Pizza/PizzaGame.cs
    similarity index 99%
    rename from 69_Pizza/csharp/PizzaGame.cs
    rename to 69_Pizza/csharp/Pizza/PizzaGame.cs
    index b4157047c..22c78e05a 100644
    --- a/69_Pizza/csharp/PizzaGame.cs
    +++ b/69_Pizza/csharp/Pizza/PizzaGame.cs
    @@ -293,4 +293,4 @@ private void WriteEmptyLine(int numberOfEmptyLines = 1)
                 }
             }
         }
    -}
    +}
    \ 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 000000000..6c21fad0a
    --- /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 000000000..f7cb828d9
    --- /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
    diff --git a/69_Pizza/csharp/Program.cs b/69_Pizza/csharp/Program.cs
    deleted file mode 100644
    index 48cc4e275..000000000
    --- a/69_Pizza/csharp/Program.cs
    +++ /dev/null
    @@ -1,11 +0,0 @@
    -namespace Pizza
    -{
    -    internal class Program
    -    {
    -        static void Main(string[] args)
    -        {
    -            var pizzaGame = new PizzaGame();
    -            pizzaGame.Play();
    -        }
    -    }
    -}
    diff --git a/69_Pizza/csharp/StringBuilderExtensions.cs b/69_Pizza/csharp/StringBuilderExtensions.cs
    deleted file mode 100644
    index d3d769d3c..000000000
    --- a/69_Pizza/csharp/StringBuilderExtensions.cs
    +++ /dev/null
    @@ -1,21 +0,0 @@
    -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);
    -            }
    -        }
    -    }
    -}
    diff --git a/69_Pizza/java/src/Pizza.java b/69_Pizza/java/src/Pizza.java
    index 051bffce3..c3986c810 100644
    --- a/69_Pizza/java/src/Pizza.java
    +++ b/69_Pizza/java/src/Pizza.java
    @@ -315,4 +315,4 @@ private String displayTextAndGetInput(String text) {
             return kbScanner.next();
         }
     
    -}
    +}
    \ No newline at end of file
    diff --git a/69_Pizza/javascript/pizza.html b/69_Pizza/javascript/pizza.html
    index b901b6e29..301344999 100644
    --- a/69_Pizza/javascript/pizza.html
    +++ b/69_Pizza/javascript/pizza.html
    @@ -1,10 +1,9 @@
     
     
     PIZZA
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/69_Pizza/javascript/pizza.js b/69_Pizza/javascript/pizza.js
    index 11547b213..ba7fe5780 100644
    --- a/69_Pizza/javascript/pizza.js
    +++ b/69_Pizza/javascript/pizza.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/69_Pizza/kotlin/README.md b/69_Pizza/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/69_Pizza/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/69_Pizza/lua/README.md b/69_Pizza/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/69_Pizza/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/69_Pizza/pascal/README.md b/69_Pizza/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/69_Pizza/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/69_Pizza/perl/pizza.pl b/69_Pizza/perl/pizza.pl
    deleted file mode 100755
    index 8d3e707fb..000000000
    --- a/69_Pizza/perl/pizza.pl
    +++ /dev/null
    @@ -1,110 +0,0 @@
    -#!/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
    diff --git a/69_Pizza/python/pizza.py b/69_Pizza/python/pizza.py
    index 33bd60b6c..e3804e754 100644
    --- a/69_Pizza/python/pizza.py
    +++ b/69_Pizza/python/pizza.py
    @@ -14,12 +14,12 @@
     street_names = [str(n) for n in range(1, 5)]
     
     
    -def print_centered(msg: str) -> None:
    +def print_centered(msg):
         spaces = " " * ((PAGE_WIDTH - len(msg)) // 2)
         print(spaces + msg)
     
     
    -def print_header(title: str) -> None:
    +def print_header(title):
         print_centered(title)
         print_centered("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
         print()
    @@ -27,16 +27,16 @@ def print_header(title: str) -> None:
         print()
     
     
    -def print_ticks() -> None:
    -    for _ in range(4):
    +def print_ticks():
    +    for t in range(4):
             print("-")
     
     
    -def print_ruler() -> None:
    +def print_ruler():
         print(" -----1-----2-----3-----4-----")
     
     
    -def print_street(i: int) -> None:
    +def print_street(i):
         street_number = 3 - i
     
         street_name = street_names[street_number]
    @@ -52,7 +52,7 @@ def print_street(i: int) -> None:
         print(line)
     
     
    -def print_map() -> None:
    +def print_map():
         print("MAP OF THE CITY OF HYATTSVILLE")
         print()
         print_ruler()
    @@ -64,7 +64,7 @@ def print_map() -> None:
         print()
     
     
    -def print_instructions() -> str:
    +def print_instructions():
         print("PIZZA DELIVERY GAME")
         print()
         print("WHAT IS YOUR FIRST NAME?")
    @@ -89,7 +89,7 @@ def print_instructions() -> str:
         return player_name
     
     
    -def yes_no_prompt(msg: str) -> bool:
    +def yes_no_prompt(msg):
         while True:
             print(msg)
             response = input().upper()
    @@ -101,7 +101,7 @@ def yes_no_prompt(msg: str) -> bool:
             print("'YES' OR 'NO' PLEASE, NOW THEN,")
     
     
    -def print_more_directions(player_name: str) -> None:
    +def print_more_directions(player_name):
         print()
         print("SOMEBODY WILL ASK FOR A PIZZA TO BE")
         print("DELIVERED.  THEN A DELIVERY BOY WILL")
    @@ -113,15 +113,15 @@ def print_more_directions(player_name: str) -> None:
         print()
     
     
    -def calculate_customer_index(x: int, y: int) -> int:
    +def calculate_customer_index(x, y):
         return 4 * (y - 1) + x - 1
     
     
    -def deliver_to(customer_index, customer_name, player_name) -> bool:
    +def deliver_to(customer_index, customer_name, player_name):
         print(f"  DRIVER TO {player_name}:  WHERE DOES {customer_name} LIVE?")
     
         coords = input()
    -    xc, yc = (int(c) for c in coords.split(","))
    +    xc, yc = [int(c) for c in coords.split(",")]
         delivery_index = calculate_customer_index(xc, yc)
         if delivery_index == customer_index:
             print(f"HELLO {player_name}.  THIS IS {customer_name}, THANKS FOR THE PIZZA.")
    @@ -133,8 +133,8 @@ def deliver_to(customer_index, customer_name, player_name) -> bool:
             return False
     
     
    -def play_game(num_turns, player_name) -> None:
    -    for _turn in range(num_turns):
    +def play_game(num_turns, player_name):
    +    for turn in range(num_turns):
             x = random.randint(1, 4)
             y = random.randint(1, 4)
             customer_index = calculate_customer_index(x, y)
    @@ -150,12 +150,14 @@ def play_game(num_turns, player_name) -> None:
                     break
     
     
    -def main() -> None:
    +def main():
         print_header("PIZZA")
     
         player_name = print_instructions()
     
    -    if yes_no_prompt("DO YOU NEED MORE DIRECTIONS?"):
    +    more_directions = yes_no_prompt("DO YOU NEED MORE DIRECTIONS?")
    +
    +    if more_directions:
             print_more_directions(player_name)
     
             understand = yes_no_prompt("UNDERSTAND?")
    @@ -169,8 +171,8 @@ def main() -> None:
         print("GOOD LUCK!!")
         print()
     
    -    num_turns = 5
         while True:
    +        num_turns = 5
             play_game(num_turns, player_name)
     
             print()
    diff --git a/69_Pizza/ruby/pizza.rb b/69_Pizza/ruby/pizza.rb
    deleted file mode 100644
    index e392239c8..000000000
    --- a/69_Pizza/ruby/pizza.rb
    +++ /dev/null
    @@ -1,159 +0,0 @@
    -class Pizza
    -  STREET_NAMES   = ['1', '2', '3', '4']
    -  CUSTOMER_NAMES = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P']
    -  def start
    -    player_name = print_instructions
    -    more_directions = yes_no_prompt("DO YOU NEED MORE DIRECTIONS?")
    -
    -    if more_directions
    -      print_more_directions(player_name)
    -
    -      understand = yes_no_prompt("UNDERSTAND?")
    -
    -      if not understand
    -        print("\nTHIS JOB IS DEFINITELY TOO DIFFICULT FOR YOU. THANKS ANYWAY")
    -        return
    -      end
    -
    -      puts "\n\nGOOD.  YOU ARE NOW READY TO START TAKING ORDERS. \n"
    -      puts "GOOD LUCK!!"
    -    end
    -
    -    while true
    -      num_turns = 5
    -      play_game(num_turns, player_name)
    -
    -      more = yes_no_prompt("DO YOU WANT TO DELIVER MORE PIZZAS?")
    -      if not more
    -        puts "\nO.K. #{player_name}, SEE YOU LATER!"
    -        return
    -      end
    -    end
    -  end
    -
    -  private
    -    def print_street index
    -      street_number = 3 - index
    -  
    -      street_name = STREET_NAMES[street_number]
    -      line = street_name
    -  
    -      space = " " * 5
    -      for customer_index in (0...4)
    -        line += space
    -        customer_name = CUSTOMER_NAMES[4 * street_number + customer_index]
    -        line += customer_name
    -      end
    -      line += space
    -      line += street_name
    -      puts "#{line}"
    -    end
    -        
    -    def print_map
    -      puts "MAP OF THE CITY OF HYATTSVILLE\n\n" 
    -      print(" -----1-----2-----3-----4-----")
    -      for i in (0...4)
    -        for _ in (0...4)
    -            puts "-"
    -        end
    -        print_street(i)
    -      end
    -      print(" -----1-----2-----3-----4-----")
    -    end
    -
    -    def print_instructions
    -      puts "PIZZA DELIVERY GAME \n\n"
    -      print "WHAT IS YOUR FIRST NAME? "
    -      player_name = gets.chomp!
    -      puts "\nHi, #{player_name}. IN THIS GAME YOU ARE TO TAKE ORDERS"
    -      puts "FOR PIZZAS.  THEN YOU ARE TO TELL A DELIVERY BOY"
    -      puts "WHERE TO DELIVER THE ORDERED PIZZAS. \n\n"
    -
    -      print_map
    -
    -      puts "\n\nTHE OUTPUT IS A MAP OF THE HOMES WHERE"
    -      puts "YOU ARE TO SEND PIZZAS."
    -      puts "YOUR JOB IS TO GIVE A TRUCK DRIVER"
    -      puts "THE LOCATION OR COORDINATES OF THE"
    -      puts "HOME ORDERING THE PIZZA."
    -
    -      return player_name
    -    end
    -
    -    def yes_no_prompt msg
    -      puts
    -      while true
    -        print "#{msg} "
    -          
    -        response = gets.chomp
    -
    -        if response == response.upcase
    -          if response == "YES"
    -            return true
    -          elsif response == "NO"
    -            return false
    -          end
    -        else
    -          print "'YES' OR 'NO' PLEASE, NOW THEN, "
    -        end
    -
    -      end
    -    end
    -
    -    def print_more_directions player_name
    -      puts "\nSOMEBODY WILL ASK FOR A PIZZA TO BE"
    -      puts "DELIVERED.  THEN A DELIVERY BOY WILL"
    -      puts "ASK YOU FOR THE LOCATION."
    -      puts "\nEXAMPLE:"
    -      puts "THIS IS J.  PLEASE SEND A PIZZA."
    -      puts "DRIVER TO #{player_name}.  WHERE DOES J LIVE?"
    -      puts "YOUR ANSWER WOULD BE 2,3"
    -    end
    -    
    -    def calculate_customer_index x,y
    -      return 4 * (y - 1) + x - 1
    -    end
    -
    -    def deliver_to customer_index, customer_name, player_name
    -      print "  DRIVER TO #{player_name}:  WHERE DOES #{customer_name} LIVE? "
    -  
    -      coords = gets.chomp!
    -      xc, yc = coords.split(/,/).map(&:to_i)
    -
    -      puts "#{xc}, #{yc}"
    -      delivery_index = calculate_customer_index(xc, yc)
    -      if delivery_index == customer_index
    -        puts "HELLO #{player_name}.  THIS IS #{customer_name}, THANKS FOR THE PIZZA."
    -        return true
    -      else  
    -          delivery_name = CUSTOMER_NAMES[delivery_index]
    -          puts "THIS IS #{defined?(delivery_name.to_i) ? "Undefined" : delivery_name.to_i}.  I DID NOT ORDER A PIZZA."
    -          puts "I LIVE AT #{xc},#{yc}"
    -          return false
    -      end
    -    end
    -
    -    def play_game num_turns, player_name
    -      for _turn in (1..num_turns)
    -        x = rand(1..4)
    -        y = rand(1..4)
    -        customer_index = calculate_customer_index(x, y)
    -        customer_name = CUSTOMER_NAMES[customer_index]
    -
    -        puts "\nHELLO #{player_name}'S PIZZA.  THIS IS #{customer_name}. \n  PLEASE SEND A PIZZA."
    -
    -        while true
    -          success = deliver_to(customer_index, customer_name, player_name)
    -          if success
    -            break
    -          end
    -        end
    -      end
    -    end
    -end
    -
    -if __FILE__ == $0
    -  pizza = Pizza.new
    -  pizza.start()
    -end
    -  
    \ No newline at end of file
    diff --git a/69_Pizza/rust/Cargo.lock b/69_Pizza/rust/Cargo.lock
    deleted file mode 100644
    index b4abe0dca..000000000
    --- a/69_Pizza/rust/Cargo.lock
    +++ /dev/null
    @@ -1,23 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "anyhow"
    -version = "1.0.75"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
    -
    -[[package]]
    -name = "fastrand"
    -version = "2.0.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    -dependencies = [
    - "anyhow",
    - "fastrand",
    -]
    diff --git a/69_Pizza/rust/Cargo.toml b/69_Pizza/rust/Cargo.toml
    deleted file mode 100644
    index 5224dbab6..000000000
    --- a/69_Pizza/rust/Cargo.toml
    +++ /dev/null
    @@ -1,10 +0,0 @@
    -[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]
    -anyhow = "1.0.75"
    -fastrand = "2.0.1"
    diff --git a/69_Pizza/rust/README.md b/69_Pizza/rust/README.md
    deleted file mode 100644
    index ce0d38dc2..000000000
    --- a/69_Pizza/rust/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Rust](https://www.rust-lang.org/).
    diff --git a/69_Pizza/rust/src/main.rs b/69_Pizza/rust/src/main.rs
    deleted file mode 100644
    index 4bfe4f226..000000000
    --- a/69_Pizza/rust/src/main.rs
    +++ /dev/null
    @@ -1,178 +0,0 @@
    -use anyhow::Result;
    -use std::io;
    -
    -fn print_centered(text: &str) {
    -    println!("{:^72}", text);
    -}
    -
    -fn read_line() -> Result {
    -    let mut input = String::new();
    -    io::stdin().read_line(&mut input)?;
    -    input.truncate(input.trim_end().len());
    -    Ok(input)
    -}
    -
    -fn read_number() -> Result {
    -    let line = read_line()?;
    -    let num = line.parse()?;
    -    Ok(num)
    -}
    -
    -fn print_banner() {
    -    print_centered("PIZZA");
    -    print_centered("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY");
    -    println!();
    -    println!();
    -    println!();
    -}
    -
    -fn print_instructions() -> Result {
    -    println!("PIZZA DELIVERY GAME");
    -    println!();
    -    println!("WHAT IS YOUR FIRST NAME");
    -
    -    let name = read_line()?;
    -    println!("HI, {name}.  IN THIS GAME YOU ARE TO TAKE ORDERS");
    -    println!("FOR PIZZAS.  THEN YOU ARE TO TELL A DELIVERY BOY");
    -    println!("WHERE TO DELIVER THE ORDERED PIZZAS.");
    -    println!();
    -    println!();
    -
    -    print_map();
    -
    -    println!("THE OUTPUT IS A MAP OF THE HOMES WHERE");
    -    println!("YOU ARE TO SEND PIZZAS.");
    -    println!();
    -    println!("YOUR JOB IS TO GIVE A TRUCK DRIVER");
    -    println!("THE LOCATION OR COORDINATES OF THE");
    -    println!("HOME ORDERING THE PIZZA.");
    -    println!();
    -
    -    Ok(name)
    -}
    -
    -fn print_ruler() {
    -    println!(" -----1-----2-----3-----4-----");
    -}
    -
    -fn print_ticks() {
    -    println!("-");
    -    println!("-");
    -    println!("-");
    -    println!("-");
    -}
    -
    -fn print_street(i: u32) {
    -    let street_number = 3 - i;
    -    let street_name = (street_number + 1).to_string();
    -
    -    let mut line = street_name.clone();
    -    let space = "     ";
    -    for customer_idx in 0..4 {
    -        line.push_str(space);
    -        let customer = 4 * street_number + customer_idx;
    -        line.push(char::from_u32(65 + customer).unwrap());
    -    }
    -    line.push_str(space);
    -    line.push_str(&street_name);
    -    println!("{line}");
    -}
    -
    -fn print_map() {
    -    println!("MAP OF THE CITY OF HYATTSVILLE");
    -    println!();
    -    print_ruler();
    -    for i in 0..4 {
    -        print_ticks();
    -        print_street(i);
    -    }
    -    print_ticks();
    -    print_ruler();
    -    println!();
    -}
    -
    -fn yes_no_prompt(text: &str) -> Result> {
    -    println!("{text}");
    -    let input = read_line()?;
    -    match input.as_str() {
    -        "YES" => Ok(Some(true)),
    -        "NO" => Ok(Some(false)),
    -        _ => Ok(None),
    -    }
    -}
    -
    -fn play_game(turns: u32, player_name: &str) -> Result<()> {
    -    for _ in 0..turns {
    -        let customer = fastrand::char('A'..='P');
    -        println!("HELLO {player_name}'S PIZZA.  THIS IS {customer}.");
    -        println!("  PLEASE SEND A PIZZA.");
    -        loop {
    -            println!("  DRIVER TO {player_name}:  WHERE DOES {customer} LIVE");
    -
    -            let x = read_number()?;
    -            let y = read_number()?;
    -
    -            let input = x - 1 + (y - 1) * 4;
    -            match char::from_u32(65 + input) {
    -                Some(c) if c == customer => {
    -                    println!("HELLO {player_name}.  THIS IS {customer}, THANKS FOR THE PIZZA.");
    -                    break;
    -                }
    -                Some(c @ 'A'..='P') => {
    -                    println!("THIS IS {c}.  I DID NOT ORDER A PIZZA.");
    -                    println!("I LIVE AT {x},{y}");
    -                }
    -                // this is out of bounds in the original game
    -                _ => (),
    -            }
    -        }
    -    }
    -
    -    Ok(())
    -}
    -
    -fn main() -> Result<()> {
    -    print_banner();
    -    let player_name = print_instructions()?;
    -    let more_directions = loop {
    -        if let Some(x) = yes_no_prompt("DO YOU NEED MORE DIRECTIONS")? {
    -            break x;
    -        } else {
    -            println!("'YES' OR 'NO' PLEASE, NOW THEN,");
    -        }
    -    };
    -
    -    if more_directions {
    -        println!();
    -        println!("SOMEBODY WILL ASK FOR A PIZZA TO BE");
    -        println!("DELIVERED.  THEN A DELIVERY BOY WILL");
    -        println!("ASK YOU FOR THE LOCATION.");
    -        println!("     EXAMPLE:");
    -        println!("THIS IS J.  PLEASE SEND A PIZZA.");
    -        println!("DRIVER TO {player_name}.  WHERE DOES J LIVE?");
    -        println!("YOUR ANSWER WOULD BE 2,3");
    -        println!();
    -
    -        if let Some(true) = yes_no_prompt("UNDERSTAND")? {
    -            println!("GOOD.  YOU ARE NOW READY TO START TAKING ORDERS.");
    -            println!();
    -            println!("GOOD LUCK!!");
    -            println!();
    -        } else {
    -            println!("THIS JOB IS DEFINITELY TOO DIFFICULT FOR YOU. THANKS ANYWAY");
    -            return Ok(());
    -        }
    -    }
    -
    -    loop {
    -        play_game(5, &player_name)?;
    -        println!();
    -
    -        if let Some(false) | None = yes_no_prompt("DO YOU WANT TO DELIVER MORE PIZZAS")? {
    -            println!();
    -            println!("O.K. {player_name}, SEE YOU LATER!");
    -            println!();
    -            return Ok(());
    -        }
    -    }
    -}
    diff --git a/69_Pizza/vbnet/Pizza.sln b/69_Pizza/vbnet/Pizza.sln
    deleted file mode 100644
    index 8fc145ee8..000000000
    --- a/69_Pizza/vbnet/Pizza.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index db16f0231..000000000
    --- a/69_Pizza/vbnet/Pizza.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Pizza
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/70_Poetry/README.md b/70_Poetry/README.md
    index be21f8bee..b04bb9153 100644
    --- a/70_Poetry/README.md
    +++ b/70_Poetry/README.md
    @@ -27,9 +27,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -- The program begins by switching on `I`, which has not been initialized.  We should probably initialize this to 0, though this means the output always begins with the phrase "midnight dreary".
    -
    -- Though the program contains an END statement (line 999), it is unreachable.  The program continues to generate output until it is forcibly interrupted.
    diff --git a/70_Poetry/csharp/Context.cs b/70_Poetry/csharp/Context.cs
    deleted file mode 100644
    index a9297915e..000000000
    --- a/70_Poetry/csharp/Context.cs
    +++ /dev/null
    @@ -1,109 +0,0 @@
    -namespace Poetry;
    -
    -internal class Context
    -{
    -    private readonly IReadWrite _io;
    -    private readonly IRandom _random;
    -    private int _phraseNumber;
    -    private int _groupNumber;
    -    private bool _skipComma;
    -    private int _lineCount;
    -    private bool _useGroup2;
    -    private bool _atStartOfLine = true;
    -
    -    public Context(IReadWrite io, IRandom random)
    -    {
    -        _io = io;
    -        _random = random;
    -    }
    -
    -    public int PhraseNumber => Math.Max(_phraseNumber - 1, 0); 
    -
    -    public int GroupNumber 
    -    { 
    -        get
    -        {
    -            var value = _useGroup2 ? 2 : _groupNumber;
    -            _useGroup2 = false;
    -            return Math.Max(value - 1, 0);
    -        }
    -    }
    -
    -    public int PhraseCount { get; set; }
    -    public bool GroupNumberIsValid => _groupNumber < 5;
    -
    -    public void WritePhrase()
    -    {
    -        Phrase.GetPhrase(this).Write(_io, this);
    -        _atStartOfLine = false;
    -    }
    -
    -    public void MaybeWriteComma()
    -    {
    -        if (!_skipComma && _random.NextFloat() <= 0.19F && PhraseCount != 0)
    -        {
    -            _io.Write(",");
    -            PhraseCount = 2;
    -        }
    -        _skipComma = false;
    -    }
    -
    -    public void WriteSpaceOrNewLine()
    -    {
    -        if (_random.NextFloat() <= 0.65F)
    -        {
    -            _io.Write(" ");
    -            PhraseCount += 1;
    -        }
    -        else
    -        {
    -            EndLine();
    -            PhraseCount = 0;
    -        }
    -    }
    -
    -    public void Update(IRandom random)
    -    {
    -        _phraseNumber = random.Next(1, 6);
    -        _groupNumber += 1;
    -        _lineCount += 1;
    -    }
    -
    -    public void MaybeIndent()
    -    {
    -        if (PhraseCount == 0 && _groupNumber % 2 == 0)
    -        {
    -            _io.Write("     ");
    -        }
    -    }
    -    
    -    public void ResetGroup()
    -    {
    -        _groupNumber = 0;
    -        EndLine();
    -    }
    -
    -    public bool MaybeCompleteStanza()
    -    {
    -        if (_lineCount > 20)
    -        {
    -            _io.WriteLine();
    -            PhraseCount = _lineCount = 0;
    -            _useGroup2 = true;
    -            return true;
    -        }
    -
    -        return false;
    -    }
    -
    -    internal string MaybeCapitalise(string text) =>
    -        _atStartOfLine ? (char.ToUpper(text[0]) + text[1..]) : text;
    -
    -    public void SkipNextComma() => _skipComma = true;
    -
    -    public void EndLine()
    -    {
    -        _io.WriteLine();
    -        _atStartOfLine = true;
    -    }
    -}
    diff --git a/70_Poetry/csharp/Phrase.cs b/70_Poetry/csharp/Phrase.cs
    deleted file mode 100644
    index f70de30bd..000000000
    --- a/70_Poetry/csharp/Phrase.cs
    +++ /dev/null
    @@ -1,78 +0,0 @@
    -namespace Poetry;
    -
    -internal class Phrase
    -{
    -    private readonly static Phrase[][] _phrases = new Phrase[][]
    -    {
    -        new Phrase[]
    -        {
    -            new("midnight dreary"),
    -            new("fiery eyes"),
    -            new("bird or fiend"),
    -            new("thing of evil"),
    -            new("prophet")
    -        },
    -        new Phrase[]
    -        {
    -            new("beguiling me", ctx => ctx.PhraseCount = 2),
    -            new("thrilled me"),
    -            new("still sitting....", ctx => ctx.SkipNextComma()),
    -            new("never flitting", ctx => ctx.PhraseCount = 2),
    -            new("burned")
    -        },
    -        new Phrase[]
    -        {
    -            new("and my soul"),
    -            new("darkness there"),
    -            new("shall be lifted"),
    -            new("quoth the raven"),
    -            new(ctx => ctx.PhraseCount != 0, "sign of parting")
    -        },
    -        new Phrase[]
    -        {
    -            new("nothing more"),
    -            new("yet again"),
    -            new("slowly creeping"),
    -            new("...evermore"),
    -            new("nevermore")
    -        }
    -    };
    -
    -    private readonly Predicate _condition;
    -    private readonly string _text;
    -    private readonly Action _update;
    -
    -    private Phrase(Predicate condition, string text)
    -        : this(condition, text, _ => { })
    -    {
    -    }
    -
    -    private Phrase(string text, Action update)
    -        : this(_ => true, text, update)
    -    {
    -    }
    -
    -    private Phrase(string text)
    -        : this(_ => true, text, _ => { })
    -    {
    -    }
    -
    -    private Phrase(Predicate condition, string text, Action update)
    -    {
    -        _condition = condition;
    -        _text = text;
    -        _update = update;
    -    }
    -
    -    public static Phrase GetPhrase(Context context) => _phrases[context.GroupNumber][context.PhraseNumber];
    -
    -    public void Write(IReadWrite io, Context context)
    -    {
    -        if (_condition.Invoke(context))
    -        {
    -            io.Write(context.MaybeCapitalise(_text));
    -        }
    -
    -        _update.Invoke(context);
    -    }
    -}
    \ No newline at end of file
    diff --git a/70_Poetry/csharp/Poem.cs b/70_Poetry/csharp/Poem.cs
    deleted file mode 100644
    index fa3d50459..000000000
    --- a/70_Poetry/csharp/Poem.cs
    +++ /dev/null
    @@ -1,32 +0,0 @@
    -using static Poetry.Resources.Resource;
    -
    -namespace Poetry;
    -
    -internal class Poem
    -{
    -    internal static void Compose(IReadWrite io, IRandom random)
    -    {
    -        io.Write(Streams.Title);
    -
    -        var context = new Context(io, random);
    -
    -        while (true)
    -        {
    -            context.WritePhrase();
    -            context.MaybeWriteComma();
    -            context.WriteSpaceOrNewLine();
    -
    -            while (true)
    -            {
    -                context.Update(random);
    -                context.MaybeIndent();
    -
    -                if (context.GroupNumberIsValid) { break; }
    -
    -                context.ResetGroup();
    -
    -                if (context.MaybeCompleteStanza()) { break; }
    -            }
    -        }
    -    }
    -}
    \ No newline at end of file
    diff --git a/70_Poetry/csharp/Poetry.csproj b/70_Poetry/csharp/Poetry.csproj
    deleted file mode 100644
    index 3870320c9..000000000
    --- a/70_Poetry/csharp/Poetry.csproj
    +++ /dev/null
    @@ -1,17 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    -  
    -    
    -  
    -
    -  
    -    
    -  
    -
    diff --git a/70_Poetry/csharp/Poetry.sln b/70_Poetry/csharp/Poetry.sln
    deleted file mode 100644
    index f62c6d2b8..000000000
    --- a/70_Poetry/csharp/Poetry.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/csharp/Program.cs b/70_Poetry/csharp/Program.cs
    deleted file mode 100644
    index 3a17d72c2..000000000
    --- a/70_Poetry/csharp/Program.cs
    +++ /dev/null
    @@ -1,5 +0,0 @@
    -global using Games.Common.IO;
    -global using Games.Common.Randomness;
    -global using Poetry;
    -
    -Poem.Compose(new ConsoleIO(), new RandomNumberGenerator());
    diff --git a/70_Poetry/csharp/Resources/Resource.cs b/70_Poetry/csharp/Resources/Resource.cs
    deleted file mode 100644
    index b789f0357..000000000
    --- a/70_Poetry/csharp/Resources/Resource.cs
    +++ /dev/null
    @@ -1,16 +0,0 @@
    -using System.Reflection;
    -using System.Runtime.CompilerServices;
    -
    -namespace Poetry.Resources;
    -
    -internal static class Resource
    -{
    -    internal static class Streams
    -    {
    -        public static Stream Title => GetStream();
    -    }
    -
    -    private static Stream GetStream([CallerMemberName] string? name = null) =>
    -        Assembly.GetExecutingAssembly().GetManifestResourceStream($"{typeof(Resource).Namespace}.{name}.txt")
    -            ?? throw new Exception($"Could not find embedded resource stream '{name}'.");
    -}
    \ No newline at end of file
    diff --git a/70_Poetry/csharp/Resources/Title.txt b/70_Poetry/csharp/Resources/Title.txt
    deleted file mode 100644
    index 861613403..000000000
    --- a/70_Poetry/csharp/Resources/Title.txt
    +++ /dev/null
    @@ -1,5 +0,0 @@
    -                              Poetry
    -               Creative Computing  Morristown, New Jersey
    -
    -
    -
    diff --git a/70_Poetry/java/Poetry.java b/70_Poetry/java/Poetry.java
    index 3b63dc1ea..80be8f216 100644
    --- a/70_Poetry/java/Poetry.java
    +++ b/70_Poetry/java/Poetry.java
    @@ -6,261 +6,261 @@
      * 

    * Note: The idea was to create a version of the 1970's BASIC game in Java, without introducing * new features - no additional text, error checking, etc has been added. - * + * * Converted from BASIC to Java by Darren Cardenas. */ - + public class Poetry { - + private final static double COMMA_RATE = 0.19; - private final static double SPACE_RATE = 0.65; + private final static double SPACE_RATE = 0.65; private final static int PARAGRAPH_RATE = 20; - + private enum Step { - WORD_GROUP1, WORD_GROUP2, WORD_GROUP3, WORD_GROUP4, RANDOMIZE_COMMA, + WORD_GROUP1, WORD_GROUP2, WORD_GROUP3, WORD_GROUP4, RANDOMIZE_COMMA, RANDOMIZE_WHITESPACE, RANDOMIZE_COUNTERS - } + } public void play() { showIntro(); startGame(); - } // End of method play - - private void showIntro() { - + } // End of method play + + private void showIntro() { + System.out.println(" ".repeat(29) + "POETRY"); System.out.println(" ".repeat(14) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); System.out.println("\n\n"); + + } // End of method showIntro - } // End of method showIntro - - private void startGame() { - + private void startGame() { + int groupIndex = 0; int paragraphIndex = 0; int punctuationIndex = 0; int wordIndex = 1; - + Step nextStep = Step.WORD_GROUP1; - // Begin outer while loop + // Begin outer while loop while (true) { - + switch (nextStep) { case WORD_GROUP1: - + if (wordIndex == 1) { - + System.out.print("MIDNIGHT DREARY"); nextStep = Step.RANDOMIZE_COMMA; - + } else if (wordIndex == 2) { - + System.out.print("FIERY EYES"); nextStep = Step.RANDOMIZE_COMMA; - + } else if (wordIndex == 3) { - + System.out.print("BIRD OR FIEND"); - nextStep = Step.RANDOMIZE_COMMA; - + nextStep = Step.RANDOMIZE_COMMA; + } else if (wordIndex == 4) { - + System.out.print("THING OF EVIL"); - nextStep = Step.RANDOMIZE_COMMA; - + nextStep = Step.RANDOMIZE_COMMA; + } else if (wordIndex == 5) { - + System.out.print("PROPHET"); - nextStep = Step.RANDOMIZE_COMMA; - } + nextStep = Step.RANDOMIZE_COMMA; + } break; - + case WORD_GROUP2: - + if (wordIndex == 1) { - + System.out.print("BEGUILING ME"); nextStep = Step.RANDOMIZE_COMMA; - + } else if (wordIndex == 2) { - + System.out.print("THRILLED ME"); nextStep = Step.RANDOMIZE_COMMA; - + } else if (wordIndex == 3) { - + System.out.print("STILL SITTING...."); - nextStep = Step.RANDOMIZE_WHITESPACE; - + nextStep = Step.RANDOMIZE_WHITESPACE; + } else if (wordIndex == 4) { - + System.out.print("NEVER FLITTING"); - nextStep = Step.RANDOMIZE_COMMA; - + nextStep = Step.RANDOMIZE_COMMA; + } else if (wordIndex == 5) { - + System.out.print("BURNED"); - nextStep = Step.RANDOMIZE_COMMA; - } + nextStep = Step.RANDOMIZE_COMMA; + } break; case WORD_GROUP3: - + if (wordIndex == 1) { - + System.out.print("AND MY SOUL"); nextStep = Step.RANDOMIZE_COMMA; - + } else if (wordIndex == 2) { - + System.out.print("DARKNESS THERE"); nextStep = Step.RANDOMIZE_COMMA; - + } else if (wordIndex == 3) { - + System.out.print("SHALL BE LIFTED"); - nextStep = Step.RANDOMIZE_COMMA; - + nextStep = Step.RANDOMIZE_COMMA; + } else if (wordIndex == 4) { - + System.out.print("QUOTH THE RAVEN"); - nextStep = Step.RANDOMIZE_COMMA; - + nextStep = Step.RANDOMIZE_COMMA; + } else if (wordIndex == 5) { - + if (punctuationIndex != 0) { - - System.out.print("SIGN OF PARTING"); - } - - nextStep = Step.RANDOMIZE_COMMA; - } - break; - + + System.out.print("SIGN OF PARTING"); + } + + nextStep = Step.RANDOMIZE_COMMA; + } + break; + case WORD_GROUP4: - + if (wordIndex == 1) { - + System.out.print("NOTHING MORE"); nextStep = Step.RANDOMIZE_COMMA; - + } else if (wordIndex == 2) { - + System.out.print("YET AGAIN"); nextStep = Step.RANDOMIZE_COMMA; - + } else if (wordIndex == 3) { - + System.out.print("SLOWLY CREEPING"); - nextStep = Step.RANDOMIZE_WHITESPACE; - + nextStep = Step.RANDOMIZE_WHITESPACE; + } else if (wordIndex == 4) { - + System.out.print("...EVERMORE"); - nextStep = Step.RANDOMIZE_COMMA; - + nextStep = Step.RANDOMIZE_COMMA; + } else if (wordIndex == 5) { - + System.out.print("NEVERMORE"); - nextStep = Step.RANDOMIZE_COMMA; - } - break; - + nextStep = Step.RANDOMIZE_COMMA; + } + break; + case RANDOMIZE_COMMA: - + // Insert commas if ((punctuationIndex != 0) && (Math.random() <= COMMA_RATE)) { - + System.out.print(","); - punctuationIndex = 2; - } + punctuationIndex = 2; + } nextStep = Step.RANDOMIZE_WHITESPACE; break; - - + + case RANDOMIZE_WHITESPACE: // Insert spaces if (Math.random() <= SPACE_RATE) { - - System.out.print(" "); - punctuationIndex++; - - } + + System.out.print(" "); + punctuationIndex++; + + } // Insert newlines - else { - + else { + System.out.println(""); - punctuationIndex = 0; - } + punctuationIndex = 0; + } nextStep = Step.RANDOMIZE_COUNTERS; break; - + case RANDOMIZE_COUNTERS: - + wordIndex = (int)((int)(10 * Math.random()) / 2) + 1; - + groupIndex++; paragraphIndex++; - + if ((punctuationIndex == 0) && (groupIndex % 2 == 0)) { - - System.out.print(" "); + + System.out.print(" "); } - + if (groupIndex == 1) { - - nextStep = Step.WORD_GROUP1; - + + nextStep = Step.WORD_GROUP1; + } else if (groupIndex == 2) { - + nextStep = Step.WORD_GROUP2; - + } else if (groupIndex == 3) { - + nextStep = Step.WORD_GROUP3; - + } else if (groupIndex == 4) { - + nextStep = Step.WORD_GROUP4; - + } else if (groupIndex == 5) { - + groupIndex = 0; System.out.println(""); - + if (paragraphIndex > PARAGRAPH_RATE) { - + System.out.println(""); punctuationIndex = 0; paragraphIndex = 0; - nextStep = Step.WORD_GROUP2; - + nextStep = Step.WORD_GROUP2; + } else { - - nextStep = Step.RANDOMIZE_COUNTERS; - } + + nextStep = Step.RANDOMIZE_COUNTERS; + } } - break; - + break; + default: System.out.println("INVALID STEP"); - break; - } - - } // End outer while loop - + break; + } + + } // End outer while loop + } // End of method startGame - + public static void main(String[] args) { - + Poetry poetry = new Poetry(); poetry.play(); - + } // End of method main } // End of class Poetry diff --git a/70_Poetry/javascript/poetry.html b/70_Poetry/javascript/poetry.html index 0da55e53f..01dd59bfe 100644 --- a/70_Poetry/javascript/poetry.html +++ b/70_Poetry/javascript/poetry.html @@ -1,10 +1,9 @@ POETRY - -

    
    +
    
     
     
     
    diff --git a/70_Poetry/javascript/poetry.js b/70_Poetry/javascript/poetry.js
    index 612e2eedc..885f1921d 100644
    --- a/70_Poetry/javascript/poetry.js
    +++ b/70_Poetry/javascript/poetry.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    @@ -50,9 +50,9 @@ async function main()
         print("\n");
         print("\n");
         print("\n");
    -
    +    
         times = 0;
    -
    +    
         i = 1;
         j = 1;
         k = 0;
    diff --git a/70_Poetry/kotlin/README.md b/70_Poetry/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/70_Poetry/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/70_Poetry/lua/README.md b/70_Poetry/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/70_Poetry/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/70_Poetry/pascal/README.md b/70_Poetry/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/70_Poetry/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/70_Poetry/perl/poetry.pl b/70_Poetry/perl/poetry.pl
    index 585915c49..610938b6c 100755
    --- a/70_Poetry/perl/poetry.pl
    +++ b/70_Poetry/perl/poetry.pl
    @@ -77,3 +77,5 @@
     Line270:
     print "\n"; $U=0; $K=0; goto Line110;
     exit;
    +
    +
    diff --git a/70_Poetry/poetry.bas b/70_Poetry/poetry.bas
    index 7fa3a1c40..3661287de 100644
    --- a/70_Poetry/poetry.bas
    +++ b/70_Poetry/poetry.bas
    @@ -1,8 +1,3 @@
    -5 Y=RND(-1)
    -6 REM FOR X = 1 TO 100
    -7 REM PRINT RND(1);","
    -8 REM NEXT X
    -9 REM GOTO 999
     10 PRINT TAB(30);"POETRY"
     20 PRINT TAB(15);"CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY"
     30 PRINT:PRINT:PRINT
    @@ -31,21 +26,17 @@
     133 PRINT "SLOWLY CREEPING";:GOTO 210
     134 PRINT "...EVERMORE";:GOTO 210
     135 PRINT "NEVERMORE";
    -210 GOSUB 500 : IF U=0 OR X>.19 THEN 212
    +210 IF U=0 OR RND(1)>.19 THEN 212
     211 PRINT ",";:U=2
    -212 GOSUB 500 : IF X>.65 THEN 214
    +212 IF RND(1)>.65 THEN 214
     213 PRINT " ";:U=U+1:GOTO 215
     214 PRINT : U=0
    -215 GOSUB 500 : I=INT(INT(10*X)/2)+1
    +215 I=INT(INT(10*RND(1))/2)+1
     220 J=J+1 : K=K+1
    -225 REM PRINT "I=";I;"; J=";J;"; K=";K;"; U=";U
     230 IF U>0 OR INT(J/2)<>J/2 THEN 240
     235 PRINT "     ";
     240 ON J GOTO 90,110,120,130,250
     250 J=0 : PRINT : IF K>20 THEN 270
     260 GOTO 215
     270 PRINT : U=0 : K=0 : GOTO 110
    -500 X = RND(1)
    -505 REM PRINT "#";X;"#"
    -510 RETURN
     999 END
    diff --git a/70_Poetry/poetry.pl b/70_Poetry/poetry.pl
    new file mode 100755
    index 000000000..610938b6c
    --- /dev/null
    +++ b/70_Poetry/poetry.pl
    @@ -0,0 +1,81 @@
    +#!/usr/bin/perl
    +#use strict;
    +# Automatic converted by bas2perl.pl
    +# Too much spaguetti code to be properly converted.
    +
    +
    +print ' 'x 30 . "POETRY\n";
    +print ' 'x 15 . "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n";
    +print "\n"; print "\n"; print "\n";
    +Line90:
    +if ($I==1) { goto Line100; } elsif ($I==2) { goto Line101; } elsif ($I==3) { goto Line102; } elsif ($I==4) { goto Line103; } elsif ($I==5) { goto Line104; } ;
    +Line100:
    +print "MIDNIGHT DREARY"; goto Line210;
    +Line101:
    +print "FIERY EYES"; goto Line210;
    +Line102:
    +print "BIRD OR FIEND"; goto Line210;
    +Line103:
    +print "THING OF EVIL"; goto Line210;
    +Line104:
    +print "PROPHET"; goto Line210;
    +Line110:
    +if ($I==1) { goto Line111; } elsif ($I==2) { goto Line112; } elsif ($I==3) { goto Line113; } elsif ($I==4) { goto Line114; } elsif ($I==5) { goto Line115; } ;
    +Line111:
    +print "BEGUILING ME"; $U=2; goto Line210;
    +Line112:
    +print "THRILLED ME"; goto Line210;
    +Line113:
    +print "STILL SITTING...."; goto Line212;
    +Line114:
    +print "NEVER FLITTING"; $U=2; goto Line210;
    +Line115:
    +print "BURNED"; goto Line210;
    +Line120:
    +if ($I==1) { goto Line121; } elsif ($I==2) { goto Line122; } elsif ($I==3) { goto Line123; } elsif ($I==4) { goto Line124; } elsif ($I==5) { goto Line125; } ;
    +Line121:
    +print "AND MY SOUL"; goto Line210;
    +Line122:
    +print "DARKNESS THERE"; goto Line210;
    +Line123:
    +print "SHALL BE LIFTED"; goto Line210;
    +Line124:
    +print "QUOTH THE RAVEN"; goto Line210;
    +Line125:
    +if ($U==0) { goto Line210; }
    +print "SIGN OF PARTING"; goto Line210;
    +Line130:
    +if ($I==1) { goto Line131; } elsif ($I==2) { goto Line132; } elsif ($I==3) { goto Line133; } elsif ($I==4) { goto Line134; } elsif ($I==5) { goto Line135; } ;
    +Line131:
    +print "NOTHING MORE"; goto Line210;
    +Line132:
    +print "YET AGAIN"; goto Line210;
    +Line133:
    +print "SLOWLY CREEPING"; goto Line210;
    +Line134:
    +print "...EVERMORE"; goto Line210;
    +Line135:
    +print "NEVERMORE";
    +Line210:
    +if ($U==0 || rand(1)>.19) { goto Line212; }
    +print ","; $U=2;
    +Line212:
    +if (rand(1)>.65) { goto Line214; }
    +print " "; $U=$U+1; goto Line215;
    +Line214:
    +print "\n"; $U=0;
    +Line215:
    +$I=int(int(10*rand(1))/2)+1;
    +$J=$J+1; $K=$K+1;
    +if ($U>0 || int($J/2)!=$J/2) { goto Line240; }
    +print " ";
    +Line240:
    +if ($J==1) { goto Line90; } elsif ($J==2) { goto Line110; } elsif ($J==3) { goto Line120; } elsif ($J==4) { goto Line130; } elsif ($J==5) { goto Line250; } ;
    +Line250:
    +$J=0; print "\n"; if ($K>20) { goto Line270; }
    +goto Line215;
    +Line270:
    +print "\n"; $U=0; $K=0; goto Line110;
    +exit;
    +
    +
    diff --git a/70_Poetry/python/poetry.pl b/70_Poetry/python/poetry.pl
    deleted file mode 100644
    index 585915c49..000000000
    --- a/70_Poetry/python/poetry.pl
    +++ /dev/null
    @@ -1,79 +0,0 @@
    -#!/usr/bin/perl
    -#use strict;
    -# Automatic converted by bas2perl.pl
    -# Too much spaguetti code to be properly converted.
    -
    -
    -print ' 'x 30 . "POETRY\n";
    -print ' 'x 15 . "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n";
    -print "\n"; print "\n"; print "\n";
    -Line90:
    -if ($I==1) { goto Line100; } elsif ($I==2) { goto Line101; } elsif ($I==3) { goto Line102; } elsif ($I==4) { goto Line103; } elsif ($I==5) { goto Line104; } ;
    -Line100:
    -print "MIDNIGHT DREARY"; goto Line210;
    -Line101:
    -print "FIERY EYES"; goto Line210;
    -Line102:
    -print "BIRD OR FIEND"; goto Line210;
    -Line103:
    -print "THING OF EVIL"; goto Line210;
    -Line104:
    -print "PROPHET"; goto Line210;
    -Line110:
    -if ($I==1) { goto Line111; } elsif ($I==2) { goto Line112; } elsif ($I==3) { goto Line113; } elsif ($I==4) { goto Line114; } elsif ($I==5) { goto Line115; } ;
    -Line111:
    -print "BEGUILING ME"; $U=2; goto Line210;
    -Line112:
    -print "THRILLED ME"; goto Line210;
    -Line113:
    -print "STILL SITTING...."; goto Line212;
    -Line114:
    -print "NEVER FLITTING"; $U=2; goto Line210;
    -Line115:
    -print "BURNED"; goto Line210;
    -Line120:
    -if ($I==1) { goto Line121; } elsif ($I==2) { goto Line122; } elsif ($I==3) { goto Line123; } elsif ($I==4) { goto Line124; } elsif ($I==5) { goto Line125; } ;
    -Line121:
    -print "AND MY SOUL"; goto Line210;
    -Line122:
    -print "DARKNESS THERE"; goto Line210;
    -Line123:
    -print "SHALL BE LIFTED"; goto Line210;
    -Line124:
    -print "QUOTH THE RAVEN"; goto Line210;
    -Line125:
    -if ($U==0) { goto Line210; }
    -print "SIGN OF PARTING"; goto Line210;
    -Line130:
    -if ($I==1) { goto Line131; } elsif ($I==2) { goto Line132; } elsif ($I==3) { goto Line133; } elsif ($I==4) { goto Line134; } elsif ($I==5) { goto Line135; } ;
    -Line131:
    -print "NOTHING MORE"; goto Line210;
    -Line132:
    -print "YET AGAIN"; goto Line210;
    -Line133:
    -print "SLOWLY CREEPING"; goto Line210;
    -Line134:
    -print "...EVERMORE"; goto Line210;
    -Line135:
    -print "NEVERMORE";
    -Line210:
    -if ($U==0 || rand(1)>.19) { goto Line212; }
    -print ","; $U=2;
    -Line212:
    -if (rand(1)>.65) { goto Line214; }
    -print " "; $U=$U+1; goto Line215;
    -Line214:
    -print "\n"; $U=0;
    -Line215:
    -$I=int(int(10*rand(1))/2)+1;
    -$J=$J+1; $K=$K+1;
    -if ($U>0 || int($J/2)!=$J/2) { goto Line240; }
    -print " ";
    -Line240:
    -if ($J==1) { goto Line90; } elsif ($J==2) { goto Line110; } elsif ($J==3) { goto Line120; } elsif ($J==4) { goto Line130; } elsif ($J==5) { goto Line250; } ;
    -Line250:
    -$J=0; print "\n"; if ($K>20) { goto Line270; }
    -goto Line215;
    -Line270:
    -print "\n"; $U=0; $K=0; goto Line110;
    -exit;
    diff --git a/70_Poetry/python/poetry.py b/70_Poetry/python/poetry.py
    index f261db375..9e9a1af16 100644
    --- a/70_Poetry/python/poetry.py
    +++ b/70_Poetry/python/poetry.py
    @@ -6,54 +6,61 @@
     Ported by Dave LeCompte
     """
     
    -import random
    -from dataclasses import dataclass
    +"""
    +PORTING EDITORIAL NOTE:
     
    -PAGE_WIDTH = 64
    +The original code is a pretty convoluted mesh of GOTOs and global
    +state. This adaptation pulls things apart into phrases, but I have
    +left the variables as globals, which makes goes against decades of
    +wisdom that global state is bad.
    +"""
     
    +PAGE_WIDTH = 64
     
    -@dataclass
    -class State:
    -    u: int = 0
    -    i: int = 0
    -    j: int = 0
    -    k: int = 0
    -    phrase: int = 1
    -    line: str = ""
    +import random
     
    +# globals
    +u = 0
    +i = 0
    +j = 0
    +k = 0
    +phrase = 1
    +line = ""
     
    -def print_centered(msg: str) -> None:
    +def print_centered(msg):
         spaces = " " * ((PAGE_WIDTH - len(msg)) // 2)
    -    print(spaces + msg)
    +    print (spaces + msg)
     
    +def process_phrase_1():
    +    global line
    +    
    +    line_1_options = ["MIDNIGHT DREARY",
    +                      "FIERY EYES",
    +                      "BIRD OR FIEND",
    +                      "THING OF EVIL",
    +                      "PROPHET"]
     
    -def process_phrase_1(state: State) -> str:
    -    line_1_options = [
    -        "MIDNIGHT DREARY",
    -        "FIERY EYES",
    -        "BIRD OR FIEND",
    -        "THING OF EVIL",
    -        "PROPHET",
    -    ]
    -    state.line = state.line + line_1_options[state.i]
    -    return state.line
    +    line = line + line_1_options[i]
    +    return line
     
    +def process_phrase_2():
    +    global line
    +    global u
     
    -def process_phrase_2(state: State) -> None:
         line_2_options = [
             ("BEGUILING ME", 2),
             ("THRILLED ME", None),
             ("STILL SITTING....", None),
             ("NEVER FLITTING", 2),
    -        ("BURNED", None),
    -    ]
    -    words, u_modifier = line_2_options[state.i]
    -    state.line += words
    -    if u_modifier is not None:
    -        state.u = u_modifier
    +        ("BURNED", None)]
    +    words, u_modifier = line_2_options[i]
    +    line += words
    +    if not (u_modifier is None):
    +        u = u_modifier
     
    +def process_phrase_3():
    +    global line
     
    -def process_phrase_3(state: State) -> None:
         phrases = [
             (False, "AND MY SOUL"),
             (False, "DARKNESS THERE"),
    @@ -62,81 +69,92 @@ def process_phrase_3(state: State) -> None:
             (True, "SIGN OF PARTING"),
         ]
     
    -    only_if_u, words = phrases[state.i]
    -    if (not only_if_u) or (state.u > 0):
    -        state.line = state.line + words
    +    only_if_u, words = phrases[i]
    +    if (not only_if_u) or (u > 0):
    +        line = line + words
     
    +def process_phrase_4():
    +    global line
     
    -def process_phrase_4(state: State) -> None:
         phrases = [
             ("NOTHING MORE"),
             ("YET AGAIN"),
             ("SLOWLY CREEPING"),
             ("...EVERMORE"),
    -        ("NEVERMORE"),
    -    ]
    +        ("NEVERMORE")]
     
    -    state.line += phrases[state.i]
    +    line += phrases[i]
     
    +def maybe_comma():
    +    # line 210
    +    global u
    +    global line
     
    -def maybe_comma(state: State) -> None:
    -    if len(state.line) > 0 and state.line[-1] == ".":
    +    if len(line) > 0 and line[-1] == ".":
             # don't follow a period with a comma, ever
             return
     
    -    if state.u != 0 and random.random() <= 0.19:
    -        state.line += ", "
    -        state.u = 2
    +    if u != 0 and random.random() <= 0.19:
    +        line += ", "
    +        u = 2
    +    # line 212
         if random.random() <= 0.65:
    -        state.line += " "
    -        state.u += 1
    +        line += " "
    +        u += 1
         else:
    -        print(state.line)
    -        state.line = ""
    -        state.u = 0
    -
    -
    -def pick_phrase(state: State) -> None:
    -    state.i = random.randint(0, 4)
    -    state.j += 1
    -    state.k += 1
    -
    -    if state.u <= 0 and (state.j % 2) != 0:
    +        # line 214
    +        print(line)
    +        line = ""
    +        u = 0
    +
    +
    +def pick_phrase():
    +    global phrase
    +    global line
    +    global i, j, k
    +    
    +    i = random.randint(0, 4)
    +    j += 1
    +    k += 1
    +
    +    if u <= 0 and (j % 2) != 0:
             # random indentation is fun!
    -        state.line += " " * 5
    -    state.phrase = state.j + 1
    +        line += " " * 5
    +    phrase = j + 1
    +    
     
    -
    -def main() -> None:
    +def main():
         print_centered("POETRY")
    -    print_centered("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n")
    +    print_centered("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
    +    print()
    +    print()
    +    print()
     
    -    state = State()
    +    global line, phrase, j, k, u
     
         phrase_processors = {
             1: process_phrase_1,
             2: process_phrase_2,
             3: process_phrase_3,
    -        4: process_phrase_4,
    +        4: process_phrase_4
         }
    -
    +    
         while True:
    -        if state.phrase >= 1 and state.phrase <= 4:
    -            phrase_processors[state.phrase](state)
    -            maybe_comma(state)
    -        elif state.phrase == 5:
    -            state.j = 0
    -            print(state.line)
    -            state.line = ""
    -            if state.k > 20:
    +        if phrase >= 1 and phrase <= 4:
    +            phrase_processors[phrase]()
    +            maybe_comma()
    +        elif phrase == 5:
    +            j = 0
    +            print(line)
    +            line = ""
    +            if k > 20:
                     print()
    -                state.u = 0
    -                state.k = 0
    +                u = 0
    +                k = 0
                 else:
    -                state.phrase = 2
    +                phrase = 2
                     continue
    -        pick_phrase(state)
    -
    -
    +        pick_phrase()
    +            
     if __name__ == "__main__":
         main()
    diff --git a/70_Poetry/ruby/poetry.rb b/70_Poetry/ruby/poetry.rb
    deleted file mode 100644
    index 4fe6afd33..000000000
    --- a/70_Poetry/ruby/poetry.rb
    +++ /dev/null
    @@ -1,141 +0,0 @@
    -PAGE_WIDTH = 64
    -
    -class State
    -    attr_accessor :u, :i, :j, :k, :phrase, :line
    -
    -    def initialize
    -        self.u = 0
    -        self.i = 0
    -        self.j = 0
    -        self.k = 0
    -        self.phrase = 1
    -        self.line = ""
    -    end
    -end
    -
    -
    -def print_centered msg
    -    spaces = " " * ((PAGE_WIDTH - msg.length).fdiv(2))
    -    print(spaces + msg)
    -end
    -
    -def process_phrase_1 state
    -    line_1_options = [
    -        "MIDNIGHT DREARY",
    -        "FIERY EYES",
    -        "BIRD OR FIEND",
    -        "THING OF EVIL",
    -        "PROPHET"
    -    ]
    -
    -    state.line = state.line + line_1_options[state.i]
    -    return state.line
    -end
    -
    -def process_phrase_2 state
    -    line_2_options = [
    -        ["BEGUILING ME", 2],
    -        ["THRILLED ME", nil],
    -        ["STILL SITTING....", nil],
    -        ["NEVER FLITTING", 2],
    -        ["BURNED", nil]
    -    ]
    -    words, u_modifier = line_2_options[state.i]
    -    state.line += words
    -    if !u_modifier.nil?
    -        state.u = u_modifier
    -    end
    -end
    -
    -def process_phrase_3 state
    -    phrases = [
    -        [false, "AND MY SOUL"],
    -        [false, "DARKNESS THERE"],
    -        [false, "SHALL BE LIFTED"],
    -        [false, "QUOTH THE RAVEN"],
    -        [true, "SIGN OF PARTING"]
    -    ]
    -
    -    only_if_u, words = phrases[state.i]
    -    if !only_if_u || state.u > 0
    -        state.line = state.line + words
    -    end
    -end
    -
    -def process_phrase_4 state
    -    phrases = [
    -        "NOTHING MORE",
    -        "YET AGAIN",
    -        "SLOWLY CREEPING",
    -        "...EVERMORE",
    -        "NEVERMORE"
    -    ]
    -
    -    state.line += phrases[state.i]
    -end
    -
    -def maybe_comma state
    -    if state.line.length > 0 && state.line[-1] == "."
    -        return
    -    end
    -
    -    if state.u != 0 && Random.rand <= 0.19
    -        state.line += ", "
    -        state.u = 2
    -    end
    -
    -    if Random.rand <= 0.65
    -        state.line += " "
    -        state.u += 1
    -    else
    -        puts state.line
    -        state.line = ""
    -        state.u = 0
    -    end
    -end
    -
    -def pick_phrase state
    -    state.i = Random.rand(0..4)
    -    state.j += 1
    -    state.k += 1
    -
    -    if state.u <= 0 && (state.j % 2) != 0
    -        state.line += (" " * 5)
    -    end
    -    state.phrase = state.j + 1
    -end
    -
    -def main
    -    print_centered("POETRY")
    -    state = State.new
    -    phrase_processors = {
    -        '1' => 'process_phrase_1',
    -        '2' => 'process_phrase_2',
    -        '3' => 'process_phrase_3',
    -        '4' => 'process_phrase_4'
    -    }
    -
    -    while true
    -        if state.phrase >= 1 && state.phrase <= 4
    -            method(phrase_processors[state.phrase.to_s]).call(state)
    -            maybe_comma state
    -        elsif state.phrase == 5
    -            state.j = 0
    -            puts state.line
    -            state.line = ""
    -            if state.k > 20
    -                puts ""
    -                state.u = 0
    -                state.k = 0
    -            else
    -                state.phrase = 2
    -                next
    -            end
    -        end
    -        pick_phrase state
    -    end
    -end
    -
    -if __FILE__ == $0
    -    main
    -end
    \ No newline at end of file
    diff --git a/70_Poetry/vbnet/Poetry.sln b/70_Poetry/vbnet/Poetry.sln
    deleted file mode 100644
    index 8e2355143..000000000
    --- a/70_Poetry/vbnet/Poetry.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index fc71a15e9..000000000
    --- a/70_Poetry/vbnet/Poetry.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Poetry
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/71_Poker/README.md b/71_Poker/README.md
    index 08bc04c63..1bad96d60 100644
    --- a/71_Poker/README.md
    +++ b/71_Poker/README.md
    @@ -14,18 +14,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Known Bugs
    -
    -- If you bet more than the computer has, it will still see you, resulting in a negative balance.  (To handle this properly, the computer would need to go "all in" and reduce your bet to an amount it can match; or else lose the game, which is what happens to the human player in the same situation.)
    -
    -- If you are low on cash and sell your watch, then make a bet much smaller than the amount you just gained from the watch, it sometimes nonetheless tells you you "blew your wad" and ends the game.
    -
    -- When the watch is sold (in either direction), the buyer does not actually lose any money.
    -
    -- The code in the program about selling your tie tack is unreachable due to a logic bug.
    -
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/71_Poker/csharp/Cards/Card.cs b/71_Poker/csharp/Cards/Card.cs
    deleted file mode 100644
    index d31762130..000000000
    --- a/71_Poker/csharp/Cards/Card.cs
    +++ /dev/null
    @@ -1,11 +0,0 @@
    -namespace Poker.Cards;
    -
    -internal record struct Card (Rank Rank, Suit Suit)
    -{
    -    public override string ToString() => $"{Rank} of {Suit}";
    -
    -    public static bool operator <(Card x, Card y) => x.Rank < y.Rank;
    -    public static bool operator >(Card x, Card y) => x.Rank > y.Rank;
    -
    -    public static int operator -(Card x, Card y) => x.Rank - y.Rank;
    -}
    diff --git a/71_Poker/csharp/Cards/Deck.cs b/71_Poker/csharp/Cards/Deck.cs
    deleted file mode 100644
    index d3a101b49..000000000
    --- a/71_Poker/csharp/Cards/Deck.cs
    +++ /dev/null
    @@ -1,28 +0,0 @@
    -using static Poker.Cards.Rank;
    -
    -namespace Poker.Cards;
    -
    -internal class Deck
    -{
    -    private readonly Card[] _cards;
    -    private int _nextCard;
    -
    -    public Deck()
    -    {
    -        _cards = Ranks.SelectMany(r => Enum.GetValues().Select(s => new Card(r, s))).ToArray();
    -    }
    -
    -    public void Shuffle(IRandom _random)
    -    {
    -        for (int i = 0; i < _cards.Length; i++)
    -        {
    -            var j = _random.Next(_cards.Length);
    -            (_cards[i], _cards[j]) = (_cards[j], _cards[i]);
    -        }
    -        _nextCard = 0;
    -    }
    -
    -    public Card DealCard() => _cards[_nextCard++];
    -
    -    public Hand DealHand() => new Hand(Enumerable.Range(0, 5).Select(_ => DealCard()));
    -}
    diff --git a/71_Poker/csharp/Cards/Hand.cs b/71_Poker/csharp/Cards/Hand.cs
    deleted file mode 100644
    index 34c14ac45..000000000
    --- a/71_Poker/csharp/Cards/Hand.cs
    +++ /dev/null
    @@ -1,131 +0,0 @@
    -using System.Text;
    -using static Poker.Cards.HandRank;
    -namespace Poker.Cards;
    -
    -internal class Hand
    -{
    -    public static readonly Hand Empty = new Hand();
    -
    -    private readonly Card[] _cards;
    -
    -    private Hand()
    -    {
    -        _cards = Array.Empty();
    -        Rank = None;
    -    }
    -
    -    public Hand(IEnumerable cards)
    -        : this(cards, isAfterDraw: false)
    -    {
    -    }
    -
    -    private Hand(IEnumerable cards, bool isAfterDraw)
    -    {
    -        _cards = cards.ToArray();
    -        (Rank, HighCard, KeepMask) = Analyze();
    -
    -        IsWeak = Rank < PartialStraight
    -            || Rank == PartialStraight && isAfterDraw
    -            || Rank <= TwoPair && HighCard.Rank <= 6;
    -    }
    -
    -    public string Name => Rank.ToString(HighCard);
    -    public HandRank Rank { get; }
    -    public Card HighCard { get; }
    -    public int KeepMask { get; set; }
    -    public bool IsWeak { get; }
    -
    -    public Hand Replace(int cardNumber, Card newCard)
    -    {
    -        if (cardNumber < 1 || cardNumber > _cards.Length) { return this; }
    -
    -        _cards[cardNumber - 1] = newCard;
    -        return new Hand(_cards, isAfterDraw: true);
    -    }
    -
    -    private (HandRank, Card, int) Analyze()
    -    {
    -        var suitMatchCount = 0;
    -        for (var i = 0; i < _cards.Length; i++)
    -        {
    -            if (i < _cards.Length-1 && _cards[i].Suit == _cards[i+1].Suit)
    -            {
    -                suitMatchCount++;
    -            }
    -        }
    -        if (suitMatchCount == 4)
    -        {
    -            return (Flush, _cards[0], 0b11111);
    -        }
    -        var sortedCards = _cards.OrderBy(c => c.Rank).ToArray();
    -
    -        var handRank = Schmaltz;
    -        var keepMask = 0;
    -        Card highCard = default;
    -        for (var i = 0; i < sortedCards.Length - 1; i++)
    -        {
    -            var matchesNextCard = sortedCards[i].Rank == sortedCards[i+1].Rank;
    -            var matchesPreviousCard = i > 0 && sortedCards[i].Rank == sortedCards[i - 1].Rank;
    -
    -            if (matchesNextCard)
    -            {
    -                keepMask |= 0b11 << i;
    -                highCard = sortedCards[i];
    -                handRank = matchesPreviousCard switch
    -                {
    -                    _ when handRank < Pair => Pair,
    -                    true when handRank == Pair => Three,
    -                    _ when handRank == Pair => TwoPair,
    -                    _ when handRank == TwoPair => FullHouse,
    -                    true => Four,
    -                    _ => FullHouse
    -                };
    -            }
    -        }
    -        if (keepMask == 0)
    -        {
    -            if (sortedCards[3] - sortedCards[0] == 3)
    -            {
    -                keepMask=0b1111;
    -                handRank=PartialStraight;
    -            }
    -            if (sortedCards[4] - sortedCards[1] == 3)
    -            {
    -                if (handRank == PartialStraight)
    -                {
    -                    return (Straight, sortedCards[4], 0b11111);
    -                }
    -                handRank=PartialStraight;
    -                keepMask=0b11110;
    -            }
    -        }
    -        return handRank < PartialStraight
    -            ? (Schmaltz, sortedCards[4], 0b11000)
    -            : (handRank, highCard, keepMask);
    -    }
    -
    -    public override string ToString()
    -    {
    -        var sb = new StringBuilder();
    -        for (var i = 0; i < _cards.Length; i++)
    -        {
    -            var cardDisplay = $" {i+1} --  {_cards[i]}";
    -            // Emulates the effect of the BASIC PRINT statement using the ',' to align text to 14-char print zones
    -            sb.Append(cardDisplay.PadRight(cardDisplay.Length + 14 - cardDisplay.Length % 14));
    -            if (i % 2 == 1)
    -            {
    -                sb.AppendLine();
    -            }
    -        }
    -        sb.AppendLine();
    -        return sb.ToString();
    -    }
    -
    -    public static bool operator >(Hand x, Hand y) =>
    -        x.Rank > y.Rank ||
    -        x.Rank == y.Rank && x.HighCard > y.HighCard;
    -
    -    public static bool operator <(Hand x, Hand y) =>
    -        x.Rank < y.Rank ||
    -        x.Rank == y.Rank && x.HighCard < y.HighCard;
    -}
    diff --git a/71_Poker/csharp/Cards/HandRank.cs b/71_Poker/csharp/Cards/HandRank.cs
    deleted file mode 100644
    index 878746ee5..000000000
    --- a/71_Poker/csharp/Cards/HandRank.cs
    +++ /dev/null
    @@ -1,34 +0,0 @@
    -namespace Poker.Cards;
    -
    -internal class HandRank
    -{
    -    public static HandRank None = new(0, "");
    -    public static HandRank Schmaltz = new(1, "schmaltz, ", c => $"{c.Rank} high");
    -    public static HandRank PartialStraight = new(2, ""); // The original code does not assign a display string here
    -    public static HandRank Pair = new(3, "a pair of ", c => $"{c.Rank}'s");
    -    public static HandRank TwoPair = new(4, "two pair, ", c => $"{c.Rank}'s");
    -    public static HandRank Three = new(5, "three ", c => $"{c.Rank}'s");
    -    public static HandRank Straight = new(6, "straight", c => $"{c.Rank} high");
    -    public static HandRank Flush = new(7, "a flush in ", c => c.Suit.ToString());
    -    public static HandRank FullHouse = new(8, "full house, ", c => $"{c.Rank}'s");
    -    public static HandRank Four = new(9, "four ", c => $"{c.Rank}'s");
    -    // The original code does not detect a straight flush or royal flush
    -
    -    private readonly int _value;
    -    private readonly string _displayName;
    -    private readonly Func _suffixSelector;
    -
    -    private HandRank(int value, string displayName, Func? suffixSelector = null)
    -    {
    -        _value = value;
    -        _displayName = displayName;
    -        _suffixSelector = suffixSelector ?? (_ => "");
    -    }
    -
    -    public string ToString(Card highCard) => $"{_displayName}{_suffixSelector.Invoke(highCard)}";
    -
    -    public static bool operator >(HandRank x, HandRank y) => x._value > y._value;
    -    public static bool operator <(HandRank x, HandRank y) => x._value < y._value;
    -    public static bool operator >=(HandRank x, HandRank y) => x._value >= y._value;
    -    public static bool operator <=(HandRank x, HandRank y) => x._value <= y._value;
    -}
    diff --git a/71_Poker/csharp/Cards/Rank.cs b/71_Poker/csharp/Cards/Rank.cs
    deleted file mode 100644
    index cd44922a6..000000000
    --- a/71_Poker/csharp/Cards/Rank.cs
    +++ /dev/null
    @@ -1,50 +0,0 @@
    -namespace Poker.Cards;
    -
    -internal struct Rank : IComparable
    -{
    -    public static IEnumerable Ranks => new[]
    -    {
    -        Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King, Ace
    -    };
    -
    -    public static Rank Two = new(2);
    -    public static Rank Three = new(3);
    -    public static Rank Four = new(4);
    -    public static Rank Five = new(5);
    -    public static Rank Six = new(6);
    -    public static Rank Seven = new(7);
    -    public static Rank Eight = new(8);
    -    public static Rank Nine = new(9);
    -    public static Rank Ten = new(10);
    -    public static Rank Jack = new(11, "Jack");
    -    public static Rank Queen = new(12, "Queen");
    -    public static Rank King = new(13, "King");
    -    public static Rank Ace = new(14, "Ace");
    -
    -    private readonly int _value;
    -    private readonly string _name;
    -
    -    private Rank(int value, string? name = null)
    -    {
    -        _value = value;
    -        _name = name ?? $" {value} ";
    -    }
    -
    -    public override string ToString() => _name;
    -
    -    public int CompareTo(Rank other) => this - other;
    -
    -    public static bool operator <(Rank x, Rank y) => x._value < y._value;
    -    public static bool operator >(Rank x, Rank y) => x._value > y._value;
    -    public static bool operator ==(Rank x, Rank y) => x._value == y._value;
    -    public static bool operator !=(Rank x, Rank y) => x._value != y._value;
    -
    -    public static int operator -(Rank x, Rank y) => x._value - y._value;
    -
    -    public static bool operator <=(Rank rank, int value) => rank._value <= value;
    -    public static bool operator >=(Rank rank, int value) => rank._value >= value;
    -
    -    public override bool Equals(object? obj) => obj is Rank other && this == other;
    -
    -    public override int GetHashCode() => _value.GetHashCode();
    -}
    diff --git a/71_Poker/csharp/Cards/Suit.cs b/71_Poker/csharp/Cards/Suit.cs
    deleted file mode 100644
    index 0a246999f..000000000
    --- a/71_Poker/csharp/Cards/Suit.cs
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -namespace Poker.Cards;
    -
    -internal enum Suit
    -{
    -    Clubs,
    -    Diamonds,
    -    Hearts,
    -    Spades
    -}
    diff --git a/71_Poker/csharp/Game.cs b/71_Poker/csharp/Game.cs
    deleted file mode 100644
    index c7621a36c..000000000
    --- a/71_Poker/csharp/Game.cs
    +++ /dev/null
    @@ -1,33 +0,0 @@
    -using Poker.Cards;
    -using Poker.Players;
    -using Poker.Resources;
    -
    -namespace Poker;
    -
    -internal class Game
    -{
    -    private readonly IReadWrite _io;
    -    private readonly IRandom _random;
    -
    -    public Game(IReadWrite io, IRandom random)
    -    {
    -        _io = io;
    -        _random = random;
    -    }
    -
    -    internal void Play()
    -    {
    -        _io.Write(Resource.Streams.Title);
    -        _io.Write(Resource.Streams.Instructions);
    -
    -        var deck = new Deck();
    -        var human = new Human(200, _io);
    -        var computer = new Computer(200, _io, _random);
    -        var table = new Table(_io, _random, deck, human, computer);
    -
    -        do
    -        {
    -            table.PlayHand();
    -        } while (table.ShouldPlayAnotherHand());
    -    }
    -}
    diff --git a/71_Poker/csharp/IReadWriteExtensions.cs b/71_Poker/csharp/IReadWriteExtensions.cs
    deleted file mode 100644
    index 7559a3289..000000000
    --- a/71_Poker/csharp/IReadWriteExtensions.cs
    +++ /dev/null
    @@ -1,48 +0,0 @@
    -using Poker.Strategies;
    -using static System.StringComparison;
    -
    -namespace Poker;
    -
    -internal static class IReadWriteExtensions
    -{
    -    internal static bool ReadYesNo(this IReadWrite io, string prompt)
    -    {
    -        while (true)
    -        {
    -            var response = io.ReadString(prompt);
    -            if (response.Equals("YES", InvariantCultureIgnoreCase)) { return true; }
    -            if (response.Equals("NO", InvariantCultureIgnoreCase)) { return false; }
    -            io.WriteLine("Answer Yes or No, please.");
    -        }
    -    }
    -
    -    internal static float ReadNumber(this IReadWrite io) => io.ReadNumber("");
    -
    -    internal static int ReadNumber(this IReadWrite io, string prompt, int max, string maxPrompt)
    -    {
    -        io.Write(prompt);
    -        while (true)
    -        {
    -            var response = io.ReadNumber();
    -            if (response <= max) { return (int)response; }
    -            io.WriteLine(maxPrompt);
    -        }
    -    }
    -
    -    internal static Strategy ReadHumanStrategy(this IReadWrite io, bool noCurrentBets)
    -    {
    -        while(true)
    -        {
    -            io.WriteLine();
    -            var bet = io.ReadNumber("What is your bet");
    -            if (bet != (int)bet)
    -            {
    -                if (noCurrentBets && bet == .5) { return Strategy.Check; }
    -                io.WriteLine("No small change, please.");
    -                continue;
    -            }
    -            if (bet == 0) { return Strategy.Fold; }
    -            return Strategy.Bet(bet);
    -        }
    -    }
    -}
    \ No newline at end of file
    diff --git a/71_Poker/csharp/Players/Computer.cs b/71_Poker/csharp/Players/Computer.cs
    deleted file mode 100644
    index 5ab2e77d8..000000000
    --- a/71_Poker/csharp/Players/Computer.cs
    +++ /dev/null
    @@ -1,130 +0,0 @@
    -using Poker.Cards;
    -using Poker.Strategies;
    -using static System.StringComparison;
    -
    -namespace Poker.Players;
    -
    -internal class Computer : Player
    -{
    -    private readonly IReadWrite _io;
    -    private readonly IRandom _random;
    -
    -    public Computer(int bank, IReadWrite io, IRandom random)
    -        : base(bank)
    -    {
    -        _io = io;
    -        _random = random;
    -        Strategy = Strategy.None;
    -    }
    -
    -    public Strategy Strategy { get; set; }
    -
    -    public override void NewHand()
    -    {
    -        base.NewHand();
    -
    -        Strategy = (Hand.IsWeak, Hand.Rank < HandRank.Three, Hand.Rank < HandRank.FullHouse) switch
    -        {
    -            (true, _, _) when _random.Next(10) < 2 => Strategy.Bluff(23, 0b11100),
    -            (true, _, _) when _random.Next(10) < 2 => Strategy.Bluff(23, 0b11110),
    -            (true, _, _) when _random.Next(10) < 1 => Strategy.Bluff(23, 0b11111),
    -            (true, _, _) => Strategy.Fold,
    -            (false, true, _) => _random.Next(10) < 2 ? Strategy.Bluff(23) : Strategy.Check,
    -            (false, false, true) => Strategy.Bet(35),
    -            (false, false, false) => _random.Next(10) < 1 ? Strategy.Bet(35) : Strategy.Raise
    -        };
    -    }
    -
    -    protected override void DrawCards(Deck deck)
    -    {
    -        var keepMask = Strategy.KeepMask ?? Hand.KeepMask;
    -        var count = 0;
    -        for (var i = 1; i <= 5; i++)
    -        {
    -            if ((keepMask & (1 << (i - 1))) == 0)
    -            {
    -                Hand = Hand.Replace(i, deck.DealCard());
    -                count++;
    -            }
    -        }
    -
    -        _io.WriteLine();
    -        _io.Write($"I am taking {count} card");
    -        if (count != 1)
    -        {
    -            _io.WriteLine("s");
    -        }
    -
    -        Strategy = (Hand.IsWeak, Hand.Rank < HandRank.Three, Hand.Rank < HandRank.FullHouse) switch
    -        {
    -            _ when Strategy is Bluff => Strategy.Bluff(28),
    -            (true, _, _) => Strategy.Fold,
    -            (false, true, _) => _random.Next(10) == 0 ? Strategy.Bet(19) : Strategy.Raise,
    -            (false, false, true) => _random.Next(10) == 0 ? Strategy.Bet(11) : Strategy.Bet(19),
    -            (false, false, false) => Strategy.Raise
    -        };
    -    }
    -
    -    public int GetWager(int wager)
    -    {
    -        wager += _random.Next(10);
    -        if (Balance < Table.Human.Bet + wager)
    -        {
    -            if (Table.Human.Bet == 0) { return Balance; }
    -
    -            if (Balance >= Table.Human.Bet)
    -            {
    -                _io.WriteLine("I'll see you.");
    -                Bet = Table.Human.Bet;
    -                Table.CollectBets();
    -            }
    -            else
    -            {
    -                RaiseFunds();
    -            }
    -        }
    -
    -        return wager;
    -    }
    -
    -    public bool TryBuyWatch()
    -    {
    -        if (!Table.Human.HasWatch) { return false; }
    -
    -        var response = _io.ReadString("Would you like to sell your watch");
    -        if (response.StartsWith("N", InvariantCultureIgnoreCase)) { return false; }
    -
    -        var (value, message) = (_random.Next(10) < 7) switch
    -        {
    -            true => (75, "I'll give you $75 for it."),
    -            false => (25, "That's a pretty crummy watch - I'll give you $25.")
    -        };
    -
    -        _io.WriteLine(message);
    -        Table.Human.SellWatch(value);
    -        // The original code does not have the computer part with any money
    -
    -        return true;
    -    }
    -
    -    public void RaiseFunds()
    -    {
    -        if (Table.Human.HasWatch) { return; }
    -
    -        var response = _io.ReadString("Would you like to buy back your watch for $50");
    -        if (response.StartsWith("N", InvariantCultureIgnoreCase)) { return; }
    -
    -        // The original code does not deduct $50 from the player
    -        Balance += 50;
    -        Table.Human.ReceiveWatch();
    -        IsBroke = true;
    -    }
    -
    -    public void CheckFunds() { IsBroke = Balance <= Table.Ante; }
    -
    -    public override void TakeWinnings()
    -    {
    -        _io.WriteLine("I win.");
    -        base.TakeWinnings();
    -    }
    -}
    diff --git a/71_Poker/csharp/Players/Human.cs b/71_Poker/csharp/Players/Human.cs
    deleted file mode 100644
    index ec3e7d3cd..000000000
    --- a/71_Poker/csharp/Players/Human.cs
    +++ /dev/null
    @@ -1,90 +0,0 @@
    -using Poker.Cards;
    -using Poker.Strategies;
    -
    -namespace Poker.Players;
    -
    -internal class Human : Player
    -{
    -    private readonly IReadWrite _io;
    -
    -    public Human(int bank, IReadWrite io)
    -        : base(bank)
    -    {
    -        HasWatch = true;
    -        _io = io;
    -    }
    -
    -    public bool HasWatch { get; set; }
    -
    -    protected override void DrawCards(Deck deck)
    -    {
    -        var count = _io.ReadNumber("How many cards do you want", 3, "You can't draw more than three cards.");
    -        if (count == 0) { return; }
    -
    -        _io.WriteLine("What are their numbers:");
    -        for (var i = 1; i <= count; i++)
    -        {
    -            Hand = Hand.Replace((int)_io.ReadNumber(), deck.DealCard());
    -        }
    -
    -        _io.WriteLine("Your new hand:");
    -        _io.Write(Hand);
    -    }
    -
    -    internal bool SetWager()
    -    {
    -        var strategy = _io.ReadHumanStrategy(Table.Computer.Bet == 0 && Bet == 0);
    -        if (strategy is Strategies.Bet or Check)
    -        {
    -            if (Bet + strategy.Value < Table.Computer.Bet)
    -            {
    -                _io.WriteLine("If you can't see my bet, then fold.");
    -                return false;
    -            }
    -            if (Balance - Bet - strategy.Value >= 0)
    -            {
    -                HasBet = true;
    -                Bet += strategy.Value;
    -                return true;
    -            }
    -            RaiseFunds();
    -        }
    -        else
    -        {
    -            Fold();
    -            Table.CollectBets();
    -        }
    -        return false;
    -    }
    -
    -    public void RaiseFunds()
    -    {
    -        _io.WriteLine();
    -        _io.WriteLine("You can't bet with what you haven't got.");
    -
    -        if (Table.Computer.TryBuyWatch()) { return; }
    -
    -        // The original program had some code about selling a tie tack, but due to a fault
    -        // in the logic the code was unreachable. I've omitted it in this port.
    -
    -        IsBroke = true;
    -    }
    -
    -    public void ReceiveWatch()
    -    {
    -        // In the original code the player does not pay any money to receive the watch back.
    -        HasWatch = true;
    -    }
    -
    -    public void SellWatch(int amount)
    -    {
    -        HasWatch = false;
    -        Balance += amount;
    -    }
    -
    -    public override void TakeWinnings()
    -    {
    -        _io.WriteLine("You win.");
    -        base.TakeWinnings();
    -    }
    -}
    diff --git a/71_Poker/csharp/Players/Player.cs b/71_Poker/csharp/Players/Player.cs
    deleted file mode 100644
    index 65e7e6855..000000000
    --- a/71_Poker/csharp/Players/Player.cs
    +++ /dev/null
    @@ -1,59 +0,0 @@
    -using Poker.Cards;
    -
    -namespace Poker.Players;
    -
    -internal abstract class Player
    -{
    -    private Table? _table;
    -    private bool _hasFolded;
    -
    -    protected Player(int bank)
    -    {
    -        Hand = Hand.Empty;
    -        Balance = bank;
    -    }
    -
    -    public Hand Hand { get; set; }
    -    public int Balance { get; set; }
    -    public bool HasBet { get; set; }
    -    public int Bet { get; set; }
    -    public bool HasFolded => _hasFolded;
    -    public bool IsBroke { get; protected set; }
    -
    -    protected Table Table =>
    -        _table ?? throw new InvalidOperationException("The player must be sitting at the table.");
    -
    -    public void Sit(Table table) => _table = table;
    -
    -    public virtual void NewHand()
    -    {
    -        Bet = 0;
    -        Hand = Table.Deck.DealHand();
    -        _hasFolded = false;
    -    }
    -
    -    public int AnteUp()
    -    {
    -        Balance -= Table.Ante;
    -        return Table.Ante;
    -    }
    -
    -    public void DrawCards()
    -    {
    -        Bet = 0;
    -        DrawCards(Table.Deck);
    -    }
    -
    -    protected abstract void DrawCards(Deck deck);
    -
    -    public virtual void TakeWinnings()
    -    {
    -        Balance += Table.Pot;
    -        Table.Pot = 0;
    -    }
    -
    -    public void Fold()
    -    {
    -        _hasFolded = true;
    -    }
    -}
    diff --git a/71_Poker/csharp/Poker.csproj b/71_Poker/csharp/Poker.csproj
    deleted file mode 100644
    index 3870320c9..000000000
    --- a/71_Poker/csharp/Poker.csproj
    +++ /dev/null
    @@ -1,17 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    -  
    -    
    -  
    -
    -  
    -    
    -  
    -
    diff --git a/71_Poker/csharp/Poker.sln b/71_Poker/csharp/Poker.sln
    deleted file mode 100644
    index 5dd63fffa..000000000
    --- a/71_Poker/csharp/Poker.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/csharp/Program.cs b/71_Poker/csharp/Program.cs
    deleted file mode 100644
    index c3200a960..000000000
    --- a/71_Poker/csharp/Program.cs
    +++ /dev/null
    @@ -1,5 +0,0 @@
    -global using Games.Common.IO;
    -global using Games.Common.Randomness;
    -global using Poker;
    -
    -new Game(new ConsoleIO(), new RandomNumberGenerator()).Play();
    \ No newline at end of file
    diff --git a/71_Poker/csharp/Resources/Instructions.txt b/71_Poker/csharp/Resources/Instructions.txt
    deleted file mode 100644
    index 7f82c07e5..000000000
    --- a/71_Poker/csharp/Resources/Instructions.txt
    +++ /dev/null
    @@ -1,5 +0,0 @@
    -Welcome to the casino.  We each have $200.
    -I will open the betting before the draw; you open after.
    -To fold bet 0; to check bet .5.
    -Enough talk -- Let's get down to business.
    -
    diff --git a/71_Poker/csharp/Resources/Resource.cs b/71_Poker/csharp/Resources/Resource.cs
    deleted file mode 100644
    index 0ceddb0dd..000000000
    --- a/71_Poker/csharp/Resources/Resource.cs
    +++ /dev/null
    @@ -1,17 +0,0 @@
    -using System.Reflection;
    -using System.Runtime.CompilerServices;
    -
    -namespace Poker.Resources;
    -
    -internal static class Resource
    -{
    -    internal static class Streams
    -    {
    -        public static Stream Instructions => GetStream();
    -        public static Stream Title => GetStream();
    -    }
    -
    -    private static Stream GetStream([CallerMemberName] string? name = null)
    -        => Assembly.GetExecutingAssembly().GetManifestResourceStream($"Poker.Resources.{name}.txt")
    -            ?? throw new ArgumentException($"Resource stream {name} does not exist", nameof(name));
    -}
    \ No newline at end of file
    diff --git a/71_Poker/csharp/Resources/Title.txt b/71_Poker/csharp/Resources/Title.txt
    deleted file mode 100644
    index 2f5c6aa23..000000000
    --- a/71_Poker/csharp/Resources/Title.txt
    +++ /dev/null
    @@ -1,5 +0,0 @@
    -                                  Poker
    -               Creative Computing  Morristown, New Jersey
    -
    -
    -
    diff --git a/71_Poker/csharp/Strategies/Bet.cs b/71_Poker/csharp/Strategies/Bet.cs
    deleted file mode 100644
    index 7299898d5..000000000
    --- a/71_Poker/csharp/Strategies/Bet.cs
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -namespace Poker.Strategies;
    -
    -internal class Bet : Strategy
    -{
    -    public Bet(int amount) => Value = amount;
    -
    -    public override int Value { get; }
    -}
    diff --git a/71_Poker/csharp/Strategies/Bluff.cs b/71_Poker/csharp/Strategies/Bluff.cs
    deleted file mode 100644
    index ed51e33ed..000000000
    --- a/71_Poker/csharp/Strategies/Bluff.cs
    +++ /dev/null
    @@ -1,12 +0,0 @@
    -namespace Poker.Strategies;
    -
    -internal class Bluff : Bet
    -{
    -    public Bluff(int amount, int? keepMask)
    -        : base(amount)
    -    {
    -        KeepMask = keepMask;
    -    }
    -
    -    public override int? KeepMask { get; }
    -}
    \ No newline at end of file
    diff --git a/71_Poker/csharp/Strategies/Check.cs b/71_Poker/csharp/Strategies/Check.cs
    deleted file mode 100644
    index 4bbab9735..000000000
    --- a/71_Poker/csharp/Strategies/Check.cs
    +++ /dev/null
    @@ -1,6 +0,0 @@
    -namespace Poker.Strategies;
    -
    -internal class Check : Strategy
    -{
    -    public override int Value => 0;
    -}
    diff --git a/71_Poker/csharp/Strategies/Fold.cs b/71_Poker/csharp/Strategies/Fold.cs
    deleted file mode 100644
    index 2ba31c33a..000000000
    --- a/71_Poker/csharp/Strategies/Fold.cs
    +++ /dev/null
    @@ -1,6 +0,0 @@
    -namespace Poker.Strategies;
    -
    -internal class Fold : Strategy
    -{
    -    public override int Value => -1;
    -}
    diff --git a/71_Poker/csharp/Strategies/None.cs b/71_Poker/csharp/Strategies/None.cs
    deleted file mode 100644
    index 4be351a8a..000000000
    --- a/71_Poker/csharp/Strategies/None.cs
    +++ /dev/null
    @@ -1,6 +0,0 @@
    -namespace Poker.Strategies;
    -
    -internal class None : Strategy
    -{
    -    public override int Value => -1;
    -}
    diff --git a/71_Poker/csharp/Strategies/Raise.cs b/71_Poker/csharp/Strategies/Raise.cs
    deleted file mode 100644
    index 7be9e5227..000000000
    --- a/71_Poker/csharp/Strategies/Raise.cs
    +++ /dev/null
    @@ -1,6 +0,0 @@
    -namespace Poker.Strategies;
    -
    -internal class Raise : Bet
    -{
    -    public Raise() : base(2) { }
    -}
    diff --git a/71_Poker/csharp/Strategies/Strategy.cs b/71_Poker/csharp/Strategies/Strategy.cs
    deleted file mode 100644
    index ae6c93d22..000000000
    --- a/71_Poker/csharp/Strategies/Strategy.cs
    +++ /dev/null
    @@ -1,15 +0,0 @@
    -namespace Poker.Strategies;
    -
    -internal abstract class Strategy
    -{
    -    public static Strategy None = new None();
    -    public static Strategy Fold = new Fold();
    -    public static Strategy Check = new Check();
    -    public static Strategy Raise = new Raise();
    -    public static Strategy Bet(float amount) => new Bet((int)amount);
    -    public static Strategy Bet(int amount) => new Bet(amount);
    -    public static Strategy Bluff(int amount, int? keepMask = null) => new Bluff(amount, keepMask);
    -
    -    public abstract int Value { get; }
    -    public virtual int? KeepMask { get; }
    -}
    diff --git a/71_Poker/csharp/Table.cs b/71_Poker/csharp/Table.cs
    deleted file mode 100644
    index da8198010..000000000
    --- a/71_Poker/csharp/Table.cs
    +++ /dev/null
    @@ -1,214 +0,0 @@
    -using Poker.Cards;
    -using Poker.Players;
    -using Poker.Strategies;
    -
    -namespace Poker;
    -
    -internal class Table
    -{
    -    private readonly IReadWrite _io;
    -    private readonly IRandom _random;
    -    public int Pot;
    -
    -    public Table(IReadWrite io, IRandom random, Deck deck, Human human, Computer computer)
    -    {
    -        _io = io;
    -        _random = random;
    -        Deck = deck;
    -        Human = human;
    -        Computer = computer;
    -
    -        human.Sit(this);
    -        computer.Sit(this);
    -    }
    -
    -    public int Ante { get; } = 5;
    -    public Deck Deck { get; }
    -    public Human Human { get; }
    -    public Computer Computer { get; }
    -
    -    internal void PlayHand()
    -    {
    -        while (true)
    -        {
    -            _io.WriteLine();
    -            Computer.CheckFunds();
    -            if (Computer.IsBroke) { return; }
    -
    -            _io.WriteLine($"The ante is ${Ante}.  I will deal:");
    -            _io.WriteLine();
    -            if (Human.Balance <= Ante)
    -            {
    -                Human.RaiseFunds();
    -                if (Human.IsBroke) { return; }
    -            }
    -
    -            Deal(_random);
    -
    -            _io.WriteLine();
    -            GetWagers("I'll open with ${0}", "I check.", allowRaiseAfterCheck: true);
    -            if (SomeoneIsBroke() || SomeoneHasFolded()) { return; }
    -
    -            Draw();
    -
    -            GetWagers();
    -            if (SomeoneIsBroke()) { return; }
    -            if (!Human.HasBet)
    -            {
    -                GetWagers("I'll bet ${0}", "I'll check");
    -            }
    -            if (SomeoneIsBroke() || SomeoneHasFolded()) { return; }
    -            if (GetWinner() is { } winner)
    -            {
    -                winner.TakeWinnings();
    -                return;
    -            }
    -        }
    -    }
    -
    -    private void Deal(IRandom random)
    -    {
    -        Deck.Shuffle(random);
    -
    -        Pot = Human.AnteUp() + Computer.AnteUp();
    -
    -        Human.NewHand();
    -        Computer.NewHand();
    -
    -        _io.WriteLine("Your hand:");
    -        _io.Write(Human.Hand);
    -    }
    -
    -    private void Draw()
    -    {
    -        _io.WriteLine();
    -        _io.Write("Now we draw -- ");
    -        Human.DrawCards();
    -        Computer.DrawCards();
    -        _io.WriteLine();
    -    }
    -
    -    private void GetWagers(string betFormat, string checkMessage, bool allowRaiseAfterCheck = false)
    -    {
    -        if (Computer.Strategy is Bet)
    -        {
    -            Computer.Bet = Computer.GetWager(Computer.Strategy.Value);
    -            if (Computer.IsBroke) { return; }
    -
    -            _io.WriteLine(betFormat, Computer.Bet);
    -        }
    -        else
    -        {
    -            _io.WriteLine(checkMessage);
    -            if (!allowRaiseAfterCheck) { return; }
    -        }
    -
    -        GetWagers();
    -    }
    -
    -    private void GetWagers()
    -    {
    -        while (true)
    -        {
    -            Human.HasBet = false;
    -            while (true)
    -            {
    -                if (Human.SetWager()) { break; }
    -                if (Human.IsBroke || Human.HasFolded) { return; }
    -            }
    -            if (Human.Bet == Computer.Bet)
    -            {
    -                CollectBets();
    -                return;
    -            }
    -            if (Computer.Strategy is Fold)
    -            {
    -                if (Human.Bet > 5)
    -                {
    -                    Computer.Fold();
    -                    _io.WriteLine("I fold.");
    -                    return;
    -                }
    -            }
    -            if (Human.Bet > 3 * Computer.Strategy.Value)
    -            {
    -                if (Computer.Strategy is not Raise)
    -                {
    -                    _io.WriteLine("I'll see you.");
    -                    Computer.Bet = Human.Bet;
    -                    CollectBets();
    -                    return;
    -                }
    -            }
    -
    -            var raise = Computer.GetWager(Human.Bet - Computer.Bet);
    -            if (Computer.IsBroke) { return; }
    -            _io.WriteLine($"I'll see you, and raise you {raise}");
    -            Computer.Bet = Human.Bet + raise;
    -        }
    -    }
    -
    -    internal void CollectBets()
    -    {
    -        Human.Balance -= Human.Bet;
    -        Computer.Balance -= Computer.Bet;
    -        Pot += Human.Bet + Computer.Bet;
    -    }
    -
    -    private bool SomeoneHasFolded()
    -    {
    -        if (Human.HasFolded)
    -        {
    -            _io.WriteLine();
    -            Computer.TakeWinnings();
    -        }
    -        else if (Computer.HasFolded)
    -        {
    -            _io.WriteLine();
    -            Human.TakeWinnings();
    -        }
    -        else
    -        {
    -            return false;
    -        }
    -
    -        Pot = 0;
    -        return true;
    -    }
    -
    -    private bool SomeoneIsBroke() => Human.IsBroke || Computer.IsBroke;
    -
    -    private Player? GetWinner()
    -    {
    -        _io.WriteLine();
    -        _io.WriteLine("Now we compare hands:");
    -        _io.WriteLine("My hand:");
    -        _io.Write(Computer.Hand);
    -        _io.WriteLine();
    -        _io.WriteLine($"You have {Human.Hand.Name}");
    -        _io.WriteLine($"and I have {Computer.Hand.Name}");
    -        if (Computer.Hand > Human.Hand) { return Computer; }
    -        if (Human.Hand > Computer.Hand) { return Human; }
    -        _io.WriteLine("The hand is drawn.");
    -        _io.WriteLine($"All $ {Pot} remains in the pot.");
    -        return null;
    -    }
    -
    -    internal bool ShouldPlayAnotherHand()
    -    {
    -        if (Computer.IsBroke)
    -        {
    -            _io.WriteLine("I'm busted.  Congratulations!");
    -            return true;
    -        }
    -
    -        if (Human.IsBroke)
    -        {
    -            _io.WriteLine("Your wad is shot.  So long, sucker!");
    -            return true;
    -        }
    -
    -        _io.WriteLine($"Now I have $ {Computer.Balance} and you have $ {Human.Balance}");
    -        return _io.ReadYesNo("Do you wish to continue");
    -    }
    -}
    \ No newline at end of file
    diff --git a/71_Poker/javascript/poker.html b/71_Poker/javascript/poker.html
    index 92758158a..c2abd4110 100644
    --- a/71_Poker/javascript/poker.html
    +++ b/71_Poker/javascript/poker.html
    @@ -1,10 +1,9 @@
     
     
     POKER
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/71_Poker/javascript/poker.js b/71_Poker/javascript/poker.js
    index 73f3c9f0d..105da0fa7 100644
    --- a/71_Poker/javascript/poker.js
    +++ b/71_Poker/javascript/poker.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    @@ -254,7 +254,7 @@ function evaluate_hand()
     function get_prompt(question, def)
     {
         var str;
    -
    +    
         str = window.prompt(question, def);
         print(question + "? " + str + "\n");
         return str;
    @@ -339,7 +339,7 @@ function computer_low_in_money()
     function ask_for_bet()
     {
         var forced;
    -
    +    
         if (t != Math.floor(t)) {
             if (k != 0 || g != 0 || t != 0.5) {
                 print("NO SMALL CHANGE, PLEASE.\n");
    diff --git a/71_Poker/kotlin/README.md b/71_Poker/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/71_Poker/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/71_Poker/lua/README.md b/71_Poker/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/71_Poker/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/71_Poker/pascal/README.md b/71_Poker/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/71_Poker/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/71_Poker/python/README.md b/71_Poker/python/README.md
    index bc58f0839..781945ec4 100644
    --- a/71_Poker/python/README.md
    +++ b/71_Poker/python/README.md
    @@ -1,30 +1,3 @@
     Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
     
    -Conversion to [Python](https://www.python.org/about/) by Alex Conconi, 2026.
    -
    ----
    -
    -### Python porting notes
    -
    -#### Known BASIC bugs — fixed
    -
    -- **Tie tack unreachable** (BASIC line 3970): The condition
    -  `IF O/3<>INT(O/3) THEN 4090` is logically inverted. It checks if the 
    -  tie tack has *not* been sold, and if so, incorrectly jumps to the 
    -  "Bust" message. This makes the tie tack sale permanently unreachable 
    -  even if the player still owns it. The Python port fixes this to restore 
    -  the original intended experience where both assets can be sold.
    -
    -#### Known BASIC bugs/quirks — kept faithful
    -
    -- **$50 buy-back materialises from nowhere** (BASIC lines 3570/3640):
    -  When the player buys back a pawned item, `C=C+50` adds $50 to the
    -  dealer's stack without deducting from the player.  Kept as-is — it
    -  models the dealer/pawnbroker liquidating the physical item.
    -
    -- **Yes/No prompts accept anything** (e.g. BASIC lines 3550, 3880):
    -  `LEFT$(J$,1)="Y"` treats every non-"Y" input as "no" with no
    -  re-prompt.  The Python port normalises all yes/no prompts to a single
    -  `_read_yes_no` that retries on invalid input (matching the stricter
    -  "Do you wish to continue?" prompt at lines 4120–4150).
    -
    +Conversion to [Python](https://www.python.org/about/)
    diff --git a/71_Poker/python/cards/__init__.py b/71_Poker/python/cards/__init__.py
    deleted file mode 100644
    index 956089deb..000000000
    --- a/71_Poker/python/cards/__init__.py
    +++ /dev/null
    @@ -1,11 +0,0 @@
    -"""Cards package initialization."""
    -
    -from .card import Card, CardRank, CardSuit
    -from .deck import Deck
    -
    -__all__ = [
    -    "Card",
    -    "CardRank",
    -    "CardSuit",
    -    "Deck",
    -]
    diff --git a/71_Poker/python/cards/card.py b/71_Poker/python/cards/card.py
    deleted file mode 100644
    index 2491c3430..000000000
    --- a/71_Poker/python/cards/card.py
    +++ /dev/null
    @@ -1,50 +0,0 @@
    -"""Card primitives: Suits, Ranks, and the Card class."""
    -
    -from dataclasses import dataclass
    -from enum import Enum, IntEnum
    -
    -
    -class CardSuit(Enum):
    -    """Enumeration of card suits."""
    -
    -    CLUBS = 0
    -    DIAMONDS = 1
    -    HEARTS = 2
    -    SPADES = 3
    -
    -    def __str__(self) -> str:
    -        return self.name.capitalize()
    -
    -
    -class CardRank(IntEnum):
    -    """Card ranks from Two (0) to Ace (12)."""
    -
    -    TWO = 0
    -    THREE = 1
    -    FOUR = 2
    -    FIVE = 3
    -    SIX = 4
    -    SEVEN = 5
    -    EIGHT = 6
    -    NINE = 7
    -    TEN = 8
    -    JACK = 9
    -    QUEEN = 10
    -    KING = 11
    -    ACE = 12
    -
    -    def __str__(self) -> str:
    -        if self.value <= 8:  # TWO(0) through TEN(8)
    -            return f" {str(self.value + 2)} "
    -        return ("Jack", "Queen", "King", "Ace")[self.value - 9]
    -
    -
    -@dataclass(frozen=True)
    -class Card:
    -    """A single playing card."""
    -
    -    suit: CardSuit
    -    rank: CardRank
    -
    -    def __str__(self) -> str:
    -        return f"{self.rank} of {self.suit}"
    diff --git a/71_Poker/python/cards/deck.py b/71_Poker/python/cards/deck.py
    deleted file mode 100644
    index 862d33e42..000000000
    --- a/71_Poker/python/cards/deck.py
    +++ /dev/null
    @@ -1,17 +0,0 @@
    -"""Deck implementation."""
    -
    -import random
    -
    -from .card import Card, CardRank, CardSuit
    -
    -
    -class Deck:  # pylint: disable=too-few-public-methods
    -    """Standard 52-card deck, shuffled on creation."""
    -
    -    def __init__(self) -> None:
    -        self._cards = [Card(suit, rank) for suit in CardSuit for rank in CardRank]
    -        random.shuffle(self._cards)
    -
    -    def deal(self) -> Card:
    -        """Remove and return the top card."""
    -        return self._cards.pop()
    diff --git a/71_Poker/python/game.py b/71_Poker/python/game.py
    deleted file mode 100644
    index be848ec36..000000000
    --- a/71_Poker/python/game.py
    +++ /dev/null
    @@ -1,401 +0,0 @@
    -"""Poker game logic — port of the 1978 Creative Computing BASIC original."""
    -
    -import random
    -from typing import NoReturn
    -
    -from cards import Deck
    -from players import Dealer, Human, Player
    -from pokerhand import Hand
    -
    -
    -class GameOver(Exception):
    -    """Raised when the game ends (either side busted, player quits, or walks away)."""
    -
    -
    -class PokerGame:  # pylint: disable=too-few-public-methods
    -    """Five-card draw poker against the house."""
    -
    -    INITIAL_MONEY: int = 200
    -    ANTE: int = 5
    -
    -    human: Human
    -    dealer: Dealer
    -    deck: Deck
    -    pot: int
    -
    -    def __init__(self) -> None:
    -        """Initialise game state and allocate both sides' starting stack."""
    -        self.human = Human(PokerGame.INITIAL_MONEY)
    -        self.dealer = Dealer(PokerGame.INITIAL_MONEY)
    -        self.pot = 0
    -
    -    # ------------------------------------------------------------------
    -    # Intro and main loop
    -    # ------------------------------------------------------------------
    -
    -    def run(self) -> None:
    -        """Execute the primary game loop until a GameOver exception occurs."""
    -        self._display_intro()
    -        while True:
    -            self._play_round()
    -
    -    # ------------------------------------------------------------------
    -    # Round
    -    # ------------------------------------------------------------------
    -
    -    def _play_round(self) -> None:
    -        """Deal one complete round: ante, bet, draw, bet, showdown."""
    -        print()
    -
    -        # Reset per-round state
    -        self.deck = Deck()
    -
    -        # --- Ante ---
    -        if self.dealer.money <= self.ANTE:
    -            self._dealer_goes_bust()
    -
    -        print(f"The ante is ${self.ANTE}.  I will deal:\n")
    -
    -        if self.human.money <= self.ANTE:
    -            self._human_try_raise_funds(self.ANTE)
    -
    -        self.pot += self.ANTE * 2
    -        self.human.pay_ante(self.ANTE)
    -        self.dealer.pay_ante(self.ANTE)
    -
    -        # --- Deal ---
    -        self.human.receive_new_hand(Hand([self.deck.deal() for _ in range(5)]))
    -        self.dealer.receive_new_hand(Hand([self.deck.deal() for _ in range(5)]))
    -
    -        print("Your hand:")
    -        print(self.human.hand)
    -        print()
    -
    -        # --- Opening bet ---
    -        dealer_action = self.dealer.get_opening_action()
    -        if self.dealer.money < self.dealer.bet:
    -            self._dealer_try_raise_funds()
    -
    -        if dealer_action == Player.Action.CHECK:
    -            print("I check.")
    -        else:
    -            print(f"I'll open with $ {self.dealer.bet}")
    -
    -        if not self._conduct_betting_round(post_draw=False):
    -            return
    -
    -        # --- Draw ---
    -        print()
    -        self._player_discard_draw()
    -        draw_count = self.dealer.discard_and_draw(self.deck)
    -        print(
    -            f"\nI am taking {draw_count} card{'s' if draw_count != 1 else ''}"
    -        )
    -
    -        # --- Post-draw bet ---
    -        self.dealer.decide_postdraw_bet()
    -        if not self._conduct_betting_round(post_draw=True):
    -            return
    -
    -        # --- Showdown ---
    -        self._showdown()
    -
    -    # ------------------------------------------------------------------
    -    # Player draw
    -    # ------------------------------------------------------------------
    -
    -    def _player_discard_draw(self) -> None:
    -        """Ask the player how many cards to replace, then deal replacements."""
    -        count = self._read_int(
    -            "Now we draw -- how many cards do you want? ",
    -            low=0,
    -            high=3,
    -            too_high_msg="You can't draw more than three cards.",
    -        )
    -
    -        if count == 0:
    -            return
    -
    -        print("What are their numbers:")
    -        for _ in range(count):
    -            pos = self._read_int("", low=1, high=5)
    -            self.human.replace_card(pos - 1, self.deck.deal())
    -
    -        print("Your new hand:")
    -        print(self.human.hand)
    -
    -    # ------------------------------------------------------------------
    -    # Betting round
    -    # ------------------------------------------------------------------
    -
    -    def _conduct_betting_round(self, post_draw: bool) -> bool:
    -        """
    -        Executes a betting round.
    -        Returns True if the betting phase completed (hand continues).
    -        Returns False if a player folded (hand ends).
    -        """
    -        while True:
    -            human_action = self._get_human_action()
    -
    -            if human_action == Player.Action.FOLD:
    -                # Human fold always ends betting loop (hand ends)
    -                self._settle_bets()
    -                self._award_pot(dealer_wins=True)
    -                return False
    -
    -            if human_action == Player.Action.CALL:
    -                # Human call always ends betting loop (proceed to next phase)
    -                self._settle_bets()
    -                return True
    -
    -            if human_action == Player.Action.CHECK:
    -                # Pre-draw: human check ends human's turn.
    -                # Post-draw: dealer gets a chance to bet/check back.
    -                if not post_draw or self._handle_human_post_draw_check():
    -                    return True
    -                # If dealer bet, we fall through and loop for human response
    -
    -            elif human_action == Player.Action.RAISE:
    -                if self._handle_human_raise():
    -                    return True
    -                # If dealer re-raised, we fall through and loop for human response
    -
    -            else:
    -                raise ValueError(f"Unknown player action: {human_action}")
    -
    -    def _handle_human_post_draw_check(self) -> bool:
    -        """Process dealer response to human check. Returns True if phase ends."""
    -        dealer_action = self.dealer.get_check_response()
    -        if self.dealer.money < self.dealer.bet:
    -            self._dealer_try_raise_funds()
    -
    -        if dealer_action == Player.Action.CHECK:
    -            print("I'll check.")
    -            self._settle_bets()
    -            return True
    -
    -        print(f"I'll bet $ {self.dealer.bet}")
    -        return False
    -
    -    def _handle_human_raise(self) -> bool:
    -        """Process dealer response to human raise. Returns True if phase ends."""
    -        dealer_action = self.dealer.get_raise_response(self.human.bet)
    -        if self.dealer.money < self.dealer.bet:
    -            self._dealer_try_raise_funds()
    -
    -        if dealer_action == Player.Action.FOLD:
    -            print("I fold.")
    -            self._settle_bets()
    -            self._award_pot(dealer_wins=False)
    -            return True  # Round ends
    -
    -        if dealer_action == Player.Action.CALL:
    -            print("I'll see you.")
    -            self._settle_bets()
    -            return True
    -
    -        if dealer_action == Player.Action.RAISE:
    -            raise_amount = self.dealer.bet - self.human.bet
    -            print(f"I'll see you, and raise you {raise_amount}")
    -            return False
    -
    -        raise ValueError(f"Unknown dealer action: {dealer_action}")
    -
    -    def _get_human_action(self) -> Player.Action:
    -        """Prompt user for a bet and return the resulting Action."""
    -        while True:
    -            print()
    -            raw = input("What is your bet? ").strip()
    -
    -            try:
    -                bet = float(raw)
    -            except ValueError:
    -                continue
    -
    -            # Fractional bet: only .5 is valid, and only as a check
    -            if bet != int(bet):
    -                if self.dealer.bet == 0 and self.human.bet == 0 and bet == 0.5:
    -                    return Player.Action.CHECK
    -                print("No small change, please.")
    -                continue
    -
    -            amount = int(bet)
    -
    -            if amount == 0:
    -                return Player.Action.FOLD
    -
    -            if self.human.bet + amount > self.human.money:
    -                self._human_try_raise_funds(self.human.bet + amount)
    -                continue
    -
    -            if self.human.bet + amount < self.dealer.bet:
    -                print("If you can't see my bet, then fold.")
    -                continue
    -
    -            self.human.bet += amount
    -
    -            if self.human.bet == self.dealer.bet:
    -                return Player.Action.CALL
    -            return Player.Action.RAISE
    -
    -    def _dealer_try_raise_funds(self) -> None:
    -        """Attempt to raise funds for the dealer. Raises GameOver if failed."""
    -        if not self.human.has_watch:
    -            if self._read_yes_no(
    -                "Would you like to buy back your watch for $50? "
    -            ):
    -                self.dealer.money += 50
    -                self.human.has_watch = True
    -                if self.dealer.money >= self.dealer.bet:
    -                    return
    -
    -        if not self.human.has_tack:
    -            if self._read_yes_no(
    -                "Would you like to buy back your tie tack for $50? "
    -            ):
    -                self.dealer.money += 50
    -                self.human.has_tack = True
    -                if self.dealer.money >= self.dealer.bet:
    -                    return
    -
    -        self._dealer_goes_bust()
    -
    -    def _dealer_goes_bust(self) -> NoReturn:
    -        """Inform the player and terminate the game."""
    -        print("I'm busted.  Congratulations!")
    -        raise GameOver
    -
    -    def _human_try_raise_funds(self, target_money: int) -> None:
    -        """Offer the player's assets for cash. Raises GameOver if short of target."""
    -        print("\nYou can't bet with what you haven't got.")
    -
    -        if self.human.has_watch:
    -            if self._read_yes_no("Would you like to sell your watch? "):
    -                if self._chance(3):
    -                    print("That's a pretty crummy watch - I'll give you $25.")
    -                    self.human.money += 25
    -                else:
    -                    print("I'll give you $75 for it.")
    -                    self.human.money += 75
    -                self.human.has_watch = False
    -                if self.human.money >= target_money:
    -                    return
    -
    -        if self.human.has_tack:
    -            if self._read_yes_no("Will you part with that diamond tie tack? "):
    -                if self._chance(4):
    -                    print("It's paste.  $25.")
    -                    self.human.money += 25
    -                else:
    -                    print("You are now $100 richer.")
    -                    self.human.money += 100
    -                self.human.has_tack = False
    -                if self.human.money >= target_money:
    -                    return
    -
    -        print("Your wad is shot.  So long, sucker!")
    -        raise GameOver
    -
    -    def _settle_bets(self) -> None:
    -        """Move both sides' committed chips into the pot."""
    -        self.pot += self.human.settle_bet()
    -        self.pot += self.dealer.settle_bet()
    -
    -    # ------------------------------------------------------------------
    -    # Showdown
    -    # ------------------------------------------------------------------
    -
    -    def _showdown(self) -> None:
    -        """Reveal hands, compare scores, and award the pot."""
    -        print("\nNow we compare hands:")
    -
    -        print("My hand:")
    -        print(self.dealer.hand)
    -        dealer_hand_eval = self.dealer.hand.evaluate()
    -
    -        player_hand_eval = self.human.hand.evaluate()
    -
    -        print(f"\nYou have {player_hand_eval}")
    -        print(f"And I have {dealer_hand_eval}")
    -
    -        if dealer_hand_eval == player_hand_eval:
    -            print("The hand is drawn.")
    -            print(f"All ${self.pot} remains in the pot.")
    -        else:
    -            self._award_pot(dealer_wins=dealer_hand_eval > player_hand_eval)
    -
    -    def _award_pot(self, dealer_wins: bool) -> None:
    -        """Announce the winner, award the pot, and prompt to continue."""
    -        if dealer_wins:
    -            print("I win.")
    -            self.dealer.win_pot(self.pot)
    -        else:
    -            print("You win.")
    -            self.human.win_pot(self.pot)
    -        print(
    -            f"Now I have $ {self.dealer.money} and you have $ {self.human.money}"
    -        )
    -        if not self._read_yes_no("Do you wish to continue? "):
    -            raise GameOver
    -        self.pot = 0  # Reset pot after awarding it
    -
    -    # ------------------------------------------------------------------
    -    # Helpers
    -    # ------------------------------------------------------------------
    -
    -    # pylint: disable=too-many-arguments
    -    def _read_int(
    -        self,
    -        prompt: str,
    -        *,
    -        low: int | None = None,
    -        high: int | None = None,
    -        too_low_msg: str | None = None,
    -        too_high_msg: str | None = None,
    -    ) -> int:
    -        """Read and validate an integer within an optional range."""
    -        while True:
    -            raw = input(prompt).strip()
    -            if not raw:
    -                continue
    -            try:
    -                val = int(raw)
    -            except ValueError:
    -                continue
    -
    -            if low is not None and val < low:
    -                if too_low_msg:
    -                    print(too_low_msg)
    -                continue
    -
    -            if high is not None and val > high:
    -                if too_high_msg:
    -                    print(too_high_msg)
    -                continue
    -
    -            return val
    -
    -    def _read_yes_no(self, prompt: str) -> bool:
    -        """Read yes/no response. Returns True for yes, False for no."""
    -        while True:
    -            response = input(prompt).strip().lower()
    -            if response in ["y", "yes"]:
    -                return True
    -            if response in ["n", "no"]:
    -                return False
    -            print("Answer yes or no, please.")
    -
    -    def _chance(self, n: int) -> bool:
    -        """Return True with probability n/10."""
    -        return random.random() < n / 10
    -
    -    def _display_intro(self) -> None:
    -        """Print the welcome banner."""
    -        print("                                POKER")
    -        print("              CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n")
    -        print(
    -            f"Welcome to the casino.  We each have ${PokerGame.INITIAL_MONEY}."
    -        )
    -        print("I will open the betting before the draw; you open after.")
    -        print("To fold bet 0; to check bet .5.")
    -        print("Enough talk -- let's get down to business.")
    diff --git a/71_Poker/python/players/__init__.py b/71_Poker/python/players/__init__.py
    deleted file mode 100644
    index 866e40a52..000000000
    --- a/71_Poker/python/players/__init__.py
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -"""Players package initialization."""
    -
    -from .dealer import Dealer
    -from .human import Human
    -from .player import Player
    -
    -__all__ = ["Player", "Human", "Dealer"]
    diff --git a/71_Poker/python/players/dealer.py b/71_Poker/python/players/dealer.py
    deleted file mode 100644
    index 71068f058..000000000
    --- a/71_Poker/python/players/dealer.py
    +++ /dev/null
    @@ -1,178 +0,0 @@
    -"""Dealer state and decision-making logic."""
    -
    -import random
    -from enum import Enum, auto
    -
    -from cards import CardRank, Deck
    -from pokerhand import Hand, HandEvaluation, HandRank
    -
    -from .player import Player
    -
    -
    -class Dealer(Player):
    -    """Dealer state: bankroll, strategy, and per-round betting."""
    -
    -    class Strategy(Enum):
    -        """The dealer's play style for the current round, set during the opening."""
    -
    -        NORMAL = auto()
    -        WEAK = auto()
    -        BLUFFING = auto()
    -
    -    strategy: Strategy
    -    bet_base: int
    -    was_bluffing: bool
    -    hand_is_weak: bool
    -    bluff_discard_count: int | None
    -
    -    def receive_new_hand(self, hand: Hand) -> None:
    -        """Reset per-round state and receive a new hand."""
    -        super().receive_new_hand(hand)
    -        self.strategy = Dealer.Strategy.NORMAL
    -        self.bet_base = 0
    -        self.was_bluffing = False
    -        self.hand_is_weak = False
    -        self.bluff_discard_count = None
    -
    -    def decide_postdraw_bet(self) -> None:
    -        """Update bluffing state, evaluate hand and set betting tier."""
    -        self.was_bluffing = self.strategy == Dealer.Strategy.BLUFFING
    -
    -        result = self.hand.evaluate()
    -        rank = result.hand_rank
    -        self.bet = 0
    -        self.hand_is_weak = self._is_hand_weak(result, is_redeal=True)
    -
    -        if self.was_bluffing:
    -            self.bet_base = 28
    -        elif self.hand_is_weak:
    -            self.bet_base = 1
    -        elif rank < HandRank.THREE_OF_A_KIND:
    -            self.bet_base = 2
    -            if self._chance(1):
    -                self.bet_base = 19
    -        elif rank <= HandRank.FLUSH:  # THREE_OF_A_KIND, STRAIGHT, FLUSH
    -            self.bet_base = 19
    -            if self._chance(1):
    -                self.bet_base = 11
    -        else:  # FULL_HOUSE, FOUR_OF_A_KIND
    -            self.bet_base = 2
    -
    -    def _is_hand_weak(self, result: HandEvaluation, is_redeal: bool) -> bool:
    -        """Check whether the hand qualifies as 'weak'."""
    -        rank = result.hand_rank
    -        if rank < HandRank.PAIR:
    -            # Schmaltz is always weak; partial straight only on re-deal
    -            return rank != HandRank.PARTIAL_STRAIGHT or is_redeal
    -        if rank <= HandRank.TWO_PAIR:
    -            # Pair/two-pair is weak only when high card is Eight or lower
    -            return result.high_card.rank <= CardRank.EIGHT
    -        return False
    -
    -    def get_opening_action(self) -> Player.Action:
    -        """Evaluate hand and set the dealer's pre-draw opening bet and strategy."""
    -        result = self.hand.evaluate()
    -
    -        if self._is_hand_weak(result, is_redeal=False):
    -            strat, base, discard, action = self._decide_weak_opening()
    -        else:
    -            strat, base, discard, action = self._decide_normal_opening(result)
    -
    -        self.strategy = strat
    -        self.bet_base = base
    -        self.bluff_discard_count = discard
    -
    -        if action == Player.Action.RAISE:
    -            self.bet = self.bet_base + random.randint(0, 9)
    -        else:
    -            self.bet = 0
    -
    -        return action
    -
    -    def _decide_weak_opening(
    -        self,
    -    ) -> tuple[Strategy, int, int | None, Player.Action]:
    -        """Pure logic for weak-hand opening decisions."""
    -        if self._chance(8):
    -            return Dealer.Strategy.BLUFFING, 23, 2, Player.Action.RAISE
    -        if self._chance(8):
    -            return Dealer.Strategy.BLUFFING, 23, 1, Player.Action.RAISE
    -        if self._chance(9):
    -            return Dealer.Strategy.WEAK, 1, None, Player.Action.CHECK
    -        return Dealer.Strategy.BLUFFING, 23, 0, Player.Action.RAISE
    -
    -    def _decide_normal_opening(
    -        self, result: HandEvaluation
    -    ) -> tuple[Strategy, int, int | None, Player.Action]:
    -        """Pure logic for normal-hand opening decisions."""
    -        rank = result.hand_rank
    -        if rank < HandRank.THREE_OF_A_KIND:
    -            if self._chance(8):
    -                return Dealer.Strategy.NORMAL, 0, None, Player.Action.CHECK
    -            return Dealer.Strategy.BLUFFING, 23, None, Player.Action.RAISE
    -
    -        # Strong hand (THREE_OF_A_KIND and above)
    -        if rank > HandRank.FULL_HOUSE:  # FOUR_OF_A_KIND
    -            base = 2 if self._chance(9) else 35
    -        else:
    -            base = 35
    -        return Dealer.Strategy.NORMAL, base, None, Player.Action.RAISE
    -
    -    def discard_and_draw(self, deck: Deck) -> int:
    -        """Evaluate hand and replace the dealer's discard cards."""
    -        if self.bluff_discard_count is not None:
    -            count = self.bluff_discard_count
    -            if count == 0:
    -                return 0
    -            ranked = sorted(range(5), key=lambda i: self.hand[i].rank.value)
    -            for i in ranked[:count]:
    -                self.replace_card(i, deck.deal())
    -            return count
    -
    -        result = self.hand.evaluate()
    -        for i in result.discard_indices:
    -            self.replace_card(i, deck.deal())
    -        return len(result.discard_indices)
    -
    -    def get_check_response(self) -> Player.Action:
    -        """Respond to a player's check. Returns the dealer's action."""
    -        if not self.was_bluffing and self.hand_is_weak:
    -            return Player.Action.CHECK
    -
    -        self.bet = self.bet_base + random.randint(0, 9)
    -        return Player.Action.RAISE
    -
    -    def get_raise_response(self, player_paid: int) -> Player.Action:
    -        """Respond to a player's raise. Returns the dealer's action."""
    -        if self.bet_base != 1:
    -            if player_paid > 3 * self.bet_base:
    -                if self.bet_base == 2 and self._chance(1):
    -                    return self._raise(player_paid)
    -                return self._call(player_paid)
    -            return self._raise(player_paid)
    -
    -        if player_paid > 5:
    -            return Player.Action.FOLD
    -
    -        if player_paid > 3:
    -            return self._call(player_paid)
    -
    -        return self._raise(player_paid)
    -
    -    def _call(self, player_paid: int) -> Player.Action:
    -        """Dealer calls the player's bet."""
    -        self.bet = player_paid
    -        return Player.Action.CALL
    -
    -    def _raise(self, player_paid: int) -> Player.Action:
    -        """Raise the player's bet."""
    -        raise_amount = player_paid - self.bet + random.randint(0, 9)
    -        if raise_amount <= 0:
    -            return self._call(player_paid)
    -
    -        self.bet = player_paid + raise_amount
    -        return Player.Action.RAISE
    -
    -    def _chance(self, n: int) -> bool:
    -        """Return True with probability n/10."""
    -        return random.random() < n / 10
    diff --git a/71_Poker/python/players/human.py b/71_Poker/python/players/human.py
    deleted file mode 100644
    index b496e1ceb..000000000
    --- a/71_Poker/python/players/human.py
    +++ /dev/null
    @@ -1,21 +0,0 @@
    -"""Human player state and behavior."""
    -
    -from .player import Player
    -
    -
    -class Human(Player):
    -    """
    -    The human player in the game.
    -
    -    Note: As a state container, this class has no logic methods;
    -    decision-making is provided by the user via the game controller.
    -    """
    -
    -    has_watch: bool
    -    has_tack: bool
    -
    -    def __init__(self, money: int) -> None:
    -        """Initialize the human player with starting assets."""
    -        super().__init__(money)
    -        self.has_watch = True
    -        self.has_tack = True
    diff --git a/71_Poker/python/players/player.py b/71_Poker/python/players/player.py
    deleted file mode 100644
    index e5925641d..000000000
    --- a/71_Poker/python/players/player.py
    +++ /dev/null
    @@ -1,51 +0,0 @@
    -"""Base Player class for both Human and Dealer."""
    -
    -from enum import Enum, auto
    -
    -from cards import Card
    -from pokerhand import Hand
    -
    -
    -class Player:
    -    """Base class representing a participant in the poker game."""
    -
    -    money: int
    -    bet: int
    -    hand: Hand
    -
    -    class Action(Enum):
    -        """Standard actions a player can take."""
    -
    -        FOLD = auto()
    -        CHECK = auto()
    -        CALL = auto()
    -        RAISE = auto()
    -
    -    def __init__(self, money: int) -> None:
    -        """Initialize the player with a starting bankroll."""
    -        self.money = money
    -        self.bet = 0
    -
    -    def receive_new_hand(self, hand: Hand) -> None:
    -        """Reset per-round state and receive a new hand."""
    -        self.bet = 0
    -        self.hand = hand
    -
    -    def pay_ante(self, amount: int) -> None:
    -        """Pay the ante."""
    -        self.money -= amount
    -
    -    def win_pot(self, amount: int) -> None:
    -        """Add the pot to the player's money."""
    -        self.money += amount
    -
    -    def settle_bet(self) -> int:
    -        """Move the current bet out of the player's money. Returns the bet amount."""
    -        amount = self.bet
    -        self.money -= amount
    -        self.bet = 0
    -        return amount
    -
    -    def replace_card(self, index: int, card: Card) -> None:
    -        """Replace a card in the player's hand."""
    -        self.hand[index] = card
    diff --git a/71_Poker/python/poker.py b/71_Poker/python/poker.py
    deleted file mode 100644
    index f027432bf..000000000
    --- a/71_Poker/python/poker.py
    +++ /dev/null
    @@ -1,38 +0,0 @@
    -"""
    -From: BASIC Computer Games (1978)
    -Edited by David H. Ahl
    -
    -You and the computer are opponents in this game of draw poker.
    -At the start of the game, each player is given $200. The game
    -ends when either player runs out of money, although if you go
    -broke the computer will offer to buy back your wristwatch or
    -diamond tie tack.
    -
    -The computer opens the betting before the draw; you open the
    -betting after the draw. If you don't have a hand that's worth
    -anything and you want to fold, bet 0. Prior to the draw, to
    -check the draw, you may bet .5. Of course, if the computer has
    -made a bet, you must match it in order to draw or, if you have
    -a good hand, you may raise the bet at any time.
    -
    -The author is A. Christopher Hall of Trinity College,
    -Hartford, Connecticut.
    -
    -
    -Python port by Alex Conconi, 2026.
    -"""
    -
    -from game import GameOver, PokerGame
    -
    -
    -def main() -> None:
    -    """Entry point for the poker game application."""
    -    game = PokerGame()
    -    try:
    -        game.run()
    -    except GameOver:
    -        pass
    -
    -
    -if __name__ == "__main__":
    -    main()
    diff --git a/71_Poker/python/pokerhand/__init__.py b/71_Poker/python/pokerhand/__init__.py
    deleted file mode 100644
    index 3de94bf24..000000000
    --- a/71_Poker/python/pokerhand/__init__.py
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -"""Hand package initialization."""
    -
    -from .evaluation import HandEvaluation
    -from .hand import Hand
    -from .rank import HandRank
    -
    -__all__ = ["Hand", "HandEvaluation", "HandRank"]
    diff --git a/71_Poker/python/pokerhand/evaluation.py b/71_Poker/python/pokerhand/evaluation.py
    deleted file mode 100644
    index 6c4693274..000000000
    --- a/71_Poker/python/pokerhand/evaluation.py
    +++ /dev/null
    @@ -1,224 +0,0 @@
    -"""Hand evaluation logic."""
    -
    -import functools
    -from collections import Counter
    -from collections.abc import Callable
    -from typing import TYPE_CHECKING
    -
    -from cards.card import Card, CardRank
    -
    -from .rank import HandRank
    -
    -if TYPE_CHECKING:
    -    from .hand import Hand
    -
    -
    -@functools.total_ordering
    -class HandEvaluation:
    -    """
    -    Evaluator and Result container for a poker hand.
    -
    -    When initialized with a Hand, it immediately performs the evaluation
    -    and stores the resulting rank, high card, and recommended discards.
    -    """
    -
    -    hand_rank: HandRank
    -    high_card: Card
    -    discard_indices: list[int]
    -    _ctx: "_EvaluationContext"
    -
    -    def __init__(self, hand: "Hand"):
    -        """Perform evaluation of the provided hand."""
    -        self.discard_indices = []
    -        self._evaluate(hand)
    -
    -    def __str__(self) -> str:
    -        rank = self.hand_rank
    -        card = self.high_card
    -
    -        if rank in (HandRank.SCHMALTZ, HandRank.PARTIAL_STRAIGHT):
    -            return f"{rank}, {card.rank} high"
    -        if rank in (
    -            HandRank.PAIR,
    -            HandRank.TWO_PAIR,
    -            HandRank.THREE_OF_A_KIND,
    -            HandRank.FULL_HOUSE,
    -            HandRank.FOUR_OF_A_KIND,
    -        ):
    -            return f"{rank} {card.rank}'s"
    -        if rank == HandRank.STRAIGHT:
    -            return f"{rank}, {card.rank} high"
    -        if rank == HandRank.FLUSH:
    -            return f"{rank} {card.suit}"
    -        return f"{rank} {card.rank}"
    -
    -    def __lt__(self, other: "HandEvaluation") -> bool:
    -        return (self.hand_rank, self.high_card.rank.value) < (
    -            other.hand_rank,
    -            other.high_card.rank.value,
    -        )
    -
    -    def __eq__(self, other: object) -> bool:
    -        # this object could be compared to any other object with ==
    -        if not isinstance(other, HandEvaluation):
    -            return NotImplemented
    -        return (self.hand_rank, self.high_card.rank.value) == (
    -            other.hand_rank,
    -            other.high_card.rank.value,
    -        )
    -
    -    def __hash__(self) -> int:
    -        return hash((self.hand_rank, self.high_card.rank.value))
    -
    -    class _EvaluationContext:  # pylint: disable=too-few-public-methods
    -        """Intermediate calculations for hand evaluation."""
    -
    -        def __init__(self, hand: "Hand"):
    -            self.cards = hand.cards
    -            self.rank_indexed = sorted(
    -                enumerate(self.cards), key=lambda item: item[1].rank.value
    -            )
    -
    -            # Frequency analysis
    -            rank_counts = Counter(c.rank for c in self.cards)
    -            sorted_groups = sorted(
    -                rank_counts.items(),
    -                key=lambda rc: (rc[1], rc[0].value),
    -                reverse=True,
    -            )
    -            self.freq_pattern = tuple(count for _, count in sorted_groups)
    -            self.ranks_by_freq = [rank for rank, _ in sorted_groups]
    -            self.sorted_ranks: list[CardRank] = [
    -                c.rank for _, c in self.rank_indexed
    -            ]
    -
    -    def _evaluate(self, hand: "Hand") -> None:
    -        """Internal algorithm to determine hand strength."""
    -        self._ctx = self._EvaluationContext(hand)
    -
    -        checks: list[Callable[[], bool]] = [
    -            self._check_four_of_a_kind,
    -            self._check_full_house,
    -            self._check_flush,
    -            self._check_straight,
    -            self._check_three_of_a_kind,
    -            self._check_two_pair,
    -            self._check_pair,
    -            self._check_partial_straight,
    -            self._check_schmaltz,
    -        ]
    -
    -        for check in checks:
    -            if check():
    -                break
    -
    -    def _check_four_of_a_kind(self) -> bool:
    -        if self._ctx.freq_pattern != (4, 1):
    -            return False
    -        self.hand_rank = HandRank.FOUR_OF_A_KIND
    -        self.high_card = next(
    -            c
    -            for _, c in reversed(self._ctx.rank_indexed)
    -            if c.rank == self._ctx.ranks_by_freq[0]
    -        )
    -        return True
    -
    -    def _check_full_house(self) -> bool:
    -        if self._ctx.freq_pattern != (3, 2):
    -            return False
    -        self.hand_rank = HandRank.FULL_HOUSE
    -        self.high_card = next(
    -            c
    -            for _, c in reversed(self._ctx.rank_indexed)
    -            if c.rank == self._ctx.ranks_by_freq[0]
    -        )
    -        return True
    -
    -    def _check_flush(self) -> bool:
    -        if len({c.suit for c in self._ctx.cards}) != 1:
    -            return False
    -        self.hand_rank = HandRank.FLUSH
    -        self.high_card = self._ctx.rank_indexed[4][1]
    -        return True
    -
    -    def _check_straight(self) -> bool:
    -        if (
    -            len(set(self._ctx.sorted_ranks)) == 5
    -            and self._ctx.sorted_ranks[4].value
    -            - self._ctx.sorted_ranks[0].value
    -            == 4
    -        ):
    -            self.hand_rank = HandRank.STRAIGHT
    -            self.high_card = self._ctx.rank_indexed[4][1]
    -            return True
    -        return False
    -
    -    def _check_three_of_a_kind(self) -> bool:
    -        if self._ctx.freq_pattern != (3, 1, 1):
    -            return False
    -        self.hand_rank = HandRank.THREE_OF_A_KIND
    -        self.high_card = next(
    -            c
    -            for _, c in reversed(self._ctx.rank_indexed)
    -            if c.rank == self._ctx.ranks_by_freq[0]
    -        )
    -        keep_rank = self._ctx.ranks_by_freq[0]
    -        self.discard_indices = [
    -            i for i, c in enumerate(self._ctx.cards) if c.rank != keep_rank
    -        ]
    -        return True
    -
    -    def _check_two_pair(self) -> bool:
    -        if self._ctx.freq_pattern != (2, 2, 1):
    -            return False
    -        self.hand_rank = HandRank.TWO_PAIR
    -        self.high_card = next(
    -            c
    -            for _, c in reversed(self._ctx.rank_indexed)
    -            if c.rank == self._ctx.ranks_by_freq[0]
    -        )
    -        keep = {self._ctx.ranks_by_freq[0], self._ctx.ranks_by_freq[1]}
    -        self.discard_indices = [
    -            i for i, c in enumerate(self._ctx.cards) if c.rank not in keep
    -        ]
    -        return True
    -
    -    def _check_pair(self) -> bool:
    -        if self._ctx.freq_pattern != (2, 1, 1, 1):
    -            return False
    -        self.hand_rank = HandRank.PAIR
    -        self.high_card = next(
    -            c
    -            for _, c in reversed(self._ctx.rank_indexed)
    -            if c.rank == self._ctx.ranks_by_freq[0]
    -        )
    -        keep_rank = self._ctx.ranks_by_freq[0]
    -        self.discard_indices = [
    -            i for i, c in enumerate(self._ctx.cards) if c.rank != keep_rank
    -        ]
    -        return True
    -
    -    def _check_partial_straight(self) -> bool:
    -        if (
    -            self._ctx.sorted_ranks[3].value - self._ctx.sorted_ranks[0].value
    -            == 3
    -        ):
    -            self.hand_rank = HandRank.PARTIAL_STRAIGHT
    -            self.high_card = self._ctx.rank_indexed[3][1]
    -            self.discard_indices = [self._ctx.rank_indexed[4][0]]
    -            return True
    -        if (
    -            self._ctx.sorted_ranks[4].value - self._ctx.sorted_ranks[1].value
    -            == 3
    -        ):
    -            self.hand_rank = HandRank.PARTIAL_STRAIGHT
    -            self.high_card = self._ctx.rank_indexed[4][1]
    -            self.discard_indices = [self._ctx.rank_indexed[0][0]]
    -            return True
    -        return False
    -
    -    def _check_schmaltz(self) -> bool:
    -        self.hand_rank = HandRank.SCHMALTZ
    -        self.high_card = self._ctx.rank_indexed[4][1]
    -        self.discard_indices = [idx for idx, _ in self._ctx.rank_indexed[0:3]]
    -        return True
    diff --git a/71_Poker/python/pokerhand/hand.py b/71_Poker/python/pokerhand/hand.py
    deleted file mode 100644
    index aef598ace..000000000
    --- a/71_Poker/python/pokerhand/hand.py
    +++ /dev/null
    @@ -1,39 +0,0 @@
    -"""Hand implementation."""
    -
    -from collections.abc import Iterator
    -
    -from cards.card import Card
    -
    -from .evaluation import HandEvaluation
    -
    -
    -class Hand:
    -    """A 5-card poker hand that acts as a simple data container."""
    -
    -    def __init__(self, cards: list[Card]):
    -        if len(cards) != 5:
    -            raise ValueError("Hand must have exactly 5 cards")
    -        self.cards = list(cards)
    -
    -    def evaluate(self) -> HandEvaluation:
    -        """Factory method to return a hand evaluation."""
    -        return HandEvaluation(self)
    -
    -    def __len__(self) -> int:
    -        return len(self.cards)
    -
    -    def __iter__(self) -> Iterator[Card]:
    -        return iter(self.cards)
    -
    -    def __getitem__(self, i: int) -> Card:
    -        return self.cards[i]
    -
    -    def __setitem__(self, i: int, card: Card) -> None:
    -        self.cards[i] = card
    -
    -    def __str__(self) -> str:
    -        """Return a multi-line formatted description of the hand."""
    -        entries = [f"{i} --  {card}" for i, card in enumerate(self.cards, 1)]
    -        lines = [f" {entries[i]:<32}{entries[i + 1]}" for i in range(0, 4, 2)]
    -        lines.append(f" {entries[4]}")
    -        return "\n".join(lines)
    diff --git a/71_Poker/python/pokerhand/rank.py b/71_Poker/python/pokerhand/rank.py
    deleted file mode 100644
    index 181cec0a1..000000000
    --- a/71_Poker/python/pokerhand/rank.py
    +++ /dev/null
    @@ -1,31 +0,0 @@
    -"""Hand rank enumeration."""
    -
    -from enum import IntEnum, auto
    -
    -
    -class HandRank(IntEnum):
    -    """Poker hand ranks ordered from weakest to strongest."""
    -
    -    SCHMALTZ = auto()
    -    PARTIAL_STRAIGHT = auto()
    -    PAIR = auto()
    -    TWO_PAIR = auto()
    -    THREE_OF_A_KIND = auto()
    -    STRAIGHT = auto()
    -    FLUSH = auto()
    -    FULL_HOUSE = auto()
    -    FOUR_OF_A_KIND = auto()
    -
    -    def __str__(self) -> str:
    -        """Return the display name of the rank."""
    -        return {
    -            HandRank.SCHMALTZ: "Schmaltz",
    -            HandRank.PARTIAL_STRAIGHT: "Schmaltz",
    -            HandRank.PAIR: "a pair of",
    -            HandRank.TWO_PAIR: "Two pair",
    -            HandRank.THREE_OF_A_KIND: "Three",
    -            HandRank.STRAIGHT: "Straight",
    -            HandRank.FLUSH: "a flush in",
    -            HandRank.FULL_HOUSE: "Full house",
    -            HandRank.FOUR_OF_A_KIND: "Four",
    -        }[self]
    diff --git a/71_Poker/vbnet/Poker.sln b/71_Poker/vbnet/Poker.sln
    deleted file mode 100644
    index f1514e74a..000000000
    --- a/71_Poker/vbnet/Poker.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 5e1a61a32..000000000
    --- a/71_Poker/vbnet/Poker.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Poker
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/72_Queen/README.md b/72_Queen/README.md
    index 6c4ef5b16..dc62cb596 100644
    --- a/72_Queen/README.md
    +++ b/72_Queen/README.md
    @@ -14,7 +14,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/72_Queen/csharp/Computer.cs b/72_Queen/csharp/Computer.cs
    deleted file mode 100644
    index 459c73377..000000000
    --- a/72_Queen/csharp/Computer.cs
    +++ /dev/null
    @@ -1,34 +0,0 @@
    -namespace Queen;
    -
    -internal class Computer
    -{
    -    private static readonly HashSet _randomiseFrom = new() { 41, 44, 73, 75, 126, 127 };
    -    private static readonly HashSet _desirable = new() { 73, 75, 126, 127, 158 };
    -    private readonly IRandom _random;
    -
    -    public Computer(IRandom random)
    -    {
    -        _random = random;
    -    }
    -
    -    public Position GetMove(Position from)
    -        => from + (_randomiseFrom.Contains(from) ? _random.NextMove() : FindMove(from));
    -
    -    private Move FindMove(Position from)
    -    {
    -        for (int i = 7; i > 0; i--)
    -        {
    -            if (IsOptimal(Move.Left, out var move)) { return move; }
    -            if (IsOptimal(Move.Down, out move)) { return move; }
    -            if (IsOptimal(Move.DownLeft, out move)) { return move; }
    -
    -            bool IsOptimal(Move direction, out Move move)
    -            {
    -                move = direction * i;
    -                return _desirable.Contains(from + move);
    -            }
    -        }
    -
    -        return _random.NextMove();
    -    }
    -}
    diff --git a/72_Queen/csharp/Game.cs b/72_Queen/csharp/Game.cs
    deleted file mode 100644
    index 35b1dc9a0..000000000
    --- a/72_Queen/csharp/Game.cs
    +++ /dev/null
    @@ -1,57 +0,0 @@
    -namespace Queen;
    -
    -internal class Game
    -{
    -    private readonly IReadWrite _io;
    -    private readonly IRandom _random;
    -    private readonly Computer _computer;
    -
    -    public Game(IReadWrite io, IRandom random)
    -    {
    -        _io = io;
    -        _random = random;
    -        _computer = new Computer(random);
    -    }
    -
    -    internal void PlaySeries()
    -    {
    -        _io.Write(Streams.Title);
    -        if (_io.ReadYesNo(Prompts.Instructions)) { _io.Write(Streams.Instructions); }
    -
    -        while (true)
    -        {
    -            var result = PlayGame();
    -            _io.Write(result switch
    -            {
    -                Result.HumanForfeits => Streams.Forfeit,
    -                Result.HumanWins => Streams.Congratulations,
    -                Result.ComputerWins => Streams.IWin,
    -                _ => throw new InvalidOperationException($"Unexpected result {result}")
    -            });
    -
    -            if (!_io.ReadYesNo(Prompts.Anyone)) { break; }
    -        }
    -
    -        _io.Write(Streams.Thanks);
    -    }
    -
    -    private Result PlayGame()
    -    {
    -        _io.Write(Streams.Board);
    -        var humanPosition = _io.ReadPosition(Prompts.Start, p => p.IsStart, Streams.IllegalStart, repeatPrompt: true);
    -        if (humanPosition.IsZero) { return Result.HumanForfeits; }
    -
    -        while (true)
    -        {
    -            var computerPosition = _computer.GetMove(humanPosition);
    -            _io.Write(Strings.ComputerMove(computerPosition));
    -            if (computerPosition.IsEnd) { return Result.ComputerWins; }
    -
    -            humanPosition = _io.ReadPosition(Prompts.Move, p => (p - computerPosition).IsValid, Streams.IllegalMove);
    -            if (humanPosition.IsZero) { return Result.HumanForfeits; }
    -            if (humanPosition.IsEnd) { return Result.HumanWins; }
    -        }
    -    }
    -
    -    private enum Result { ComputerWins, HumanWins, HumanForfeits };
    -}
    diff --git a/72_Queen/csharp/IOExtensions.cs b/72_Queen/csharp/IOExtensions.cs
    deleted file mode 100644
    index 519599674..000000000
    --- a/72_Queen/csharp/IOExtensions.cs
    +++ /dev/null
    @@ -1,38 +0,0 @@
    -namespace Queen;
    -
    -internal static class IOExtensions
    -{
    -    internal static bool ReadYesNo(this IReadWrite io, string prompt)
    -    {
    -        while (true)
    -        {
    -            var answer = io.ReadString(prompt).ToLower();
    -            if (answer == "yes") { return true; }
    -            if (answer == "no") { return false; }
    -
    -            io.Write(Streams.YesOrNo);
    -        }
    -    }
    -
    -    internal static Position ReadPosition(
    -        this IReadWrite io,
    -        string prompt,
    -        Predicate isValid,
    -        Stream error,
    -        bool repeatPrompt = false)
    -    {
    -        while (true)
    -        {
    -            var response = io.ReadNumber(prompt);
    -            var number = (int)response;
    -            var position = new Position(number);
    -            if (number == response && (position.IsZero || isValid(position)))
    -            {
    -                return position;
    -            }
    -
    -            io.Write(error);
    -            if (!repeatPrompt) { prompt = ""; }
    -        }
    -    }
    -}
    diff --git a/72_Queen/csharp/Move.cs b/72_Queen/csharp/Move.cs
    deleted file mode 100644
    index 4e18647b6..000000000
    --- a/72_Queen/csharp/Move.cs
    +++ /dev/null
    @@ -1,15 +0,0 @@
    -namespace Queen;
    -
    -internal record struct Move(int Diagonal, int Row)
    -{
    -    public static readonly Move Left = new(1, 0);
    -    public static readonly Move DownLeft = new(2, 1);
    -    public static readonly Move Down = new(1, 1);
    -
    -    public bool IsValid => Diagonal > 0 && (IsLeft || IsDown || IsDownLeft);
    -    private bool IsLeft => Row == 0;
    -    private bool IsDown => Row == Diagonal;
    -    private bool IsDownLeft => Row * 2 == Diagonal;
    -
    -    public static Move operator *(Move move, int scale) => new(move.Diagonal * scale, move.Row * scale);
    -}
    \ No newline at end of file
    diff --git a/72_Queen/csharp/Position.cs b/72_Queen/csharp/Position.cs
    deleted file mode 100644
    index 69971163a..000000000
    --- a/72_Queen/csharp/Position.cs
    +++ /dev/null
    @@ -1,24 +0,0 @@
    -namespace Queen;
    -
    -internal record struct Position(int Diagonal, int Row)
    -{
    -    public static readonly Position Zero = new(0);
    -
    -    public Position(int number)
    -        : this(Diagonal: number / 10, Row: number % 10)
    -    {
    -    }
    -
    -    public bool IsZero => Row == 0 && Diagonal == 0;
    -    public bool IsStart => Row == 1 || Row == Diagonal;
    -    public bool IsEnd => Row == 8 && Diagonal == 15;
    -
    -    public override string ToString() => $"{Diagonal}{Row}";
    -
    -    public static implicit operator Position(int value) => new(value);
    -
    -    public static Position operator +(Position position, Move move)
    -        => new(Diagonal: position.Diagonal + move.Diagonal, Row: position.Row + move.Row);
    -    public static Move operator -(Position to, Position from)
    -        => new(Diagonal: to.Diagonal - from.Diagonal, Row: to.Row - from.Row);
    -}
    diff --git a/72_Queen/csharp/Program.cs b/72_Queen/csharp/Program.cs
    deleted file mode 100644
    index 5e017df63..000000000
    --- a/72_Queen/csharp/Program.cs
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -global using Games.Common.IO;
    -global using Games.Common.Randomness;
    -global using static Queen.Resources.Resource;
    -
    -using Queen;
    -
    -new Game(new ConsoleIO(), new RandomNumberGenerator()).PlaySeries();
    \ No newline at end of file
    diff --git a/72_Queen/csharp/Queen.csproj b/72_Queen/csharp/Queen.csproj
    deleted file mode 100644
    index 3870320c9..000000000
    --- a/72_Queen/csharp/Queen.csproj
    +++ /dev/null
    @@ -1,17 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    -  
    -    
    -  
    -
    -  
    -    
    -  
    -
    diff --git a/72_Queen/csharp/Queen.sln b/72_Queen/csharp/Queen.sln
    deleted file mode 100644
    index b4d865ab2..000000000
    --- a/72_Queen/csharp/Queen.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/csharp/RandomExtensions.cs b/72_Queen/csharp/RandomExtensions.cs
    deleted file mode 100644
    index b4e375fdf..000000000
    --- a/72_Queen/csharp/RandomExtensions.cs
    +++ /dev/null
    @@ -1,12 +0,0 @@
    -namespace Queen;
    -
    -internal static class RandomExtensions
    -{
    -    internal static Move NextMove(this IRandom random)
    -        => random.NextFloat() switch
    -        {
    -            > 0.6F => Move.Down,
    -            > 0.3F => Move.DownLeft,
    -            _ => Move.Left
    -        };
    -}
    diff --git a/72_Queen/csharp/Resources/AnyonePrompt.txt b/72_Queen/csharp/Resources/AnyonePrompt.txt
    deleted file mode 100644
    index a0289fd62..000000000
    --- a/72_Queen/csharp/Resources/AnyonePrompt.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Anyone else care to try
    \ No newline at end of file
    diff --git a/72_Queen/csharp/Resources/Board.txt b/72_Queen/csharp/Resources/Board.txt
    deleted file mode 100644
    index 854be1bbc..000000000
    --- a/72_Queen/csharp/Resources/Board.txt
    +++ /dev/null
    @@ -1,27 +0,0 @@
    -
    - 
    - 81  71  61  51  41  31  21  11
    -
    -
    - 92  82  72  62  52  42  32  22
    -
    -
    - 103  93  83  73  63  53  43  33
    -
    -
    - 114  104  94  84  74  64  54  44
    -
    -
    - 125  115  105  95  85  75  65  55
    -
    -
    - 136  126  116  106  96  86  76  66
    -
    -
    - 147  137  127  117  107  97  87  77
    -
    -
    - 158  148  138  128  118  108  98  88
    -
    -
    -
    diff --git a/72_Queen/csharp/Resources/ComputerMove.txt b/72_Queen/csharp/Resources/ComputerMove.txt
    deleted file mode 100644
    index f31b8e32d..000000000
    --- a/72_Queen/csharp/Resources/ComputerMove.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Computer moves to square {0}
    diff --git a/72_Queen/csharp/Resources/Congratulations.txt b/72_Queen/csharp/Resources/Congratulations.txt
    deleted file mode 100644
    index 9f1db2322..000000000
    --- a/72_Queen/csharp/Resources/Congratulations.txt
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -
    -C O N G R A T U L A T I O N S . . .
    -
    -You have won--very well played.
    -It looks like I have met my match.
    -Thanks for playing--I can't win all the time.
    -
    diff --git a/72_Queen/csharp/Resources/Forfeit.txt b/72_Queen/csharp/Resources/Forfeit.txt
    deleted file mode 100644
    index 09858bc15..000000000
    --- a/72_Queen/csharp/Resources/Forfeit.txt
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -
    -It looks like I have won by forfeit.
    -
    diff --git a/72_Queen/csharp/Resources/IWin.txt b/72_Queen/csharp/Resources/IWin.txt
    deleted file mode 100644
    index ced5d7163..000000000
    --- a/72_Queen/csharp/Resources/IWin.txt
    +++ /dev/null
    @@ -1,4 +0,0 @@
    -
    -Nice try, but it looks like I have won.
    -Thanks for playing.
    -
    diff --git a/72_Queen/csharp/Resources/IllegalMove.txt b/72_Queen/csharp/Resources/IllegalMove.txt
    deleted file mode 100644
    index ae4a3bbcc..000000000
    --- a/72_Queen/csharp/Resources/IllegalMove.txt
    +++ /dev/null
    @@ -1,2 +0,0 @@
    -
    -Y O U   C H E A T . . .  Try again
    \ No newline at end of file
    diff --git a/72_Queen/csharp/Resources/IllegalStart.txt b/72_Queen/csharp/Resources/IllegalStart.txt
    deleted file mode 100644
    index 25402bb64..000000000
    --- a/72_Queen/csharp/Resources/IllegalStart.txt
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Please read the instructions again.
    -You have begun illegally.
    -
    diff --git a/72_Queen/csharp/Resources/Instructions.txt b/72_Queen/csharp/Resources/Instructions.txt
    deleted file mode 100644
    index fc2e85b08..000000000
    --- a/72_Queen/csharp/Resources/Instructions.txt
    +++ /dev/null
    @@ -1,15 +0,0 @@
    -We are going to play a game based on one of the chess
    -moves.  Our queen will be able to move only to the left,
    -down, or diagonally down and to the left.
    -
    -The object of the game is to place the queen in the lower
    -left hand square by alternating moves between you and the
    -computer.  The first one to place the queen there wins.
    -
    -You go first and place the queen in any one of the squares
    -on the top row or right hand column.
    -That will be your first move.
    -We alternate moves.
    -You may forfeit by typing '0' as your move.
    -Be sure to press the return key after each response.
    -
    diff --git a/72_Queen/csharp/Resources/InstructionsPrompt.txt b/72_Queen/csharp/Resources/InstructionsPrompt.txt
    deleted file mode 100644
    index 0d311b605..000000000
    --- a/72_Queen/csharp/Resources/InstructionsPrompt.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Do you want instructions
    \ No newline at end of file
    diff --git a/72_Queen/csharp/Resources/MovePrompt.txt b/72_Queen/csharp/Resources/MovePrompt.txt
    deleted file mode 100644
    index 8cb189992..000000000
    --- a/72_Queen/csharp/Resources/MovePrompt.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -What is your move
    \ No newline at end of file
    diff --git a/72_Queen/csharp/Resources/Resource.cs b/72_Queen/csharp/Resources/Resource.cs
    deleted file mode 100644
    index e8297ecad..000000000
    --- a/72_Queen/csharp/Resources/Resource.cs
    +++ /dev/null
    @@ -1,47 +0,0 @@
    -using System.Reflection;
    -using System.Runtime.CompilerServices;
    -
    -namespace Queen.Resources;
    -
    -internal static class Resource
    -{
    -    internal static class Streams
    -    {
    -        public static Stream Title => GetStream();
    -        public static Stream Instructions => GetStream();
    -        public static Stream YesOrNo => GetStream();
    -        public static Stream Board => GetStream();
    -        public static Stream IllegalStart => GetStream();
    -        public static Stream IllegalMove => GetStream();
    -        public static Stream Forfeit => GetStream();
    -        public static Stream IWin => GetStream();
    -        public static Stream Congratulations => GetStream();
    -        public static Stream Thanks => GetStream();
    -    }
    -
    -    internal static class Prompts
    -    {
    -        public static string Instructions => GetPrompt();
    -        public static string Start => GetPrompt();
    -        public static string Move => GetPrompt();
    -        public static string Anyone => GetPrompt();
    -    }
    -
    -    internal static class Strings
    -    {
    -        public static string ComputerMove(Position position) => string.Format(GetString(), position);
    -    }
    -
    -    private static string GetPrompt([CallerMemberName] string? name = null) => GetString($"{name}Prompt");
    -
    -    private static string GetString([CallerMemberName] string? name = null)
    -    {
    -        using var stream = GetStream(name);
    -        using var reader = new StreamReader(stream);
    -        return reader.ReadToEnd();
    -    }
    -
    -    private static Stream GetStream([CallerMemberName] string? name = null) =>
    -        Assembly.GetExecutingAssembly().GetManifestResourceStream($"{typeof(Resource).Namespace}.{name}.txt")
    -            ?? throw new Exception($"Could not find embedded resource stream '{name}'.");
    -}
    \ No newline at end of file
    diff --git a/72_Queen/csharp/Resources/StartPrompt.txt b/72_Queen/csharp/Resources/StartPrompt.txt
    deleted file mode 100644
    index 0b6f395b0..000000000
    --- a/72_Queen/csharp/Resources/StartPrompt.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Where would you like to start
    \ No newline at end of file
    diff --git a/72_Queen/csharp/Resources/Thanks.txt b/72_Queen/csharp/Resources/Thanks.txt
    deleted file mode 100644
    index 2e2e7b635..000000000
    --- a/72_Queen/csharp/Resources/Thanks.txt
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -
    -
    -Ok --- thanks again.
    \ No newline at end of file
    diff --git a/72_Queen/csharp/Resources/Title.txt b/72_Queen/csharp/Resources/Title.txt
    deleted file mode 100644
    index 63549d09c..000000000
    --- a/72_Queen/csharp/Resources/Title.txt
    +++ /dev/null
    @@ -1,5 +0,0 @@
    -                                  Queen
    -               Creative Computing  Morristown, New Jersey
    -
    -
    -
    diff --git a/72_Queen/csharp/Resources/YesOrNo.txt b/72_Queen/csharp/Resources/YesOrNo.txt
    deleted file mode 100644
    index 657bf8aab..000000000
    --- a/72_Queen/csharp/Resources/YesOrNo.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Please answer 'Yes' or 'No'.
    diff --git a/72_Queen/java/Queen.java b/72_Queen/java/Queen.java
    deleted file mode 100644
    index 7dfb6353c..000000000
    --- a/72_Queen/java/Queen.java
    +++ /dev/null
    @@ -1,370 +0,0 @@
    -import java.util.List;
    -import java.util.Optional;
    -import java.util.Scanner;
    -
    -/**
    - * QUEEN
    - * 

    - * Converted from BASIC to Java by Aldrin Misquitta (@aldrinm) - */ -public class Queen { - - public static final int WINNING_POSITION = 158; - public static final int FORFEIT_MOVE = 0; - - // @formatter:off - private static final int[] S = { - 81, 71, 61, 51, 41, 31, 21, 11, - 92, 82, 72, 62, 52, 42, 32, 22, - 103, 93, 83, 73, 63, 53, 43, 33, - 114, 104, 94, 84, 74, 64, 54, 44, - 125, 115, 105, 95, 85, 75, 65, 55, - 136, 126, 116, 106, 96, 86, 76, 66, - 147, 137, 127, 117, 107, 97, 87, 77, - 158, 148, 138, 128, 118, 108, 98, 88 - }; - // @formatter:on - - private static final Scanner scanner = new Scanner(System.in); - - - public static void main(String[] args) { - printWithTab("QUEEN", 33); - printWithTab("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY", 15); - System.out.println("\n\n"); - - askAndShowInstructions(); - - boolean anotherGame; - do { - printBoard(); - - Move firstMove = getUserFirstMove(); - if (firstMove.move == 0) { - printWonByForfeit(); - } - - if (isTopmostRowOrRightmostColumn(firstMove)) { - playOneGame(firstMove); - } - - anotherGame = askForAnotherGame(); - - } while (anotherGame); - - - System.out.println("\nOK --- THANKS AGAIN."); - } - - /** - * Play one game starting with the first move from the user - */ - private static void playOneGame(Move firstMove) { - boolean gameInProgress = true; - Move userMove = firstMove; - - while (gameInProgress) { - - if (userMove.move == WINNING_POSITION) { - //players wins - printCongratulatoryMessage(); - gameInProgress = false; - } else { - - ComputerMove computerMove = getComputerMove(userMove); - - System.out.printf("COMPUTER MOVES TO SQUARE %d\n", computerMove.move); - - if (computerMove.move == WINNING_POSITION) { - printComputerWins(); - gameInProgress = false; - } else { - userMove = getValidUserMove(computerMove); - - if (userMove.move == FORFEIT_MOVE) { - printWonByForfeit(); - gameInProgress = false; - } else if (userMove.move == WINNING_POSITION) { - printCongratulatoryMessage(); - gameInProgress = false; - } - } - } - } - } - - /** - * Get the user's first move - */ - private static Move getUserFirstMove() { - boolean validMove; - Move move; - do { - System.out.print("WHERE WOULD YOU LIKE TO START? "); - int movePosition = scanner.nextInt(); - move = new Move(movePosition); - validMove = false; - if (!isTopmostRowOrRightmostColumn(move)) { - System.out.println("PLEASE READ THE DIRECTIONS AGAIN."); - System.out.println("YOU HAVE BEGUN ILLEGALLY."); - System.out.println(); - } else { - validMove = true; - } - scanner.nextLine(); - } while (!validMove); - return move; - } - - /** - * Prompt and get a valid move from the user. Uses the computer's latest move to validate the next move. - */ - private static Move getValidUserMove(ComputerMove latestComputerMove) { - boolean validUserMove = false; - Move userMove = null; - while (!validUserMove) { - userMove = getUserMove(); - if (!validateUserMove(userMove, latestComputerMove)) { - System.out.println("\nY O U C H E A T . . . TRY AGAIN"); - } else { - validUserMove = true; - } - } - return userMove; - } - - private static void printWonByForfeit() { - System.out.println("\nIT LOOKS LIKE I HAVE WON BY FORFEIT.\n"); - } - - private static boolean validateUserMove(Move userMove, ComputerMove computerMove) { - if (userMove.move <= computerMove.move) { - return false; - } - - if (userMove.move == FORFEIT_MOVE || userMove.move == WINNING_POSITION) { - return true; - } - - int tensValueUser = userMove.move / 10; - int unitsValueUser = userMove.move - (tensValueUser * 10); - int unitsValueComputer = computerMove.u; - int tensValueComputer = computerMove.t; - int p = unitsValueUser - unitsValueComputer; - if (p != 0) { - if ((tensValueUser - tensValueComputer) != p) { - return (tensValueUser - tensValueComputer) == 2 * p; - } else { - return true; - } - } else { - int l = tensValueUser - tensValueComputer; - return l > 0; - } - } - - private static Move getUserMove() { - System.out.print("WHAT IS YOUR MOVE? "); - int movePosition = scanner.nextInt(); - scanner.nextLine(); - return new Move(movePosition); - } - - private static void printComputerWins() { - System.out.println("\nNICE TRY, BUT IT LOOKS LIKE I HAVE WON."); - System.out.println("THANKS FOR PLAYING.\n"); - } - - private static boolean askForAnotherGame() { - System.out.print("ANYONE ELSE CARE TO TRY? "); - do { - String response = Queen.scanner.nextLine(); - if (response.equals("NO")) { - return false; - } else if (response.equals("YES")) { - return true; - } else { - System.out.println("PLEASE ANSWER 'YES' OR 'NO'."); - } - } while (true); - } - - private static boolean isTopmostRowOrRightmostColumn(Move move) { - return move.unitsPlaceValue == 1 || move.unitsPlaceValue == move.tensPlaceValue; - } - - private static ComputerMove getComputerMove(Move userMove) { - int unitsValueUser = userMove.unitsPlaceValue; - int tensValueUser = userMove.tensPlaceValue; - - List moveRandomlyFromPositions = List.of(41, 44, 73, 75, 126, 127); - - if (moveRandomlyFromPositions.contains(userMove.move)) { - //random move - return getMovePositionInRandomDirection(unitsValueUser, tensValueUser); - } else { - - for (int k = 7; k >= 1; k--) { - // consider same row first, left-most position - Optional move = evaluatePositionAndGetMove(unitsValueUser, tensValueUser + k); - if (move.isPresent()) return move.get(); - - //try same column, bottom-most - move = evaluatePositionAndGetMove(unitsValueUser + k, tensValueUser + k); - if (move.isPresent()) return move.get(); - - //now left-most at the bottom-most - move = evaluatePositionAndGetMove(unitsValueUser + k, tensValueUser + k + k); - if (move.isPresent()) return move.get(); - } - - //else move one step in a random direction - return getMovePositionInRandomDirection(unitsValueUser, tensValueUser); - } - - } - - private static Optional evaluatePositionAndGetMove(int newUnitsValue, int newTensValue) { - EvaluationResult result = evaluateComputerMove(newUnitsValue, newTensValue); - if (result.favourablePosition) { - return Optional.of(new ComputerMove(result.move)); - } - return Optional.empty(); - } - - private static EvaluationResult evaluateComputerMove(int u, int t) { - int m = 10 * t + u; - if (m == 158 || m == 127 || m == 126 || m == 75 || m == 73) { - return new EvaluationResult(m, true); - } else { - return new EvaluationResult(m, false); - } - } - - private static void printCongratulatoryMessage() { - System.out.println(); - System.out.println("C O N G R A T U L A T I O N S . . ."); - System.out.println(); - System.out.println("YOU HAVE WON--VERY WELL PLAYED."); - System.out.println("IT LOOKS LIKE I HAVE MET MY MATCH."); - System.out.println("THANKS FOR PLAYING---I CAN'T WIN ALL THE TIME."); - System.out.println(); - - } - - private static ComputerMove getMovePositionInRandomDirection(int u1, int t1) { - double randomValue = Math.random(); - - if (randomValue > 0.6) { - // Move directly down - return new ComputerMove(calculateMove(u1, t1, 1, 1)); - } else if (randomValue > 0.3) { - // Move down left - return new ComputerMove(calculateMove(u1, t1, 1, 2)); - } else { - // Move left - return new ComputerMove(calculateMove(u1, t1, 0, 1)); - } - } - - private static int calculateMove(int u, int t, int uChange, int tChange) { - int newU = u + uChange; - int newT = t + tChange; - return 10 * newT + newU; // Combine units and tens to corresponding position value - } - - - private static void printBoard() { - System.out.println(); - for (int A = 0; A <= 7; A++) { - for (int B = 0; B <= 7; B++) { - int I = 8 * A + B; - System.out.printf(" %d ", S[I]); - } - System.out.println(); - System.out.println(); - System.out.println(); - } - System.out.println(); - } - - private static void askAndShowInstructions() { - do { - System.out.print("DO YOU WANT INSTRUCTIONS? "); - String wish = scanner.nextLine(); - if (wish.equals("NO")) { - break; - } else if (wish.equals("YES")) { - showInstructions(); - break; - } else { - System.out.println("PLEASE ANSWER 'YES' OR 'NO'."); - } - } while (true); - } - - private static void printWithTab(String message, int tab) { - for (int i = 0; i < tab; i++) { - System.out.print(" "); - } - System.out.println(message); - } - - - private static void showInstructions() { - System.out.println("WE ARE GOING TO PLAY A GAME BASED ON ONE OF THE CHESS"); - System.out.println("MOVES. OUR QUEEN WILL BE ABLE TO MOVE ONLY TO THE LEFT,"); - System.out.println("DOWN, OR DIAGONALLY DOWN AND TO THE LEFT."); - System.out.println(); - System.out.println("THE OBJECT OF THE GAME IS TO PLACE THE QUEEN IN THE LOWER"); - System.out.println("LEFT HAND SQUARE BY ALTERNATING MOVES BETWEEN YOU AND THE"); - System.out.println("COMPUTER. THE FIRST ONE TO PLACE THE QUEEN THERE WINS."); - System.out.println(); - System.out.println("YOU GO FIRST AND PLACE THE QUEEN IN ANY ONE OF THE SQUARES"); - System.out.println("ON THE TOP ROW OR RIGHT HAND COLUMN."); - System.out.println("THAT WILL BE YOUR FIRST MOVE."); - System.out.println("WE ALTERNATE MOVES."); - System.out.println("YOU MAY FORFEIT BY TYPING '0' AS YOUR MOVE."); - System.out.println("BE SURE TO PRESS THE RETURN KEY AFTER EACH RESPONSE."); - System.out.println(); - } - - - private static class ComputerMove { - private final int move; - private final int u; - private final int t; - - private ComputerMove(int move) { - this.move = move; - this.t = move / 10; - this.u = move - (t * 10); - } - - } - - private static class EvaluationResult { - private final int move; - private final boolean favourablePosition; - - public EvaluationResult(int move, boolean favourablePosition) { - this.move = move; - this.favourablePosition = favourablePosition; - } - - - } - - private static class Move { - private final int move; - private final int unitsPlaceValue; - private final int tensPlaceValue; - - private Move(int move) { - this.move = move; - this.tensPlaceValue = move / 10; - this.unitsPlaceValue = move % 10; - } - - } -} diff --git a/72_Queen/javascript/queen.html b/72_Queen/javascript/queen.html index 0613d97fe..ce1918135 100644 --- a/72_Queen/javascript/queen.html +++ b/72_Queen/javascript/queen.html @@ -1,10 +1,9 @@ QUEEN - -

    
    +
    
     
     
     
    diff --git a/72_Queen/javascript/queen.js b/72_Queen/javascript/queen.js
    index f07e1dd51..0adee46c5 100644
    --- a/72_Queen/javascript/queen.js
    +++ b/72_Queen/javascript/queen.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    @@ -147,7 +147,7 @@ async function main()
         print("\n");
         print("\n");
         print("\n");
    -
    +    
         while (1) {
             print("DO YOU WANT INSTRUCTIONS");
             str = await input();
    diff --git a/72_Queen/kotlin/README.md b/72_Queen/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/72_Queen/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/72_Queen/lua/README.md b/72_Queen/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/72_Queen/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/72_Queen/pascal/README.md b/72_Queen/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/72_Queen/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/72_Queen/python/.flake8 b/72_Queen/python/.flake8
    deleted file mode 100644
    index 6f094a9de..000000000
    --- a/72_Queen/python/.flake8
    +++ /dev/null
    @@ -1,4 +0,0 @@
    -[flake8]
    -max-line-length = 88
    -select = C,E,F,W,B,B950
    -extend-ignore = E203, E501
    diff --git a/72_Queen/python/README.md b/72_Queen/python/README.md
    index bfa388b7b..781945ec4 100644
    --- a/72_Queen/python/README.md
    +++ b/72_Queen/python/README.md
    @@ -1,4 +1,3 @@
     Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
     
    -Conversion to [Python](https://www.python.org/about/) by Christopher Phan.
    -Supports Python version 3.8 or later.
    +Conversion to [Python](https://www.python.org/about/)
    diff --git a/72_Queen/python/queen.py b/72_Queen/python/queen.py
    deleted file mode 100755
    index 327c43f6e..000000000
    --- a/72_Queen/python/queen.py
    +++ /dev/null
    @@ -1,272 +0,0 @@
    -#!/usr/bin/env python3
    -"""
    -Implementation of Queens game in Python 3.
    -
    -Original game in BASIC by David Ahl in _BASIC Comuter Games_, published in 1978,
    -as reproduced here:
    -    https://www.atariarchives.org/basicgames/showpage.php?page=133
    -
    -Port to Python 3 by Christopher L. Phan 
    -
    -Supports Python version 3.8 or later.
    -"""
    -
    -from random import random
    -from typing import Final, FrozenSet, Optional, Tuple
    -
    -########################################################################################
    -#                                  Optional configs
    -########################################################################################
    -# You can edit these variables to change the behavior of the game.
    -#
    -# The original implementation has a bug that allows a player to move off the board,
    -# e.g. start at the nonexistant space 91. Change the variable FIX_BOARD_BUG to ``True``
    -# to fix this behavior.
    -#
    -
    -FIX_BOARD_BUG: Final[bool] = False
    -
    -# In the original implementation, the board is only printed once. Change the variable
    -# SHOW_BOARD_ALWAYS to ``True`` to display the board every time.
    -
    -SHOW_BOARD_ALWAYS: Final[bool] = False
    -
    -# In the original implementaiton, the board is printed a bit wonky because of the
    -# differing widths of the numbers. Change the variable ALIGNED_BOARD to ``True`` to
    -# fix this.
    -
    -ALIGNED_BOARD: Final[bool] = False
    -
    -########################################################################################
    -
    -INSTR_TXT: Final[
    -    str
    -] = """WE ARE GOING TO PLAY A GAME BASED ON ONE OF THE CHESS
    -MOVES.  OUR QUEEN WILL BE ABLE TO MOVE ONLY TO THE LEFT,
    -DOWN, OR DIAGONALLY DOWN AND TO THE LEFT.
    -
    -THE OBJECT OF THE GAME IS TO PLACE THE QUEEN IN THE LOWER
    -LEFT HAND SQUARE BY ALTERNATING MOVES BETWEEN YOU AND THE
    -COMPUTER.  THE FIRST ONE TO PLACE THE QUEEN THERE WINS.
    -
    -YOU GO FIRST AND PLACE THE QUEEN IN ANY ONE OF THE SQUARES
    -ON THE TOP ROW OR RIGHT HAND COLUMN.
    -THAT WILL BE YOUR FIRST MOVE.
    -WE ALTERNATE MOVES.
    -YOU MAY FORFEIT BY TYPING '0' AS YOUR MOVE.
    -BE SURE TO PRESS THE RETURN KEY AFTER EACH RESPONSE.
    -
    -"""
    -
    -
    -WIN_MSG: Final[
    -    str
    -] = """C O N G R A T U L A T I O N S . . .
    -
    -YOU HAVE WON--VERY WELL PLAYED.
    -IT LOOKS LIKE I HAVE MET MY MATCH.
    -THANKS FOR PLAYING---I CAN'T WIN ALL THE TIME.
    -
    -"""
    -
    -LOSE_MSG: Final[
    -    str
    -] = """
    -NICE TRY, BUT IT LOOKS LIKE I HAVE WON.
    -THANKS FOR PLAYING.
    -
    -"""
    -
    -
    -def loc_to_num(location: Tuple[int, int], fix_align: bool = False) -> str:
    -    """Convert a position given by row, column into a space number."""
    -    row, col = location
    -    out_str: str = f"{row + 8 - col}{row + 1}"
    -    return out_str if not fix_align or len(out_str) == 3 else f"{out_str} "
    -
    -
    -GAME_BOARD: Final[str] = (
    -    "\n"
    -    + "\n\n\n".join(
    -        "".join(f" {loc_to_num((row, col), ALIGNED_BOARD)} " for col in range(8))
    -        for row in range(8)
    -    )
    -    + "\n\n\n"
    -)
    -
    -
    -def num_to_loc(num: int) -> Tuple[int, int]:
    -    """Convert a space number into a position given by row, column."""
    -    row: int = num % 10 - 1
    -    col: int = row + 8 - (num - row - 1) // 10
    -    return row, col
    -
    -
    -# The win location
    -WIN_LOC: Final[Tuple[int, int]] = (7, 0)
    -
    -# These are the places (other than the win condition) that the computer will always
    -# try to move into.
    -COMPUTER_SAFE_SPOTS: Final[FrozenSet[Tuple[int, int]]] = frozenset(
    -    [
    -        (2, 3),
    -        (4, 5),
    -        (5, 1),
    -        (6, 2),
    -    ]
    -)
    -
    -# These are the places that the computer will always try to move into.
    -COMPUTER_PREF_MOVES: Final[FrozenSet[Tuple[int, int]]] = (
    -    COMPUTER_SAFE_SPOTS | frozenset([WIN_LOC])
    -)
    -
    -# These are the locations (not including the win location) from which either player can
    -# force a win (but the computer will always choose one of the COMPUTER_PREF_MOVES).
    -SAFE_SPOTS: Final[FrozenSet[Tuple[int, int]]] = COMPUTER_SAFE_SPOTS | frozenset(
    -    [
    -        (0, 4),
    -        (3, 7),
    -    ]
    -)
    -
    -
    -def intro() -> None:
    -    """Print the intro and print instructions if desired."""
    -    print(" " * 33 + "Queen")
    -    print(" " * 15 + "Creative Computing  Morristown, New Jersey")
    -    print("\n" * 2)
    -    if ask("DO YOU WANT INSTRUCTIONS"):
    -        print(INSTR_TXT)
    -
    -
    -def get_move(current_loc: Optional[Tuple[int, int]]) -> Tuple[int, int]:
    -    """Get the next move from the player."""
    -    prompt: str
    -    player_resp: str
    -    move_raw: int
    -    new_row: int
    -    new_col: int
    -    if current_loc is None:  # It's the first turn
    -        prompt = "WHERE WOULD YOU LIKE TO START? "
    -    else:
    -        prompt = "WHAT IS YOUR MOVE? "
    -        row, col = current_loc
    -    while True:
    -        player_resp = input(prompt).strip()
    -        try:
    -            move_raw = int(player_resp)
    -            if move_raw == 0:  # Forfeit
    -                return 8, 8
    -            new_row, new_col = num_to_loc(move_raw)
    -            if current_loc is None:
    -                if (new_row == 0 or new_col == 7) and (
    -                    not FIX_BOARD_BUG or (new_col >= 0 and new_row < 8)
    -                ):
    -                    return new_row, new_col
    -                else:
    -                    prompt = (
    -                        "PLEASE READ THE DIRECTIONS AGAIN.\n"
    -                        "YOU HAVE BEGUN ILLEGALLY.\n\n"
    -                        "WHERE WOULD YOU LIKE TO START? "
    -                    )
    -            elif (
    -                (new_row == row and new_col < col)  # move left
    -                or (new_col == col and new_row > row)  # move down
    -                or (new_row - row == col - new_col)  # move diag left and down
    -            ) and (not FIX_BOARD_BUG or (new_col >= 0 and new_row < 8)):
    -                return new_row, new_col
    -            else:
    -                prompt = "Y O U   C H E A T . . .  TRY AGAIN? "
    -
    -        except ValueError:
    -            prompt = "!NUMBER EXPECTED - RETRY INPUT LINE\n? "
    -
    -
    -def random_computer_move(location: Tuple[int, int]) -> Tuple[int, int]:
    -    """Make a random move."""
    -    row, col = location
    -    if (z := random()) > 0.6:
    -        # Move down one space
    -        return row + 1, col
    -    elif z > 0.3:
    -        # Move diagonaly (left and down) one space
    -        return row + 1, col - 1
    -    else:
    -        # Move left one space
    -        return row, col - 1
    -
    -
    -def computer_move(location: Tuple[int, int]) -> Tuple[int, int]:
    -    """Get the computer's move."""
    -    # If the player has made an optimal move, then choose a random move
    -    if location in SAFE_SPOTS:
    -        return random_computer_move(location)
    -    # We don't need to implmement the logic of checking for the player's win,
    -    # because that is checked before this function is called.
    -    row, col = location
    -    for k in range(7, 0, -1):
    -        # If the computer can move left k spaces and end in up in a safe spot or win,
    -        # do it.
    -        if (new_loc := (row, col - k)) in COMPUTER_PREF_MOVES:
    -            return new_loc
    -        # If the computer can move down k spaces and end up in a safe spot or win, do it.
    -        if (new_loc := (row + k, col)) in COMPUTER_PREF_MOVES:
    -            return new_loc
    -        # If the computer can move diagonally k spaces and end up in a safe spot or win,
    -        # do it.
    -        if (new_loc := (row + k, col - k)) in COMPUTER_PREF_MOVES:
    -            return new_loc
    -        # As a fallback, do a random move. (NOTE: This shouldn't actally happen--it
    -        # should always be possible to make an optimal move if the player doesn't play
    -        # in a location in SAFE_SPOTS.
    -    return random_computer_move(location)
    -
    -
    -def main_game() -> None:
    -    """Execute the main game."""
    -    game_over: bool = False
    -    location: Optional[Tuple[int, int]] = None  # Indicate it is the first turn
    -    while not game_over:
    -        location = get_move(location)
    -        if location == (8, 8):  # (8, 8) is returned when the player enters 0
    -            print("\nIT LOOKS LIKE I HAVE WON BY FORFEIT.\n")
    -            game_over = True
    -        elif location == WIN_LOC:  # Player wins (in lower left corner)
    -            print(WIN_MSG)
    -            game_over = True
    -        else:
    -            location = computer_move(location)
    -            print(f"COMPUTER MOVES TO SQUARE {loc_to_num(location)}")
    -            if location == WIN_LOC:  # Computer wins (in lower left corner)
    -                print(LOSE_MSG)
    -                game_over = True
    -        # The default behavior is not to show the board each turn, but
    -        # this can be modified by changing a flag at the start of the file.
    -        if not game_over and SHOW_BOARD_ALWAYS:
    -            print(GAME_BOARD)
    -
    -
    -def ask(prompt: str) -> bool:
    -    """Ask a yes/no question until user gives an understandable response."""
    -    inpt: str
    -    while True:
    -        # Normalize input to uppercase, no whitespace, then get first character
    -        inpt = input(f"{prompt}? ").upper().strip()[0]
    -        print()
    -        if inpt == "N":
    -            return False
    -        elif inpt == "Y":
    -            return True
    -        print("PLEASE ANSWER 'YES' OR 'NO'.")
    -    return False
    -
    -
    -if __name__ == "__main__":
    -    intro()
    -    still_playing: bool = True
    -    while still_playing:
    -        print(GAME_BOARD)
    -        main_game()
    -        still_playing = ask("ANYONE ELSE CARE TO TRY")
    -    print("\nOK --- THANKS AGAIN.")
    diff --git a/72_Queen/queen.bas b/72_Queen/queen.bas
    index e7b808105..9672338c6 100644
    --- a/72_Queen/queen.bas
    +++ b/72_Queen/queen.bas
    @@ -104,7 +104,7 @@
     3290 REM     PLAYER WINS
     3300 PRINT
     3310 PRINT "C O N G R A T U L A T I O N S . . ."
    -3320 PRINT
    +3320 PRINT 
     3330 PRINT "YOU HAVE WON--VERY WELL PLAYED."
     3340 PRINT "IT LOOKS LIKE I HAVE MET MY MATCH."
     3350 PRINT "THANKS FOR PLAYING---I CAN'T WIN ALL THE TIME."
    @@ -130,7 +130,7 @@
     4000 PRINT "ANYONE ELSE CARE TO TRY";
     4010 INPUT Q$
     4020 PRINT
    -4030 IF Q$="YES" THEN 30
    +4030 IF Q$="YES" THEN 30 
     4040 IF Q$="NO" THEN 4050
     4042 PRINT "PLEASE ANSWER 'YES' OR 'NO'."
     4045 GOTO 4000
    diff --git a/72_Queen/rust/Cargo.lock b/72_Queen/rust/Cargo.lock
    deleted file mode 100644
    index 4fe2abbea..000000000
    --- a/72_Queen/rust/Cargo.lock
    +++ /dev/null
    @@ -1,75 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.10"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.147"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/72_Queen/rust/Cargo.toml b/72_Queen/rust/Cargo.toml
    deleted file mode 100644
    index 3b1d02f52..000000000
    --- a/72_Queen/rust/Cargo.toml
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -[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/72_Queen/rust/src/ai.rs b/72_Queen/rust/src/ai.rs
    deleted file mode 100644
    index cf4d03103..000000000
    --- a/72_Queen/rust/src/ai.rs
    +++ /dev/null
    @@ -1,30 +0,0 @@
    -use crate::util;
    -
    -const PREFERRED_MOVES: [u8; 5] = [158, 72, 75, 126, 127];
    -const SAFE_MOVES: [u8; 2] = [44, 41];
    -
    -pub fn get_computer_move(loc: u8) -> u8 {
    -    if SAFE_MOVES.contains(&loc) {
    -        return random_move(loc);
    -    }
    -
    -    for m in PREFERRED_MOVES {
    -        if util::is_move_legal(loc, m) && m != loc {
    -            return m;
    -        }
    -    }
    -
    -    random_move(loc)
    -}
    -
    -fn random_move(l: u8) -> u8 {
    -    let r: f32 = rand::random();
    -
    -    if r > 0.6 {
    -        l + 11
    -    } else if r > 0.3 {
    -        l + 21
    -    } else {
    -        l + 10
    -    }
    -}
    diff --git a/72_Queen/rust/src/game.rs b/72_Queen/rust/src/game.rs
    deleted file mode 100644
    index 2445980b6..000000000
    --- a/72_Queen/rust/src/game.rs
    +++ /dev/null
    @@ -1,180 +0,0 @@
    -use crate::{
    -    ai,
    -    util::{self, prompt, PromptResult::*},
    -};
    -
    -pub struct Game {
    -    blocks: [u8; 64],
    -    location: Option,
    -    player_move: bool,
    -    show_board: bool,
    -    forfeit: bool,
    -}
    -
    -impl Game {
    -    pub fn new() -> Self {
    -        let mut blocks = [0 as u8; 64];
    -
    -        let mut block = 91;
    -        let mut i = 0;
    -
    -        for _ in 0..8 {
    -            for _ in 0..8 {
    -                block -= 10;
    -                blocks[i] = block;
    -                i += 1;
    -            }
    -            block += 91;
    -        }
    -
    -        Game {
    -            blocks,
    -            location: None,
    -            player_move: true,
    -            show_board: false,
    -            forfeit: false,
    -        }
    -    }
    -
    -    pub fn update(&mut self) -> bool {
    -        let mut still_going = true;
    -
    -        if let Some(l) = self.location {
    -            if self.show_board {
    -                self.draw(l);
    -            }
    -
    -            match self.player_move {
    -                true => self.player_move(l),
    -                false => {
    -                    std::thread::sleep(std::time::Duration::from_secs(1));
    -                    let loc = ai::get_computer_move(l);
    -                    println!("COMPUTER MOVES TO SQUARE {}", loc);
    -                    self.location = Some(loc);
    -                }
    -            }
    -
    -            still_going = self.check_location();
    -        } else {
    -            self.set_start_location();
    -        }
    -        self.player_move = !self.player_move;
    -        still_going
    -    }
    -
    -    fn set_start_location(&mut self) {
    -        self.draw(0);
    -
    -        if let YesNo(yes) = prompt(Some(false), "UPDATE BOARD?") {
    -            self.show_board = yes;
    -        }
    -
    -        loop {
    -            if let Numeric(n) = prompt(Some(true), "WHERE WOULD YOU LIKE TO START?") {
    -                let n = n as u8;
    -
    -                if util::is_legal_start(n) {
    -                    self.location = Some(n);
    -                    break;
    -                } else {
    -                    println!("PLEASE READ THE DIRECTIONS AGAIN.\nYOU HAVE BEGUN ILLEGALLY.\n")
    -                }
    -            }
    -        }
    -    }
    -
    -    fn player_move(&mut self, loc: u8) {
    -        loop {
    -            if let Numeric(n) = prompt(Some(true), "WHAT IS YOUR MOVE?") {
    -                if n == 0 {
    -                    self.forfeit = true;
    -                    break;
    -                }
    -
    -                let n = n as u8;
    -
    -                if util::is_move_legal(loc, n) {
    -                    self.location = Some(n);
    -                    break;
    -                } else {
    -                    println!("Y O U   C H E A T . . .  TRY AGAIN? ");
    -                }
    -            }
    -        }
    -    }
    -
    -    fn check_location(&self) -> bool {
    -        if self.location == Some(158) {
    -            util::print_gameover(self.player_move, self.forfeit);
    -            return false;
    -        }
    -
    -        true
    -    }
    -
    -    fn draw(&self, loc: u8) {
    -        let draw_h_border = |top: Option| {
    -            let corners;
    -
    -            if let Some(top) = top {
    -                if top {
    -                    corners = ("┌", "┐", "┬");
    -                } else {
    -                    corners = ("└", "┘", "┴");
    -                }
    -            } else {
    -                corners = ("├", "┤", "┼");
    -            }
    -
    -            print!("{}", corners.0);
    -
    -            for i in 0..8 {
    -                let corner = if i == 7 { corners.1 } else { corners.2 };
    -
    -                print!("───{}", corner);
    -            }
    -            println!();
    -        };
    -
    -        draw_h_border(Some(true));
    -
    -        let mut column = 0;
    -        let mut row = 0;
    -
    -        for block in self.blocks.iter() {
    -            let block = *block as u8;
    -
    -            let n = if block == loc {
    -                format!("│{}", "*Q*".to_string())
    -            } else {
    -                let b = block.to_string();
    -
    -                if block > 99 {
    -                    format!("│{}", b)
    -                } else {
    -                    format!("│{} ", b)
    -                }
    -            };
    -
    -            print!("{}", n);
    -
    -            column += 1;
    -
    -            if column != 1 && (column % 8) == 0 {
    -                column = 0;
    -                row += 1;
    -
    -                print!("│");
    -                println!();
    -
    -                if row == 8 {
    -                    draw_h_border(Some(false));
    -                } else {
    -                    draw_h_border(None);
    -                }
    -            }
    -        }
    -
    -        println!();
    -    }
    -}
    diff --git a/72_Queen/rust/src/main.rs b/72_Queen/rust/src/main.rs
    deleted file mode 100644
    index 57d65e0f4..000000000
    --- a/72_Queen/rust/src/main.rs
    +++ /dev/null
    @@ -1,29 +0,0 @@
    -use crate::{
    -    game::Game,
    -    util::{prompt, PromptResult::*},
    -};
    -
    -mod game;
    -mod util;
    -mod ai;
    -
    -fn main() {
    -    util::intro();
    -
    -    loop {
    -        let mut game = Game::new();
    -
    -        loop {
    -            if !game.update() {
    -                break;
    -            }
    -        }
    -
    -        if let YesNo(y) = prompt(Some(false), "\nANYONE ELSE CARE TO TRY?") {
    -            if !y {
    -                println!("OK --- THANKS AGAIN.");
    -                break;
    -            }
    -        }
    -    }
    -}
    diff --git a/72_Queen/rust/src/util.rs b/72_Queen/rust/src/util.rs
    deleted file mode 100644
    index 3439aabb0..000000000
    --- a/72_Queen/rust/src/util.rs
    +++ /dev/null
    @@ -1,114 +0,0 @@
    -use std::io;
    -
    -pub enum PromptResult {
    -    Normal(String),
    -    YesNo(bool),
    -    Numeric(i32),
    -}
    -
    -pub fn prompt(is_numeric: Option, msg: &str) -> PromptResult {
    -    use PromptResult::*;
    -
    -    println!("{msg}");
    -
    -    loop {
    -        let mut input = String::new();
    -
    -        io::stdin()
    -            .read_line(&mut input)
    -            .expect("**Failed to read input**");
    -
    -        if let Some(is_numeric) = is_numeric {
    -            let input = input.trim();
    -
    -            if is_numeric {
    -                if let Ok(n) = input.parse::() {
    -                    return Numeric(n);
    -                }
    -                println!("PLEASE ENTER A VALID NUMBER!");
    -            } else {
    -                match input.to_uppercase().as_str() {
    -                    "YES" | "Y" => return YesNo(true),
    -                    "NO" | "N" => return YesNo(false),
    -                    _ => println!("PLEASE ENTER (Y)ES OR (N)O."),
    -                }
    -            }
    -        } else {
    -            return Normal(input);
    -        }
    -    }
    -}
    -
    -pub fn is_move_legal(loc: u8, mov: u8) -> bool {
    -    let dt: i32 = mov as i32 - loc as i32;
    -
    -    if dt.is_negative() {
    -        return false;
    -    }
    -
    -    if (dt % 21) == 0 || (dt % 10) == 0 || (dt % 11) == 0 {
    -        return true;
    -    }
    -
    -    false
    -}
    -
    -pub fn is_legal_start(loc: u8) -> bool {
    -    let mut legal_spots = Vec::new();
    -    let start: u8 = 11;
    -
    -    legal_spots.push(start);
    -
    -    for i in 1..=7 {
    -        legal_spots.push(start + (10 * i));
    -    }
    -
    -    for i in 1..=7 {
    -        legal_spots.push(start + (11 * i));
    -    }
    -
    -    if legal_spots.contains(&loc) {
    -        true
    -    } else {
    -        false
    -    }
    -}
    -
    -pub fn print_gameover(win: bool, forfeit: bool) {
    -    if win {
    -        println!("C O N G R A T U L A T I O N S . . .\nYOU HAVE WON--VERY WELL PLAYED.");
    -        println!(
    -            "IT LOOKS LIKE I HAVE MET MY MATCH.\nTHANKS FOR PLAYING---I CAN'T WIN ALL THE TIME.\n",
    -        );
    -    } else {
    -        if forfeit {
    -            println!("IT LOOKS LIKE I HAVE WON BY FORFEIT.\n");
    -        } else {
    -            println!("NICE TRY, BUT IT LOOKS LIKE I HAVE WON.\nTHANKS FOR PLAYING.");
    -        }
    -    }
    -}
    -
    -pub fn intro() {
    -    println!("\n\n\t\tQUEEN");
    -    println!("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
    -
    -    if let PromptResult::YesNo(yes) = prompt(Some(false), "DO YOU WANT INSTRUCTIONS?") {
    -        if yes {
    -            println!(
    -                r#"WE ARE GOING TO PLAY A GAME BASED ON ONE OF THE CHESS
    -MOVES.  OUR QUEEN WILL BE ABLE TO MOVE ONLY TO THE LEFT,
    -DOWN, OR DIAGONALLY DOWN AND TO THE LEFT.
    -THE OBJECT OF THE GAME IS TO PLACE THE QUEEN IN THE LOWER
    -LEFT HAND SQUARE BY ALTERNATING MOVES BETWEEN YOU AND THE
    -COMPUTER.  THE FIRST ONE TO PLACE THE QUEEN THERE WINS.
    -YOU GO FIRST AND PLACE THE QUEEN IN ANY ONE OF THE SQUARES
    -ON THE TOP ROW OR RIGHT HAND COLUMN.
    -THAT WILL BE YOUR FIRST MOVE.
    -WE ALTERNATE MOVES.
    -YOU MAY FORFEIT BY TYPING '0' AS YOUR MOVE.
    -BE SURE TO PRESS THE RETURN KEY AFTER EACH RESPONSE."#
    -            )
    -        }
    -    }
    -}
    diff --git a/72_Queen/vbnet/Queen.sln b/72_Queen/vbnet/Queen.sln
    deleted file mode 100644
    index 33f87b9a6..000000000
    --- a/72_Queen/vbnet/Queen.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 19b46d900..000000000
    --- a/72_Queen/vbnet/Queen.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Queen
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/73_Reverse/README.md b/73_Reverse/README.md
    index 1070c1175..a753e8a81 100644
    --- a/73_Reverse/README.md
    +++ b/73_Reverse/README.md
    @@ -29,7 +29,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/73_Reverse/csharp/Reverse.Tests/Generators/PositiveIntegerGenerator.cs b/73_Reverse/csharp/Reverse/Reverse.Tests/Generators/PositiveIntegerGenerator.cs
    similarity index 100%
    rename from 73_Reverse/csharp/Reverse.Tests/Generators/PositiveIntegerGenerator.cs
    rename to 73_Reverse/csharp/Reverse/Reverse.Tests/Generators/PositiveIntegerGenerator.cs
    diff --git a/73_Reverse/csharp/Reverse.Tests/Reverse.Tests.csproj b/73_Reverse/csharp/Reverse/Reverse.Tests/Reverse.Tests.csproj
    similarity index 100%
    rename from 73_Reverse/csharp/Reverse.Tests/Reverse.Tests.csproj
    rename to 73_Reverse/csharp/Reverse/Reverse.Tests/Reverse.Tests.csproj
    diff --git a/73_Reverse/csharp/Reverse.Tests/ReverserTests.cs b/73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs
    similarity index 100%
    rename from 73_Reverse/csharp/Reverse.Tests/ReverserTests.cs
    rename to 73_Reverse/csharp/Reverse/Reverse.Tests/ReverserTests.cs
    diff --git a/73_Reverse/csharp/Reverse.Tests/TestReverser.cs b/73_Reverse/csharp/Reverse/Reverse.Tests/TestReverser.cs
    similarity index 100%
    rename from 73_Reverse/csharp/Reverse.Tests/TestReverser.cs
    rename to 73_Reverse/csharp/Reverse/Reverse.Tests/TestReverser.cs
    diff --git a/73_Reverse/csharp/Reverse.sln b/73_Reverse/csharp/Reverse/Reverse.sln
    similarity index 100%
    rename from 73_Reverse/csharp/Reverse.sln
    rename to 73_Reverse/csharp/Reverse/Reverse.sln
    diff --git a/73_Reverse/csharp/Reverse/Program.cs b/73_Reverse/csharp/Reverse/Reverse/Program.cs
    similarity index 100%
    rename from 73_Reverse/csharp/Reverse/Program.cs
    rename to 73_Reverse/csharp/Reverse/Reverse/Program.cs
    diff --git a/73_Reverse/csharp/Reverse/Reverse.csproj b/73_Reverse/csharp/Reverse/Reverse/Reverse.csproj
    similarity index 100%
    rename from 73_Reverse/csharp/Reverse/Reverse.csproj
    rename to 73_Reverse/csharp/Reverse/Reverse/Reverse.csproj
    diff --git a/73_Reverse/csharp/Reverse/Reverser.cs b/73_Reverse/csharp/Reverse/Reverse/Reverser.cs
    similarity index 100%
    rename from 73_Reverse/csharp/Reverse/Reverser.cs
    rename to 73_Reverse/csharp/Reverse/Reverse/Reverser.cs
    diff --git a/73_Reverse/java/Reverse.java b/73_Reverse/java/Reverse.java
    index 603ef7639..22c1d0731 100644
    --- a/73_Reverse/java/Reverse.java
    +++ b/73_Reverse/java/Reverse.java
    @@ -9,43 +9,43 @@
      * 

    * Note: The idea was to create a version of the 1970's BASIC game in Java, without introducing * new features - no additional text, error checking, etc has been added. - * + * * Converted from BASIC to Java by Darren Cardenas. */ - -public class Reverse { - + +public class Reverse { + private final int NUMBER_COUNT = 9; - + private final Scanner scan; // For user input - + private enum Step { INITIALIZE, PERFORM_REVERSE, TRY_AGAIN, END_GAME - } - + } + public Reverse() { - + scan = new Scanner(System.in); - - } // End of constructor Reverse + + } // End of constructor Reverse public void play() { - + showIntro(); startGame(); - - } // End of method play - + + } // End of method play + private static void showIntro() { - + System.out.println(" ".repeat(31) + "REVERSE"); System.out.println(" ".repeat(14) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); System.out.println("\n\n"); System.out.println("REVERSE -- A GAME OF SKILL"); System.out.println(""); - } // End of method showIntro - + } // End of method showIntro + private void startGame() { int index = 0; @@ -53,162 +53,162 @@ private void startGame() { int numReverse = 0; int tempVal = 0; int[] numList = new int[NUMBER_COUNT + 1]; - + Step nextStep = Step.INITIALIZE; - + String userResponse = ""; - + System.out.print("DO YOU WANT THE RULES? "); userResponse = scan.nextLine(); - + if (!userResponse.toUpperCase().equals("NO")) { - - this.printRules(); + + this.printRules(); } - + // Begin outer while loop while (true) { - + // Begin outer switch switch (nextStep) { - + case INITIALIZE: - - // Make a random list of numbers + + // Make a random list of numbers numList[1] = (int)((NUMBER_COUNT - 1) * Math.random() + 2); - + for (index = 2; index <= NUMBER_COUNT; index++) { - + // Keep generating lists if there are duplicates while (true) { - + numList[index] = (int)(NUMBER_COUNT * Math.random() + 1); // Search for duplicates - if (!this.findDuplicates(numList, index)) { + if (!this.findDuplicates(numList, index)) { break; - } + } } } - + System.out.println(""); System.out.println("HERE WE GO ... THE LIST IS:"); - + numMoves = 0; - + this.printBoard(numList); - + nextStep = Step.PERFORM_REVERSE; break; - + case PERFORM_REVERSE: - + System.out.print("HOW MANY SHALL I REVERSE? "); numReverse = Integer.parseInt(scan.nextLine()); - - if (numReverse == 0) { - - nextStep = Step.TRY_AGAIN; - + + if (numReverse == 0) { + + nextStep = Step.TRY_AGAIN; + } else if (numReverse > NUMBER_COUNT) { - - System.out.println("OOPS! TOO MANY! I CAN REVERSE AT MOST " + NUMBER_COUNT); - nextStep = Step.PERFORM_REVERSE; - + + System.out.println("OOPS! TOO MANY! I CAN REVERSE AT MOST " + NUMBER_COUNT); + nextStep = Step.PERFORM_REVERSE; + } else { - + numMoves++; - + for (index = 1; index <= (int)(numReverse / 2.0); index++) { - + tempVal = numList[index]; numList[index] = numList[numReverse - index + 1]; numList[numReverse - index + 1] = tempVal; } this.printBoard(numList); - + nextStep = Step.TRY_AGAIN; - - // Check for a win + + // Check for a win for (index = 1; index <= NUMBER_COUNT; index++) { - - if (numList[index] != index) { - nextStep = Step.PERFORM_REVERSE; - } + + if (numList[index] != index) { + nextStep = Step.PERFORM_REVERSE; + } } - + if (nextStep == Step.TRY_AGAIN) { - System.out.println("YOU WON IT IN " + numMoves + " MOVES!!!"); + System.out.println("YOU WON IT IN " + numMoves + " MOVES!!!"); System.out.println(""); - } - } + } + } break; - + case TRY_AGAIN: - + System.out.println(""); System.out.print("TRY AGAIN (YES OR NO)? "); userResponse = scan.nextLine(); - + if (userResponse.toUpperCase().equals("YES")) { nextStep = Step.INITIALIZE; } else { nextStep = Step.END_GAME; } break; - + case END_GAME: - + System.out.println(""); System.out.println("O.K. HOPE YOU HAD FUN!!"); - return; - + return; + default: - - System.out.println("INVALID STEP"); + + System.out.println("INVALID STEP"); break; - } // End outer switch - - } // End outer while loop - - } // End of method startGame - + } // End outer switch + + } // End outer while loop + + } // End of method startGame + public boolean findDuplicates(int[] board, int length) { - + int index = 0; - + for (index = 1; index <= length - 1; index++) { - + // Identify duplicates if (board[length] == board[index]) { - + return true; // Found a duplicate - } + } } - + return false; // No duplicates found - + } // End of method findDuplicates - + public void printBoard(int[] board) { - + int index = 0; - + System.out.println(""); - + for (index = 1; index <= NUMBER_COUNT; index++) { - - System.out.format("%2d", board[index]); + + System.out.format("%2d", board[index]); } - - System.out.println("\n"); - + + System.out.println("\n"); + } // End of method printBoard - + public void printRules() { - + System.out.println(""); System.out.println("THIS IS THE GAME OF 'REVERSE'. TO WIN, ALL YOU HAVE"); System.out.println("TO DO IS ARRANGE A LIST OF NUMBERS (1 THROUGH " + NUMBER_COUNT + ")"); @@ -229,14 +229,14 @@ public void printRules() { System.out.println("NO DOUBT YOU WILL LIKE THIS GAME, BUT"); System.out.println("IF YOU WANT TO QUIT, REVERSE 0 (ZERO)."); System.out.println(""); - + } // End of method printRules - + public static void main(String[] args) { - + Reverse game = new Reverse(); game.play(); - + } // End of method main - + } // End of class Reverse diff --git a/73_Reverse/javascript/reverse.html b/73_Reverse/javascript/reverse.html index bb89bfbaf..3abddb0e0 100644 --- a/73_Reverse/javascript/reverse.html +++ b/73_Reverse/javascript/reverse.html @@ -1,10 +1,9 @@ REVERSE - -

    
    +
    
     
     
     
    diff --git a/73_Reverse/javascript/reverse.js b/73_Reverse/javascript/reverse.js
    index 802df4c06..44937b518 100644
    --- a/73_Reverse/javascript/reverse.js
    +++ b/73_Reverse/javascript/reverse.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    @@ -94,9 +94,9 @@ async function main()
             a[i] = 0;
         // *** N=NUMBER OF NUMBER
         n = 9;
    -    print("DO YOU WANT THE RULES? (YES OR NO)");
    +    print("DO YOU WANT THE RULES");
         str = await input();
    -    if (str.toUpperCase() === "YES" || str.toUpperCase() === "Y")
    +    if (str != "NO")
             print_rules();
         while (1) {
             // *** Make a random list a(1) to a(n)
    @@ -123,7 +123,7 @@ async function main()
                         break;
                     if (r <= n)
                         break;
    -                print("OOPS! WRONG! I CAN REVERSE AT MOST " + n + "\n");
    +                print("OOPS! TOO MANY! I CAN REVERSE AT MOST " + n + "\n");
                 }
                 if (r == 0)
                     break;
    @@ -147,9 +147,9 @@ async function main()
                 }
             }
             print("\n");
    -        print("TRY AGAIN? (YES OR NO)");
    +        print("TRY AGAIN (YES OR NO)");
             str = await input();
    -        if (str.toUpperCase() === "NO" || str.toUpperCase() === "N")
    +        if (str != "YES")
                 break;
         }
         print("\n");
    diff --git a/73_Reverse/kotlin/README.md b/73_Reverse/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/73_Reverse/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/73_Reverse/lua/README.md b/73_Reverse/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/73_Reverse/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/73_Reverse/pascal/README.md b/73_Reverse/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/73_Reverse/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/73_Reverse/python/reverse.py b/73_Reverse/python/reverse.py
    index e34378406..b73c779da 100755
    --- a/73_Reverse/python/reverse.py
    +++ b/73_Reverse/python/reverse.py
    @@ -2,28 +2,29 @@
     import random
     import textwrap
     
    +
     NUMCNT = 9  # How many numbers are we playing with?
     
     
    -def main() -> None:
    -    print("REVERSE".center(72))
    -    print("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY".center(72))
    +def play():
    +    print('REVERSE'.center(72))
    +    print('CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY'.center(72))
         print()
         print()
    -    print("REVERSE -- A GAME OF SKILL")
    +    print('REVERSE -- A GAME OF SKILL')
         print()
     
    -    if not input("DO YOU WANT THE RULES? (yes/no) ").lower().startswith("n"):
    -        print_rules()
    +    if not input('DO YOU WANT THE RULES? (yes/no) ').lower().startswith('n'):
    +        rules()
     
         while True:
             game_loop()
     
    -        if not input("TRY AGAIN? (yes/no) ").lower().startswith("y"):
    +        if not input('TRY AGAIN? (yes/no) ').lower().startswith('y'):
                 return
     
     
    -def game_loop() -> None:
    +def game_loop():
         """Play the main game."""
         # Make a random list from 1 to NUMCNT
         numbers = list(range(1, NUMCNT + 1))
    @@ -31,13 +32,13 @@ def game_loop() -> None:
     
         # Print original list and start the game
         print()
    -    print("HERE WE GO ... THE LIST IS:")
    +    print('HERE WE GO ... THE LIST IS:')
         print_list(numbers)
     
         turns = 0
         while True:
             try:
    -            howmany = int(input("HOW MANY SHALL I REVERSE? "))
    +            howmany = int(input('HOW MANY SHALL I REVERSE? '))
                 assert howmany >= 0
             except (ValueError, AssertionError):
                 continue
    @@ -46,13 +47,13 @@ def game_loop() -> None:
                 return
     
             if howmany > NUMCNT:
    -            print("OOPS! WRONG! I CAN REVERSE AT MOST", NUMCNT)
    +            print('OOPS! WRONG! I CAN REVERSE AT MOST', NUMCNT)
                 continue
     
             turns += 1
     
             # Reverse as many items as requested.
    -        newnums = numbers[:howmany]
    +        newnums = numbers[0:howmany]
             newnums.reverse()
             newnums.extend(numbers[howmany:])
             numbers = newnums
    @@ -61,18 +62,19 @@ def game_loop() -> None:
     
             # Check for a win
             if all(numbers[i] == i + 1 for i in range(NUMCNT)):
    -            print(f"YOU WON IT IN {turns} MOVES!")
    +            print('YOU WON IT IN {} MOVES!'.format(turns))
                 print()
                 return
     
     
    -def print_list(numbers) -> None:
    -    print(" ".join(map(str, numbers)))
    +def print_list(numbers):
    +    """Print out the list"""
    +    print(' '.join(map(str, numbers)))
     
     
    -def print_rules() -> None:
    -    help = textwrap.dedent(
    -        """
    +def rules():
    +    """Print out the rules"""
    +    help = textwrap.dedent("""
             THIS IS THE GAME OF "REVERSE".  TO WIN, ALL YOU HAVE
             TO DO IS ARRANGE A LIST OF NUMBERS (1 THROUGH {})
             IN NUMERICAL ORDER FROM LEFT TO RIGHT.  TO MOVE, YOU
    @@ -91,16 +93,13 @@ def print_rules() -> None:
     
             NO DOUBT YOU WILL LIKE THIS GAME, BUT
             IF YOU WANT TO QUIT, REVERSE 0 (ZERO).
    -        """.format(
    -            NUMCNT
    -        )
    -    )
    +        """.format(NUMCNT))
         print(help)
         print()
     
     
    -if __name__ == "__main__":
    +if __name__ == '__main__':
         try:
    -        main()
    +        play()
         except KeyboardInterrupt:
             pass
    diff --git a/73_Reverse/ruby/reverse.rb b/73_Reverse/ruby/reverse.rb
    index 021eed182..0e2f79346 100644
    --- a/73_Reverse/ruby/reverse.rb
    +++ b/73_Reverse/ruby/reverse.rb
    @@ -55,7 +55,7 @@ def reverseIt (howManyToReverse, triesSoFar)
         # 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
    @@ -108,3 +108,4 @@ def askHowManyToReverse
         end
         r = askHowManyToReverse
     end
    +
    diff --git a/73_Reverse/rust/Cargo.lock b/73_Reverse/rust/Cargo.lock
    deleted file mode 100644
    index 0da17814e..000000000
    --- a/73_Reverse/rust/Cargo.lock
    +++ /dev/null
    @@ -1,243 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "bitflags"
    -version = "2.9.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
    -
    -[[package]]
    -name = "byteorder"
    -version = "1.5.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    - "windows-targets",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.170"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.20"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
    -dependencies = [
    - "zerocopy 0.7.35",
    -]
    -
    -[[package]]
    -name = "proc-macro2"
    -version = "1.0.94"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
    -dependencies = [
    - "unicode-ident",
    -]
    -
    -[[package]]
    -name = "quote"
    -version = "1.0.39"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "c1f1914ce909e1658d9907913b4b91947430c7d9be598b15a1912935b8c04801"
    -dependencies = [
    - "proc-macro2",
    -]
    -
    -[[package]]
    -name = "rand"
    -version = "0.9.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
    -dependencies = [
    - "rand_chacha",
    - "rand_core",
    - "zerocopy 0.8.21",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.9.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.9.3"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "syn"
    -version = "2.0.99"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e02e925281e18ffd9d640e234264753c43edc62d64b2d4cf898f1bc5e75f3fc2"
    -dependencies = [
    - "proc-macro2",
    - "quote",
    - "unicode-ident",
    -]
    -
    -[[package]]
    -name = "unicode-ident"
    -version = "1.0.18"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
    -
    -[[package]]
    -name = "wasi"
    -version = "0.13.3+wasi-0.2.2"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2"
    -dependencies = [
    - "wit-bindgen-rt",
    -]
    -
    -[[package]]
    -name = "windows-targets"
    -version = "0.52.6"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
    -dependencies = [
    - "windows_aarch64_gnullvm",
    - "windows_aarch64_msvc",
    - "windows_i686_gnu",
    - "windows_i686_gnullvm",
    - "windows_i686_msvc",
    - "windows_x86_64_gnu",
    - "windows_x86_64_gnullvm",
    - "windows_x86_64_msvc",
    -]
    -
    -[[package]]
    -name = "windows_aarch64_gnullvm"
    -version = "0.52.6"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
    -
    -[[package]]
    -name = "windows_aarch64_msvc"
    -version = "0.52.6"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
    -
    -[[package]]
    -name = "windows_i686_gnu"
    -version = "0.52.6"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
    -
    -[[package]]
    -name = "windows_i686_gnullvm"
    -version = "0.52.6"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
    -
    -[[package]]
    -name = "windows_i686_msvc"
    -version = "0.52.6"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
    -
    -[[package]]
    -name = "windows_x86_64_gnu"
    -version = "0.52.6"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
    -
    -[[package]]
    -name = "windows_x86_64_gnullvm"
    -version = "0.52.6"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
    -
    -[[package]]
    -name = "windows_x86_64_msvc"
    -version = "0.52.6"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
    -
    -[[package]]
    -name = "wit-bindgen-rt"
    -version = "0.33.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c"
    -dependencies = [
    - "bitflags",
    -]
    -
    -[[package]]
    -name = "zerocopy"
    -version = "0.7.35"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
    -dependencies = [
    - "byteorder",
    - "zerocopy-derive 0.7.35",
    -]
    -
    -[[package]]
    -name = "zerocopy"
    -version = "0.8.21"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "dcf01143b2dd5d134f11f545cf9f1431b13b749695cb33bcce051e7568f99478"
    -dependencies = [
    - "zerocopy-derive 0.8.21",
    -]
    -
    -[[package]]
    -name = "zerocopy-derive"
    -version = "0.7.35"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
    -dependencies = [
    - "proc-macro2",
    - "quote",
    - "syn",
    -]
    -
    -[[package]]
    -name = "zerocopy-derive"
    -version = "0.8.21"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "712c8386f4f4299382c9abee219bee7084f78fb939d88b6840fcc1320d5f6da2"
    -dependencies = [
    - "proc-macro2",
    - "quote",
    - "syn",
    -]
    diff --git a/73_Reverse/rust/Cargo.toml b/73_Reverse/rust/Cargo.toml
    deleted file mode 100644
    index 3a87396aa..000000000
    --- a/73_Reverse/rust/Cargo.toml
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -[package]
    -name = "rust"
    -version = "0.1.0"
    -edition = "2021"
    -
    -[dependencies]
    -rand = "0.9.0"
    \ No newline at end of file
    diff --git a/73_Reverse/rust/src/main.rs b/73_Reverse/rust/src/main.rs
    deleted file mode 100644
    index 8fd06505e..000000000
    --- a/73_Reverse/rust/src/main.rs
    +++ /dev/null
    @@ -1,209 +0,0 @@
    -/** REVERSE GAME 
    - * https://github.com/marquesrs/basic-computer-games/blob/main/73_Reverse/reverse.bas
    - * Direct conversion from BASIC to Rust by Pablo Marques (marquesrs).
    - * No additional features or improvements were added. As a faithful translation, 
    - * many of the code here are done in an unrecommended way by today's standards.
    - * 03/03/25
    -*/
    -
    -use rand::Rng;
    -use std::io::Write;
    -
    -fn input(msg: &str) -> String {
    -    print!("{}", msg);
    -    let _ =std::io::stdout().flush().unwrap();
    -    let mut input = String::new();
    -    std::io::stdin().read_line(&mut input).unwrap();
    -    return input.trim().to_uppercase();
    -}
    -
    -fn main() {
    -    // 10 PRINT TAB(32);"REVERSE"
    -    // 20 PRINT TAB(15);"CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY"
    -    // 30 PRINT:PRINT:PRINT
    -    // 100 PRINT "REVERSE -- A GAME OF SKILL": PRINT
    -    print!("{}", format!("{}{}{}{}{}{}{}{}",
    -        " ".repeat(31),
    -        "REVERSE",
    -        "\n",
    -        " ".repeat(14),
    -        "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n",
    -        "\n\n\n",
    -        "REVERSE -- A GAME OF SKILL\n",
    -        "\n"
    -    ));
    -
    -    // 130 DIM A(20)
    -    let mut a = vec![0; 20];
    -    
    -    // 140 REM *** N=NUMBER OF NUMBERS
    -    // 150 N=9
    -    let n = 9;
    -    
    -    // 160 PRINT "DO YOU WANT THE RULES";
    -    // 170 INPUT A$
    -    let opt = input("DO YOU WANT THE RULES (YES OR NO)? ");
    -
    -    
    -    if opt == "YES" || opt == "Y" {
    -        // 190 GOSUB 710        
    -        sub1(n);
    -    }
    -    // 180 IF A$="NO" THEN 210
    -    'c : loop {
    -        // 200 REM *** MAKE A RANDOM LIST A(1) TO A(N)
    -        // 210 A(1)=INT((N-1)*RND(1)+2)
    -        // element 0
    -        a[0] = ((n-1) as f32 * rand::rng().random_range(0.0..=1.0) + 2.0) as i32;
    -    
    -        // 220 FOR K=2 TO N
    -        for k in 2..=n {
    -            'a : loop {
    -                // element k
    -                // 230 A(K)=INT(N*RND(1)+1)
    -                a[k-1] = (n as f32 * rand::rng().random_range(0.0..=1.0) + 1.0) as i32;
    -                
    -                // element 0 to k-1
    -                // 240 FOR J=1 TO K-1
    -                for j in 1..k {
    -                    // 250 IF A(K)=A(J) THEN 230
    -                    if a[k-1] == a[j-1] {
    -                        continue 'a;
    -                    }
    -                    // 260 NEXT J:
    -                }
    -                break;
    -            }
    -            //NEXT K
    -        }    
    -
    -        // 280 REM *** PRINT ORIGINAL LIST AND START GAME
    -        // 290 PRINT: PRINT "HERE WE GO ... THE LIST IS:"
    -        print!("\nHERE WE GO ... THE LIST IS:\n");
    -
    -        // 310 T=0
    -        let mut t = 0;
    -
    -        // 320 GOSUB 610
    -        sub2(&a, n);
    -
    -        'b : loop {
    -            // 330 PRINT "HOW MANY SHALL I REVERSE";
    -            // 340 INPUT R
    -            let r = input("HOW MANY SHALL I REVERSE: ").parse::().unwrap();
    -
    -            // 350 IF R=0 THEN 520
    -            if r == 0 {
    -                if replay() { continue 'c; }
    -                else { break 'c; }
    -            }
    -            // 360 IF R<=N THEN 390
    -            if r <= n {
    -                // 390 T=T+1
    -                t = t + 1;
    -
    -                // 400 REM *** REVERSE R NUMBERS AND PRINT NEW LIST
    -                // 410 FOR K=1 TO INT(R/2)
    -                for k in 1..=((r/2) as usize) {
    -                    // 420 Z=A(K)
    -                    let z = a[k-1];
    -                    // 430 A(K)=A(R-K+1)
    -                    a[k-1] = a[r-k];
    -                    // 440 A(R-K+1)=Z
    -                    a[r-k] = z;
    -
    -                    // 450 NEXT K
    -                }
    -                // 460 GOSUB 610
    -                sub2(&a, n);
    -
    -                // 470 REM *** CHECK FOR A WIN
    -                // 480 FOR K=1 TO N
    -                for k in 1..=n {
    -                    // 490 IF A(K)<>K THEN 330
    -                    if a[k-1] != k as i32 {
    -                        continue 'b;
    -                    }
    -                    // 500 NEXT K
    -                }
    -                // 510 PRINT "YOU WON IT IN";T;"MOVES!!!":PRINT
    -                print!("{}{}{}", "YOU WON IT IN ", t, " MOVES!!!\n\n");
    -
    -                if replay() { continue 'c; }
    -                else { break 'c; }
    -            }
    -            else {
    -                // 370 PRINT "OOPS! TOO MANY! I CAN REVERSE AT MOST";N:GOTO 330
    -                print!("OOPS! TOO MANY! I CAN REVERSE AT MOST {n}");
    -            }
    -        }
    -    }
    -    // 999 END
    -}
    -
    -// 600 REM *** SUBROUTINE TO PRINT LIST
    -fn sub2(a: &Vec, n: usize) {
    -    // 610 PRINT:FOR K=1 TO N:PRINT A(K);:NEXT K
    -    // 650 PRINT:PRINT:RETURN
    -    for k in 1..=n {
    -        print!("{} ", a[k-1]);
    -    }
    -    print!("\n\n");
    -}
    -
    -// 700 REM *** SUBROUTINE TO PRINT THE RULES
    -fn sub1(n: usize) {
    -    // 710 PRINT:PRINT "THIS IS THE GAME OF 'REVERSE'.  TO WIN, ALL YOU HAVE"
    -    // 720 PRINT "TO DO IS ARRANGE A LIST OF NUMBERS (1 THROUGH";N;")"
    -    // 730 PRINT "IN NUMERICAL ORDER FROM LEFT TO RIGHT.  TO MOVE, YOU"
    -    // 740 PRINT "TELL ME HOW MANY NUMBERS (COUNTING FROM THE LEFT) TO"
    -    // 750 PRINT "REVERSE.  FOR EXAMPLE, IF THE CURRENT LIST IS:"
    -    // 760 PRINT:PRINT "2 3 4 5 1 6 7 8 9"
    -    // 770 PRINT:PRINT "AND YOU REVERSE 4, THE RESULT WILL BE:"
    -    // 780 PRINT:PRINT "5 4 3 2 1 6 7 8 9"
    -    // 790 PRINT:PRINT "NOW IF YOU REVERSE 5, YOU WIN!"
    -    // 800 PRINT:PRINT "1 2 3 4 5 6 7 8 9":PRINT
    -    // 810 PRINT "NO DOUBT YOU WILL LIKE THIS GAME, BUT"
    -    // 820 PRINT "IF YOU WANT TO QUIT, REVERSE 0 (ZERO).":PRINT: RETURN
    -
    -    print!("{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 
    -        "\n",
    -        "THIS IS THE GAME OF 'REVERSE'. TO WIN, ALL YOU HAVE\n",
    -        "TO DO IS ARRANGE A LIST OF NUMBERS (1 THROUGH ",
    -        n,
    -        ")\n",
    -        "IN NUMERICAL ORDER FROM LEFT TO RIGHT. TO MOVE, YOU\n",
    -        "TELL ME HOW MANY NUMBERS (COUNTING FROM THE LEFT) TO\n",
    -        "REVERSE. FOR EXAMPLE, IF THE CURRENT LIST IS:\n",
    -        "\n",
    -        "2 3 4 5 1 6 7 8 9\n",
    -        "\n",
    -        "AND YOU REVERSE 4, THE RESULT WILL BE:\n",
    -        "\n",
    -        "5 4 3 2 1 6 7 8 9\n",
    -        "\n",
    -        "NOW IF YOU REVERSE 5, YOU WIN!\n",
    -        "\n",
    -        "1 2 3 4 5 6 7 8 9\n",
    -        "\n",
    -        "NO DOUBT YOU WILL LIKE THIS GAME, BUT\n",
    -        "IF YOU WANT TO QUIT, REVERSE 0 (ZERO).\n",
    -        "\n",
    -    )
    -}
    -
    -fn replay() -> bool {
    -    // 520 PRINT
    -    // 530 PRINT "TRY AGAIN (YES OR NO)";
    -    // 540 INPUT A$
    -    let r = input("\nTRY AGAIN (YES OR NO): ");
    -    // 550 IF A$="YES" THEN 210
    -    if r == "YES" || r == "Y" {
    -        return true;
    -    }
    -    else {
    -        // 560 PRINT: PRINT "O.K. HOPE YOU HAD FUN!!":GOTO 999
    -        println!("\nO.K. HOPE YOU HAD FUN!!");
    -        return false; 
    -    }
    -}
    \ No newline at end of file
    diff --git a/73_Reverse/vbnet/Reverse.sln b/73_Reverse/vbnet/Reverse.sln
    deleted file mode 100644
    index 8e8fa1eeb..000000000
    --- a/73_Reverse/vbnet/Reverse.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 978b4e564..000000000
    --- a/73_Reverse/vbnet/Reverse.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Reverse
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/74_Rock_Scissors_Paper/README.md b/74_Rock_Scissors_Paper/README.md
    index fdaa0f30b..1b9fa865d 100644
    --- a/74_Rock_Scissors_Paper/README.md
    +++ b/74_Rock_Scissors_Paper/README.md
    @@ -19,7 +19,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/74_Rock_Scissors_Paper/csharp/RockScissorsPaper.sln b/74_Rock_Scissors_Paper/csharp/RockScissorsPaper.sln
    deleted file mode 100644
    index 5c563dd81..000000000
    --- a/74_Rock_Scissors_Paper/csharp/RockScissorsPaper.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/java/src/RockScissors.java b/74_Rock_Scissors_Paper/java/src/RockScissors.java
    index 2720028a5..952cd80ed 100644
    --- a/74_Rock_Scissors_Paper/java/src/RockScissors.java
    +++ b/74_Rock_Scissors_Paper/java/src/RockScissors.java
    @@ -209,4 +209,4 @@ public static void main(String[] args) {
             RockScissors rockScissors = new RockScissors();
             rockScissors.play();
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/74_Rock_Scissors_Paper/javascript/rockscissors.html b/74_Rock_Scissors_Paper/javascript/rockscissors.html
    new file mode 100644
    index 000000000..2b938a5fa
    --- /dev/null
    +++ b/74_Rock_Scissors_Paper/javascript/rockscissors.html
    @@ -0,0 +1,9 @@
    +
    +
    +ROCK, SCISSORS, PAPER
    +
    +
    +
    
    +
    +
    +
    diff --git a/74_Rock_Scissors_Paper/javascript/rockscissors.js b/74_Rock_Scissors_Paper/javascript/rockscissors.js
    new file mode 100644
    index 000000000..a5d868621
    --- /dev/null
    +++ b/74_Rock_Scissors_Paper/javascript/rockscissors.js
    @@ -0,0 +1,107 @@
    +// ROCK, SCISSORS, PAPER
    +//
    +// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
    +//
    +
    +function print(str)
    +{
    +    document.getElementById("output").appendChild(document.createTextNode(str));
    +}
    +
    +function input()
    +{
    +    var input_element;
    +    var input_str;
    +    
    +    return new Promise(function (resolve) {
    +                       input_element = document.createElement("INPUT");
    +                       
    +                       print("? ");
    +                       input_element.setAttribute("type", "text");
    +                       input_element.setAttribute("length", "50");
    +                       document.getElementById("output").appendChild(input_element);
    +                       input_element.focus();
    +                       input_str = undefined;
    +                       input_element.addEventListener("keydown", function (event) {
    +                                                      if (event.keyCode == 13) {
    +                                                      input_str = input_element.value;
    +                                                      document.getElementById("output").removeChild(input_element);
    +                                                      print(input_str);
    +                                                      print("\n");
    +                                                      resolve(input_str);
    +                                                      }
    +                                                      });
    +                       });
    +}
    +
    +function tab(space)
    +{
    +    var str = "";
    +    while (space-- > 0)
    +        str += " ";
    +    return str;
    +}
    +
    +// Main control section
    +async function main()
    +{
    +    print(tab(21) + "GAME OF ROCK, SCISSORS, PAPER\n");
    +    print(tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n");
    +    print("\n");
    +    print("\n");
    +    print("\n");
    +    while (1) {
    +        print("HOW MANY GAMES");
    +        q = parseInt(await input());
    +        if (q >= 11)
    +            print("SORRY, BUT WE AREN'T ALLOWED TO PLAY THAT MANY.\n");
    +        else
    +            break;
    +    }
    +    h = 0;  // Human
    +    c = 0;  // Computer
    +    for (g = 1; g <= q; g++ ) {
    +        print("\n");
    +        print("GAME NUMBER " + g + "\n");
    +        x = Math.floor(Math.random() * 3 + 1);
    +        while (1) {
    +            print("3=ROCK...2=SCISSORS...1=PAPER\n");
    +            print("1...2...3...WHAT'S YOUR CHOICE");
    +            k = parseInt(await input());
    +            if (k != 1 && k != 2 && k != 3)
    +                print("INVALID.\n");
    +            else
    +                break;
    +        }
    +        print("THIS IS MY CHOICE...");
    +        switch (x) {
    +            case 1:
    +                print("...PAPER\n");
    +                break;
    +            case 2:
    +                print("...SCISSORS\n");
    +                break;
    +            case 3:
    +                print("...ROCK\n");
    +                break;
    +        }
    +        if (x == k) {
    +            print("TIE GAME.  NO WINNER.\n");
    +        } else if ((x > k && (k != 1 || x != 3)) || (x == 1 && k == 3)) {
    +            print("WOW!  I WIN!!!\n");
    +            c++;
    +        } else {
    +            print("YOU WIN!!!\n");
    +            h++;
    +        }
    +    }
    +    print("\n");
    +    print("HERE IS THE FINAL GAME SCORE:\n");
    +    print("I HAVE WON " + c + " GAME(S).\n");
    +    print("YOU HAVE WON " + h + " GAME(S).\n");
    +    print("AND " + (q - (c + h)) + " GAME(S) ENDED IN A TIE.\n");
    +    print("\n");
    +    print("THANKS FOR PLAYING!!\n");
    +}
    +
    +main();
    diff --git a/74_Rock_Scissors_Paper/javascript/rockscissors.mjs b/74_Rock_Scissors_Paper/javascript/rockscissors.mjs
    deleted file mode 100644
    index be2328f28..000000000
    --- a/74_Rock_Scissors_Paper/javascript/rockscissors.mjs
    +++ /dev/null
    @@ -1,117 +0,0 @@
    -#!/usr/bin/env node
    -// ROCK, SCISSORS, PAPER
    -//
    -// Converted from BASIC to Javascript by Alexander Wunschik (mojoaxel)
    -
    -import { println, tab, input } from '../../00_Common/javascript/common.mjs';
    -
    -let userWins = 0;
    -let computerWins = 0;
    -let ties = 0;
    -
    -// 30 INPUT "HOW MANY GAMES";Q
    -// 40 IF Q<11 THEN 60
    -// 50 PRINT "SORRY, BUT WE AREN'T ALLOWED TO PLAY THAT MANY.": GOTO 30
    -// 60 FOR G=1 TO Q
    -async function getGameCount() {
    -	let gameCount = await input("HOW MANY GAMES");
    -	if (gameCount > 10) {
    -		println("SORRY, BUT WE AREN'T ALLOWED TO PLAY THAT MANY.");
    -		return await getGameCount();
    -	}
    -	return gameCount;
    -}
    -
    -// #90 PRINT "3=ROCK...2=SCISSORS...1=PAPER"
    -// #100 INPUT "1...2...3...WHAT'S YOUR CHOICE";K
    -// #110 IF (K-1)*(K-2)*(K-3)<>0 THEN PRINT "INVALID.": GOTO 90
    -async function getUserInput() {
    -	println("3=ROCK...2=SCISSORS...1=PAPER");
    -	const userChoice = await input("1...2...3...WHAT'S YOUR CHOICE");
    -	if (userChoice < 1 || userChoice > 3) {
    -		println("INVALID.");
    -		return await getUserInput();
    -	}
    -	return userChoice;
    -}
    -
    -async function game() {
    -	// 10 PRINT TAB(21);"GAME OF ROCK, SCISSORS, PAPER"
    -	// 20 PRINT TAB(15);"CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY"
    -	// 25 PRINT:PRINT:PRINT
    -	println(tab(21), 'GAME OF ROCK, SCISSORS, PAPER');
    -	println(tab(15), 'CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY');
    -	println('\n\n');
    -
    -	let gameCount = await getGameCount();
    -
    -	async function playGame(gameNumber) {
    -		// 70 PRINT: PRINT "GAME NUMBER";G
    -		println("\nGAME NUMBER ", gameNumber);
    -
    -		const ROCK = 3;
    -		const SCISSORS = 2;
    -		const PAPER = 1;
    -
    -		const usersChoice = await getUserInput();
    -
    -		// 80 X=INT(RND(1)*3+1)
    -		const computersChoice = Math.floor(Math.random()*3) + 1;
    -
    -		// 120 PRINT "THIS IS MY CHOICE..."
    -		// 130 ON X GOTO 140,150,160
    -		// 140 PRINT "...PAPER": GOTO 170
    -		// 150 PRINT "...SCISSORS": GOTO 170
    -		// 160 PRINT "...ROCK"
    -		println("THIS IS MY CHOICE...", 
    -			computersChoice === PAPER ? "...PAPER" : 
    -				computersChoice === SCISSORS ? "...SCISSORS" : 
    -					"...ROCK");
    -
    -
    -		// 170 IF X=K THEN 250
    -		// 180 IF X>K THEN 230
    -		// 190 IF X=1 THEN 210
    -		// 200 PRINT "YOU WIN!!!":H=H+1: GOTO 260
    -		// 210 IF K<>3 THEN 200
    -		// 220 PRINT "WOW!  I WIN!!!":C=C+1:GOTO 260
    -		// 230 IF K<>1 OR X<>3 THEN 220
    -		// 240 GOTO 200
    -		// 250 PRINT "TIE GAME.  NO WINNER."
    -		if (computersChoice == usersChoice) {
    -			println("TIE GAME.  NO WINNER.");
    -			ties++;
    -		} else if (
    -			(computersChoice == ROCK && usersChoice == SCISSORS) ||
    -			(computersChoice == PAPER && usersChoice == ROCK) ||
    -			(computersChoice == SCISSORS && usersChoice == PAPER)
    -		) {
    -			println("WOW!  I WIN!!!");
    -			computerWins++;
    -		} else {
    -			println("YOU WIN!!!");
    -			userWins++;
    -		}
    -	}
    -
    -	for (let gameNumber = 1; gameNumber <= gameCount; gameNumber++) {
    -		await playGame(gameNumber);
    -		// 260 NEXT G
    -	}
    -
    -	// 270 PRINT: PRINT "HERE IS THE FINAL GAME SCORE:"
    -	// 280 PRINT "I HAVE WON";C;"GAME(S)."
    -	// 290 PRINT "YOU HAVE WON";H;"GAME(S)."
    -	// 300 PRINT "AND";Q-(C+H20);"GAME(S) ENDED IN A TIE."
    -	println("\nHERE IS THE FINAL GAME SCORE:");
    -	println(`I HAVE WON ${computerWins} GAME(S).`);
    -	println(`YOU HAVE WON ${userWins} GAME(S).`);
    -	println(`AND ${ties} GAME(S) ENDED IN A TIE.`);
    -
    -	// 310 PRINT: PRINT "THANKS FOR PLAYING!!"
    -	println("\nTHANKS FOR PLAYING!!");
    -	
    -	// 320 END
    -	process.exit(0);
    -}
    -game();
    diff --git a/74_Rock_Scissors_Paper/kotlin/README.md b/74_Rock_Scissors_Paper/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/74_Rock_Scissors_Paper/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/74_Rock_Scissors_Paper/lua/README.md b/74_Rock_Scissors_Paper/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/74_Rock_Scissors_Paper/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/74_Rock_Scissors_Paper/lua/rockscissors.lua b/74_Rock_Scissors_Paper/lua/rockscissors.lua
    deleted file mode 100644
    index 8a19d5da0..000000000
    --- a/74_Rock_Scissors_Paper/lua/rockscissors.lua
    +++ /dev/null
    @@ -1,99 +0,0 @@
    --- rockscissors.lua
    --- Ported by Brian Wilkins (BrianWilkinsFL)
    --- Utilized has_key again and choice. A lot of these basic programs
    --- follow a similar choice structure so I think I'll use these functions alot.
    -
    -function getInput(prompt)
    -    io.write(prompt)
    -    io.flush()
    -    local input = io.read("l") 
    -    if not input then  --- test for EOF
    -        print("GOODBYE")
    -        os.exit(0)
    -    end
    -    return input
    -end
    -
    -function has_key(table, key)
    -   return table[key]~=nil
    -end
    - 
    -function choice(prompt, table)
    -   resp = getInput(prompt)
    -   while not has_key(table, resp) do
    -      print("INVALID.")
    -      resp = getInput(prompt)
    -   end
    -   return resp
    -end
    -
    -function playGame(n)
    -   local computerWins = 0
    -   local humanWins = 0
    -   itemChoices = {
    -        ["1"] = "PAPER",
    -        ["2"] = "SCISSORS",
    -        ["3"] = "ROCK",
    -   }
    -   print("GAME NUMBER " .. n)
    -
    -   math.randomseed(os.time())
    -   computerChoice = math.random(1,3)
    -  
    -   humanChoice = choice("3=ROCK...2=SCISSORS...1=PAPER\n1...2...3...WHAT'S YOUR CHOICE? ", itemChoices)
    -   humanChoice = tonumber(humanChoice)
    -   print("THIS IS MY CHOICE...")
    -
    -   print("... " .. itemChoices[tostring(computerChoice)])
    -
    -   -- Working around a Lua thing where I can't seem to interact
    -   -- with function values outside of the function itself
    -   -- So the total wins are calculated outside of this function
    -   -- and summarized. 
    -   if computerChoice == humanChoice then 
    -      print("TIE GAME.  NO WINNER.")
    -   elseif computerChoice > humanChoice then
    -      if humanChoice ~=1 or computerChoice ~= 3 then 
    -         computerWins = 1
    -         print("WOW!  I WIN!!!")
    -      else
    -         humanWins = 1
    -         print("YOU WIN!!!")
    -      end
    -   elseif computerChoice == 1 then
    -      if humanChoice ~= 3 then
    -         humanWins = 1
    -         print("YOU WIN!!!")
    -      else
    -         computerWins = 1
    -         print("WOW! I WIN!!!")
    -      end
    -   end
    -   return computerWins, humanWins
    -end
    -
    -local games = 0
    -while games == 0 or games >= 11 do
    -   resp = getInput("HOW MANY GAMES? ")
    -   
    -   assert(tonumber(resp))
    -   games = tonumber(resp)
    -   if games < 11 then break end
    -   
    -   print("SORRY, BUT WE AREN'T ALLOWED TO PLAY THAT MANY.")
    -end
    -
    -totalComputerWins = 0
    -totalHumanWins = 0
    -
    -for n=1, games, 1 do
    -   computerWins, humanWins = playGame(n)
    -   totalComputerWins = totalComputerWins + computerWins
    -   totalHumanWins = totalHumanWins + humanWins
    -end
    -
    -print("HERE IS THE FINAL GAME SCORE:")
    -print("I HAVE WON " .. totalComputerWins .. " GAME(S).")
    -print("YOU HAVE WON " .. totalHumanWins .." GAME(S).")
    -print("AND " .. games-(totalComputerWins+totalHumanWins) .. " GAME(S) ENDED IN A TIE.")
    -print("THANKS FOR PLAYING!!")
    \ No newline at end of file
    diff --git a/74_Rock_Scissors_Paper/pascal/README.md b/74_Rock_Scissors_Paper/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/74_Rock_Scissors_Paper/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/74_Rock_Scissors_Paper/perl/rockscissors.pl b/74_Rock_Scissors_Paper/perl/rockscissors.pl
    index 2f2316519..ac83f5cf2 100755
    --- a/74_Rock_Scissors_Paper/perl/rockscissors.pl
    +++ b/74_Rock_Scissors_Paper/perl/rockscissors.pl
    @@ -24,7 +24,7 @@
     	do {
     		print "3=ROCK...2=SCISSORS...1=PAPER\n";
     		print "1...2...3...WHAT'S YOUR CHOICE? "; chomp($K = );
    -		if (($K-1)*($K-2)*($K-3)!=0) { print "INVALID.\n"; $K=0; }
    +		if (($K-1)*($K-2)*($K-3)!=0) { print "INVALID.\n"; $K=0; } 
     		} until ($K!=0);
     
     
    @@ -52,3 +52,5 @@
     print "AND ".($Q-($C+$H))." GAME(S) ENDED IN A TIE.\n";
     print "\n"; print "THANKS FOR PLAYING!!\n";
     exit;
    +
    +
    diff --git a/74_Rock_Scissors_Paper/python/rockscissors.py b/74_Rock_Scissors_Paper/python/rockscissors.py
    index 3d150bd4f..688a894ba 100644
    --- a/74_Rock_Scissors_Paper/python/rockscissors.py
    +++ b/74_Rock_Scissors_Paper/python/rockscissors.py
    @@ -6,7 +6,7 @@
     import random
     
     
    -def play_game() -> None:
    +def play_game():
         """Play one round of the game"""
     
         while True:
    @@ -44,27 +44,22 @@ def play_game() -> None:
                 print("...Scissors")
             elif guess_computer == 3:
                 print("...Rock")
    -        if (
    -            guess_computer != guess_human
    -            and guess_computer > guess_human
    -            and (guess_human != 1 or guess_computer != 3)
    -            or guess_computer != guess_human
    -            and guess_computer <= guess_human
    -            and guess_computer == 1
    -            and guess_human == 3
    -        ):
    -            print("Wow! I win!!!")
    -            won_computer = won_computer + 1
    -        elif (
    -            guess_computer != guess_human
    -            and guess_computer > guess_human
    -            or guess_computer != guess_human
    -            and guess_computer == 1
    -        ):
    -            print("You win!!!")
    -            won_human = won_human + 1
    -        elif guess_computer == guess_human:
    +        if guess_computer == guess_human:
                 print("Tie Game. No winner")
    +        elif guess_computer > guess_human:
    +            if guess_human != 1 or guess_computer != 3:
    +                print("Wow! I win!!!")
    +                won_computer = won_computer + 1
    +            else:
    +                print("You win!!!")
    +                won_human = won_human + 1
    +        elif guess_computer == 1:
    +            if guess_human != 3:
    +                print("You win!!!")
    +                won_human = won_human + 1
    +            else:
    +                print("Wow! I win!!!")
    +                won_computer = won_computer + 1
         print("\nHere is the final game score:")
         print("I have won", won_computer, "game(s).")
         print("You have won", won_human, "game(s).")
    @@ -72,7 +67,7 @@ def play_game() -> None:
         print("\nThanks for playing!!\n")
     
     
    -def main() -> None:
    +def main():
         print(" " * 21 + "GAME OF ROCK, SCISSORS, PAPER")
         print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n")
     
    @@ -81,7 +76,8 @@ def main() -> None:
     
             play_game()
     
    -        keep_playing = input("Play again? (yes or no) ").lower().startswith("y")
    +        keep_playing = input(
    +            "Play again? (yes or no) ").lower().startswith("y")
     
     
     if __name__ == "__main__":
    diff --git a/74_Rock_Scissors_Paper/ruby/rockscissors.rb b/74_Rock_Scissors_Paper/ruby/rockscissors.rb
    index deae2a3fa..9b24ac9a9 100644
    --- a/74_Rock_Scissors_Paper/ruby/rockscissors.rb
    +++ b/74_Rock_Scissors_Paper/ruby/rockscissors.rb
    @@ -18,7 +18,7 @@ def center_text(text)
     
     def ask_for_number_of_games
       loop do
    -    puts "HOW MANY GAMES"
    +    puts "HOW MANY GAMES" 
         response = STDIN.gets.to_i
         return response if response > 0 and response < 11
         puts "SORRY, BUT WE AREN'T ALLOWED TO PLAY THAT MANY."
    @@ -58,7 +58,7 @@ def calculate_result(human_move, computer_move)
       human_move = ask_for_human_move
       puts "THIS IS MY CHOICE..."
       puts "...#{MOVE_WORDS[computer_move]}"
    -
    +  
       case calculate_result(human_move, computer_move)
       when 'WIN'
         puts "YOU WIN!!!"
    @@ -77,3 +77,4 @@ def calculate_result(human_move, computer_move)
     puts "YOU HAVE WON #{games_won} GAME(S)."
     puts "AND #{number_of_games - (games_lost + games_won)} GAME(S) ENDED IN A TIE."
     puts "THANKS FOR PLAYING!!"
    +
    diff --git a/74_Rock_Scissors_Paper/rust/Cargo.lock b/74_Rock_Scissors_Paper/rust/Cargo.lock
    deleted file mode 100644
    index 81a95200e..000000000
    --- a/74_Rock_Scissors_Paper/rust/Cargo.lock
    +++ /dev/null
    @@ -1,91 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "heck"
    -version = "0.4.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
    -
    -[[package]]
    -name = "nanorand"
    -version = "0.6.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "729eb334247daa1803e0a094d0a5c55711b85571179f5ec6e53eccfdf7008958"
    -
    -[[package]]
    -name = "proc-macro2"
    -version = "1.0.66"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9"
    -dependencies = [
    - "unicode-ident",
    -]
    -
    -[[package]]
    -name = "quote"
    -version = "1.0.33"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
    -dependencies = [
    - "proc-macro2",
    -]
    -
    -[[package]]
    -name = "rock_scissors_paper"
    -version = "1.0.0"
    -dependencies = [
    - "nanorand",
    - "strum",
    - "strum_macros",
    - "text_io",
    -]
    -
    -[[package]]
    -name = "rustversion"
    -version = "1.0.14"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
    -
    -[[package]]
    -name = "strum"
    -version = "0.24.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f"
    -
    -[[package]]
    -name = "strum_macros"
    -version = "0.24.3"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59"
    -dependencies = [
    - "heck",
    - "proc-macro2",
    - "quote",
    - "rustversion",
    - "syn",
    -]
    -
    -[[package]]
    -name = "syn"
    -version = "1.0.109"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
    -dependencies = [
    - "proc-macro2",
    - "quote",
    - "unicode-ident",
    -]
    -
    -[[package]]
    -name = "text_io"
    -version = "0.1.12"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "d5f0c8eb2ad70c12a6a69508f499b3051c924f4b1cfeae85bfad96e6bc5bba46"
    -
    -[[package]]
    -name = "unicode-ident"
    -version = "1.0.11"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
    diff --git a/74_Rock_Scissors_Paper/rust/Cargo.toml b/74_Rock_Scissors_Paper/rust/Cargo.toml
    deleted file mode 100644
    index b5162ec43..000000000
    --- a/74_Rock_Scissors_Paper/rust/Cargo.toml
    +++ /dev/null
    @@ -1,10 +0,0 @@
    -[package]
    -name = "rock_scissors_paper"
    -version = "1.0.0"
    -edition = "2021"
    -
    -[dependencies]
    -text_io = "0.1.10"
    -strum = "0.24"
    -strum_macros = "0.24"
    -nanorand = "0.6.1"
    diff --git a/74_Rock_Scissors_Paper/rust/README.md b/74_Rock_Scissors_Paper/rust/README.md
    deleted file mode 100644
    index cd7631d46..000000000
    --- a/74_Rock_Scissors_Paper/rust/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Rust](https://www.rust-lang.org)
    diff --git a/74_Rock_Scissors_Paper/rust/src/main.rs b/74_Rock_Scissors_Paper/rust/src/main.rs
    deleted file mode 100644
    index 98511bff0..000000000
    --- a/74_Rock_Scissors_Paper/rust/src/main.rs
    +++ /dev/null
    @@ -1,147 +0,0 @@
    -/*
    - * Rock paper scissors
    - * Originally from the wonderful book: _Basic Computer Games_
    - * Port to Rust By David Lotts
    -*/
    -use nanorand::{tls::TlsWyRand, Rng};
    -use std::io::{self, Write};
    -use strum::EnumCount;
    -use strum_macros::{Display, EnumCount, FromRepr};
    -use text_io::try_read;
    -fn main() {
    -    let mut computer_wins = 0;
    -    let mut human_wins = 0;
    -    let mut rng = nanorand::tls_rng();
    -    println!("{:>21}", "GAME OF ROCK, SCISSORS, PAPER");
    -    println!("{:>15}", "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY");
    -    print!("\n\n\n");
    -    // pass by reference in rust! input() modifies this variable.
    -    let mut qty_games = 0;
    -    loop {
    -        input_int("HOW MANY GAMES", &mut qty_games);
    -        if qty_games < 11 {
    -            break;
    -        }
    -        println!("SORRY, BUT WE AREN'T ALLOWED TO PLAY THAT MANY.");
    -    }
    -    for game_number in 1..=qty_games {
    -        println!();
    -        println!("GAME NUMBER {}", game_number);
    -        let mut your_choice = 0;
    -        loop {
    -            println!("3=ROCK...2=SCISSORS...1=PAPER");
    -            input_int("1...2...3...WHAT'S YOUR CHOICE", &mut your_choice);
    -            // interesting validation in original BASIC: IF (K-1)*(K-2)*(K-3)==0
    -            if (1..=3).contains(&your_choice) {
    -                break;
    -            }
    -            println!("INVALID.");
    -        }
    -        // Convert number to enum.  Note the type change.  Really it is a new variable.
    -        let your_choice = Choice::from_repr((your_choice - 1) as usize).unwrap();
    -        let my_choice = Choice::new_random(&mut rng);
    -
    -        println!("THIS IS MY CHOICE...");
    -        println!("...{}", my_choice.to_string());
    -        let winner = Winner::decide_winner(my_choice, your_choice);
    -        println!(
    -            "{}",
    -            match winner {
    -                Winner::Tie => {
    -                    "TIE GAME.  NO WINNER."
    -                }
    -                Winner::Computer => {
    -                    computer_wins = computer_wins + 1;
    -                    "WOW!  I WIN!!!"
    -                }
    -                Winner::Human => {
    -                    human_wins = human_wins + 1;
    -                    "YOU WIN!!!"
    -                }
    -            }
    -        )
    -    }
    -    println!();
    -    println!("HERE IS THE FINAL GAME SCORE:");
    -    println!("I HAVE WON {} GAME(S).", computer_wins);
    -    println!("YOU HAVE WON {} GAME(S).", human_wins);
    -    println!(
    -        "AND {} GAME(S) ENDED IN A TIE.",
    -        qty_games - (computer_wins + human_wins)
    -    );
    -    println!();
    -    println!("THANKS FOR PLAYING!!");
    -}
    -
    -#[derive(FromRepr, Debug, PartialEq, EnumCount, Display)]
    -pub enum Choice {
    -    PAPER,
    -    SCISSORS,
    -    ROCK,
    -}
    -
    -impl Choice {
    -    /// Returns randomly selected paper..rock.
    -    fn new_random(rng: &mut TlsWyRand) -> Choice {
    -        Choice::from_repr(rng.generate_range(0..Choice::COUNT)).unwrap()
    -    }
    -}
    -
    -#[derive(FromRepr, Debug, PartialEq, EnumCount)]
    -pub enum Winner {
    -    Human,
    -    Computer,
    -    Tie,
    -}
    -
    -impl Winner {
    -    /// take opponent's choices and decide the winner
    -    // I really learned alot about enums here, and now you can too!
    -    // Originally I broke this out for auto testing.
    -    pub fn decide_winner(my_choice: Choice, your_choice: Choice) -> Winner {
    -        let my_choice = my_choice as u8;
    -        let your_choice = your_choice as u8;
    -        if my_choice == your_choice {
    -            return Winner::Tie;
    -        }
    -        // wordy but clear way:
    -        //    if (my_choice == 1 && your_choice == 3) || (my_choice > your_choice)
    -        // consice but opaque way:
    -        if 1 == (3 + my_choice - your_choice) % 3 {
    -            return Winner::Computer;
    -        }
    -        return Winner::Human;
    -    }
    -}
    -
    -/// print the prompt, wait for a number and newline.  Loop if invalid.
    -fn input_int(prompt: &str, number: &mut i32) {
    -    loop {
    -        print!("{} ? ", prompt);
    -        io::stdout().flush().unwrap();
    -        if let Ok(n) = try_read!() {
    -            *number = n;
    -            return;
    -        }
    -    }
    -}
    -
    -/// Test winner decider for every case.
    -#[cfg(test)]
    -mod tests {
    -    #[test]
    -    fn winner_test() {
    -        use super::*;
    -        use Choice::*;
    -        use Winner::*; //decide_winner(my_choice=computer, your_choice=human)
    -        assert_eq!(Winner::decide_winner(PAPER, PAPER), Tie);
    -        assert_eq!(Winner::decide_winner(PAPER, SCISSORS), Human);
    -        assert_eq!(Winner::decide_winner(PAPER, ROCK), Computer);
    -        assert_eq!(Winner::decide_winner(SCISSORS, PAPER), Computer);
    -        assert_eq!(Winner::decide_winner(SCISSORS, SCISSORS), Tie);
    -        assert_eq!(Winner::decide_winner(SCISSORS, ROCK), Human);
    -        assert_eq!(Winner::decide_winner(ROCK, PAPER), Human);
    -        assert_eq!(Winner::decide_winner(ROCK, SCISSORS), Computer);
    -        assert_eq!(Winner::decide_winner(ROCK, ROCK), Tie);
    -    }
    -}
    diff --git a/74_Rock_Scissors_Paper/vbnet/RockScissorsPaper.sln b/74_Rock_Scissors_Paper/vbnet/RockScissorsPaper.sln
    deleted file mode 100644
    index 481f31058..000000000
    --- a/74_Rock_Scissors_Paper/vbnet/RockScissorsPaper.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index e6cf95c5f..000000000
    --- a/74_Rock_Scissors_Paper/vbnet/RockScissorsPaper.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    RockScissorsPaper
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/75_Roulette/README.md b/75_Roulette/README.md
    index b68a2ad1b..517192485 100644
    --- a/75_Roulette/README.md
    +++ b/75_Roulette/README.md
    @@ -14,7 +14,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -- The program keeps a count of how often each number comes up in array `X`, but never makes use of this information.
    diff --git a/75_Roulette/csharp/Bet.cs b/75_Roulette/csharp/Bet.cs
    deleted file mode 100644
    index da0e31b71..000000000
    --- a/75_Roulette/csharp/Bet.cs
    +++ /dev/null
    @@ -1,6 +0,0 @@
    -namespace Roulette;
    -
    -internal record struct Bet(BetType Type, int Number, int Wager)
    -{
    -    public int Payout => Wager * Type.Payout;
    -}
    diff --git a/75_Roulette/csharp/BetType.cs b/75_Roulette/csharp/BetType.cs
    deleted file mode 100644
    index 79b3b67c4..000000000
    --- a/75_Roulette/csharp/BetType.cs
    +++ /dev/null
    @@ -1,13 +0,0 @@
    -namespace Roulette;
    -
    -internal record struct BetType(int Value)
    -{
    -    public static implicit operator BetType(int value) => new(value);
    -
    -    public int Payout => Value switch
    -        {
    -            <= 36 or >= 49 => 35,
    -            <= 42 => 2,
    -            <= 48 => 1
    -        };
    -}
    diff --git a/75_Roulette/csharp/Croupier.cs b/75_Roulette/csharp/Croupier.cs
    deleted file mode 100644
    index 32f76c33b..000000000
    --- a/75_Roulette/csharp/Croupier.cs
    +++ /dev/null
    @@ -1,41 +0,0 @@
    -namespace Roulette;
    -
    -internal class Croupier
    -{
    -    private const int _initialHouse = 100_000;
    -    private const int _initialPlayer = 1_000;
    -
    -    private int _house = _initialHouse;
    -    private int _player = _initialPlayer;
    -
    -    public string Totals => Strings.Totals(_house, _player);
    -    public bool PlayerIsBroke => _player <= 0;
    -    public bool HouseIsBroke => _house <= 0;
    -
    -    internal string Pay(Bet bet)
    -    {
    -        _house -= bet.Payout;
    -        _player += bet.Payout;
    -
    -        if (_house <= 0)
    -        {
    -            _player = _initialHouse + _initialPlayer;
    -        }
    -
    -        return Strings.Win(bet);
    -    }
    -
    -    internal string Take(Bet bet)
    -    {
    -        _house += bet.Wager;
    -        _player -= bet.Wager;
    -
    -        return Strings.Lose(bet);
    -    }
    -
    -    public void CutCheck(IReadWrite io, IRandom random)
    -    {
    -        var name = io.ReadString(Prompts.Check);
    -        io.Write(Strings.Check(random, name, _player));
    -    }
    -}
    diff --git a/75_Roulette/csharp/Game.cs b/75_Roulette/csharp/Game.cs
    deleted file mode 100644
    index 75a6d7e54..000000000
    --- a/75_Roulette/csharp/Game.cs
    +++ /dev/null
    @@ -1,42 +0,0 @@
    -namespace Roulette;
    -
    -internal class Game
    -{
    -    private readonly IReadWrite _io;
    -    private readonly IRandom _random;
    -    private readonly Table _table;
    -    private readonly Croupier _croupier;
    -
    -    public Game(IReadWrite io, IRandom random)
    -    {
    -        _io = io;
    -        _random = random;
    -        _croupier = new();
    -        _table = new(_croupier, io, random);
    -    }
    -
    -    public void Play()
    -    {
    -        _io.Write(Streams.Title);
    -        if (!_io.ReadString(Prompts.Instructions).ToLowerInvariant().StartsWith('n'))
    -        {
    -            _io.Write(Streams.Instructions);
    -        }
    -
    -        while (_table.Play());
    -
    -        if (_croupier.PlayerIsBroke)
    -        {
    -            _io.Write(Streams.LastDollar);
    -            _io.Write(Streams.Thanks);
    -            return;
    -        }
    -
    -        if (_croupier.HouseIsBroke)
    -        {
    -            _io.Write(Streams.BrokeHouse);
    -        }
    -
    -        _croupier.CutCheck(_io, _random);
    -    }
    -}
    diff --git a/75_Roulette/csharp/IOExtensions.cs b/75_Roulette/csharp/IOExtensions.cs
    deleted file mode 100644
    index 49326bef7..000000000
    --- a/75_Roulette/csharp/IOExtensions.cs
    +++ /dev/null
    @@ -1,34 +0,0 @@
    -namespace Roulette;
    -
    -internal static class IOExtensions
    -{
    -    internal static int ReadBetCount(this IReadWrite io)
    -    {
    -        while (true)
    -        {
    -            var betCount = io.ReadNumber(Prompts.HowManyBets);
    -            if (betCount.IsValidInt(1)) { return (int)betCount; }
    -        }
    -    }
    -
    -    internal static Bet ReadBet(this IReadWrite io, int number)
    -    {
    -        while (true)
    -        {
    -            var (type, amount) = io.Read2Numbers(Prompts.Bet(number));
    -
    -            if (type.IsValidInt(1, 50) && amount.IsValidInt(5, 500))
    -            {
    -                return new()
    -                {
    -                    Type = (int)type, 
    -                    Number = number, 
    -                    Wager = (int)amount
    -                };
    -            }
    -        }
    -    }
    -
    -    internal static bool IsValidInt(this float value, int minValue, int maxValue = int.MaxValue)
    -        => value == (int)value && value >= minValue && value <= maxValue;
    -}
    \ No newline at end of file
    diff --git a/75_Roulette/csharp/Program.cs b/75_Roulette/csharp/Program.cs
    deleted file mode 100644
    index 4be74962b..000000000
    --- a/75_Roulette/csharp/Program.cs
    +++ /dev/null
    @@ -1,6 +0,0 @@
    -global using Games.Common.IO;
    -global using Games.Common.Randomness;
    -global using static Roulette.Resources.Resource;
    -using Roulette;
    -
    -new Game(new ConsoleIO(), new RandomNumberGenerator()).Play();
    diff --git a/75_Roulette/csharp/Resources/AgainPrompt.txt b/75_Roulette/csharp/Resources/AgainPrompt.txt
    deleted file mode 100644
    index bd1d18b62..000000000
    --- a/75_Roulette/csharp/Resources/AgainPrompt.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Again
    \ No newline at end of file
    diff --git a/75_Roulette/csharp/Resources/BetAlready.txt b/75_Roulette/csharp/Resources/BetAlready.txt
    deleted file mode 100644
    index be86cbeaf..000000000
    --- a/75_Roulette/csharp/Resources/BetAlready.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -You made that bet once already,dum-dum
    \ No newline at end of file
    diff --git a/75_Roulette/csharp/Resources/BetPrompt.txt b/75_Roulette/csharp/Resources/BetPrompt.txt
    deleted file mode 100644
    index 500398400..000000000
    --- a/75_Roulette/csharp/Resources/BetPrompt.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Number {0} 
    \ No newline at end of file
    diff --git a/75_Roulette/csharp/Resources/BrokeHouse.txt b/75_Roulette/csharp/Resources/BrokeHouse.txt
    deleted file mode 100644
    index 638dafb4e..000000000
    --- a/75_Roulette/csharp/Resources/BrokeHouse.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -You broke the house!
    diff --git a/75_Roulette/csharp/Resources/Check.txt b/75_Roulette/csharp/Resources/Check.txt
    deleted file mode 100644
    index ffdd640ab..000000000
    --- a/75_Roulette/csharp/Resources/Check.txt
    +++ /dev/null
    @@ -1,16 +0,0 @@
    -
    -------------------------------------------------------------------------Check No.  {0}
    -
    -                                        {1:MMMM d',' yyyy}
    -
    -
    -Pay to the order of-----{2}-----$  {3}
    -
    -
    -              The Memory Bank of New YORK
    -
    -                                          The Computer
    -                                        ----------X-----
    -
    ---------------------------------------------------------------Come back soon!
    -
    diff --git a/75_Roulette/csharp/Resources/CheckPrompt.txt b/75_Roulette/csharp/Resources/CheckPrompt.txt
    deleted file mode 100644
    index 16321fe95..000000000
    --- a/75_Roulette/csharp/Resources/CheckPrompt.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -To whom shall I make the check
    \ No newline at end of file
    diff --git a/75_Roulette/csharp/Resources/HowManyBetsPrompt.txt b/75_Roulette/csharp/Resources/HowManyBetsPrompt.txt
    deleted file mode 100644
    index 0b6abdfa3..000000000
    --- a/75_Roulette/csharp/Resources/HowManyBetsPrompt.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -How many bets
    \ No newline at end of file
    diff --git a/75_Roulette/csharp/Resources/Instructions.txt b/75_Roulette/csharp/Resources/Instructions.txt
    deleted file mode 100644
    index 8ced724b5..000000000
    --- a/75_Roulette/csharp/Resources/Instructions.txt
    +++ /dev/null
    @@ -1,48 +0,0 @@
    -
    -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.
    -
    diff --git a/75_Roulette/csharp/Resources/InstructionsPrompt.txt b/75_Roulette/csharp/Resources/InstructionsPrompt.txt
    deleted file mode 100644
    index 0d311b605..000000000
    --- a/75_Roulette/csharp/Resources/InstructionsPrompt.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Do you want instructions
    \ No newline at end of file
    diff --git a/75_Roulette/csharp/Resources/LastDollar.txt b/75_Roulette/csharp/Resources/LastDollar.txt
    deleted file mode 100644
    index 632516de0..000000000
    --- a/75_Roulette/csharp/Resources/LastDollar.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Oops! you just spent your last dollar!
    diff --git a/75_Roulette/csharp/Resources/Outcome.txt b/75_Roulette/csharp/Resources/Outcome.txt
    deleted file mode 100644
    index 30e227f7c..000000000
    --- a/75_Roulette/csharp/Resources/Outcome.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -You {0} {1} dollars on bet {2}
    diff --git a/75_Roulette/csharp/Resources/Resource.cs b/75_Roulette/csharp/Resources/Resource.cs
    deleted file mode 100644
    index dd9c86723..000000000
    --- a/75_Roulette/csharp/Resources/Resource.cs
    +++ /dev/null
    @@ -1,59 +0,0 @@
    -using System.Reflection;
    -using System.Runtime.CompilerServices;
    -using Games.Common.Randomness;
    -
    -namespace Roulette.Resources;
    -
    -internal static class Resource
    -{
    -    internal static class Streams
    -    {
    -        public static Stream Title => GetStream();
    -        public static Stream Instructions => GetStream();
    -        public static Stream BetAlready => GetStream();
    -        public static Stream Spinning => GetStream();
    -        public static Stream LastDollar => GetStream();
    -        public static Stream BrokeHouse => GetStream();
    -        public static Stream Thanks => GetStream();
    -    }
    -
    -    internal static class Strings
    -    {
    -        public static string Black(int number) => Slot(number);
    -        public static string Red(int number) => Slot(number);
    -        private static string Slot(int number, [CallerMemberName] string? colour = null)
    -            => string.Format(GetString(), number, colour);
    -
    -        public static string Lose(Bet bet) => Outcome(bet.Wager, bet.Number);
    -        public static string Win(Bet bet) => Outcome(bet.Payout, bet.Number);
    -        private static string Outcome(int amount, int number, [CallerMemberName] string? winlose = null)
    -            => string.Format(GetString(), winlose, amount, number);
    -
    -        public static string Totals(int me, int you) => string.Format(GetString(), me, you);
    -
    -        public static string Check(IRandom random, string payee, int amount)
    -            => string.Format(GetString(), random.Next(100), DateTime.Now, payee, amount);
    -    }
    -
    -    internal static class Prompts
    -    {
    -        public static string Instructions => GetPrompt();
    -        public static string HowManyBets => GetPrompt();
    -        public static string Bet(int number) => string.Format(GetPrompt(), number);
    -        public static string Again => GetPrompt();
    -        public static string Check => GetPrompt();
    -    }
    -
    -    private static string GetPrompt([CallerMemberName] string? name = null) => GetString($"{name}Prompt");
    -
    -    private static string GetString([CallerMemberName] string? name = null)
    -    {
    -        using var stream = GetStream(name);
    -        using var reader = new StreamReader(stream);
    -        return reader.ReadToEnd();
    -    }
    -
    -    private static Stream GetStream([CallerMemberName] string? name = null) =>
    -        Assembly.GetExecutingAssembly().GetManifestResourceStream($"{typeof(Resource).Namespace}.{name}.txt")
    -            ?? throw new Exception($"Could not find embedded resource stream '{name}'.");
    -}
    \ No newline at end of file
    diff --git a/75_Roulette/csharp/Resources/Slot.txt b/75_Roulette/csharp/Resources/Slot.txt
    deleted file mode 100644
    index de02695df..000000000
    --- a/75_Roulette/csharp/Resources/Slot.txt
    +++ /dev/null
    @@ -1,2 +0,0 @@
    - {0} {1}
    -
    diff --git a/75_Roulette/csharp/Resources/Spinning.txt b/75_Roulette/csharp/Resources/Spinning.txt
    deleted file mode 100644
    index 0d87fe392..000000000
    --- a/75_Roulette/csharp/Resources/Spinning.txt
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Spinning
    -
    -
    diff --git a/75_Roulette/csharp/Resources/Thanks.txt b/75_Roulette/csharp/Resources/Thanks.txt
    deleted file mode 100644
    index 0b8352376..000000000
    --- a/75_Roulette/csharp/Resources/Thanks.txt
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Thanks for you money.
    -I'll use it to buy a solid gold roulette WHEEL
    -
    diff --git a/75_Roulette/csharp/Resources/Title.txt b/75_Roulette/csharp/Resources/Title.txt
    deleted file mode 100644
    index 0d53f1a80..000000000
    --- a/75_Roulette/csharp/Resources/Title.txt
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -                                Roulette
    -               Creative Computing  Morristown, New Jersey
    -
    -
    -
    -Welcome to the roulette table
    -
    diff --git a/75_Roulette/csharp/Resources/Totals.txt b/75_Roulette/csharp/Resources/Totals.txt
    deleted file mode 100644
    index 4cecae3f1..000000000
    --- a/75_Roulette/csharp/Resources/Totals.txt
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -
    -Totals        Me            You
    -               {0,-14}{1}
    diff --git a/75_Roulette/csharp/Roulette.csproj b/75_Roulette/csharp/Roulette.csproj
    deleted file mode 100644
    index 23d27b76d..000000000
    --- a/75_Roulette/csharp/Roulette.csproj
    +++ /dev/null
    @@ -1,17 +0,0 @@
    -
    -  
    -    Exe
    -    net7.0
    -    10
    -    enable
    -    enable
    -  
    -
    -  
    -    
    -  
    -
    -  
    -    
    -  
    -
    diff --git a/75_Roulette/csharp/Roulette.sln b/75_Roulette/csharp/Roulette.sln
    deleted file mode 100644
    index de44173b2..000000000
    --- a/75_Roulette/csharp/Roulette.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/csharp/Slot.cs b/75_Roulette/csharp/Slot.cs
    deleted file mode 100644
    index df30cea1f..000000000
    --- a/75_Roulette/csharp/Slot.cs
    +++ /dev/null
    @@ -1,18 +0,0 @@
    -using System.Collections.Immutable;
    -
    -namespace Roulette;
    -
    -internal class Slot
    -{
    -    private readonly ImmutableHashSet _coveringBets;
    -
    -    public Slot (string name, params BetType[] coveringBets)
    -    {
    -        Name = name;
    -        _coveringBets = coveringBets.ToImmutableHashSet();
    -    }
    -
    -    public string Name { get; }
    -
    -    public bool IsCoveredBy(Bet bet) => _coveringBets.Contains(bet.Type);
    -}
    diff --git a/75_Roulette/csharp/Table.cs b/75_Roulette/csharp/Table.cs
    deleted file mode 100644
    index 026152d1c..000000000
    --- a/75_Roulette/csharp/Table.cs
    +++ /dev/null
    @@ -1,71 +0,0 @@
    -namespace Roulette;
    -
    -internal class Table
    -{
    -    private readonly IReadWrite _io;
    -    private readonly Wheel _wheel;
    -    private readonly Croupier _croupier;
    -
    -    public Table(Croupier croupier, IReadWrite io, IRandom random)
    -    {
    -        _croupier = croupier;
    -        _io = io;
    -        _wheel = new(random);
    -    }
    -
    -    public bool Play()
    -    {
    -        var bets = AcceptBets();
    -        var slot = SpinWheel();
    -        SettleBets(bets, slot);
    -
    -        _io.Write(_croupier.Totals);
    -
    -        if (_croupier.PlayerIsBroke || _croupier.HouseIsBroke) { return false; }
    -
    -        return _io.ReadString(Prompts.Again).ToLowerInvariant().StartsWith('y');
    -    }
    -
    -    private Slot SpinWheel()
    -    {
    -        _io.Write(Streams.Spinning);
    -        var slot = _wheel.Spin();
    -        _io.Write(slot.Name);
    -        return slot;
    -    }
    -
    -    private IReadOnlyList AcceptBets()
    -    {
    -        var betCount = _io.ReadBetCount();
    -        var betTypes = new HashSet();
    -        var bets = new List();
    -        for (int i = 1; i <= betCount; i++)
    -        {
    -            while (!TryAdd(_io.ReadBet(i)))
    -            {
    -                _io.Write(Streams.BetAlready);
    -            }
    -        }
    -
    -        return bets.AsReadOnly();
    -
    -        bool TryAdd(Bet bet)
    -        {
    -            if (betTypes.Add(bet.Type))
    -            {
    -                bets.Add(bet);
    -                return true;
    -            }
    -
    -            return false;
    -        }
    -    }
    -
    -    private void SettleBets(IReadOnlyList bets, Slot slot)
    -    {
    -        foreach (var bet in bets)
    -        {
    -            _io.Write(slot.IsCoveredBy(bet) ? _croupier.Pay(bet) : _croupier.Take(bet));
    -        }
    -    }
    -}
    diff --git a/75_Roulette/csharp/Wheel.cs b/75_Roulette/csharp/Wheel.cs
    deleted file mode 100644
    index dfcecd293..000000000
    --- a/75_Roulette/csharp/Wheel.cs
    +++ /dev/null
    @@ -1,52 +0,0 @@
    -using System.Collections.Immutable;
    -
    -namespace Roulette;
    -
    -internal class Wheel
    -{
    -    private static readonly ImmutableArray _slots = ImmutableArray.Create(
    -        new Slot(Strings.Red(1), 1, 37, 40, 43, 46, 47),
    -        new Slot(Strings.Black(2), 2, 37, 41, 43, 45, 48),
    -        new Slot(Strings.Red(3), 3, 37, 42, 43, 46, 47),
    -        new Slot(Strings.Black(4), 4, 37, 40, 43, 45, 48),
    -        new Slot(Strings.Red(5), 5, 37, 41, 43, 46, 47),
    -        new Slot(Strings.Black(6), 6, 37, 42, 43, 45, 48),
    -        new Slot(Strings.Red(7), 7, 37, 40, 43, 46, 47),
    -        new Slot(Strings.Black(8), 8, 37, 41, 43, 45, 48),
    -        new Slot(Strings.Red(9), 9, 37, 42, 43, 46, 47),
    -        new Slot(Strings.Black(10), 10, 37, 40, 43, 45, 48),
    -        new Slot(Strings.Black(11), 11, 37, 41, 43, 46, 48),
    -        new Slot(Strings.Red(12), 12, 37, 42, 43, 45, 47),
    -        new Slot(Strings.Black(13), 13, 38, 40, 43, 46, 48),
    -        new Slot(Strings.Red(14), 14, 38, 41, 43, 45, 47),
    -        new Slot(Strings.Black(15), 15, 38, 42, 43, 46, 48),
    -        new Slot(Strings.Red(16), 16, 38, 40, 43, 45, 47),
    -        new Slot(Strings.Black(17), 17, 38, 41, 43, 46, 48),
    -        new Slot(Strings.Red(18), 18, 38, 42, 43, 45, 47),
    -        new Slot(Strings.Red(19), 19, 38, 40, 44, 46, 47),
    -        new Slot(Strings.Black(20), 20, 38, 41, 44, 45, 48),
    -        new Slot(Strings.Red(21), 21, 38, 42, 44, 46, 47),
    -        new Slot(Strings.Black(22), 22, 38, 40, 44, 45, 48),
    -        new Slot(Strings.Red(23), 23, 38, 41, 44, 46, 47),
    -        new Slot(Strings.Black(24), 24, 38, 42, 44, 45, 48),
    -        new Slot(Strings.Red(25), 25, 39, 40, 44, 46, 47),
    -        new Slot(Strings.Black(26), 26, 39, 41, 44, 45, 48),
    -        new Slot(Strings.Red(27), 27, 39, 42, 44, 46, 47),
    -        new Slot(Strings.Black(28), 28, 39, 40, 44, 45, 48),
    -        new Slot(Strings.Black(29), 29, 39, 41, 44, 46, 48),
    -        new Slot(Strings.Red(30), 30, 39, 42, 44, 45, 47),
    -        new Slot(Strings.Black(31), 31, 39, 40, 44, 46, 48),
    -        new Slot(Strings.Red(32), 32, 39, 41, 44, 45, 47),
    -        new Slot(Strings.Black(33), 33, 39, 42, 44, 46, 48),
    -        new Slot(Strings.Red(34), 34, 39, 40, 44, 45, 47),
    -        new Slot(Strings.Black(35), 35, 39, 41, 44, 46, 48),
    -        new Slot(Strings.Red(36), 36, 39, 42, 44, 45, 47),
    -        new Slot("0", 49),
    -        new Slot("00", 50));
    -    
    -    private readonly IRandom _random;
    -
    -    public Wheel(IRandom random) => _random = random;
    -
    -    public Slot Spin() => _slots[_random.Next(_slots.Length)];
    -}
    diff --git a/75_Roulette/java/README.md b/75_Roulette/java/README.md
    index ffa8a3ef2..bc05d92c5 100644
    --- a/75_Roulette/java/README.md
    +++ b/75_Roulette/java/README.md
    @@ -6,5 +6,5 @@ Two versions of Roulette has been contributed. They are indicated within given s
     
     - [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.
    -    - Does make use of some object oriented programming, but acts as a more iterative solution.
    +    - 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
    diff --git a/75_Roulette/java/oop/Bet.java b/75_Roulette/java/oop/Bet.java
    index 8742ca6b0..6d9ea48a3 100644
    --- a/75_Roulette/java/oop/Bet.java
    +++ b/75_Roulette/java/oop/Bet.java
    @@ -16,7 +16,7 @@ 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;
    diff --git a/75_Roulette/java/oop/Roulette.java b/75_Roulette/java/oop/Roulette.java
    index e7f9c4445..77ae3463f 100644
    --- a/75_Roulette/java/oop/Roulette.java
    +++ b/75_Roulette/java/oop/Roulette.java
    @@ -17,7 +17,7 @@ public static void main(String args[]) throws Exception {
     
         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();
    @@ -156,7 +156,7 @@ private boolean betAndSpin() throws IOException {
             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) {
    +        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 {
    diff --git a/75_Roulette/java/oop/Wheel.java b/75_Roulette/java/oop/Wheel.java
    index a454b22c7..497c8b53d 100644
    --- a/75_Roulette/java/oop/Wheel.java
    +++ b/75_Roulette/java/oop/Wheel.java
    @@ -36,7 +36,7 @@ public void spin() {
                 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";
    diff --git a/75_Roulette/javascript/roulette.html b/75_Roulette/javascript/roulette.html
    index ee9684a70..024958926 100644
    --- a/75_Roulette/javascript/roulette.html
    +++ b/75_Roulette/javascript/roulette.html
    @@ -1,10 +1,9 @@
     
     
     ROULETTE
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/75_Roulette/javascript/roulette.js b/75_Roulette/javascript/roulette.js
    index db153017e..7c3399bd4 100644
    --- a/75_Roulette/javascript/roulette.js
    +++ b/75_Roulette/javascript/roulette.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/75_Roulette/kotlin/README.md b/75_Roulette/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/75_Roulette/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/75_Roulette/lua/README.md b/75_Roulette/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/75_Roulette/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/75_Roulette/pascal/README.md b/75_Roulette/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/75_Roulette/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/75_Roulette/perl/roulette.pl b/75_Roulette/perl/roulette.pl
    index 7cd5de70d..ad3ce9652 100755
    --- a/75_Roulette/perl/roulette.pl
    +++ b/75_Roulette/perl/roulette.pl
    @@ -38,21 +38,21 @@ sub main {
       (*=red)
     
      1*    2     3*
    - 4     5*    6
    + 4     5*    6 
      7*    8     9*
     10    11    12*
     ---------------
    -13    14*   15
    +13    14*   15 
     16*   17    18*
     19*   20    21*
    -22    23*   24
    +22    23*   24 
     ---------------
     25*   26    27*
     28    29    30*
    -31    32*   33
    +31    32*   33 
     34*   35    36*
     ---------------
    -    00    0
    +    00    0    
     
     Types of bets:
     
    diff --git a/75_Roulette/python/roulette.py b/75_Roulette/python/roulette.py
    index eec68bed7..c839adc72 100644
    --- a/75_Roulette/python/roulette.py
    +++ b/75_Roulette/python/roulette.py
    @@ -1,14 +1,11 @@
    -import random
     from datetime import date
    -from typing import List, Tuple
    +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]
     
    -
    -def print_instructions() -> None:
    -    print(
    -        """
    +def print_instructions():
    +    print("""
     THIS IS THE BETTING LAYOUT
       (*=RED)
     
    @@ -56,101 +53,101 @@ def print_instructions() -> None:
     
     THE MINIMUM BET IS $5, THE MAXIMUM IS $500.
     
    -    """
    -    )
    +    """)
     
    -
    -def query_bets() -> Tuple[List[int], List[int]]:
    +def query_bets():
         """Queries the user to input their bets"""
    -    bet_count = -1
    -    while bet_count <= 0:
    +    betCount = -1
    +    while betCount <= 0:
             try:
    -            bet_count = int(input("HOW MANY BETS? "))
    -        except Exception:
    +            betCount = int(input("HOW MANY BETS? "))
    +        except:
                 ...
     
    -    bet_ids = [-1] * bet_count
    -    bet_values = [0] * bet_count
    +    bet_IDs = [-1] * betCount
    +    bet_Values = [0] * betCount
     
    -    for i in range(bet_count):
    -        while bet_ids[i] == -1:
    +    for i in range(betCount):
    +        while(bet_IDs[i] == -1):
                 try:
    -                in_string = input(f"NUMBER {str(i + 1)}? ").split(",")
    -                id_, val = int(in_string[0]), int(in_string[1])
    +                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
    +                    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 Exception:
    -                pass
    -    return bet_ids, bet_values
    -
    +                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: List[int], bet_values: List[int], result) -> int:
    +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_: int, num: int) -> int:
    -        if (
    -            (id_ == 37 and num <= 12)
    -            or (id_ == 38 and num > 12 and num <= 24)
    -            or (id_ == 39 and num > 24 and num < 37)
    -            or (id_ == 40 and num < 37 and num % 3 == 1)
    -            or (id_ == 41 and num < 37 and num % 3 == 2)
    -            or (id_ == 42 and num < 37 and num % 3 == 0)
    -        ):
    +    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_ == 43 and num <= 18)
    -            or (id_ == 44 and num > 18 and num <= 36)
    -            or (id_ == 45 and num % 2 == 0)
    -            or (id_ == 46 and num % 2 == 1)
    -            or (id_ == 47 and num in RED_NUMBERS)
    -            or (id_ == 48 and num not in RED_NUMBERS)
    -        ):
    +        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_ < 37 and id_ == num:
    +        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)
    +    for i in range(len(bet_IDs)):
    +        winnings = bet_Values[i] * get_modifier(bet_IDs[i],result)
             total_winnings += winnings
     
             if winnings >= 0:
    -            print(f"YOU WIN {str(winnings)} DOLLARS ON BET {str(i + 1)}")
    +            print("YOU WIN " + str(winnings) + " DOLLARS ON BET " + str(i + 1))
             else:
    -            print(f"YOU LOSE {str(winnings * -1)} DOLLARS ON BET {str(i + 1)}")
    +            print("YOU LOSE " + str(winnings * -1) + " DOLLARS ON BET " + str(i + 1))
     
         return winnings
     
    -
    -def print_check(amount: int) -> None:
    -    """Print a check of a given amount"""
    +def print_check(amount):
    +    """Prints a check of a given amount"""
         name = input("TO WHOM SHALL I MAKE THE CHECK? ")
     
         print("-" * 72)
         print()
    -    print(" " * 40 + "CHECK NO. " + str(random.randint(0, 100)))
    +    print(" " * 40 + "CHECK NO. " + str(random.randint(0,100)))
         print(" " * 40 + str(date.today()))
         print()
    -    print(f"PAY TO THE ORDER OF -----{name}----- ${amount}")
    +    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() -> None:
    +def main():
         player_balance = 1000
         host_balance = 100000
     
    @@ -160,28 +157,28 @@ def main() -> None:
         print()
         print()
     
    -    if string_to_bool(input("DO YOU WANT INSTRUCTIONS? ")):
    +    if stringtobool(input("DO YOU WANT INSTRUCTIONS? ")):
             print_instructions()
     
         while True:
    -        bet_ids, bet_values = query_bets()
    +        bet_IDs,bet_Values = query_bets()
     
             print("SPINNING")
             print()
             print()
     
    -        val = random.randint(0, 38)
    +        val = random.randint(0,38)
             if val == 38:
                 print("0")
             elif val == 37:
                 print("00")
             elif val in RED_NUMBERS:
    -            print(f"{val} RED")
    +            print(str(val) + " RED")
             else:
    -            print(f"{val} BLACK")
    +            print(str(val) + " BLACK")
     
             print()
    -        total_winnings = bet_results(bet_ids, bet_values, val)
    +        total_winnings = bet_results(bet_IDs,bet_Values,val)
             player_balance += total_winnings
             host_balance -= total_winnings
     
    @@ -196,9 +193,10 @@ def main() -> None:
                 print("YOU BROKE THE HOUSE!")
                 player_balance = 101000
                 break
    -        if not string_to_bool(input("PLAY AGAIN? ")):
    +        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")
    @@ -207,10 +205,9 @@ def main() -> None:
         print("COME BACK SOON!")
     
     
    -def string_to_bool(string: str) -> bool:
    +def stringtobool(string):
         """Converts a string to a bool"""
    -    return string.lower() in {"y", "true", "t", "yes"}
    -
    +    return string.lower() in ("yes","y","true","t","yes")
     
    -if __name__ == "__main__":
    +if __name__ == '__main__':
         main()
    diff --git a/75_Roulette/roulette.bas b/75_Roulette/roulette.bas
    index 461231c0b..50b7134ff 100644
    --- a/75_Roulette/roulette.bas
    +++ b/75_Roulette/roulette.bas
    @@ -6,14 +6,14 @@
     1000 REM-ROULETTE
     1010 REM-DAVID JOSLIN
     1020 PRINT "WELCOME TO THE ROULETTE TABLE"
    -1030 PRINT
    +1030 PRINT 
     1040 PRINT "DO YOU WANT INSTRUCTIONS";
     1050 INPUT Y$
     1060 IF LEFT$(Y$,1)="N" THEN 1550
     1070 PRINT
     1080 PRINT "THIS IS THE BETTING LAYOUT"
     1090 PRINT "  (*=RED)"
    -1100 PRINT
    +1100 PRINT 
     1110 PRINT " 1*    2     3*"
     1120 PRINT " 4     5*    6 "
     1130 PRINT " 7*    8     9*"
    @@ -32,21 +32,21 @@
     1260 PRINT "    00    0    "
     1270 PRINT
     1280 PRINT "TYPES OF BETS"
    -1290 PRINT
    +1290 PRINT 
     1300 PRINT "THE NUMBERS 1 TO 36 SIGNIFY A STRAIGHT BET"
     1310 PRINT "ON THAT NUMBER."
     1320 PRINT "THESE PAY OFF 35:1"
    -1330 PRINT
    +1330 PRINT 
     1340 PRINT "THE 2:1 BETS ARE:"
     1350 PRINT " 37) 1-12     40) FIRST COLUMN"
     1360 PRINT " 38) 13-24    41) SECOND COLUMN"
     1370 PRINT " 39) 25-36    42) THIRD COLUMN"
    -1380 PRINT
    +1380 PRINT 
     1390 PRINT "THE EVEN MONEY BETS ARE:"
     1400 PRINT " 43) 1-18     46) ODD"
     1410 PRINT " 44) 19-36    47) RED"
     1420 PRINT " 45) EVEN     48) BLACK"
    -1430 PRINT
    +1430 PRINT 
     1440 PRINT " 49)0 AND 50)00 PAY OFF 35:1"
     1450 PRINT " NOTE: 0 AND 00 DO NOT COUNT UNDER ANY"
     1460 PRINT "       BETS EXCEPT THEIR OWN."
    @@ -55,9 +55,9 @@
     1490 PRINT "AND THE AMOUNT, SEPARATED BY A COMMA."
     1500 PRINT "FOR EXAMPLE: TO BET $500 ON BLACK, TYPE 48,500"
     1510 PRINT "WHEN I ASK FOR A BET."
    -1520 PRINT
    +1520 PRINT 
     1530 PRINT "THE MINIMUM BET IS $5, THE MAXIMUM IS $500."
    -1540 PRINT
    +1540 PRINT 
     1550 REM-PROGRAM BEGINS HERE
     1560 REM-TYPE OF BET(NUMBER) ODDS
     1570 REM  DON'T NEED TO DIMENSION STRINGS
    @@ -84,8 +84,8 @@
     1780 A(X)=1
     1790 NEXT C
     1800 PRINT "SPINNING"
    -1810 PRINT
    -1820 PRINT
    +1810 PRINT 
    +1820 PRINT 
     1830 S=INT(RND(1)*100)
     1840 IF S=0 OR S>38 THEN 1830
     1850 X(S)=X(S)+1
    @@ -95,7 +95,7 @@
     1890 GOTO 2020
     1900 PRINT "0"
     1910 GOTO 2020
    -1920 RESTORE
    +1920 RESTORE 
     1930 FOR I1=1 TO 18
     1940 READ R
     1950 IF R=S THEN 2000
    @@ -160,14 +160,14 @@
     2540 IF S/2<>INT(S/2) AND S<37 THEN 2430
     2550 GOTO 2110
     2560 REM  RED(47) 1:1
    -2570 RESTORE
    +2570 RESTORE 
     2580 FOR I=1 TO 18
     2590 READ R
     2600 IF S=R THEN 2430
     2610 NEXT I
     2620 GOTO 2110
     2630 REM  BLACK(48) 1:1
    -2640 RESTORE
    +2640 RESTORE 
     2650 FOR I=1 TO 18
     2660 READ R
     2670 IF S=R THEN 2110
    @@ -185,7 +185,7 @@
     2790 D=D-B(C)*35
     2800 P=P+B(C)*35
     2810 NEXT C
    -2820 PRINT
    +2820 PRINT 
     2830 PRINT "TOTALS:","ME","YOU"
     2840 PRINT " ",D,P
     2850 IF P>0 THEN 2880
    @@ -202,29 +202,29 @@
     2960 IF P<1 THEN 3190
     2970 PRINT "TO WHOM SHALL I MAKE THE CHECK";
     2980 INPUT B$
    -2990 PRINT
    +2990 PRINT 
     3000 FOR I=1 TO 72: PRINT "-";: NEXT I: REM PRINT 72 DASHES
     3010 PRINT TAB(50);"CHECK NO. ";INT(RND(1)*100)
    -3020 PRINT
    +3020 PRINT 
     3030 GOSUB 3230
     3040 PRINT TAB(40);M$
    -3050 PRINT
    -3060 PRINT
    +3050 PRINT 
    +3060 PRINT 
     3070 PRINT "PAY TO THE ORDER OF-----";B$;"-----$ ";
     3080 PRINT P
    -3090 PRINT
    -3100 PRINT
    +3090 PRINT 
    +3100 PRINT 
     3110 PRINT TAB(10),"THE MEMORY BANK OF NEW YORK"
    -3120 PRINT
    +3120 PRINT 
     3130 PRINT TAB(40),"THE COMPUTER"
     3140 PRINT TAB(40)"----------X-----"
    -3150 PRINT
    +3150 PRINT 
     3160 FOR I=1 TO 62: PRINT "-";: NEXT I
     3170 PRINT "COME BACK SOON!"
     3180 GOTO 3210
     3190 PRINT "THANKS FOR YOUR MONEY."
     3200 PRINT "I'LL USE IT TO BUY A SOLID GOLD ROULETTE WHEEL"
    -3210 PRINT
    +3210 PRINT 
     3220 GOTO 3420
     3230 REM
     3240 REM     THIS ROUTINE RETURNS THE CURRENT DATE IN M$
    diff --git a/75_Roulette/rust/Cargo.lock b/75_Roulette/rust/Cargo.lock
    deleted file mode 100644
    index 81365033b..000000000
    --- a/75_Roulette/rust/Cargo.lock
    +++ /dev/null
    @@ -1,82 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.10"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.147"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
    -
    -[[package]]
    -name = "morristown"
    -version = "0.1.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "f83b191fd96370b91c2925125774011a7a0f69b4db9e2045815e4fd20af725f6"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    -dependencies = [
    - "morristown",
    - "rand",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/75_Roulette/rust/Cargo.toml b/75_Roulette/rust/Cargo.toml
    deleted file mode 100644
    index 37f4add75..000000000
    --- a/75_Roulette/rust/Cargo.toml
    +++ /dev/null
    @@ -1,10 +0,0 @@
    -[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]
    -morristown = "0.1.4"
    -rand = "0.8.5"
    diff --git a/75_Roulette/rust/src/main.rs b/75_Roulette/rust/src/main.rs
    deleted file mode 100644
    index b0fd8765b..000000000
    --- a/75_Roulette/rust/src/main.rs
    +++ /dev/null
    @@ -1,106 +0,0 @@
    -mod util;
    -
    -use morristown::{Instructions, PromptMultiOption};
    -use rand::Rng;
    -use util::INSTRUCTIONS;
    -
    -fn main() {
    -    morristown::print_intro("ROULETTE");
    -
    -    let date = morristown::prompt_multi_string(
    -        "ENTER CURRENT DATE (AS IN 'JANUARY 23, 1978)",
    -        ",",
    -        Some(PromptMultiOption::UnitAmount(2)),
    -    );
    -
    -    Instructions::new_multiline(
    -        true,
    -        false,
    -        "DO YOU WANT INSTRUCTIONS?",
    -        INSTRUCTIONS.to_vec(),
    -    )
    -    .print();
    -
    -    let mut house: usize = 100000;
    -    let mut player: usize = 1000;
    -
    -    loop {
    -        let bet_count = morristown::prompt_number_range::("HOW MANY BETS?", 1..=10);
    -        let mut bets: Vec> = Vec::new();
    -
    -        for i in 1..=bet_count {
    -            loop {
    -                let msg = format!("NUMBER {}?", i);
    -                let bet_input = morristown::prompt_multi_number::(
    -                    msg.as_str(),
    -                    ",",
    -                    Some(PromptMultiOption::UnitAmount(2)),
    -                    None,
    -                );
    -                let (bet_num, wager) = (bet_input[0], bet_input[1]);
    -
    -                if let Some(_) = bets.iter().find(|bet| bet[0] == bet_num) {
    -                    println!("YOU MADE THAT BET ONCE ALREADY, DUM-DUM");
    -                } else if bet_num > 0 && bet_num <= 50 && wager >= 5 && wager <= 500 {
    -                    bets.push(bet_input);
    -                    player -= wager;
    -                    house += wager;
    -                    break;
    -                } else if wager > player {
    -                    println!("NOT ENOUGH MONEY")
    -                } else {
    -                    println!("INVALID BET. TRY AGAIN");
    -                }
    -            }
    -        }
    -
    -        println!("\nSPINNING");
    -        std::thread::sleep(std::time::Duration::from_secs(1));
    -        let spin: u8 = rand::thread_rng().gen_range(1..=38);
    -
    -        let color = if util::REDS.contains(&spin) {
    -            "RED"
    -        } else {
    -            "BLACK"
    -        };
    -
    -        println!("\n{} {}\n", spin, color);
    -
    -        for (i, bet) in bets.iter().enumerate() {
    -            let (bet_num, wager) = (bet[0] as u8, bet[1]);
    -            let (win, payoff) = util::process_bet(bet_num, spin);
    -
    -            let msg = if win {
    -                let pay = wager * payoff as usize;
    -                player += wager + pay;
    -                house -= pay;
    -                "WIN"
    -            } else {
    -                "LOSE"
    -            };
    -
    -            println!("YOU {msg} {wager} DOLLARS ON BET {}", i + 1);
    -        }
    -
    -        println!("\nTOTALS:\t\tME\t\tYOU");
    -        println!("\t\t{house}\t\t{player}");
    -
    -        if player <= 0 {
    -            println!("OOPS! YOU JUST SPENT YOUR LAST DOLLAR");
    -            println!("THANKS FOR YOUR MONEY");
    -            println!("I'LL USE IT TO BUY A SOLID GOLD ROULETTE WHEEL");
    -            break;
    -        }
    -
    -        if house <= 0 {
    -            println!("YOU BROKE THE HOUSE!");
    -            util::print_check(player, date);
    -            break;
    -        }
    -
    -        if !morristown::prompt_bool("AGAIN?", false) {
    -            util::print_check(player, date);
    -            break;
    -        }
    -    }
    -}
    diff --git a/75_Roulette/rust/src/util.rs b/75_Roulette/rust/src/util.rs
    deleted file mode 100644
    index 321a14167..000000000
    --- a/75_Roulette/rust/src/util.rs
    +++ /dev/null
    @@ -1,91 +0,0 @@
    -use std::ops::RangeInclusive;
    -
    -use rand::{thread_rng, Rng};
    -
    -pub const INSTRUCTIONS: [&str; 38] = [
    -    "\nTHIS IS THE BETTING LAYOUT",
    -    "\n(*=RED)\n",
    -    "1*\t2\t3*",
    -    "4\t5*\t6",
    -    "7*\t8\t9*",
    -    "10\t11\t12*",
    -    "--------------------",
    -    "13\t14*\t15",
    -    "16*\t17\t18*",
    -    "19*\t20\t21*",
    -    "22\t23*\t24",
    -    "--------------------",
    -    "25*\t26\t27*",
    -    "28\t29\t30*",
    -    "31\t32*\t33",
    -    "34*\t35\t36*",
    -    "--------------------",
    -    "     00      0\n",
    -    "TYPES OF BETS\n",
    -    "THE NUMBERS 1 TO 36 SIGNIFY A STRAIGHT BET",
    -    "ON THAT NUMBER",
    -    "THESE PAY OFF 35:1\n",
    -    "THE 2:1 BETS ARE:",
    -    "37) 1-12\t40) FIRST COLUMN",
    -    "38) 13-24\t41) SECOND COLUMN",
    -    "39) 25-36\t42) THIRD COLUMN\n",
    -    "THE EVEN MONEY BETS ARE:",
    -    "43) 1-18\t46) ODD",
    -    "44) 19-36\t47) RED",
    -    "45) EVEN\t48) BLACK\n",
    -    "\n49)0 AND 50)00 PAY OFF 35:1",
    -    "NOTE: 0 AND 00 DO NOT COUNT UNDER ANY",
    -    "\tBETS EXCEPT THEIR OWN\n",
    -    "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\n",
    -    "MINIMUM BET IS $5,MAXIMUM IS $500\n",
    -];
    -
    -pub const REDS: [u8; 18] = [
    -    1, 3, 5, 7, 9, 12, 14, 16, 18, 19, 21, 23, 25, 27, 30, 32, 34, 36,
    -];
    -
    -pub fn process_bet(bet_num: u8, spin: u8) -> (bool, u8) {
    -    match bet_num {
    -        1..=36 => (bet_num == spin, 35),
    -        37 => (is_within_range(1..=12, spin), 2),
    -        38 => (is_within_range(13..=24, spin), 2),
    -        39 => (is_within_range(25..=36, spin), 2),
    -        40 => (spin % 3 == 1, 2),
    -        41 => (spin % 3 == 2, 2),
    -        42 => (spin % 3 == 0, 2),
    -        43 => (is_within_range(1..=18, spin), 1),
    -        44 => (is_within_range(19..=36, spin), 1),
    -        45 => (spin % 2 == 0, 1),
    -        46 => (spin % 2 == 1, 1),
    -        47 => (REDS.contains(&spin), 1),
    -        48 => (!REDS.contains(&spin), 1),
    -        _ => {
    -            println!("##INVALID BET##");
    -            return (false, 0);
    -        }
    -    }
    -}
    -
    -fn is_within_range(r: RangeInclusive, n: u8) -> bool {
    -    r.contains(&n)
    -}
    -
    -pub fn print_check(money: usize, date: Vec) {
    -    let name = morristown::prompt_string("TO WHOM SHALL I MAKE THE CHECK?");
    -    let check_no = thread_rng().gen_range(1..=100);
    -
    -    let dashes = 60;
    -
    -    println!("\n{}", "-".repeat(dashes));
    -    println!("CHECK NO.  {}\n", check_no);
    -    println!("{}{}, {}\n\n", "\t".repeat(4), date[0], date[1]);
    -    println!("PAY TO THE ORDER OF-----{name}-----$  {money}\n\n");
    -    println!("\t\tTHE MEMORY BANK OF VIRGINIA\n");
    -    println!("\t\t\t\tTHE COMPUTER");
    -    println!("\t\t\t      ----------X-----\t");
    -    println!("{}", "-".repeat(dashes));
    -    println!("COME BACK SOON!\n")
    -}
    diff --git a/75_Roulette/vbnet/Roulette.sln b/75_Roulette/vbnet/Roulette.sln
    deleted file mode 100644
    index a9db1b6e2..000000000
    --- a/75_Roulette/vbnet/Roulette.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index d5c17f884..000000000
    --- a/75_Roulette/vbnet/Roulette.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Roulette
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/76 Russian Roulette/perl/russianroulette.pl b/76 Russian Roulette/perl/russianroulette.pl
    new file mode 100644
    index 000000000..0fa0cff7b
    --- /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;
    +
    +
    diff --git a/76_Russian_Roulette/README.md b/76_Russian_Roulette/README.md
    index a581f717c..5ec8148e5 100644
    --- a/76_Russian_Roulette/README.md
    +++ b/76_Russian_Roulette/README.md
    @@ -14,7 +14,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/76_Russian_Roulette/csharp/Program.cs b/76_Russian_Roulette/csharp/RussianRoulette/Program.cs
    similarity index 100%
    rename from 76_Russian_Roulette/csharp/Program.cs
    rename to 76_Russian_Roulette/csharp/RussianRoulette/Program.cs
    diff --git a/76_Russian_Roulette/csharp/RussianRoulette.csproj b/76_Russian_Roulette/csharp/RussianRoulette/RussianRoulette.csproj
    similarity index 100%
    rename from 76_Russian_Roulette/csharp/RussianRoulette.csproj
    rename to 76_Russian_Roulette/csharp/RussianRoulette/RussianRoulette.csproj
    diff --git a/76_Russian_Roulette/csharp/RussianRoulette.sln b/76_Russian_Roulette/csharp/RussianRoulette/RussianRoulette.sln
    similarity index 100%
    rename from 76_Russian_Roulette/csharp/RussianRoulette.sln
    rename to 76_Russian_Roulette/csharp/RussianRoulette/RussianRoulette.sln
    diff --git a/76_Russian_Roulette/java/src/RussianRoulette.java b/76_Russian_Roulette/java/src/RussianRoulette.java
    index dd799a06a..1bbf37bc2 100644
    --- a/76_Russian_Roulette/java/src/RussianRoulette.java
    +++ b/76_Russian_Roulette/java/src/RussianRoulette.java
    @@ -140,4 +140,4 @@ public static void main(String[] args) {
             RussianRoulette russianRoulette = new RussianRoulette();
             russianRoulette.play();
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/76_Russian_Roulette/javascript/russianroulette.html b/76_Russian_Roulette/javascript/russianroulette.html
    index fe8acf94e..782fa23e3 100644
    --- a/76_Russian_Roulette/javascript/russianroulette.html
    +++ b/76_Russian_Roulette/javascript/russianroulette.html
    @@ -1,10 +1,9 @@
     
     
     RUSSIAN ROULETTE
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/76_Russian_Roulette/javascript/russianroulette.js b/76_Russian_Roulette/javascript/russianroulette.js
    index cb50c6ca8..d528cfff7 100644
    --- a/76_Russian_Roulette/javascript/russianroulette.js
    +++ b/76_Russian_Roulette/javascript/russianroulette.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/76_Russian_Roulette/kotlin/README.md b/76_Russian_Roulette/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/76_Russian_Roulette/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/76_Russian_Roulette/lua/README.md b/76_Russian_Roulette/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/76_Russian_Roulette/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/76_Russian_Roulette/lua/russianroulette.lua b/76_Russian_Roulette/lua/russianroulette.lua
    deleted file mode 100644
    index 546ec6c4e..000000000
    --- a/76_Russian_Roulette/lua/russianroulette.lua
    +++ /dev/null
    @@ -1,58 +0,0 @@
    -print [[
    -                    RUSSIAN ROULETTE
    -        CREATIVE COMPUTING  MORRISTOWN, NEW JERSY
    -This is a game of >>>>>>>>>>Russian Roulette
    -Here is a Revolver
    -
    -]]
    -
    -local function parse_input()
    -    local incorrect_input = true
    -    local input = nil
    -    while incorrect_input do
    -        input = io.read(1)
    -        if input == "1" or input == "2" then incorrect_input = false end
    -    end
    -    return input
    -end
    -
    -local function russian_roulette()
    -    local NUMBER_OF_ROUNDS = 9
    -
    -    while true do
    -        local dead = false
    -        local n = 0
    -        print("Type '1' to Spin chamber and pull trigger")
    -        print("Type '2' to Give up")
    -        print("Go")
    -
    -        while not dead do
    -            local choice = parse_input()
    -            if choice == "2" then break end
    -
    -            if math.random() > 0.833333333333334 then
    -                dead = true
    -            else
    -                print("CLICK")
    -                n = n + 1
    -            end
    -
    -            if n > NUMBER_OF_ROUNDS then break end
    -        end
    -
    -        if dead then
    -            print("BANG!!!!!   You're Dead!")
    -            print("Condolences will be sent to your relatives.\n\n\n")
    -            print("...Next victim...")
    -        elseif n > NUMBER_OF_ROUNDS then
    -            print("You win!!!!!")
    -            print("Let someone else blow his brain out.\n")
    -        else
    -            print("     Chicken!!!!!\n\n\n")
    -            print("...Next victim....")
    -        end
    -    end
    -end
    -
    -russian_roulette()
    -
    diff --git a/76_Russian_Roulette/pascal/README.md b/76_Russian_Roulette/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/76_Russian_Roulette/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/76_Russian_Roulette/perl/russianroulette.pl b/76_Russian_Roulette/perl/russianroulette.pl
    index dbb5ac98a..0fa0cff7b 100755
    --- a/76_Russian_Roulette/perl/russianroulette.pl
    +++ b/76_Russian_Roulette/perl/russianroulette.pl
    @@ -35,3 +35,5 @@
     print "LET SOMEONE ELSE BLOW HIS BRAINS OUT.\n";
     goto Line10;
     exit;
    +
    +
    diff --git a/76_Russian_Roulette/python/russianroulette.py b/76_Russian_Roulette/python/russianroulette.py
    index 71e0ee129..bac04dc67 100644
    --- a/76_Russian_Roulette/python/russianroulette.py
    +++ b/76_Russian_Roulette/python/russianroulette.py
    @@ -1,17 +1,19 @@
    -"""
    -Russian Roulette
    -
    -From Basic Computer Games (1978)
    -
    -   In this game, you are given by the computer a
    -  revolver loaded with one bullet and five empty
    -  chambers. You spin the chamber and pull the trigger
    -  by inputting a "1", or, if you want to quit, input
    -  a "2". You win if you play ten times and are still
    -  alive.
    -   Tom Adametx wrote this program while a student at
    -  Curtis Jr. High School in Sudbury, Massachusetts.
    -"""
    +########################################################
    +#
    +# Russian Roulette
    +#
    +# From Basic Computer Games (1978)
    +#
    +#    In this game, you are given by the computer a
    +#   revolver loaded with one bullet and five empty
    +#   chambers. You spin the chamber and pull the trigger
    +#   by inputting a "1", or, if you want to quit, input
    +#   a "2". You win if you play ten times and are still
    +#   alive.
    +#    Tom Adametx wrote this program while a student at
    +#   Curtis Jr. High School in Sudbury, Massachusetts.
    +#
    +########################################################
     
     
     from random import random
    @@ -19,48 +21,51 @@
     NUMBER_OF_ROUNDS = 9
     
     
    -def initial_message() -> None:
    +def initial_message():
         print(" " * 28 + "Russian Roulette")
         print(" " * 15 + "Creative Computing  Morristown, New Jersey\n\n\n")
         print("This is a game of >>>>>>>>>>Russian Roulette.\n")
         print("Here is a Revolver.")
     
     
    -def parse_input() -> int:
    -    while True:
    +def parse_input():
    +    correct_input = False
    +    while not correct_input:
             try:
    -            return int(input("? "))
    +            i = int(input('? '))
    +            correct_input = True
             except ValueError:
    -            print("Number expected...")
    -
    +            print('Number expected...')
    +    return i
     
    -def main() -> None:
    -    initial_message()
    -    while True:
    -        dead = False
    -        n = 0
    -        print("Type '1' to Spin chamber and pull trigger")
    -        print("Type '2' to Give up")
    -        print("Go")
    -        while not dead:
    -            i = parse_input()
     
    -            if i == 2:
    -                break
    +initial_message()
    +while True:
    +    dead = False
    +    n = 0
    +    print("Type \'1\' to Spin chamber and pull trigger")
    +    print("Type \'2\' to Give up")
    +    print("Go")
    +    while not dead:
    +        i = parse_input()
     
    -            if random() > 0.8333333333333334:
    -                dead = True
    -            else:
    -                print("- CLICK -\n")
    -                n += 1
    +        if i == 2:
    +            break
     
    -            if n > NUMBER_OF_ROUNDS:
    -                break
    -        if dead:
    -            print("BANG!!!!!   You're Dead!")
    -            print("Condolences will be sent to your relatives.\n\n\n")
    -            print("...Next victim...")
    -        elif n > NUMBER_OF_ROUNDS:
    +        if random() > 0.8333333333333334:
    +            dead = True
    +        else:
    +            print("- CLICK -\n")
    +            n += 1
    +
    +        if n > NUMBER_OF_ROUNDS:
    +            break
    +    if dead:
    +        print("BANG!!!!!   You're Dead!")
    +        print("Condolences will be sent to your relatives.\n\n\n")
    +        print("...Next victim...")
    +    else:
    +        if n > NUMBER_OF_ROUNDS:
                 print("You win!!!!!")
                 print("Let someone else blow his brain out.\n")
             else:
    @@ -68,9 +73,6 @@ def main() -> None:
                 print("...Next victim....")
     
     
    -if __name__ == "__main__":
    -    main()
    -
     ########################################################
     # Porting Notes
     #
    diff --git a/76_Russian_Roulette/rust/Cargo.lock b/76_Russian_Roulette/rust/Cargo.lock
    deleted file mode 100644
    index 4fe2abbea..000000000
    --- a/76_Russian_Roulette/rust/Cargo.lock
    +++ /dev/null
    @@ -1,75 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.10"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.147"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/76_Russian_Roulette/rust/Cargo.toml b/76_Russian_Roulette/rust/Cargo.toml
    deleted file mode 100644
    index 3b1d02f52..000000000
    --- a/76_Russian_Roulette/rust/Cargo.toml
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -[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/76_Russian_Roulette/rust/src/main.rs b/76_Russian_Roulette/rust/src/main.rs
    deleted file mode 100644
    index 7475ad5cf..000000000
    --- a/76_Russian_Roulette/rust/src/main.rs
    +++ /dev/null
    @@ -1,67 +0,0 @@
    -use std::time::Duration;
    -
    -use rand::Rng;
    -
    -fn main() {
    -    println!("\n\t\tRUSSIAN ROULETTE");
    -    println!("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
    -    println!("\nTHIS IS A GAME OF >>>>>>>>>>RUSSIAN ROULETTE.\n");
    -    println!("HERE IS A REVOLVER.");
    -
    -    loop {
    -        println!("TYPE '1' TO SPIN CHAMBER AND PULL TRIGGER");
    -        println!("TYPE '2' TO GIVE UP.");
    -        println!("GO");
    -
    -        let mut tries = 0;
    -
    -        loop {
    -            let mut pull_trigger = true;
    -
    -            loop {
    -                println!("?");
    -                let mut input = String::new();
    -
    -                std::io::stdin()
    -                    .read_line(&mut input)
    -                    .expect("Error reading line!");
    -
    -                match input.trim() {
    -                    "1" => break,
    -                    "2" => {
    -                        pull_trigger = false;
    -                        break;
    -                    }
    -                    _ => println!("Invalid input."),
    -                }
    -            }
    -
    -            if pull_trigger {
    -                std::thread::sleep(Duration::from_secs(1));
    -
    -                match rand::thread_rng().gen_range(0..6) {
    -                    0 => {
    -                        println!("\tBANG!!!!!   YOU'RE DEAD!");
    -                        println!("CONDOLENCES WILL BE SENT TO YOUR RELATIVES.");
    -                        println!("\n\n...NEXT VICTIM...");
    -                        break;
    -                    }
    -                    _ => {
    -                        println!("- CLICK -");
    -                        tries += 1;
    -                    }
    -                }
    -
    -                if tries >= 10 {
    -                    println!("YOU WIN!!!!!");
    -                    println!("LET SOMEONE ELSE BLOW HIS BRAINS OUT.\n");
    -                    break;
    -                }
    -            } else {
    -                println!("\tCHICKEN!!!!!");
    -                println!("\n\n...NEXT VICTIM...");
    -                break;
    -            }
    -        }
    -    }
    -}
    diff --git a/76_Russian_Roulette/vbnet/RussianRoulette.sln b/76_Russian_Roulette/vbnet/RussianRoulette.sln
    deleted file mode 100644
    index 8a87ebbb7..000000000
    --- a/76_Russian_Roulette/vbnet/RussianRoulette.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index dbfebdae6..000000000
    --- a/76_Russian_Roulette/vbnet/RussianRoulette.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    RussianRoulette
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/77_Salvo/README.md b/77_Salvo/README.md
    index 3ef9f21c9..fbf938ca9 100644
    --- a/77_Salvo/README.md
    +++ b/77_Salvo/README.md
    @@ -23,24 +23,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -The program does no validation of ship positions; your ship coordinates may be scattered around the board in any way you like.  (Computer ships will not do this, but they may be placed diagonally in such a way that they cross each other.)  Scattering your ships in this way probably defeats whatever all that spaghetti-code logic the computer is using to pick its moves, which is based on the assumption of contiguous ships.
    -
    -Moreover: as per the analysis in
    -
    -https://forums.raspberrypi.com/viewtopic.php?p=1997950#p1997950
    -
    -see also the earlier post
    -
    -https://forums.raspberrypi.com/viewtopic.php?p=1994961#p1994961
    -
    -in the same thread, there is a typo in later published versions of the SALVO Basic source code compared to the original edition of 101 Basic Computer Games.
    -
    -This typo is interesting because it causes the program to play by a much weaker strategy while exhibiting no other obvious side effects. I would recommend changing the line 3970 in the Basic program back to the original
    -
    -`3970 K(R,S)=K(R,S)+E(U)-2*INT(H(U)+.5)`
    -
    -and to change the JavaScript program accordingly.  (And note that some ports — looking at you, Python — do not implement the original strategy at all, but merely pick random unshot locations for every shot.)
    -
    diff --git a/77_Salvo/csharp/Coordinate.cs b/77_Salvo/csharp/Coordinate.cs
    deleted file mode 100644
    index 4cd2c4334..000000000
    --- a/77_Salvo/csharp/Coordinate.cs
    +++ /dev/null
    @@ -1,45 +0,0 @@
    -namespace Salvo;
    -
    -internal record struct Coordinate(int Value)
    -{
    -    public const int MinValue = 1;
    -    public const int MaxValue = 10;
    -
    -    public static IEnumerable Range => Enumerable.Range(1, 10).Select(v => new Coordinate(v));
    -
    -    public bool IsInRange => Value is >= MinValue and <= MaxValue;
    -
    -    public static Coordinate Create(float value) => new((int)value);
    -
    -    public static bool TryCreateValid(float value, out Coordinate coordinate)
    -    {
    -        coordinate = default;
    -        if (value != (int)value) { return false; }
    -
    -        var result = Create(value);
    -
    -        if (result.IsInRange)
    -        {
    -            coordinate = result;
    -            return true;
    -        }
    -
    -        return false;
    -    }
    -
    -    public Coordinate BringIntoRange(IRandom random)
    -        => Value switch
    -        {
    -            < MinValue => new(MinValue + (int)random.NextFloat(2.5F)),
    -            > MaxValue => new(MaxValue - (int)random.NextFloat(2.5F)),
    -            _ => this
    -        };
    -
    -    public static implicit operator Coordinate(float value) => Create(value);
    -    public static implicit operator int(Coordinate coordinate) => coordinate.Value;
    -
    -    public static Coordinate operator +(Coordinate coordinate, int offset) => new(coordinate.Value + offset);
    -    public static int operator -(Coordinate a, Coordinate b) => a.Value - b.Value;
    -
    -    public override string ToString() => $" {Value} ";
    -}
    diff --git a/77_Salvo/csharp/Extensions/IOExtensions.cs b/77_Salvo/csharp/Extensions/IOExtensions.cs
    deleted file mode 100644
    index 6d021deb3..000000000
    --- a/77_Salvo/csharp/Extensions/IOExtensions.cs
    +++ /dev/null
    @@ -1,27 +0,0 @@
    -namespace Games.Common.IO;
    -
    -internal static class IOExtensions
    -{
    -    internal static Position ReadPosition(this IReadWrite io) => Position.Create(io.Read2Numbers(""));
    -
    -    internal static Position ReadValidPosition(this IReadWrite io)
    -    {
    -        while (true)
    -        {
    -            if (Position.TryCreateValid(io.Read2Numbers(""), out var position)) 
    -            { 
    -                return position; 
    -            }
    -            io.Write(Streams.Illegal);
    -        }
    -    }
    -
    -    internal static IEnumerable ReadPositions(this IReadWrite io, string shipName, int shipSize)
    -    {
    -        io.WriteLine(shipName);
    -        for (var i = 0; i < shipSize; i++)
    -        {
    -             yield return io.ReadPosition();
    -        }
    -    }
    -}
    diff --git a/77_Salvo/csharp/Extensions/RandomExtensions.cs b/77_Salvo/csharp/Extensions/RandomExtensions.cs
    deleted file mode 100644
    index e83ab2657..000000000
    --- a/77_Salvo/csharp/Extensions/RandomExtensions.cs
    +++ /dev/null
    @@ -1,32 +0,0 @@
    -namespace Games.Common.Randomness;
    -
    -internal static class RandomExtensions
    -{
    -    internal static (Position, Offset) NextShipPosition(this IRandom random)
    -    {
    -        var startX = random.NextCoordinate();
    -        var startY = random.NextCoordinate();
    -        var deltaY = random.NextOffset();
    -        var deltaX = random.NextOffset();
    -        return (new(startX, startY), new(deltaX, deltaY));
    -    }
    -
    -    private static Coordinate NextCoordinate(this IRandom random)
    -        => random.Next(Coordinate.MinValue, Coordinate.MaxValue + 1);
    -
    -    private static int NextOffset(this IRandom random) => random.Next(-1, 2);
    -
    -    internal static (Position, Offset) GetRandomShipPositionInRange(this IRandom random, int shipSize)
    -    {
    -        while (true)
    -        {
    -            var (start, delta) = random.NextShipPosition();
    -            var shipSizeLessOne = shipSize - 1;
    -            var end = start + delta * shipSizeLessOne;
    -            if (delta != 0 && end.IsInRange) 
    -            {
    -                return (start, delta);
    -            }
    -        }
    -    }
    -}
    diff --git a/77_Salvo/csharp/Fleet.cs b/77_Salvo/csharp/Fleet.cs
    deleted file mode 100644
    index 5f267225f..000000000
    --- a/77_Salvo/csharp/Fleet.cs
    +++ /dev/null
    @@ -1,66 +0,0 @@
    -using System.Collections.Immutable;
    -using System.Diagnostics.CodeAnalysis;
    -
    -namespace Salvo;
    -
    -internal class Fleet
    -{
    -    private readonly List _ships;
    -
    -    internal Fleet(IReadWrite io)
    -    {
    -        io.WriteLine(Prompts.Coordinates);
    -        _ships = new()
    -        {
    -            new Battleship(io),
    -            new Cruiser(io),
    -            new Destroyer("A", io),
    -            new Destroyer("B", io)
    -        };
    -    }
    -
    -    internal Fleet(IRandom random)
    -    {
    -        _ships = new();
    -        while (true)
    -        {
    -            _ships.Add(new Battleship(random));
    -            if (TryPositionShip(() => new Cruiser(random)) &&
    -                TryPositionShip(() => new Destroyer("A", random)) &&
    -                TryPositionShip(() => new Destroyer("B", random)))
    -            {
    -                return;
    -            } 
    -            _ships.Clear();
    -        }
    -
    -        bool TryPositionShip(Func shipFactory)
    -        {
    -            var shipGenerationAttempts = 0;
    -            while (true)
    -            {
    -                var ship = shipFactory.Invoke();
    -                shipGenerationAttempts++;
    -                if (shipGenerationAttempts > 25) { return false; }
    -                if (_ships.Min(ship.DistanceTo) >= 3.59)
    -                {
    -                    _ships.Add(ship);
    -                    return true; 
    -                }
    -            }
    -        }
    -    }
    -
    -    internal IEnumerable Ships => _ships.AsEnumerable();
    -
    -    internal void ReceiveShots(IEnumerable shots, Action reportHit)
    -    {
    -        foreach (var position in shots)
    -        {
    -            var ship = _ships.FirstOrDefault(s => s.IsHit(position));
    -            if (ship == null) { continue; }
    -            if (ship.IsDestroyed) { _ships.Remove(ship); }
    -            reportHit(ship);
    -        }
    -    }
    -}
    diff --git a/77_Salvo/csharp/Game.cs b/77_Salvo/csharp/Game.cs
    deleted file mode 100644
    index a0223d8ba..000000000
    --- a/77_Salvo/csharp/Game.cs
    +++ /dev/null
    @@ -1,29 +0,0 @@
    -namespace Salvo;
    -
    -internal class Game 
    -{
    -    private readonly IReadWrite _io;
    -    private readonly IRandom _random;
    -
    -    public Game(IReadWrite io, IRandom random)
    -    {
    -        _io = io;
    -        _random = random;
    -    }
    -
    -    internal void Play()
    -    {
    -        _io.Write(Streams.Title);
    -
    -        var turnHandler = new TurnHandler(_io, _random);
    -        _io.WriteLine();
    -
    -        Winner? winner;
    -        do 
    -        {
    -            winner = turnHandler.PlayTurn();
    -        } while (winner == null);
    -
    -        _io.Write(winner == Winner.Computer ? Streams.IWon : Streams.YouWon);
    -    }
    -}
    diff --git a/77_Salvo/csharp/Offset.cs b/77_Salvo/csharp/Offset.cs
    deleted file mode 100644
    index 3c873f101..000000000
    --- a/77_Salvo/csharp/Offset.cs
    +++ /dev/null
    @@ -1,25 +0,0 @@
    -namespace Salvo;
    -
    -internal record struct Offset(int X, int Y)
    -{
    -    public static readonly Offset Zero = 0;
    -
    -    public static Offset operator *(Offset offset, int scale) => new(offset.X * scale, offset.Y * scale);
    -
    -    public static implicit operator Offset(int value) => new(value, value);
    -
    -    public static IEnumerable Units
    -    {
    -        get
    -        {
    -            for (int x = -1; x <= 1; x++)
    -            {
    -                for (int y = -1; y <= 1; y++)
    -                {
    -                    var offset = new Offset(x, y);
    -                    if (offset != Zero) { yield return offset; }
    -                }
    -            }
    -        }
    -    }
    -}
    diff --git a/77_Salvo/csharp/Position.cs b/77_Salvo/csharp/Position.cs
    deleted file mode 100644
    index 3bafe2179..000000000
    --- a/77_Salvo/csharp/Position.cs
    +++ /dev/null
    @@ -1,52 +0,0 @@
    -namespace Salvo;
    -
    -internal record struct Position(Coordinate X, Coordinate Y)
    -{
    -    public bool IsInRange => X.IsInRange && Y.IsInRange;
    -    public bool IsOnDiagonal => X == Y;
    -
    -    public static Position Create((float X, float Y) coordinates) => new(coordinates.X, coordinates.Y);
    -
    -    public static bool TryCreateValid((float X, float Y) coordinates, out Position position)
    -    {
    -        if (Coordinate.TryCreateValid(coordinates.X, out var x) && Coordinate.TryCreateValid(coordinates.Y, out var y))
    -        {
    -            position = new(x, y);
    -            return true;
    -        }
    -
    -        position = default;
    -        return false;
    -    }
    -
    -    public static IEnumerable All
    -        => Coordinate.Range.SelectMany(x => Coordinate.Range.Select(y => new Position(x, y)));
    -
    -    public IEnumerable Neighbours
    -    {
    -        get
    -        {
    -            foreach (var offset in Offset.Units)
    -            {
    -                var neighbour = this + offset;
    -                if (neighbour.IsInRange) { yield return neighbour; }
    -            }
    -        }
    -    }
    -
    -    internal float DistanceTo(Position other)
    -    {
    -        var (deltaX, deltaY) = (X - other.X, Y - other.Y);
    -        return (float)Math.Sqrt(deltaX * deltaX + deltaY * deltaY);
    -    }
    -
    -    internal Position BringIntoRange(IRandom random)
    -        => IsInRange ? this : new(X.BringIntoRange(random), Y.BringIntoRange(random));
    -
    -    public static Position operator +(Position position, Offset offset) 
    -        => new(position.X + offset.X, position.Y + offset.Y);
    -
    -    public static implicit operator Position(int value) => new(value, value);
    -
    -    public override string ToString() => $"{X}{Y}";
    -}
    diff --git a/77_Salvo/csharp/Program.cs b/77_Salvo/csharp/Program.cs
    deleted file mode 100644
    index 5dde4d052..000000000
    --- a/77_Salvo/csharp/Program.cs
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -global using System;
    -global using Games.Common.IO;
    -global using Games.Common.Randomness;
    -global using Salvo;
    -global using Salvo.Ships;
    -global using static Salvo.Resources.Resource;
    -
    -//new Game(new ConsoleIO(), new RandomNumberGenerator()).Play();
    -new Game(new ConsoleIO(), new DataRandom()).Play();
    diff --git a/77_Salvo/csharp/Resources/Coordinates.txt b/77_Salvo/csharp/Resources/Coordinates.txt
    deleted file mode 100644
    index 387d7a6b4..000000000
    --- a/77_Salvo/csharp/Resources/Coordinates.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Enter coordinates for...
    diff --git a/77_Salvo/csharp/Resources/IHaveMoreShotsThanSquares.txt b/77_Salvo/csharp/Resources/IHaveMoreShotsThanSquares.txt
    deleted file mode 100644
    index a6f371107..000000000
    --- a/77_Salvo/csharp/Resources/IHaveMoreShotsThanSquares.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -I have more shots than blank squares.
    diff --git a/77_Salvo/csharp/Resources/IHaveShots.txt b/77_Salvo/csharp/Resources/IHaveShots.txt
    deleted file mode 100644
    index 9157e1a7b..000000000
    --- a/77_Salvo/csharp/Resources/IHaveShots.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -I have {0} shots.
    diff --git a/77_Salvo/csharp/Resources/IHit.txt b/77_Salvo/csharp/Resources/IHit.txt
    deleted file mode 100644
    index 3b43216cd..000000000
    --- a/77_Salvo/csharp/Resources/IHit.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -I hit your {0}
    diff --git a/77_Salvo/csharp/Resources/IWon.txt b/77_Salvo/csharp/Resources/IWon.txt
    deleted file mode 100644
    index b3f506348..000000000
    --- a/77_Salvo/csharp/Resources/IWon.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -I have won.
    diff --git a/77_Salvo/csharp/Resources/Illegal.txt b/77_Salvo/csharp/Resources/Illegal.txt
    deleted file mode 100644
    index 6a71787a7..000000000
    --- a/77_Salvo/csharp/Resources/Illegal.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Illegal, enter again.
    diff --git a/77_Salvo/csharp/Resources/Resource.cs b/77_Salvo/csharp/Resources/Resource.cs
    deleted file mode 100644
    index 8be52fdb0..000000000
    --- a/77_Salvo/csharp/Resources/Resource.cs
    +++ /dev/null
    @@ -1,49 +0,0 @@
    -using System.Reflection;
    -using System.Runtime.CompilerServices;
    -
    -namespace Salvo.Resources;
    -
    -internal static class Resource
    -{
    -    internal static class Streams
    -    {
    -        public static Stream Title => GetStream();
    -        public static Stream YouHaveMoreShotsThanSquares => GetStream();
    -        public static Stream YouWon => GetStream();
    -        public static Stream IHaveMoreShotsThanSquares => GetStream();
    -        public static Stream IWon => GetStream();
    -        public static Stream Illegal => GetStream();
    -    }
    -
    -    internal static class Strings
    -    {
    -        public static string WhereAreYourShips => GetString();
    -        public static string YouHaveShots(int number) => Format(number);
    -        public static string IHaveShots(int number) => Format(number);
    -        public static string YouHit(string shipName) => Format(shipName);
    -        public static string IHit(string shipName) => Format(shipName);
    -        public static string ShotBefore(int turnNumber) => Format(turnNumber);
    -        public static string Turn(int number) => Format(number);
    -    }
    -
    -    internal static class Prompts
    -    {
    -        public static string Coordinates => GetString();
    -        public static string Start => GetString();
    -        public static string SeeShots => GetString();
    -    }
    -
    -    private static string Format(T value, [CallerMemberName] string? name = null) 
    -        => string.Format(GetString(name), value);
    -
    -    private static string GetString([CallerMemberName] string? name = null)
    -    {
    -        using var stream = GetStream(name);
    -        using var reader = new StreamReader(stream);
    -        return reader.ReadToEnd();
    -    }
    -
    -    private static Stream GetStream([CallerMemberName] string? name = null) =>
    -        Assembly.GetExecutingAssembly().GetManifestResourceStream($"{typeof(Resource).Namespace}.{name}.txt")
    -            ?? throw new Exception($"Could not find embedded resource stream '{name}'.");
    -}
    \ No newline at end of file
    diff --git a/77_Salvo/csharp/Resources/SeeShots.txt b/77_Salvo/csharp/Resources/SeeShots.txt
    deleted file mode 100644
    index 7f608b0ba..000000000
    --- a/77_Salvo/csharp/Resources/SeeShots.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Do you want to see my shots
    \ No newline at end of file
    diff --git a/77_Salvo/csharp/Resources/ShotBefore.txt b/77_Salvo/csharp/Resources/ShotBefore.txt
    deleted file mode 100644
    index 18e90fcbd..000000000
    --- a/77_Salvo/csharp/Resources/ShotBefore.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -You shot there before on turn {0}
    diff --git a/77_Salvo/csharp/Resources/Start.txt b/77_Salvo/csharp/Resources/Start.txt
    deleted file mode 100644
    index 283a0fbb0..000000000
    --- a/77_Salvo/csharp/Resources/Start.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Do you want to start
    \ No newline at end of file
    diff --git a/77_Salvo/csharp/Resources/Title.txt b/77_Salvo/csharp/Resources/Title.txt
    deleted file mode 100644
    index 6b2ba9b31..000000000
    --- a/77_Salvo/csharp/Resources/Title.txt
    +++ /dev/null
    @@ -1,5 +0,0 @@
    -                                Salvo
    -               Creative Computing  Morristown, New Jersey
    -
    -
    -
    diff --git a/77_Salvo/csharp/Resources/Turn.txt b/77_Salvo/csharp/Resources/Turn.txt
    deleted file mode 100644
    index 14bf316ea..000000000
    --- a/77_Salvo/csharp/Resources/Turn.txt
    +++ /dev/null
    @@ -1,2 +0,0 @@
    -
    -Turn {0}
    diff --git a/77_Salvo/csharp/Resources/WhereAreYourShips.txt b/77_Salvo/csharp/Resources/WhereAreYourShips.txt
    deleted file mode 100644
    index e8391a465..000000000
    --- a/77_Salvo/csharp/Resources/WhereAreYourShips.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Where are your ships?
    \ No newline at end of file
    diff --git a/77_Salvo/csharp/Resources/YouHaveMoreShotsThanSquares.txt b/77_Salvo/csharp/Resources/YouHaveMoreShotsThanSquares.txt
    deleted file mode 100644
    index 04d58f92e..000000000
    --- a/77_Salvo/csharp/Resources/YouHaveMoreShotsThanSquares.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -You have more shots than there are blank squares.
    diff --git a/77_Salvo/csharp/Resources/YouHaveShots.txt b/77_Salvo/csharp/Resources/YouHaveShots.txt
    deleted file mode 100644
    index 43abeda83..000000000
    --- a/77_Salvo/csharp/Resources/YouHaveShots.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -You have {0} shots.
    diff --git a/77_Salvo/csharp/Resources/YouHit.txt b/77_Salvo/csharp/Resources/YouHit.txt
    deleted file mode 100644
    index b5b5d7614..000000000
    --- a/77_Salvo/csharp/Resources/YouHit.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -You hit my {0}.
    diff --git a/77_Salvo/csharp/Resources/YouWon.txt b/77_Salvo/csharp/Resources/YouWon.txt
    deleted file mode 100644
    index 1f71343bc..000000000
    --- a/77_Salvo/csharp/Resources/YouWon.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -You have won.
    diff --git a/77_Salvo/csharp/Salvo.csproj b/77_Salvo/csharp/Salvo.csproj
    deleted file mode 100644
    index 51470ec9f..000000000
    --- a/77_Salvo/csharp/Salvo.csproj
    +++ /dev/null
    @@ -1,17 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    11
    -    enable
    -    enable
    -  
    -
    -  
    -    
    -  
    -
    -  
    -    
    -  
    -
    diff --git a/77_Salvo/csharp/Salvo.sln b/77_Salvo/csharp/Salvo.sln
    deleted file mode 100644
    index 290237a35..000000000
    --- a/77_Salvo/csharp/Salvo.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/csharp/Ships/Battleship.cs b/77_Salvo/csharp/Ships/Battleship.cs
    deleted file mode 100644
    index 4f864eb6f..000000000
    --- a/77_Salvo/csharp/Ships/Battleship.cs
    +++ /dev/null
    @@ -1,17 +0,0 @@
    -namespace Salvo.Ships;
    -
    -internal sealed class Battleship : Ship
    -{
    -    internal Battleship(IReadWrite io) 
    -        : base(io) 
    -    { 
    -    }
    -
    -    internal Battleship(IRandom random)
    -        : base(random)
    -    {
    -    }
    -
    -    internal override int Shots => 3;
    -    internal override int Size => 5;
    -}
    diff --git a/77_Salvo/csharp/Ships/Cruiser.cs b/77_Salvo/csharp/Ships/Cruiser.cs
    deleted file mode 100644
    index d004f24cf..000000000
    --- a/77_Salvo/csharp/Ships/Cruiser.cs
    +++ /dev/null
    @@ -1,17 +0,0 @@
    -namespace Salvo.Ships;
    -
    -internal sealed class Cruiser : Ship
    -{
    -    internal Cruiser(IReadWrite io) 
    -        : base(io) 
    -    { 
    -    }
    -    
    -    internal Cruiser(IRandom random)
    -        : base(random)
    -    {
    -    }
    -
    -    internal override int Shots => 2;
    -    internal override int Size => 3;
    -}
    diff --git a/77_Salvo/csharp/Ships/Destroyer.cs b/77_Salvo/csharp/Ships/Destroyer.cs
    deleted file mode 100644
    index 6523395d3..000000000
    --- a/77_Salvo/csharp/Ships/Destroyer.cs
    +++ /dev/null
    @@ -1,17 +0,0 @@
    -namespace Salvo.Ships;
    -
    -internal sealed class Destroyer : Ship
    -{
    -    internal Destroyer(string nameIndex, IReadWrite io)
    -        : base(io, $"<{nameIndex}>")
    -    {
    -    }
    -
    -    internal Destroyer(string nameIndex, IRandom random)
    -        : base(random, $"<{nameIndex}>")
    -    {
    -    }
    -
    -    internal override int Shots => 1;
    -    internal override int Size => 2;
    -}
    diff --git a/77_Salvo/csharp/Ships/Ship.cs b/77_Salvo/csharp/Ships/Ship.cs
    deleted file mode 100644
    index ee204d3f3..000000000
    --- a/77_Salvo/csharp/Ships/Ship.cs
    +++ /dev/null
    @@ -1,37 +0,0 @@
    -namespace Salvo.Ships;
    -
    -internal abstract class Ship
    -{
    -    private readonly List _positions = new();
    -
    -    protected Ship(IReadWrite io, string? nameSuffix = null)
    -    {
    -        Name = GetType().Name + nameSuffix;
    -        _positions = io.ReadPositions(Name, Size).ToList();
    -    }
    -
    -    protected Ship(IRandom random, string? nameSuffix = null)
    -    {
    -        Name = GetType().Name + nameSuffix;
    -
    -        var (start, delta) = random.GetRandomShipPositionInRange(Size);
    -        for (var i = 0; i < Size; i++)
    -        {
    -            _positions.Add(start + delta * i);
    -        }
    -    }
    -
    -    internal string Name { get; }
    -    internal abstract int Shots { get; }
    -    internal abstract int Size { get; }
    -    internal bool IsDamaged => _positions.Count > 0 && _positions.Count < Size;
    -    internal bool IsDestroyed => _positions.Count == 0;
    -
    -    internal bool IsHit(Position position) => _positions.Remove(position);
    -
    -    internal float DistanceTo(Ship other)
    -        => _positions.SelectMany(a => other._positions.Select(b => a.DistanceTo(b))).Min();
    -
    -    public override string ToString() 
    -        => string.Join(Environment.NewLine, _positions.Select(p => p.ToString()).Prepend(Name));
    -}
    diff --git a/77_Salvo/csharp/Targetting/ComputerShotSelector.cs b/77_Salvo/csharp/Targetting/ComputerShotSelector.cs
    deleted file mode 100644
    index 721f50c50..000000000
    --- a/77_Salvo/csharp/Targetting/ComputerShotSelector.cs
    +++ /dev/null
    @@ -1,33 +0,0 @@
    -namespace Salvo.Targetting;
    -
    -internal class ComputerShotSelector : ShotSelector
    -{
    -    private readonly KnownHitsShotSelectionStrategy _knownHitsStrategy;
    -    private readonly SearchPatternShotSelectionStrategy _searchPatternStrategy;
    -    private readonly IReadWrite _io;
    -    private readonly bool _showShots;
    -
    -    internal ComputerShotSelector(Fleet source, IRandom random, IReadWrite io) 
    -        : base(source)
    -    {
    -        _knownHitsStrategy = new KnownHitsShotSelectionStrategy(this);
    -        _searchPatternStrategy = new SearchPatternShotSelectionStrategy(this, random);
    -        _io = io;
    -        _showShots = io.ReadString(Prompts.SeeShots).Equals("yes", StringComparison.InvariantCultureIgnoreCase);
    -    }
    -
    -    protected override IEnumerable GetShots()
    -    {
    -        var shots = GetSelectionStrategy().GetShots(NumberOfShots).ToArray();
    -        if (_showShots)
    -        {
    -            _io.WriteLine(string.Join(Environment.NewLine, shots));
    -        }
    -        return shots;
    -    }
    -
    -    internal void RecordHit(Ship ship, int turn) => _knownHitsStrategy.RecordHit(ship, turn);
    -
    -    private ShotSelectionStrategy GetSelectionStrategy()
    -        => _knownHitsStrategy.KnowsOfDamagedShips ? _knownHitsStrategy : _searchPatternStrategy;
    -}
    diff --git a/77_Salvo/csharp/Targetting/HumanShotSelector.cs b/77_Salvo/csharp/Targetting/HumanShotSelector.cs
    deleted file mode 100644
    index ea49bf124..000000000
    --- a/77_Salvo/csharp/Targetting/HumanShotSelector.cs
    +++ /dev/null
    @@ -1,34 +0,0 @@
    -namespace Salvo.Targetting;
    -
    -internal class HumanShotSelector : ShotSelector
    -{
    -    private readonly IReadWrite _io;
    -
    -    internal HumanShotSelector(Fleet source, IReadWrite io) 
    -        : base(source)
    -    {
    -        _io = io;
    -    }
    -
    -    protected override IEnumerable GetShots()
    -    {
    -        var shots = new Position[NumberOfShots];
    -        
    -        for (var i = 0; i < shots.Length; i++)
    -        {
    -            while (true)
    -            {
    -                var position = _io.ReadValidPosition();
    -                if (WasSelectedPreviously(position, out var turnTargeted)) 
    -                { 
    -                    _io.WriteLine($"YOU SHOT THERE BEFORE ON TURN {turnTargeted}");
    -                    continue;
    -                }
    -                shots[i] = position;
    -                break;
    -            }
    -        }
    -
    -        return shots;
    -    }
    -}
    diff --git a/77_Salvo/csharp/Targetting/KnownHitsShotSelectionStrategy.cs b/77_Salvo/csharp/Targetting/KnownHitsShotSelectionStrategy.cs
    deleted file mode 100644
    index 5e0b9d2ca..000000000
    --- a/77_Salvo/csharp/Targetting/KnownHitsShotSelectionStrategy.cs
    +++ /dev/null
    @@ -1,71 +0,0 @@
    -namespace Salvo.Targetting;
    -
    -internal class KnownHitsShotSelectionStrategy : ShotSelectionStrategy
    -{
    -    private readonly List<(int Turn, Ship Ship)> _damagedShips = new();
    -
    -    internal KnownHitsShotSelectionStrategy(ShotSelector shotSelector)
    -        : base(shotSelector)
    -    {
    -    }
    -
    -    internal bool KnowsOfDamagedShips => _damagedShips.Any();
    -
    -    internal override IEnumerable GetShots(int numberOfShots)
    -    {
    -        var tempGrid = Position.All.ToDictionary(x => x, _ => 0);
    -        var shots = Enumerable.Range(1, numberOfShots).Select(x => new Position(x, x)).ToArray();
    -
    -        foreach (var (hitTurn, ship) in _damagedShips)
    -        {
    -            foreach (var position in Position.All)
    -            {
    -                if (WasSelectedPreviously(position))
    -                {  
    -                    tempGrid[position]=-10000000;
    -                    continue;
    -                }
    -
    -                foreach (var neighbour in position.Neighbours)    
    -                {
    -                    if (WasSelectedPreviously(neighbour, out var turn) && turn == hitTurn)
    -                    {
    -                        tempGrid[position] += hitTurn + 10 - position.Y * ship.Shots;
    -                    }
    -                }
    -            }
    -        }
    -
    -        foreach (var position in Position.All)
    -        {
    -            var Q9=0;
    -            for (var i = 0; i < numberOfShots; i++)
    -            {
    -                if (tempGrid[shots[i]] < tempGrid[shots[Q9]]) 
    -                { 
    -                    Q9 = i;
    -                }
    -            }
    -            if (position.X <= numberOfShots && position.IsOnDiagonal) { continue; }
    -            if (tempGrid[position] x.Ship == ship);
    -        }
    -        else
    -        {
    -            _damagedShips.Add((turn, ship));
    -        }
    -    }
    -}
    diff --git a/77_Salvo/csharp/Targetting/SearchPattern.cs b/77_Salvo/csharp/Targetting/SearchPattern.cs
    deleted file mode 100644
    index ac2071c8f..000000000
    --- a/77_Salvo/csharp/Targetting/SearchPattern.cs
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -using System.Collections.Immutable;
    -
    -namespace Salvo.Targetting;
    -
    -internal class SearchPattern
    -{
    -    private static readonly ImmutableArray _offsets =
    -        ImmutableArray.Create(new(1, 1), new(-1, 1), new(1, -3), new(1, 1), new(0, 2), new(-1, 1));
    -
    -    private int _nextIndex;
    -
    -    internal bool TryGetOffset(out Offset offset)
    -    {
    -        offset = default;
    -        if (_nextIndex >= _offsets.Length) { return false; }
    -        
    -        offset = _offsets[_nextIndex++];
    -        return true;
    -    }
    -
    -    internal void Reset() => _nextIndex = 0;
    -}
    \ No newline at end of file
    diff --git a/77_Salvo/csharp/Targetting/SearchPatternShotSelector.cs b/77_Salvo/csharp/Targetting/SearchPatternShotSelector.cs
    deleted file mode 100644
    index 1eae88f81..000000000
    --- a/77_Salvo/csharp/Targetting/SearchPatternShotSelector.cs
    +++ /dev/null
    @@ -1,55 +0,0 @@
    -namespace Salvo.Targetting;
    -
    -internal class SearchPatternShotSelectionStrategy : ShotSelectionStrategy
    -{
    -    private const int MaxSearchPatternAttempts = 100;
    -    private readonly IRandom _random;
    -    private readonly SearchPattern _searchPattern = new();
    -    private readonly List _shots = new();
    -
    -    internal SearchPatternShotSelectionStrategy(ShotSelector shotSelector, IRandom random) 
    -        : base(shotSelector)
    -    {
    -        _random = random;
    -    }
    -
    -    internal override IEnumerable GetShots(int numberOfShots)
    -    {
    -        _shots.Clear();
    -        while(_shots.Count < numberOfShots)
    -        {
    -            var (seed, _) = _random.NextShipPosition();
    -            SearchFrom(numberOfShots, seed);
    -        }
    -        return _shots;
    -    }
    -
    -    private void SearchFrom(int numberOfShots, Position candidateShot)
    -    {
    -        var attemptsLeft = MaxSearchPatternAttempts;
    -        while (true)
    -        {
    -            _searchPattern.Reset();
    -            if (attemptsLeft-- == 0) { return; }
    -            candidateShot = candidateShot.BringIntoRange(_random);
    -            if (FindValidShots(numberOfShots, ref candidateShot)) { return; }
    -        }
    -    }
    -
    -    private bool FindValidShots(int numberOfShots, ref Position candidateShot)
    -    {
    -        while (true)
    -        {
    -            if (IsValidShot(candidateShot))
    -            {
    -                _shots.Add(candidateShot);
    -                if (_shots.Count == numberOfShots) { return true; }
    -            }
    -            if (!_searchPattern.TryGetOffset(out var offset)) { return false; }
    -            candidateShot += offset;
    -        }
    -    }
    -
    -    private bool IsValidShot(Position candidate)
    -        => candidate.IsInRange && !WasSelectedPreviously(candidate) && !_shots.Contains(candidate);
    -}
    \ No newline at end of file
    diff --git a/77_Salvo/csharp/Targetting/ShotSelectionStrategy.cs b/77_Salvo/csharp/Targetting/ShotSelectionStrategy.cs
    deleted file mode 100644
    index b4cf14b16..000000000
    --- a/77_Salvo/csharp/Targetting/ShotSelectionStrategy.cs
    +++ /dev/null
    @@ -1,17 +0,0 @@
    -namespace Salvo.Targetting;
    -
    -internal abstract class ShotSelectionStrategy
    -{
    -    private readonly ShotSelector _shotSelector;
    -    protected ShotSelectionStrategy(ShotSelector shotSelector)
    -    {
    -        _shotSelector = shotSelector;
    -    }
    -
    -    internal abstract IEnumerable GetShots(int numberOfShots);
    -
    -    protected bool WasSelectedPreviously(Position position) => _shotSelector.WasSelectedPreviously(position);
    -
    -    protected bool WasSelectedPreviously(Position position, out int turn)
    -        => _shotSelector.WasSelectedPreviously(position, out turn);
    -}
    diff --git a/77_Salvo/csharp/Targetting/ShotSelector.cs b/77_Salvo/csharp/Targetting/ShotSelector.cs
    deleted file mode 100644
    index 695dbc42d..000000000
    --- a/77_Salvo/csharp/Targetting/ShotSelector.cs
    +++ /dev/null
    @@ -1,31 +0,0 @@
    -namespace Salvo.Targetting;
    -
    -internal abstract class ShotSelector
    -{
    -    private readonly Fleet _source;
    -    private readonly Dictionary _previousShots = new();
    -
    -    internal ShotSelector(Fleet source)
    -    {
    -        _source = source;
    -    }
    -
    -    internal int NumberOfShots => _source.Ships.Sum(s => s.Shots);
    -    internal bool CanTargetAllRemainingSquares => NumberOfShots >= 100 - _previousShots.Count;
    -
    -    internal bool WasSelectedPreviously(Position position) => _previousShots.ContainsKey(position);
    -
    -    internal bool WasSelectedPreviously(Position position, out int turn)
    -        => _previousShots.TryGetValue(position, out turn);
    -
    -    internal IEnumerable GetShots(int turnNumber)
    -    {
    -        foreach (var shot in GetShots())
    -        {
    -            _previousShots.Add(shot, turnNumber);
    -            yield return shot;
    -        }
    -    }
    -
    -    protected abstract IEnumerable GetShots();
    -}
    diff --git a/77_Salvo/csharp/TurnHandler.cs b/77_Salvo/csharp/TurnHandler.cs
    deleted file mode 100644
    index afde96133..000000000
    --- a/77_Salvo/csharp/TurnHandler.cs
    +++ /dev/null
    @@ -1,92 +0,0 @@
    -using Salvo.Targetting;
    -
    -namespace Salvo;
    -
    -internal class TurnHandler
    -{
    -    private readonly IReadWrite _io;
    -    private readonly Fleet _humanFleet;
    -    private readonly Fleet _computerFleet;
    -    private readonly bool _humanStarts;
    -    private readonly HumanShotSelector _humanShotSelector;
    -    private readonly ComputerShotSelector _computerShotSelector;
    -    private readonly Func _turnAction;
    -    private int _turnNumber;
    -
    -    public TurnHandler(IReadWrite io, IRandom random)
    -    {
    -        _io = io;
    -        _computerFleet = new Fleet(random);
    -        _humanFleet = new Fleet(io);
    -        _turnAction = AskWhoStarts()
    -            ? () => PlayHumanTurn() ?? PlayComputerTurn()
    -            : () => PlayComputerTurn() ?? PlayHumanTurn();
    -        _humanShotSelector = new HumanShotSelector(_humanFleet, io);
    -        _computerShotSelector = new ComputerShotSelector(_computerFleet, random, io);
    -    }
    -
    -    public Winner? PlayTurn()
    -    {
    -        _io.Write(Strings.Turn(++_turnNumber));
    -        return _turnAction.Invoke();
    -    }
    -
    -    private bool AskWhoStarts()
    -    {
    -        while (true)
    -        {
    -            var startResponse = _io.ReadString(Prompts.Start);
    -            if (startResponse.Equals(Strings.WhereAreYourShips, StringComparison.InvariantCultureIgnoreCase))
    -            {
    -                foreach (var ship in _computerFleet.Ships)
    -                {
    -                    _io.WriteLine(ship);
    -                }
    -            }
    -            else
    -            {
    -                return startResponse.Equals("yes", StringComparison.InvariantCultureIgnoreCase);
    -            }
    -        }
    -    }
    -
    -    private Winner? PlayComputerTurn()
    -    {
    -        var numberOfShots = _computerShotSelector.NumberOfShots;
    -        _io.Write(Strings.IHaveShots(numberOfShots));
    -        if (numberOfShots == 0) { return Winner.Human; }
    -        if (_computerShotSelector.CanTargetAllRemainingSquares)
    -        {
    -            _io.Write(Streams.IHaveMoreShotsThanSquares);
    -            return Winner.Computer;
    -        }
    -
    -        _humanFleet.ReceiveShots(
    -            _computerShotSelector.GetShots(_turnNumber),
    -            ship =>
    -            { 
    -                _io.Write(Strings.IHit(ship.Name));
    -                _computerShotSelector.RecordHit(ship, _turnNumber);
    -            });
    -
    -        return null;
    -    }
    -
    -    private Winner? PlayHumanTurn()
    -    {
    -        var numberOfShots = _humanShotSelector.NumberOfShots;
    -        _io.Write(Strings.YouHaveShots(numberOfShots));
    -        if (numberOfShots == 0) { return Winner.Computer; }
    -        if (_humanShotSelector.CanTargetAllRemainingSquares) 
    -        { 
    -            _io.WriteLine(Streams.YouHaveMoreShotsThanSquares);
    -            return Winner.Human;
    -        }
    -        
    -        _computerFleet.ReceiveShots(
    -            _humanShotSelector.GetShots(_turnNumber), 
    -            ship => _io.Write(Strings.YouHit(ship.Name)));
    -        
    -        return null;
    -    }
    -}
    diff --git a/77_Salvo/csharp/Winner.cs b/77_Salvo/csharp/Winner.cs
    deleted file mode 100644
    index a5a73eb47..000000000
    --- a/77_Salvo/csharp/Winner.cs
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -namespace Salvo;
    -
    -internal enum Winner
    -{
    -    Human,
    -    Computer
    -}
    diff --git a/77_Salvo/javascript/salvo.html b/77_Salvo/javascript/salvo.html
    index 0b5471c6e..25752f0ff 100644
    --- a/77_Salvo/javascript/salvo.html
    +++ b/77_Salvo/javascript/salvo.html
    @@ -1,10 +1,9 @@
     
     
     SALVO
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/77_Salvo/javascript/salvo.js b/77_Salvo/javascript/salvo.js
    index 7fb9d6dfc..b75f50880 100644
    --- a/77_Salvo/javascript/salvo.js
    +++ b/77_Salvo/javascript/salvo.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/77_Salvo/kotlin/README.md b/77_Salvo/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/77_Salvo/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/77_Salvo/lua/README.md b/77_Salvo/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/77_Salvo/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/77_Salvo/pascal/README.md b/77_Salvo/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/77_Salvo/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/77_Salvo/python/salvo.ipynb b/77_Salvo/python/salvo.ipynb
    new file mode 100644
    index 000000000..7b98691b5
    --- /dev/null
    +++ b/77_Salvo/python/salvo.ipynb
    @@ -0,0 +1,337 @@
    +{
    + "metadata": {
    +  "language_info": {
    +   "codemirror_mode": {
    +    "name": "ipython",
    +    "version": 3
    +   },
    +   "file_extension": ".py",
    +   "mimetype": "text/x-python",
    +   "name": "python",
    +   "nbconvert_exporter": "python",
    +   "pygments_lexer": "ipython3",
    +   "version": "3.7.3-final"
    +  },
    +  "orig_nbformat": 2,
    +  "kernelspec": {
    +   "name": "python3",
    +   "display_name": "Python 3",
    +   "language": "python"
    +  }
    + },
    + "nbformat": 4,
    + "nbformat_minor": 2,
    + "cells": [
    +  {
    +   "cell_type": "code",
    +   "execution_count": 727,
    +   "metadata": {},
    +   "outputs": [],
    +   "source": [
    +    "import random"
    +   ]
    +  },
    +  {
    +   "cell_type": "code",
    +   "execution_count": 728,
    +   "metadata": {},
    +   "outputs": [],
    +   "source": [
    +    "BOARD_WIDTH = 10\n",
    +    "BOARD_HEIGHT = 10\n",
    +    "\n",
    +    "SHIPS = [ (\"BATTLESHIP\", 5),\n",
    +    "          (\"CRUISER\", 3),\n",
    +    "          (\"DESTROYER
    \", 2),\n", + " (\"DESTROYER\", 2) ]\n", + " \n", + "VALID_MOVES = [[-1, 0],\n", + " [-1, 1],\n", + " [ 0, 1],\n", + " [ 1, 1],\n", + " [ 1, 0],\n", + " [ 1,-1],\n", + " [ 0,-1],\n", + " [-1,-1]]" + ] + }, + { + "cell_type": "code", + "execution_count": 729, + "metadata": {}, + "outputs": [], + "source": [ + "# random number functions\n", + "#\n", + "# seed the random number generator\n", + "random.seed()\n", + "\n", + "# random_x_y\n", + "#\n", + "# generate a valid x,y coordinate on the board\n", + "# returns: x,y\n", + "# x: integer between 1 and BOARD_HEIGHT\n", + "# y: integer between 1 and BOARD WIDTH\n", + "def random_x_y():\n", + " x = random.randrange(1,BOARD_WIDTH+1)\n", + " y = random.randrange(1,BOARD_HEIGHT+1)\n", + " return (x,y)" + ] + }, + { + "cell_type": "code", + "execution_count": 730, + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "5 3\n" + ] + } + ], + "source": [ + "x,y = random_x_y()\n", + "print (x,y)" + ] + }, + { + "cell_type": "code", + "execution_count": 731, + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: add an optional starting coordinate for testing\n", + "# purposes\n", + "def generate_ship_coordinates(ship):\n", + " \n", + " # randomly generate starting x,y coordinates\n", + " start_x, start_y = random_x_y()\n", + "\n", + " # using starting coordinates and the ship type,\n", + " # generate a vector of possible directions the ship \n", + " # could be placed. directions are numbered 0-7 along\n", + " # points of the compass (N, NE, E, SE, S, SW, W, NW)\n", + " # clockwise. a vector of valid directions where the\n", + " # ship does not go off the board is determined\n", + " ship_len = SHIPS[ship][1] - 1\n", + " dirs = [False for x in range(8)]\n", + " dirs[0] = (start_x - ship_len) >=1\n", + " dirs[2] = (start_y + ship_len) <= BOARD_WIDTH\n", + " dirs[1] = dirs[0] and dirs[2]\n", + " dirs[4] = (start_x + ship_len) <= BOARD_HEIGHT\n", + " dirs[3] = dirs[2] and dirs[4]\n", + " dirs[6] = (start_y - ship_len) >= 1\n", + " dirs[5] = dirs[4] and dirs[6]\n", + " dirs[7] = dirs[6] and dirs[0]\n", + " directions = [p for p in range(len(dirs)) if dirs[p]]\n", + "\n", + " # using the vector of valid directions, pick a\n", + " # random direction to place the ship\n", + " dir_idx = random.randrange(len(directions))\n", + " direction = directions[dir_idx]\n", + "\n", + " # using the starting x,y, direction and ship\n", + " # type, return the coordinates of each point \n", + " # of the ship. VALID_MOVES is a staic array\n", + " # of coordinate offsets to walk from starting\n", + " # coordinate to the end coordinate in the \n", + " # chosen direction\n", + " ship_len = SHIPS[ship][1] - 1\n", + " d_x = VALID_MOVES[direction][0]\n", + " d_y = VALID_MOVES[direction][1]\n", + "\n", + " coords = [(start_x,start_y)]\n", + " x_coord = start_x\n", + " y_coord = start_y\n", + " for i in range(ship_len):\n", + " x_coord = x_coord + d_x\n", + " y_coord = y_coord + d_y\n", + " coords.append((x_coord,y_coord))\n", + " return coords\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 732, + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "BATTLESHIP 5 [(10, 2), (10, 3), (10, 4), (10, 5), (10, 6)]\nCRUISER 3 [(9, 4), (8, 4), (7, 4)]\nDESTROYER 2 [(2, 5), (1, 5)]\nDESTROYER 2 [(7, 8), (7, 9)]\n" + ] + } + ], + "source": [ + "\n", + "for ship in range(len(SHIPS)):\n", + " coords = generate_ship_coordinates(ship)\n", + " print(f'{SHIPS[ship][0]:15}',f'{SHIPS[ship][1]:2}',coords)" + ] + }, + { + "cell_type": "code", + "execution_count": 733, + "metadata": {}, + "outputs": [], + "source": [ + "def create_blank_board():\n", + " return [ [ None for y in range(BOARD_WIDTH)] \n", + " for x in range(BOARD_HEIGHT)]" + ] + }, + { + "cell_type": "code", + "execution_count": 734, + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + " 1 2 3 4 5 6 7 8 9 10\n 1 \n 2 \n 3 \n 4 \n 5 \n 6 \n 7 \n 8 \n 9 \n10 \n" + ] + } + ], + "source": [ + "def print_board(board):\n", + "\n", + " # print board header (column numbers)\n", + " print(' ',end='')\n", + " for z in range(BOARD_WIDTH):\n", + " print(f'{z+1:3}',end='')\n", + " print('')\n", + "\n", + " for x in range(len(board)):\n", + " print(f'{x+1:2}',end='')\n", + " for y in range(len(board[x])):\n", + " if(board[x][y] is None):\n", + " print(f\"{' ':3}\",end='')\n", + " else:\n", + " print(f\"{board[x][y]:3}\",end='')\n", + " print('')\n", + "\n", + "computer_board = create_blank_board()\n", + "print_board(computer_board)" + ] + }, + { + "cell_type": "code", + "execution_count": 735, + "metadata": {}, + "outputs": [], + "source": [ + "def place_ship(board,coords,ship):\n", + " for coord in coords:\n", + " board[coord[0]-1][coord[1]-1] = ship" + ] + }, + { + "cell_type": "code", + "execution_count": 736, + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "DESTROYER 2 [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]\n 1 2 3 4 5 6 7 8 9 10\n 1 0 \n 2 0 \n 3 0 \n 4 0 \n 5 0 \n 6 \n 7 \n 8 \n 9 \n10 \n" + ] + } + ], + "source": [ + "# test place_ship\n", + "board = create_blank_board()\n", + "coords = generate_ship_coordinates(0)\n", + "print(f'{SHIPS[ship][0]:15}',f'{SHIPS[ship][1]:2}',coords)\n", + "place_ship(board,coords,0)\n", + "print_board(board)" + ] + }, + { + "cell_type": "code", + "execution_count": 737, + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + " 1 2 3 4 5 6 7 8 9 10\n", + " 1 \n", + " 2 1 \n", + " 3 1 2 \n", + " 4 1 2 \n", + " 5 0 \n", + " 6 0 \n", + " 7 0 \n", + " 8 0 \n", + " 9 0 3 \n", + "10 3 \n" + ] + } + ], + "source": [ + "# NOTE: A little quirk that exists here and in the orginal\n", + "# game: Ships are allowed to cross each other!\n", + "# For example: 2 destroyers, length 2, one at\n", + "# [(1,1),(2,2)] and other at [(2,1),(1,2)]\n", + "\n", + "def generate_board():\n", + " board = create_blank_board()\n", + "\n", + " for ship in range(len(SHIPS)):\n", + " placed = False\n", + " coords = []\n", + " while not placed:\n", + " coords = generate_ship_coordinates(ship)\n", + " clear = True\n", + " for coord in coords:\n", + " if board[coord[0]-1][coord[1]-1] is not None:\n", + " clear = False\n", + " break\n", + " if clear:\n", + " placed = True\n", + " place_ship(board,coords,ship)\n", + " return board\n", + "\n", + "print_board(generate_board())" + ] + }, + { + "cell_type": "code", + "execution_count": 738, + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "[(4, 1), (3, 6), (6, 10), (10, 6), (4, 5)]\n" + ] + } + ], + "source": [ + "def generate_shots(number):\n", + " shots = []\n", + " for i in range(number):\n", + " shots.append(random_x_y())\n", + " return shots\n", + "\n", + "shots = generate_shots(5)\n", + "print(shots)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ] +} \ No newline at end of file diff --git a/77_Salvo/python/salvo.py b/77_Salvo/python/salvo.py index 417bebc14..0dd19816a 100644 --- a/77_Salvo/python/salvo.py +++ b/77_Salvo/python/salvo.py @@ -1,14 +1,17 @@ -import random import re -from typing import List, Optional, Tuple +import random -BoardType = List[List[Optional[int]]] -CoordinateType = Tuple[int, int] +################### +# +# static variables +# +################### BOARD_WIDTH = 10 BOARD_HEIGHT = 10 - +# game ships +# # data structure keeping track of information # about the ships in the game. for each ship, # the following information is provided: @@ -17,37 +20,41 @@ # length - number of "parts" on the ship that # can be shot # shots - number of shots the ship counts for -SHIPS = [ - ("BATTLESHIP", 5, 3), - ("CRUISER", 3, 2), - ("DESTROYER", 2, 1), - ("DESTROYER", 2, 1), -] - -VALID_MOVES = [ - [-1, 0], # North - [-1, 1], # North East - [0, 1], # East - [1, 1], # South East - [1, 0], # South - [1, -1], # South West - [0, -1], # West - [-1, -1], # North West -] - -COORD_REGEX = "[ \t]{0,}(-?[0-9]{1,3})[ \t]{0,},[ \t]{0,}(-?[0-9]{1,2})" +SHIPS = [("BATTLESHIP", 5, 3), + ("CRUISER", 3, 2), + ("DESTROYER", 2, 1), + ("DESTROYER", 2, 1)] + +VALID_MOVES = [[-1, 0], # North + [-1, 1], # North East + [0, 1], # East + [1, 1], # South East + [1, 0], # South + [1, -1], # South West + [0, -1], # West + [-1, -1]] # North West + +COORD_REGEX = '[ \t]{0,}(-?[0-9]{1,3})[ \t]{0,},[ \t]{0,}(-?[0-9]{1,2})' +#################### +# +# global variables +# +#################### # array of BOARD_HEIGHT arrays, BOARD_WIDTH in length, # representing the human player and computer -player_board: BoardType = [] -computer_board: BoardType = [] +player_board = [] +computer_board = [] # array representing the coordinates # for each ship for player and computer # array is in the same order as SHIPS -computer_ship_coords: List[List[CoordinateType]] = [] +player_ship_coords = [] +computer_ship_coords = [] +# keep track of the turn +current_turn = 0 #################################### # @@ -80,9 +87,10 @@ # #################################### -# flag indicating whose turn it currently is -COMPUTER = False -PLAYER = True +# flag indicating whose turn +# it currently is +COMPUTER = 0 +PLAYER = 1 active_turn = COMPUTER #################### @@ -99,27 +107,26 @@ # random_x_y # - - -def random_x_y() -> CoordinateType: - """Generate a valid x,y coordinate on the board""" - - x = random.randrange(1, BOARD_WIDTH + 1) - y = random.randrange(1, BOARD_HEIGHT + 1) +# generate a valid x,y coordinate on the board +# returns: x,y +# x: integer between 1 and BOARD_HEIGHT +# y: integer between 1 and BOARD WIDTH +def random_x_y(): + x = random.randrange(1, BOARD_WIDTH+1) + y = random.randrange(1, BOARD_HEIGHT+1) return (x, y) -def input_coord() -> CoordinateType: - """ - Ask user for single (x,y) coordinate - - validate the coordinates are within the bounds - of the board width and height. mimic the behavior - of the original program which exited with error - messages if coordinates where outside of array bounds. - if input is not numeric, print error out to user and - let them try again. - """ +# input_coord +# +# ask user for single (x,y) coordinate +# validate the coordinates are within the bounds +# of the board width and height. mimic the behavior +# of the original program which exited with error +# messages if coordinates where outside of array bounds. +# if input is not numeric, print error out to user and +# let them try again. +def input_coord(): match = None while not match: coords = input("? ") @@ -140,25 +147,25 @@ def input_coord() -> CoordinateType: return x, y -def generate_ship_coordinates(ship: int) -> List[CoordinateType]: - """ - given a ship from the SHIPS array, generate - the coordinates of the ship. the starting point - of the ship's first coordinate is generated randomly. - once the starting coordinates are determined, the - possible directions of the ship, accounting for the - edges of the board, are determined. once possible - directions are found, a direction is randomly - determined and the remaining coordinates are - generated by adding or substraction from the starting - coordinates as determined by direction. - - arguments: - ship - index into the SHIPS array - - returns: - array of sets of coordinates (x,y) - """ +# generate_ship_coordinates +# +# given a ship from the SHIPS array, generate +# the coordinates of the ship. the starting point +# of the ship's first coordinate is generated randomly. +# once the starting coordinates are determined, the +# possible directions of the ship, accounting for the +# edges of the board, are determined. once possible +# directions are found, a direction is randomly +# determined and the remaining coordinates are +# generated by adding or substraction from the starting +# coordinates as determined by direction. +# +# arguments: +# ship - index into the SHIPS array +# +# returns: +# array of sets of coordinates (x,y) +def generate_ship_coordinates(ship): # randomly generate starting x,y coordinates start_x, start_y = random_x_y() @@ -169,7 +176,7 @@ def generate_ship_coordinates(ship: int) -> List[CoordinateType]: # clockwise. a vector of valid directions where the # ship does not go off the board is determined ship_len = SHIPS[ship][1] - 1 - dirs = [False for _ in range(8)] + dirs = [False for x in range(8)] dirs[0] = (start_x - ship_len) >= 1 dirs[2] = (start_y + ship_len) <= BOARD_WIDTH dirs[1] = dirs[0] and dirs[2] @@ -198,61 +205,65 @@ def generate_ship_coordinates(ship: int) -> List[CoordinateType]: coords = [(start_x, start_y)] x_coord = start_x y_coord = start_y - for _ in range(ship_len): + for i in range(ship_len): x_coord = x_coord + d_x y_coord = y_coord + d_y coords.append((x_coord, y_coord)) return coords -def create_blank_board() -> BoardType: - """Create a blank game board""" - return [[None for _y in range(BOARD_WIDTH)] for _x in range(BOARD_HEIGHT)] +# create_blank_board +# +# helper function to create a game board +# that is blank +def create_blank_board(): + return [[None for y in range(BOARD_WIDTH)] + for x in range(BOARD_HEIGHT)] + +# print_board +# +# print out the game board for testing +# purposes +def print_board(board): -def print_board(board: BoardType) -> None: - """Print out the game board for testing purposes""" # print board header (column numbers) - print(" ", end="") + print(' ', end='') for z in range(BOARD_WIDTH): - print(f"{z+1:3}", end="") - print() + print(f'{z+1:3}', end='') + print('') for x in range(len(board)): - print(f"{x+1:2}", end="") + print(f'{x+1:2}', end='') for y in range(len(board[x])): - if board[x][y] is None: - print(f"{' ':3}", end="") + if(board[x][y] is None): + print(f"{' ':3}", end='') else: - print(f"{board[x][y]:3}", end="") - print() - - -def place_ship(board: BoardType, coords: List[CoordinateType], ship: int) -> None: - """ - Place a ship on a given board. + print(f"{board[x][y]:3}", end='') + print('') - updates - the board's row,column value at the given - coordinates to indicate where a ship is - on the board. - inputs: board - array of BOARD_HEIGHT by BOARD_WIDTH - coords - array of sets of (x,y) coordinates of each - part of the given ship - ship - integer representing the type of ship (given in SHIPS) - """ +# place_ship +# +# place a ship on a given board. updates +# the board's row,column value at the given +# coordinates to indicate where a ship is +# on the board. +# +# inputs: board - array of BOARD_HEIGHT by BOARD_WIDTH +# coords - array of sets of (x,y) coordinates of each +# part of the given ship +# ship - integer repreesnting the type of ship (given in SHIPS) +def place_ship(board, coords, ship): for coord in coords: - board[coord[0] - 1][coord[1] - 1] = ship + board[coord[0]-1][coord[1]-1] = ship -def generate_board() -> Tuple[BoardType, List[List[CoordinateType]]]: - """ - NOTE: A little quirk that exists here and in the orginal - game: Ships are allowed to cross each other! - For example: 2 destroyers, length 2, one at - [(1,1),(2,2)] and other at [(2,1),(1,2)] - """ +# NOTE: A little quirk that exists here and in the orginal +# game: Ships are allowed to cross each other! +# For example: 2 destroyers, length 2, one at +# [(1,1),(2,2)] and other at [(2,1),(1,2)] +def generate_board(): board = create_blank_board() ship_coords = [] @@ -261,7 +272,11 @@ def generate_board() -> Tuple[BoardType, List[List[CoordinateType]]]: coords = [] while not placed: coords = generate_ship_coordinates(ship) - clear = all(board[coord[0] - 1][coord[1] - 1] is None for coord in coords) + clear = True + for coord in coords: + if board[coord[0]-1][coord[1]-1] is not None: + clear = False + break if clear: placed = True place_ship(board, coords, ship) @@ -269,54 +284,68 @@ def generate_board() -> Tuple[BoardType, List[List[CoordinateType]]]: return board, ship_coords -def execute_shot( - turn: bool, board: BoardType, x: int, y: int, current_turn: int -) -> int: - """ - given a board and x, y coordinates, - execute a shot. returns True if the shot - is valid, False if not - """ - square = board[x - 1][y - 1] +# execute_shot +# +# given a board and x, y coordinates, +# execute a shot. returns True if the shot +# is valid, False if not +def execute_shot(turn, board, x, y): + + global current_turn + square = board[x-1][y-1] ship_hit = -1 - if square is not None and square >= 0 and square < len(SHIPS): - ship_hit = square - board[x - 1][y - 1] = 10 + current_turn + if square is not None: + if square >= 0 and square < len(SHIPS): + ship_hit = square + board[x-1][y-1] = 10 + current_turn return ship_hit -def calculate_shots(board: BoardType) -> int: - """Examine each board and determine how many shots remaining""" - ships_found = [0 for _ in range(len(SHIPS))] +# calculate_shots +# +# function to examine each board +# and determine how many shots remaining +def calculate_shots(board): + + ships_found = [0 for x in range(len(SHIPS))] for x in range(BOARD_HEIGHT): for y in range(BOARD_WIDTH): - square = board[x - 1][y - 1] - if square is not None and square >= 0 and square < len(SHIPS): - ships_found[square] = 1 - return sum( - SHIPS[ship][2] - for ship in range(len(ships_found)) - if ships_found[ship] == 1 - ) - - -def initialize_game() -> None: - # initialize the global player and computer boards + square = board[x-1][y-1] + if square is not None: + if square >= 0 and square < len(SHIPS): + ships_found[square] = 1 + shots = 0 + for ship in range(len(ships_found)): + if ships_found[ship] == 1: + shots += SHIPS[ship][2] + + return shots + + +# initialize +# +# function to initialize global variables used +# during game play. +def initialize_game(): + + # initialize the global player and computer + # boards global player_board player_board = create_blank_board() - # generate the ships for the computer's board + # generate the ships for the computer's + # board global computer_board global computer_ship_coords computer_board, computer_ship_coords = generate_board() # print out the title 'screen' - print("{:>38}".format("SALVO")) - print("{:>57s}".format("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY")) - print() - print("{:>52s}".format("ORIGINAL BY LAWRENCE SIEGEL, 1973")) - print("{:>56s}".format("PYTHON 3 PORT BY TODD KAISER, MARCH 2021")) - print("\n") + print('{0:>38}'.format("SALVO")) + print('{0:>57s}'.format("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY")) + print('') + print('{0:>52s}'.format("ORIGINAL BY LAWRENCE SIEGEL, 1973")) + print('{0:>56s}'.format("PYTHON 3 PORT BY TODD KAISER, MARCH 2021")) + print('\n') # ask the player for ship coordinates print("ENTER COORDINATES FOR...") @@ -324,14 +353,14 @@ def initialize_game() -> None: for ship in SHIPS: print(ship[0]) list = [] - for _ in range(ship[1]): + for i in range(ship[1]): x, y = input_coord() list.append((x, y)) ship_coords.append(list) # add ships to the user's board - for ship_index in range(len(SHIPS)): - place_ship(player_board, ship_coords[ship_index], ship_index) + for ship in range(len(SHIPS)): + place_ship(player_board, ship_coords[ship], ship) # see if the player wants the computer's ship # locations printed out and if the player wants to @@ -341,13 +370,13 @@ def initialize_game() -> None: while input_loop: player_start = input("DO YOU WANT TO START? ") if player_start == "WHERE ARE YOUR SHIPS?": - for ship_index in range(len(SHIPS)): - print(SHIPS[ship_index][0]) - coords = computer_ship_coords[ship_index] + for ship in range(len(SHIPS)): + print(SHIPS[ship][0]) + coords = computer_ship_coords[ship] for coord in coords: x = coord[0] y = coord[1] - print(f"{x:2}", f"{y:2}") + print('{0:2}'.format(x), '{0:2}'.format(y)) else: input_loop = False @@ -359,11 +388,14 @@ def initialize_game() -> None: print_computer_shots = True global first_turn + global second_turn if player_start.lower() != "yes": first_turn = COMPUTER + second_turn = PLAYER # calculate the initial number of shots for each - global num_computer_shots, num_player_shots + global num_computer_shots + global num_player_shots num_player_shots = calculate_shots(player_board) num_computer_shots = calculate_shots(computer_board) @@ -379,27 +411,36 @@ def initialize_game() -> None: # forth, replicating the gotos in the original game -# initialize the first_turn function to the player's turn +# initialize the first_turn function to the +# player's turn first_turn = PLAYER -def execute_turn(turn: bool, current_turn: int) -> int: - global num_computer_shots, num_player_shots +# initialize the second_turn to the computer's +# turn +second_turn = COMPUTER + + +def execute_turn(turn): - # print out the number of shots the current player has + global num_computer_shots + global num_player_shots + + # print out the number of shots the current + # player has board = None num_shots = 0 if turn == COMPUTER: - print(f"I HAVE {num_computer_shots} SHOTS.") + print("I HAVE", num_computer_shots, "SHOTS.") board = player_board num_shots = num_computer_shots else: - print(f"YOU HAVE {num_player_shots} SHOTS.") + print("YOU HAVE", num_player_shots, "SHOTS.") board = computer_board num_shots = num_player_shots shots = [] - for _shot in range(num_shots): + for shot in range(num_shots): valid_shot = False x = -1 y = -1 @@ -408,22 +449,27 @@ def execute_turn(turn: bool, current_turn: int) -> int: # computer, we randomly pick a shot. for the # player we request shots while not valid_shot: - x, y = random_x_y() if turn == COMPUTER else input_coord() - square = board[x - 1][y - 1] - if square is not None and square > 10: - if turn == PLAYER: - print("YOU SHOT THERE BEFORE ON TURN", square - 10) - continue + if turn == COMPUTER: + x, y = random_x_y() + else: + x, y = input_coord() + square = board[x-1][y-1] + if square is not None: + if square > 10: + if turn == PLAYER: + print("YOU SHOT THERE BEFORE ON TURN", square - 10) + continue shots.append((x, y)) valid_shot = True hits = [] for shot in shots: - hit = execute_shot(turn, board, shot[0], shot[1], current_turn) + hit = execute_shot(turn, board, shot[0], shot[1]) if hit >= 0: hits.append(hit) - if turn == COMPUTER and print_computer_shots: - print(shot[0], shot[1]) + if turn == COMPUTER: + if print_computer_shots: + print(shot[0], shot[1]) for hit in hits: if turn == COMPUTER: @@ -431,6 +477,7 @@ def execute_turn(turn: bool, current_turn: int) -> int: else: print("YOU HIT MY", SHIPS[hit][0]) + if turn == COMPUTER: num_player_shots = calculate_shots(board) return num_player_shots @@ -444,27 +491,36 @@ def execute_turn(turn: bool, current_turn: int) -> int: # ###################################### +###################### +# +# main game flow +# +###################### -def main() -> None: - current_turn = 0 - initialize_game() - - # execute turns until someone wins or we run - # out of squares to shoot - game_over = False - while not game_over: - current_turn += 1 +# initialize the player and computer +# boards +initialize_game() - print("\n") - print("TURN", current_turn) +# execute turns until someone wins or we run +# out of squares to shoot - if ( - execute_turn(first_turn, current_turn) == 0 - or execute_turn(not first_turn, current_turn) == 0 - ): - game_over = True - continue +game_over = False +while not game_over: + # increment the turn + current_turn = current_turn + 1 -if __name__ == "__main__": - main() + print("\n") + print("TURN", current_turn) + + # print("computer") + # print_board(computer_board) + # print("player") + # print_board(player_board) + + if execute_turn(first_turn) == 0: + game_over = True + continue + if execute_turn(second_turn) == 0: + game_over = True + continue diff --git a/77_Salvo/vbnet/Salvo.sln b/77_Salvo/vbnet/Salvo.sln deleted file mode 100644 index 3acb94496..000000000 --- a/77_Salvo/vbnet/Salvo.sln +++ /dev/null @@ -1,22 +0,0 @@ - -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 deleted file mode 100644 index 90ec0e380..000000000 --- a/77_Salvo/vbnet/Salvo.vbproj +++ /dev/null @@ -1,8 +0,0 @@ - - - Exe - Salvo - net6.0 - 16.9 - - diff --git a/78_Sine_Wave/README.md b/78_Sine_Wave/README.md index c5c340f3c..c38234a2d 100644 --- a/78_Sine_Wave/README.md +++ b/78_Sine_Wave/README.md @@ -1,6 +1,6 @@ ### Sine Wave -Did you ever go to a computer show and see a bunch of CRT terminals just sitting there waiting forlornly for someone to give a demo on them. It was one of those moments when I was at DEC that I decided there should be a little bit of background activity. And why not plot with words instead of the usual X’s? Thus SINE WAVE was born and lives on in dozens of different versions. At least those CRTs don’t look so lifeless anymore. +Did you ever go to a computer show and see a bunch of CRT terminals just sitting there waiting forlornly for someone to give a demo on them. It was one of those moments when I was at DEC that I decided there should be a little bit of background activity. And why not plot with words instead of the usual X’s? Thus SINE WAVE was born and lives on in dozens on different versions. At least those CRTs don’t look so lifeless anymore. --- @@ -10,7 +10,3 @@ As published in Basic Computer Games (1978): Downloaded from Vintage Basic at http://www.vintage-basic.net/games.html - -#### Porting Notes - -(please note any difficulties or challenges in porting here) diff --git a/78_Sine_Wave/csharp/Program.cs b/78_Sine_Wave/csharp/Program.cs deleted file mode 100644 index 69b2dee6e..000000000 --- a/78_Sine_Wave/csharp/Program.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -Console.WriteLine(Tab(30) + "Sine Wave"); -Console.WriteLine(Tab(15) + "Creative Computing Morristown, New Jersey\n\n\n\n\n"); - -bool isCreative = true; -for (double t = 0.0; t <= 40.0; t += 0.25) -{ - int a = (int)(26 + 25 * Math.Sin(t)); - string word = isCreative ? "Creative" : "Computing"; - Console.WriteLine($"{Tab(a)}{word}"); - isCreative = !isCreative; -} - -static string Tab(int n) => new string(' ', n); diff --git a/78_Sine_Wave/csharp/SineWave.sln b/78_Sine_Wave/csharp/SineWave.sln deleted file mode 100644 index adcc993f5..000000000 --- a/78_Sine_Wave/csharp/SineWave.sln +++ /dev/null @@ -1,25 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.31005.135 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SineWave", "SineWave.csproj", "{730FA2CC-5AA5-4BE2-8DF9-8E55FDC8FB30}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {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 - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {32A37343-2955-4124-8765-9143F6C529DC} - EndGlobalSection -EndGlobal diff --git a/78_Sine_Wave/csharp/SineWave/SineWave.sln b/78_Sine_Wave/csharp/SineWave/SineWave.sln new file mode 100644 index 000000000..f32a06cd3 --- /dev/null +++ b/78_Sine_Wave/csharp/SineWave/SineWave.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31005.135 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SineWave", "SineWave\SineWave.csproj", "{B316DD7F-5755-4216-AFDC-D83720F8ACA2}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B316DD7F-5755-4216-AFDC-D83720F8ACA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B316DD7F-5755-4216-AFDC-D83720F8ACA2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B316DD7F-5755-4216-AFDC-D83720F8ACA2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B316DD7F-5755-4216-AFDC-D83720F8ACA2}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {32A37343-2955-4124-8765-9143F6C529DC} + EndGlobalSection +EndGlobal diff --git a/78_Sine_Wave/csharp/SineWave/SineWave/Program.cs b/78_Sine_Wave/csharp/SineWave/SineWave/Program.cs new file mode 100644 index 000000000..6f44f8d52 --- /dev/null +++ b/78_Sine_Wave/csharp/SineWave/SineWave/Program.cs @@ -0,0 +1,15 @@ +using System; + +Console.WriteLine(Tab(30) + "Sine Wave"); +Console.WriteLine(Tab(15) + "Creative Computing Morristown, New Jersey\n\n\n\n\n"); + +bool isCreative = true; +for (double t = 0.0; t <= 40.0; t += 0.25) +{ + int a = (int)(26 + 25 * Math.Sin(t)); + string word = isCreative ? "Creative" : "Computing"; + Console.WriteLine($"{Tab(a)}{word}"); + isCreative = !isCreative; +} + +static string Tab(int n) => new string(' ', n); \ No newline at end of file diff --git a/78_Sine_Wave/csharp/SineWave.csproj b/78_Sine_Wave/csharp/SineWave/SineWave/SineWave.csproj similarity index 100% rename from 78_Sine_Wave/csharp/SineWave.csproj rename to 78_Sine_Wave/csharp/SineWave/SineWave/SineWave.csproj diff --git a/78_Sine_Wave/javascript/sinewave.js b/78_Sine_Wave/javascript/sinewave.js new file mode 100644 index 000000000..3823273d9 --- /dev/null +++ b/78_Sine_Wave/javascript/sinewave.js @@ -0,0 +1,22 @@ +print(tab(30), "SINE WAVE"); +print(tab(15), "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); +print("\n\n\n\n"); + +// REMARKABLE PROGRAM BY DAVID AHL +// Transliterated to Javascript by Les Orchard + +let toggleWord = true; + +for (let step = 0; step < 40; step += 0.25) { + let indent = Math.floor(26 + 25 * Math.sin(step)); + print(tab(indent), toggleWord ? "CREATIVE" : "COMPUTING"); + toggleWord = !toggleWord; +} + +function print(...messages) { + console.log(messages.join(" ")); +} + +function tab(count) { + return " ".repeat(count); +} diff --git a/78_Sine_Wave/javascript/sinewave.mjs b/78_Sine_Wave/javascript/sinewave.mjs deleted file mode 100644 index bd390e75d..000000000 --- a/78_Sine_Wave/javascript/sinewave.mjs +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env node - -import { println, tab } from '../../00_Common/javascript/common.mjs'; - -println(tab(30), "SINE WAVE"); -println(tab(15), "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); -println("\n".repeat(4)); - -// REMARKABLE PROGRAM BY DAVID AHL -// Transliterated to Javascript by Les Orchard - -let toggleWord = true; - -for (let step = 0; step < 40; step += 0.25) { - let indent = Math.floor(26 + 25 * Math.sin(step)); - println(tab(indent), toggleWord ? "CREATIVE" : "COMPUTING"); - toggleWord = !toggleWord; -} diff --git a/78_Sine_Wave/kotlin/README.md b/78_Sine_Wave/kotlin/README.md deleted file mode 100644 index f43a5b700..000000000 --- a/78_Sine_Wave/kotlin/README.md +++ /dev/null @@ -1,3 +0,0 @@ -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) - -Conversion to [Kotlin](https://kotlinlang.org/) diff --git a/78_Sine_Wave/lua/README.md b/78_Sine_Wave/lua/README.md deleted file mode 100644 index c063f42fd..000000000 --- a/78_Sine_Wave/lua/README.md +++ /dev/null @@ -1,3 +0,0 @@ -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) - -Conversion to [Lua](https://www.lua.org/) diff --git a/78_Sine_Wave/lua/sinewave.lua b/78_Sine_Wave/lua/sinewave.lua deleted file mode 100644 index 0ea2630b1..000000000 --- a/78_Sine_Wave/lua/sinewave.lua +++ /dev/null @@ -1,21 +0,0 @@ -require("math") -require("string") - -print("\n Sine Wave") -print(" Creative Computing Morriston, New Jersy") -print("\n\n\n\n") - --- Original BASIC version by David Ahl --- Ported to lua by BeeverFeever(github), 2022 - -local toggleWord = true - -for t = 0, 40, 0.25 do - local gap = math.floor(26 + 25 * math.sin(t)) - if toggleWord == true then - -- string.rep used to add the gat at the front of the printed out words - print(string.rep(" ", math.floor(gap)) .. "Creative") - elseif toggleWord == false then - print(string.rep(" ", math.floor(gap)) .. "Computing") - end -end diff --git a/78_Sine_Wave/pascal/README.md b/78_Sine_Wave/pascal/README.md new file mode 100644 index 000000000..aa1b3ae5d --- /dev/null +++ b/78_Sine_Wave/pascal/README.md @@ -0,0 +1,3 @@ +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) + +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language)) diff --git a/78_Sine_Wave/python/sinewave.py b/78_Sine_Wave/python/sinewave.py index 4f001b567..d1d0024d8 100644 --- a/78_Sine_Wave/python/sinewave.py +++ b/78_Sine_Wave/python/sinewave.py @@ -21,54 +21,51 @@ # ######################################################## -import math -import time +import math, time +# Constants +STRINGS = ('Creative', 'Computing') # Text to display +MAX_LINES = 160 +STEP_SIZE = 0.25 # Number of radians to increase at each + # line. Controls speed of horizontal + # printing movement. +CENTER = 26 # Controls left edge of "middle" string +DELAY = 0.05 # Amount of seconds to wait between lines -def main() -> None: - # Constants - STRINGS = ("Creative", "Computing") # Text to display - MAX_LINES = 160 - STEP_SIZE = 0.25 # Number of radians to increase at each - # line. Controls speed of horizontal - # printing movement. - CENTER = 26 # Controls left edge of "middle" string - DELAY = 0.05 # Amount of seconds to wait between lines - # Display "intro" text - print("\n Sine Wave") - print(" Creative Computing Morristown, New Jersey") - print("\n\n\n\n") - # "REMarkable program by David Ahl" +# Display "intro" text +print("\n Sine Wave") +print(" Creative Computing Morristown, New Jersey") +print("\n\n\n\n") +# "REMarkable program by David Ahl" - string_index = 0 - radians: float = 0 - width = CENTER - 1 - # "Start long loop" - for _line_num in range(MAX_LINES): +string_index = 0 +radians = 0 +width = CENTER - 1 - # Get string to display on this line - curr_string = STRINGS[string_index] +# "Start long loop" +for line_num in range(MAX_LINES): + + # Get string to display on this line + curr_string = STRINGS[string_index] + + # Calculate how far over to print the text + sine = math.sin(radians) + padding = int(CENTER + width * sine) + print(curr_string.rjust(padding + len(curr_string))) - # Calculate how far over to print the text - sine = math.sin(radians) - padding = int(CENTER + width * sine) - print(curr_string.rjust(padding + len(curr_string))) + # Increase radians and increment our tuple index + radians += STEP_SIZE + string_index += 1 + if string_index >= len(STRINGS): + string_index = 0 - # Increase radians and increment our tuple index - radians += STEP_SIZE - string_index += 1 - if string_index >= len(STRINGS): - string_index = 0 + # Make sure the text doesn't fly by too fast... + time.sleep(DELAY) - # Make sure the text doesn't fly by too fast... - time.sleep(DELAY) -if __name__ == "__main__": - main() - ######################################################## # # Porting Notes @@ -109,3 +106,10 @@ def main() -> None: # What happens? Why? How would you fix it? # ######################################################## + + + + + + + diff --git a/78_Sine_Wave/ruby/sinewave.rb b/78_Sine_Wave/ruby/sinewave.rb index 6cb19cd9f..001e2cd8a 100644 --- a/78_Sine_Wave/ruby/sinewave.rb +++ b/78_Sine_Wave/ruby/sinewave.rb @@ -12,4 +12,4 @@ def main end end -main +main \ No newline at end of file diff --git a/78_Sine_Wave/rust/Cargo.lock b/78_Sine_Wave/rust/Cargo.lock deleted file mode 100644 index b21cc6a2d..000000000 --- a/78_Sine_Wave/rust/Cargo.lock +++ /dev/null @@ -1,7 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "rust" -version = "0.1.0" diff --git a/78_Sine_Wave/rust/Cargo.toml b/78_Sine_Wave/rust/Cargo.toml deleted file mode 100644 index 1ec696335..000000000 --- a/78_Sine_Wave/rust/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[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] diff --git a/78_Sine_Wave/rust/README.md b/78_Sine_Wave/rust/README.md deleted file mode 100644 index 7e85f9a15..000000000 --- a/78_Sine_Wave/rust/README.md +++ /dev/null @@ -1,3 +0,0 @@ -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) - -Conversion to [Rust](https://www.rust-lang.org/) by Anthony Rubick [AnthonyMichaelTDM](https://github.com/AnthonyMichaelTDM) diff --git a/78_Sine_Wave/rust/src/main.rs b/78_Sine_Wave/rust/src/main.rs deleted file mode 100644 index f8a1cecee..000000000 --- a/78_Sine_Wave/rust/src/main.rs +++ /dev/null @@ -1,37 +0,0 @@ -fn main() { - let mut ticker:f64 = 0.0; - let mut spaces ; - - //pring welcome message - welcome(); - - //drawing loop - loop { - //print however many spaces - spaces = (26.0 + 25.0*ticker.sin()).round() as i32; - for _i in 0..=spaces{ - print!(" "); //print a space - } - - //print Creative or Computing - if (ticker.round() as i32) % 2 == 0 { - println!("CREATIVE"); - } else { - println!("COMPUTING"); - } - - //increment ticker - ticker += 0.25; - } - -} - -/** - * prints welcome message - */ -fn welcome() { - println!(" - SINE WAVE - CREATIVE COMPUTING MORRISTOWN, NEW JERSEY - "); -} \ No newline at end of file diff --git a/78_Sine_Wave/vbnet/SineWave.sln b/78_Sine_Wave/vbnet/SineWave.sln deleted file mode 100644 index 37f4bf7e1..000000000 --- a/78_Sine_Wave/vbnet/SineWave.sln +++ /dev/null @@ -1,22 +0,0 @@ - -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 deleted file mode 100644 index 610c360fe..000000000 --- a/78_Sine_Wave/vbnet/SineWave.vbproj +++ /dev/null @@ -1,8 +0,0 @@ - - - Exe - SineWave - net6.0 - 16.9 - - diff --git a/79_Slalom/README.md b/79_Slalom/README.md index c95309ceb..7e46e3a57 100644 --- a/79_Slalom/README.md +++ b/79_Slalom/README.md @@ -14,11 +14,3 @@ As published in Basic Computer Games (1978): Downloaded from Vintage Basic at http://www.vintage-basic.net/games.html - -#### Known 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, `READ Q'. - -- It also doesn't restore the data pointer after executing the MAX command to see the gate speeds, meaning that if you use this command, it effectively skips those gates, and the speeds shown are completely incorrect. - -#### Porting Notes diff --git a/79_Slalom/csharp/Slalom.csproj b/79_Slalom/csharp/Slalom.csproj deleted file mode 100644 index d3fe4757c..000000000 --- a/79_Slalom/csharp/Slalom.csproj +++ /dev/null @@ -1,9 +0,0 @@ - - - Exe - net6.0 - 10 - enable - enable - - diff --git a/79_Slalom/csharp/Slalom.sln b/79_Slalom/csharp/Slalom.sln deleted file mode 100644 index c1621f2e5..000000000 --- a/79_Slalom/csharp/Slalom.sln +++ /dev/null @@ -1,22 +0,0 @@ - -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/csharp/program.cs b/79_Slalom/csharp/program.cs deleted file mode 100644 index df70ba426..000000000 --- a/79_Slalom/csharp/program.cs +++ /dev/null @@ -1,433 +0,0 @@ -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(); - - } - } -} diff --git a/79_Slalom/java/Slalom.java b/79_Slalom/java/Slalom.java deleted file mode 100644 index aaff59a40..000000000 --- a/79_Slalom/java/Slalom.java +++ /dev/null @@ -1,373 +0,0 @@ -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; - } - } - - -} diff --git a/79_Slalom/javascript/slalom.html b/79_Slalom/javascript/slalom.html index 4221ea220..d91f71ad6 100644 --- a/79_Slalom/javascript/slalom.html +++ b/79_Slalom/javascript/slalom.html @@ -1,10 +1,9 @@ SLALOM - -

    
    +
    
     
     
     
    diff --git a/79_Slalom/javascript/slalom.js b/79_Slalom/javascript/slalom.js
    index 196ddb5dd..7944e62e0 100644
    --- a/79_Slalom/javascript/slalom.js
    +++ b/79_Slalom/javascript/slalom.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    @@ -88,7 +88,7 @@ async function main()
         var gold = 0;
         var silver = 0;
         var bronze = 0;
    -
    +    
         print(tab(33) + "SLALOM\n");
         print(tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n");
         print("\n");
    diff --git a/79_Slalom/kotlin/README.md b/79_Slalom/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/79_Slalom/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/79_Slalom/lua/README.md b/79_Slalom/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/79_Slalom/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/79_Slalom/pascal/README.md b/79_Slalom/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/79_Slalom/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/79_Slalom/python/slalom.py b/79_Slalom/python/slalom.py
    deleted file mode 100644
    index e3387e6f6..000000000
    --- a/79_Slalom/python/slalom.py
    +++ /dev/null
    @@ -1,204 +0,0 @@
    -from random import random
    -
    -medals = {
    -    "gold": 0,
    -    "silver": 0,
    -    "bronze": 0,
    -}
    -
    -
    -def ask(question: str) -> str:
    -    print(question, end="? ")
    -    return input().upper()
    -
    -
    -def ask_int(question: str) -> int:
    -    reply = ask(question)
    -    return int(reply) if reply.isnumeric() else -1
    -
    -
    -def pre_run(gates, max_speeds) -> None:
    -    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 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(" # 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(gates, lvl, max_speeds) -> None:
    -    global medals
    -    print("The starter counts down...5...4...3...2...1...Go!")
    -    time: float = 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() < 0.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" {speed} M.P.H.")
    -                if speed > max_speeds[i]:
    -                    if random() < ((speed - max_speeds[i]) * 0.1) + 0.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 maximum 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 += 0.5
    -                break
    -    print(f"\nYou took {int(time + random())} seconds.")
    -    avg = time / gates
    -    if avg < 1.5 - (lvl * 0.1):
    -        print("Yout won a gold medal!")
    -        medals["gold"] += 1
    -    elif avg < 2.9 - (lvl * 0.1):
    -        print("You won a silver medal!")
    -        medals["silver"] += 1
    -    elif avg < 4.4 - (lvl * 0.01):
    -        print("You won a bronze medal!")
    -        medals["bronze"] += 1
    -
    -
    -def main() -> None:
    -    print("Slalom".rjust(39))
    -    print("Creative Computing Morristown, New Jersey\n\n\n".rjust(57))
    -
    -    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,
    -    ]
    -
    -    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(gates, max_speeds)
    -
    -    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(gates, lvl, max_speeds)
    -        while True:
    -            answer = ask("Do you want to play again?")
    -            if answer in ["YES", "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']}")
    -
    -
    -if __name__ == "__main__":
    -    main()
    diff --git a/79_Slalom/slalom.bas b/79_Slalom/slalom.bas
    index 47c6d8010..b46cc39be 100644
    --- a/79_Slalom/slalom.bas
    +++ b/79_Slalom/slalom.bas
    @@ -58,7 +58,7 @@
     825 PRINT "*** SLALOM: THIS IS THE 1976 WINTER OLYMPIC GIANT SLALOM.  YOU ARE"
     830 PRINT "            THE AMERICAN TEAM'S ONLY HOPE OF A GOLD MEDAL."
     840 PRINT
    -845 PRINT "     0 -- TYPE THIS IF YOU WANT TO SEE HOW LONG YOU'VE TAKEN."
    +845 PRINT "     0 -- TYPE THIS IS YOU WANT TO SEE HOW LONG YOU'VE TAKEN."
     850 PRINT "     1 -- TYPE THIS IF YOU WANT TO SPEED UP A LOT."
     860 PRINT "     2 -- TYPE THIS IF YOU WANT TO SPEED UP A LITTLE."
     870 PRINT "     3 -- TYPE THIS IF YOU WANT TO SPEED UP A TEENSY."
    diff --git a/79_Slalom/vbnet/Slalom.sln b/79_Slalom/vbnet/Slalom.sln
    deleted file mode 100644
    index daa61623c..000000000
    --- a/79_Slalom/vbnet/Slalom.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 0622bcd9f..000000000
    --- a/79_Slalom/vbnet/Slalom.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Slalom
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/80_Slots/README.md b/80_Slots/README.md
    index 522c7c811..952fa03e4 100644
    --- a/80_Slots/README.md
    +++ b/80_Slots/README.md
    @@ -16,11 +16,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Known Bugs
    -
    -- The original program does not correctly detect identical draws in the first and third position as a double (instead, it counts as a loss).  This is probably not intended.  Some of the ports fix this, so that any two matches count as a double.
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/80_Slots/csharp/README.md b/80_Slots/csharp/README.md
    index 32f406f89..4983614ce 100644
    --- a/80_Slots/csharp/README.md
    +++ b/80_Slots/csharp/README.md
    @@ -2,7 +2,7 @@ Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/gam
     
     Conversion to [Microsoft C#](https://docs.microsoft.com/en-us/dotnet/csharp/)
     
    -This C# implementation of slots was done using a [C# script](https://github.com/filipw/dotnet-script).
    +This C# implementation of slots was done using a [C# script](https://github.com/filipw/dotnet-script).  
     
     # Required
     [.NET Core SDK (i.e., .NET 6.0)](https://dotnet.microsoft.com/en-us/download)
    @@ -15,4 +15,4 @@ dotnet tool install -g dotnet-script
     # Run
     ```
     dotnet script .\slots.csx
    -```
    +```
    \ No newline at end of file
    diff --git a/80_Slots/csharp/Slots.csproj b/80_Slots/csharp/Slots.csproj
    deleted file mode 100644
    index d3fe4757c..000000000
    --- a/80_Slots/csharp/Slots.csproj
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    diff --git a/80_Slots/csharp/Slots.sln b/80_Slots/csharp/Slots.sln
    deleted file mode 100644
    index 60f900465..000000000
    --- a/80_Slots/csharp/Slots.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/csharp/slots.csx b/80_Slots/csharp/slots.csx
    index 5c2ff5ccd..b812d9425 100644
    --- a/80_Slots/csharp/slots.csx
    +++ b/80_Slots/csharp/slots.csx
    @@ -49,7 +49,7 @@ public void Play()
             }
         }
         else if(x == y)
    -    {
    +    {       
             if(y == Slot.BAR)
             {
                 DoubleBar(bet);
    @@ -57,7 +57,7 @@ public void Play()
             else
             {
                 Double(bet);
    -        }
    +        }        
         }
         else if(x == z)
         {
    diff --git a/80_Slots/javascript/slots.html b/80_Slots/javascript/slots.html
    index b0e1e0381..33b8e73f1 100644
    --- a/80_Slots/javascript/slots.html
    +++ b/80_Slots/javascript/slots.html
    @@ -1,10 +1,9 @@
     
     
     SLOTS
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/80_Slots/javascript/slots.js b/80_Slots/javascript/slots.js
    index 93c860b4f..2bafd26ed 100644
    --- a/80_Slots/javascript/slots.js
    +++ b/80_Slots/javascript/slots.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/80_Slots/kotlin/README.md b/80_Slots/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/80_Slots/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/80_Slots/lua/README.md b/80_Slots/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/80_Slots/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/80_Slots/pascal/README.md b/80_Slots/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/80_Slots/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/80_Slots/python/slots.py b/80_Slots/python/slots.py
    index 6464458b6..fbae665b3 100644
    --- a/80_Slots/python/slots.py
    +++ b/80_Slots/python/slots.py
    @@ -31,22 +31,21 @@
     #
     ########################################################
     
    -import sys
    -from collections import Counter
     from random import choices
    -from typing import List
    +from collections import Counter
    +import sys
     
     
    -def initial_message() -> None:
    -    print(" " * 30 + "Slots")
    -    print(" " * 15 + "Creative Computing Morrison, New Jersey")
    -    print("\n" * 3)
    +def initial_message():
    +    print(" "*30 + "Slots")
    +    print(" "*15 + "Creative Computing Morrison, New Jersey")
    +    print("\n"*3)
         print("You are in the H&M Casino, in front of one of our")
         print("one-arm Bandits. Bet from $1 to $100.")
         print("To pull the arm, punch the return key after making your bet.")
     
     
    -def input_betting() -> int:
    +def input_betting():
         print("\n")
         b = -1
         while b < 1 or b > 100:
    @@ -59,18 +58,18 @@ def input_betting() -> int:
             elif b < 1:
                 print("Minium bet is $1")
         beeping()
    -    return b
    +    return int(b)
     
     
    -def beeping() -> None:
    +def beeping():
         # Function to produce a beep sound.
         # In the original program is the subroutine at line 1270
         for _ in range(5):
    -        sys.stdout.write("\a")
    +        sys.stdout.write('\a')
             sys.stdout.flush()
     
     
    -def spin_wheels() -> List[str]:
    +def spin_wheels():
         possible_fruits = ["Bar", "Bell", "Orange", "Lemon", "Plum", "Cherry"]
         wheel = choices(possible_fruits, k=3)
     
    @@ -80,7 +79,7 @@ def spin_wheels() -> List[str]:
         return wheel
     
     
    -def adjust_profits(wheel: List[str], m: int, profits: int) -> int:
    +def adjust_profits(wheel, m, profits):
         # we remove the duplicates
         s = set(wheel)
     
    @@ -90,10 +89,10 @@ def adjust_profits(wheel: List[str], m: int, profits: int) -> int:
     
             if fruit == "Bar":
                 print("\n***Jackpot***")
    -            profits = ((100 * m) + m) + profits
    +            profits = (((100*m)+m)+profits)
             else:
                 print("\n**Top Dollar**")
    -            profits = ((10 * m) + m) + profits
    +            profits = (((10*m)+m)+profits)
     
             print("You Won!")
         elif len(s) == 2:
    @@ -104,21 +103,21 @@ def adjust_profits(wheel: List[str], m: int, profits: int) -> int:
     
             if fruit == "Bar":
                 print("\n*Double Bar*")
    -            profits = ((5 * m) + m) + profits
    +            profits = (((5*m)+m)+profits)
             else:
                 print("\nDouble!!")
    -            profits = ((2 * m) + m) + profits
    +            profits = (((2*m)+m)+profits)
     
             print("You Won!")
         else:
             # three different fruits
             print("\nYou Lost.")
    -        profits -= m
    +        profits = profits - m
     
         return profits
     
     
    -def final_message(profits: int) -> None:
    +def final_message(profits):
         if profits < 0:
             print("Pay up!  Please leave your money on the terminal")
         elif profits == 0:
    @@ -127,30 +126,26 @@ def final_message(profits: int) -> None:
             print("Collect your winings from the H&M cashier.")
     
     
    -def main() -> None:
    -    profits = 0
    -    keep_betting = True
    +profits = 0
    +keep_betting = True
     
    -    initial_message()
    -    while keep_betting:
    -        m = input_betting()
    -        w = spin_wheels()
    -        profits = adjust_profits(w, m, profits)
    +initial_message()
    +while keep_betting:
    +    m = input_betting()
    +    w = spin_wheels()
    +    profits = adjust_profits(w, m, profits)
     
    -        print(f"Your standings are ${profits}")
    -        answer = input("Again?")
    +    print("Your standings are ${}".format(profits))
    +    answer = input("Again?")
     
    -        try:
    -            if answer[0].lower() != "y":
    -                keep_betting = False
    -        except IndexError:
    +    try:
    +        if not answer[0].lower() == "y":
                 keep_betting = False
    +    except IndexError:
    +        keep_betting = False
     
    -    final_message(profits)
    -
    +final_message(profits)
     
    -if __name__ == "__main__":
    -    main()
     
     ######################################################################
     #
    diff --git a/80_Slots/ruby/slots.rb b/80_Slots/ruby/slots.rb
    index 1e6fc22d3..a4c3e7ef0 100644
    --- a/80_Slots/ruby/slots.rb
    +++ b/80_Slots/ruby/slots.rb
    @@ -91,7 +91,7 @@ def win winType, bet
         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)]
    diff --git a/80_Slots/slots.bas b/80_Slots/slots.bas
    index ef7ed841d..2d1b84d4a 100644
    --- a/80_Slots/slots.bas
    +++ b/80_Slots/slots.bas
    @@ -12,7 +12,7 @@
     180 IF M>100 THEN 860
     190 IF M<1 THEN 880
     200 M=INT(M)
    -210 GOSUB 1270
    +210 GOSUB 1270 
     220 PRINT
     230 LET X=INT(6*RND(1)+1)
     240 LET Y=INT(6*RND(1)+1)
    @@ -118,7 +118,7 @@
     1240 GOTO 450
     1250 PRINT" CHERRY"
     1260 GOTO 450
    -1270 FOR Q4=1 TO 10
    +1270 FOR Q4=1 TO 10 
     1280 PRINT CHR$(7);
     1290 NEXT Q4
     1300 RETURN
    diff --git a/80_Slots/vbnet/Slots.sln b/80_Slots/vbnet/Slots.sln
    deleted file mode 100644
    index 1f493198f..000000000
    --- a/80_Slots/vbnet/Slots.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 04f381a32..000000000
    --- a/80_Slots/vbnet/Slots.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Slots
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/81_Splat/README.md b/81_Splat/README.md
    index 9708ac2b8..246312176 100644
    --- a/81_Splat/README.md
    +++ b/81_Splat/README.md
    @@ -14,7 +14,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/81_Splat/csharp/Program.cs b/81_Splat/csharp/Program.cs
    deleted file mode 100644
    index 6ca973a41..000000000
    --- a/81_Splat/csharp/Program.cs
    +++ /dev/null
    @@ -1,330 +0,0 @@
    -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();
    -
    -        }
    -    }
    -}
    diff --git a/81_Splat/csharp/Splat.csproj b/81_Splat/csharp/Splat.csproj
    deleted file mode 100644
    index d3fe4757c..000000000
    --- a/81_Splat/csharp/Splat.csproj
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    diff --git a/81_Splat/csharp/Splat.sln b/81_Splat/csharp/Splat.sln
    deleted file mode 100644
    index d71848599..000000000
    --- a/81_Splat/csharp/Splat.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/java/src/Splat.java b/81_Splat/java/src/Splat.java
    index e28a2bb8d..e042c326c 100644
    --- a/81_Splat/java/src/Splat.java
    +++ b/81_Splat/java/src/Splat.java
    @@ -354,4 +354,4 @@ float getTimeOfTerminalAccelerationReached() {
                 return terminalVelocity / acceleration;
             }
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/81_Splat/javascript/splat.html b/81_Splat/javascript/splat.html
    index df7e37679..195039738 100644
    --- a/81_Splat/javascript/splat.html
    +++ b/81_Splat/javascript/splat.html
    @@ -1,10 +1,9 @@
     
     
     SPLAT
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/81_Splat/javascript/splat.js b/81_Splat/javascript/splat.js
    index 8b51786bc..e037d1907 100644
    --- a/81_Splat/javascript/splat.js
    +++ b/81_Splat/javascript/splat.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/81_Splat/kotlin/README.md b/81_Splat/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/81_Splat/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/81_Splat/lua/README.md b/81_Splat/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/81_Splat/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/81_Splat/pascal/README.md b/81_Splat/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/81_Splat/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/81_Splat/perl/splat.pl b/81_Splat/perl/splat.pl
    index 6114e7fc7..eebfcb6b1 100755
    --- a/81_Splat/perl/splat.pl
    +++ b/81_Splat/perl/splat.pl
    @@ -21,7 +21,7 @@
     
     
     Welcome to 'Splat' -- the game that simulates a parachute
    -jump.  Try to open your chute at the last possible
    +jump.  Try to open your chute at the last possible 
     moment without going splat.
     EOD
     
    @@ -115,8 +115,8 @@
                 if ( $fractile <= 0.1 ) {
                     print <<"EOD";
     Wow!  That's some jumping.  Of the $jumps successful jumps
    -before yours, only $better opened their chutes lower than
    -you did.
    +before yours, only $better opened their chutes lower than 
    +you did. 
     EOD
                 } elsif ( $fractile <= 0.25 ) {
                     print <<"EOD";
    @@ -126,7 +126,7 @@
     EOD
                 } elsif ( $fractile <= 0.5 ) {
                     print <<"EOD";
    -Not bad.  There have been $jumps successful jumps before yours.
    +Not bad.  There have been $jumps successful jumps before yours. 
     You were beaten out by $better of them.
     EOD
                 } elsif ( $fractile <= 0.75 ) {
    @@ -136,7 +136,7 @@
     EOD
                 } elsif ( $fractile <= 0.9 ) {
                     print <<"EOD";
    -Humph!  Don't you have any sporting blood?  There were
    +Humph!  Don't you have any sporting blood?  There were 
     $jumps successful jumps before yours and you came in $worse jumps
     better than the worst.  Shape up!!!
     EOD
    diff --git a/81_Splat/python/splat.py b/81_Splat/python/splat.py
    index f521f3a23..6e08083bc 100644
    --- a/81_Splat/python/splat.py
    +++ b/81_Splat/python/splat.py
    @@ -24,22 +24,21 @@
     """
     from math import sqrt
     from random import choice, random, uniform
    -from typing import List, Tuple
     
     PAGE_WIDTH = 72
     
     
    -def numeric_input(question, default=0) -> float:
    +def numeric_input(question, default=0):
         """Ask user for a numeric value."""
         while True:
    -        answer_str = input(f"{question} [{default}]: ").strip() or default
    +        answer = input(f"{question} [{default}]: ").strip() or default
             try:
    -            return float(answer_str)
    +            return float(answer)
             except ValueError:
                 pass
     
     
    -def yes_no_input(question: str, default="YES") -> bool:
    +def yes_no_input(question, default="YES"):
         """Ask user a yes/no question and returns True if yes, otherwise False."""
         answer = input(f"{question} (YES OR NO) [{default}]: ").strip() or default
         while answer.lower() not in ["n", "no", "y", "yes"]:
    @@ -47,7 +46,7 @@ def yes_no_input(question: str, default="YES") -> bool:
         return answer.lower() in ["y", "yes"]
     
     
    -def get_terminal_velocity() -> float:
    +def get_terminal_velocity():
         """Terminal velocity by user or picked by computer."""
         if yes_no_input("SELECT YOUR OWN TERMINAL VELOCITY", default="NO"):
             v1 = numeric_input("WHAT TERMINAL VELOCITY (MI/HR)", default=100)
    @@ -60,7 +59,7 @@ def get_terminal_velocity() -> float:
         return v1 * (5280 / 3600)
     
     
    -def get_acceleration() -> float:
    +def get_acceleration():
         """Acceleration due to gravity by user or picked by computer."""
         if yes_no_input("WANT TO SELECT ACCELERATION DUE TO GRAVITY", default="NO"):
             a2 = numeric_input("WHAT ACCELERATION (FT/SEC/SEC)", default=32.16)
    @@ -70,14 +69,14 @@ def get_acceleration() -> float:
         return a2
     
     
    -def get_freefall_time() -> float:
    +def get_freefall_time():
         """User-guessed freefall time.
     
         The idea of the game is to pick a freefall time, given initial
         altitude, terminal velocity and acceleration, so the parachute
         as close to the ground as possible without going splat.
         """
    -    t_freefall: float = 0
    +    t_freefall = 0
         # A zero or negative freefall time is not handled by the motion
         # equations during the jump.
         while t_freefall <= 0:
    @@ -85,13 +84,13 @@ def get_freefall_time() -> float:
         return t_freefall
     
     
    -def jump() -> float:
    +def jump():
         """Simulate a jump and returns the altitude where the chute opened.
     
         The idea is to open the chute as late as possible -- but not too late.
         """
    -    v: float = 0  # Terminal velocity.
    -    a: float = 0  # Acceleration.
    +    v = 0  # Terminal velocity.
    +    a = 0  # Acceleration.
         initial_altitude = int(9001 * random() + 1000)
     
         v1 = get_terminal_velocity()
    @@ -138,7 +137,7 @@ def jump() -> float:
                 #    here, the displacement is just a function of the terminal
                 #    velocity and the time passed after having reached terminal
                 #    velocity: d2 = v * (t - t_reached_term_vel)
    -            d1 = (v**2) / (2 * a)
    +            d1 = (v ** 2) / (2 * a)
                 d2 = v * (t - (v / a))
                 altitude = initial_altitude - (d1 + d2)
                 if altitude <= 0:
    @@ -161,7 +160,7 @@ def jump() -> float:
                 #    From the second equation of motion,
                 #    d = v_0 * t + 0.5 * a * t^2, with v_0 = 0, we can get
                 #    the displacement using d1 = a / 2 * t^2
    -            d1 = (a / 2) * (t**2)
    +            d1 = (a / 2) * (t ** 2)
                 altitude = initial_altitude - d1
                 if altitude <= 0:
                     # Time taken for an object to fall to the ground given that
    @@ -181,9 +180,9 @@ def jump() -> float:
         return altitude
     
     
    -def pick_random_celestial_body() -> Tuple[str, float]:
    +def pick_random_celestial_body():
         """Pick a random planet, the moon, or the sun with associated gravity."""
    -    return choice(
    +    body, gravity = choice(
             [
                 ("MERCURY", 12.2),
                 ("VENUS", 28.3),
    @@ -197,20 +196,21 @@ def pick_random_celestial_body() -> Tuple[str, float]:
                 ("THE SUN", 896.0),
             ]
         )
    +    return body, gravity
     
     
    -def jump_stats(previous_jumps, chute_altitude) -> Tuple[int, int]:
    +def jump_stats(previous_jumps, chute_altitude):
         """Compare altitude when chute opened with previous successful jumps.
     
         Return the number of previous jumps and the number of times
         the current jump is better.
         """
         n_previous_jumps = len(previous_jumps)
    -    n_better = sum(1 for pj in previous_jumps if chute_altitude < pj)
    +    n_better = sum([1 for pj in previous_jumps if chute_altitude < pj])
         return n_previous_jumps, n_better
     
     
    -def print_splat(time_on_impact) -> None:
    +def print_splat(time_on_impact):
         """Parachute opened too late!"""
         print(f"{time_on_impact:.2f}\t\tSPLAT")
         print(
    @@ -231,7 +231,7 @@ def print_splat(time_on_impact) -> None:
         )
     
     
    -def print_results(n_previous_jumps, n_better) -> None:
    +def print_results(n_previous_jumps, n_better):
         """Compare current jump to previous successful jumps."""
         k = n_previous_jumps
         k1 = n_better
    @@ -276,13 +276,13 @@ def print_results(n_previous_jumps, n_better) -> None:
             )
     
     
    -def print_centered(msg: str) -> None:
    +def print_centered(msg):
         """Print centered text."""
         spaces = " " * ((PAGE_WIDTH - len(msg)) // 2)
         print(spaces + msg)
     
     
    -def print_header() -> None:
    +def print_header():
         print_centered("SPLAT")
         print_centered("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
         print(
    @@ -293,28 +293,27 @@ def print_header() -> None:
         )
     
     
    -def main() -> None:
    -    print_header()
    +#
    +# Main program.
    +#
     
    -    successful_jumps: List[float] = []
    -    while True:
    -        chute_altitude = jump()
    -        if chute_altitude > 0:
    -            # We want the statistics on previous jumps (i.e. not including the
    -            # current jump.)
    -            n_previous_jumps, n_better = jump_stats(successful_jumps, chute_altitude)
    -            successful_jumps.append(chute_altitude)
    -            print_results(n_previous_jumps, n_better)
    -        else:
    -            # Splat!
    -            print("I'LL GIVE YOU ANOTHER CHANCE.")
    -        z = yes_no_input("DO YOU WANT TO PLAY AGAIN")
    -        if not z:
    -            z = yes_no_input("PLEASE")
    +print_header()
    +
    +successful_jumps = []
    +while True:
    +    chute_altitude = jump()
    +    if chute_altitude > 0:
    +        # We want the statistics on previous jumps (i.e. not including the
    +        # current jump.)
    +        n_previous_jumps, n_better = jump_stats(successful_jumps, chute_altitude)
    +        successful_jumps.append(chute_altitude)
    +        print_results(n_previous_jumps, n_better)
    +    else:
    +        # Splat!
    +        print("I'LL GIVE YOU ANOTHER CHANCE.")
    +    z = yes_no_input("DO YOU WANT TO PLAY AGAIN")
    +    if not z:
    +        z = yes_no_input("PLEASE")
             if not z:
                 print("SSSSSSSSSS.")
                 break
    -
    -
    -if __name__ == "__main__":
    -    main()
    diff --git a/81_Splat/rust/Cargo.lock b/81_Splat/rust/Cargo.lock
    deleted file mode 100644
    index 4fe2abbea..000000000
    --- a/81_Splat/rust/Cargo.lock
    +++ /dev/null
    @@ -1,75 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.10"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.147"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/81_Splat/rust/Cargo.toml b/81_Splat/rust/Cargo.toml
    deleted file mode 100644
    index 3b1d02f52..000000000
    --- a/81_Splat/rust/Cargo.toml
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -[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/81_Splat/rust/src/celestial_body.rs b/81_Splat/rust/src/celestial_body.rs
    deleted file mode 100644
    index 594a3bcbe..000000000
    --- a/81_Splat/rust/src/celestial_body.rs
    +++ /dev/null
    @@ -1,64 +0,0 @@
    -use rand::{prelude::SliceRandom, Rng};
    -
    -#[derive(Debug)]
    -pub enum CelestialBody {
    -    MERCURY,
    -    VENUS,
    -    EARTH,
    -    MOON,
    -    MARS,
    -    JUPITER,
    -    SATURN,
    -    URANUS,
    -    NEPTUNE,
    -    SUN,
    -}
    -
    -impl CelestialBody {
    -    pub fn get_acceleration(&self) -> f32 {
    -        use CelestialBody::*;
    -
    -        match self {
    -            MERCURY => 12.2,
    -            VENUS => 28.3,
    -            EARTH => 32.16,
    -            MOON => 5.12,
    -            MARS => 12.5,
    -            JUPITER => 85.2,
    -            SATURN => 37.6,
    -            URANUS => 33.8,
    -            NEPTUNE => 39.6,
    -            SUN => 896.,
    -        }
    -    }
    -
    -    pub fn print_acceleration_message(&self) {
    -        let messages: [&str; 3] = ["Fine,", "All right,", "Then"];
    -        let m = messages.choose(&mut rand::thread_rng()).unwrap();
    -
    -        println!(
    -            "{} YOU'RE ON {:?}. ACCELERATION = {} FT/SEC/SEC.",
    -            m.to_uppercase(),
    -            self,
    -            self.get_acceleration()
    -        );
    -    }
    -}
    -
    -pub fn random_celestial_body() -> Option {
    -    use CelestialBody::*;
    -
    -    match rand::thread_rng().gen_range(0..10) {
    -        0 => Some(MERCURY),
    -        1 => Some(VENUS),
    -        2 => Some(EARTH),
    -        3 => Some(MOON),
    -        4 => Some(MARS),
    -        5 => Some(JUPITER),
    -        6 => Some(SATURN),
    -        7 => Some(URANUS),
    -        8 => Some(NEPTUNE),
    -        9 => Some(SUN),
    -        _ => None,
    -    }
    -}
    diff --git a/81_Splat/rust/src/game.rs b/81_Splat/rust/src/game.rs
    deleted file mode 100644
    index 8b3bba184..000000000
    --- a/81_Splat/rust/src/game.rs
    +++ /dev/null
    @@ -1,105 +0,0 @@
    -use crate::utility;
    -
    -pub struct Game {
    -    altitude: f32,
    -    terminal_velocity: f32,
    -    acceleration: f32,
    -    interval: f32,
    -}
    -
    -impl Game {
    -    pub fn new() -> Game {
    -        let altitude = utility::get_altitude();
    -
    -        let terminal_velocity = utility::get_terminal_velocity(
    -            "SELECT YOUR OWN TERMINAL VELOCITY",
    -            "WHAT TERMINAL VELOCITY (MI/HR)?",
    -        );
    -
    -        let acceleration = utility::get_acceleration(
    -            "WANT TO SELECT ACCELERATION DUE TO GRAVITY",
    -            "WHAT ACCELERATION (FT/SEC/SEC)?",
    -        );
    -
    -        println!("");
    -        println!("      ALTITUDE        = {} FT", altitude);
    -        println!("      TERM. VELOCITY  = {} FT/SEC +-5%", terminal_velocity);
    -        println!("      ACCELERATION    = {} FT/SEC/SEC +-5%", acceleration);
    -
    -        let seconds =
    -            utility::prompt_numeric("\nSET THE TIMER FOR YOUR FREEFALL.\nHOW MANY SECONDS?");
    -
    -        println!("\nHERE WE GO.\n");
    -
    -        println!("TIME (SEC)\tDIST TO FALL (FT)");
    -        println!("==========\t=================");
    -
    -        Game {
    -            altitude,
    -            terminal_velocity,
    -            acceleration,
    -            interval: seconds / 8.,
    -        }
    -    }
    -
    -    pub fn tick(&mut self) -> f32 {
    -        let mut splat = false;
    -        let mut terminal_velocity_reached = false;
    -
    -        let (v, a) = (self.terminal_velocity, self.acceleration);
    -        let terminal_velocity_time = v / a;
    -
    -        let initial_altitude = self.altitude;
    -
    -        for i in 0..=8 {
    -            let dt = i as f32 * self.interval;
    -
    -            if dt >= terminal_velocity_time {
    -                if !terminal_velocity_reached {
    -                    println!(
    -                        "TERMINAL VELOCITY REACHED AT T PLUS {} SECONDS.",
    -                        terminal_velocity_time
    -                    );
    -                    terminal_velocity_reached = true;
    -                }
    -
    -                let d1 = v.powi(2) / (2. * a);
    -                let d2 = v * (dt - (terminal_velocity_time));
    -                self.altitude = initial_altitude - (d1 + d2);
    -
    -                if self.altitude <= 0. {
    -                    let t = (initial_altitude - d1) / v;
    -                    utility::print_splat(t + terminal_velocity_time);
    -
    -                    splat = true;
    -                    break;
    -                }
    -            } else {
    -                let d1 = (a * 0.5) * (dt.powi(2));
    -                self.altitude = initial_altitude - d1;
    -
    -                if self.altitude <= 0. {
    -                    let t = (2. * initial_altitude / a).sqrt();
    -                    utility::print_splat(t);
    -
    -                    splat = true;
    -                    break;
    -                }
    -            }
    -
    -            println!("{}\t\t{}", dt, self.altitude);
    -
    -            std::thread::sleep(std::time::Duration::from_secs(1));
    -        }
    -
    -        let mut a = -1.;
    -
    -        if !splat {
    -            println!("\nCHUTE OPEN\n");
    -
    -            a = self.altitude;
    -        }
    -
    -        a
    -    }
    -}
    diff --git a/81_Splat/rust/src/main.rs b/81_Splat/rust/src/main.rs
    deleted file mode 100644
    index eec8bfe6b..000000000
    --- a/81_Splat/rust/src/main.rs
    +++ /dev/null
    @@ -1,39 +0,0 @@
    -use crate::{game::Game, stats::Stats};
    -
    -mod celestial_body;
    -mod game;
    -mod stats;
    -mod utility;
    -
    -fn main() {
    -    println!("\n\n\n                       SPLAT");
    -    println!("      CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n\n");
    -
    -    println!("WELCOME TO 'SPLAT' -- THE GAME THAT SIMULATES");
    -    println!("A PARACHUTE JUMP. TRY OPEN YOUR CHUTE AT THE");
    -    println!("LAST POSSIBLE MOMENT WITHOUT GOING SPLAT.\n");
    -
    -    let mut stats = Stats::new();
    -
    -    loop {
    -        let mut game = Game::new();
    -
    -        let latest_altitude = game.tick();
    -
    -        if latest_altitude > 0. {
    -            if let Some(s) = &mut stats {
    -                s.add_altitude(latest_altitude);
    -            }
    -        }
    -
    -        use utility::prompt_bool;
    -        if !prompt_bool("DO YOU WANT TO PLAY AGAIN?", true) {
    -            if !prompt_bool("PLEASE?", false) {
    -                if !prompt_bool("YES OR NO PLEASE?", false) {
    -                    println!("SSSSSSSSSS.");
    -                    break;
    -                }
    -            }
    -        }
    -    }
    -}
    diff --git a/81_Splat/rust/src/stats.rs b/81_Splat/rust/src/stats.rs
    deleted file mode 100644
    index c86b83ae8..000000000
    --- a/81_Splat/rust/src/stats.rs
    +++ /dev/null
    @@ -1,88 +0,0 @@
    -use std::{
    -    fs::{self, File},
    -    io::Write,
    -};
    -
    -use crate::utility;
    -
    -pub struct Stats {
    -    altitudes: Vec,
    -}
    -
    -impl Stats {
    -    pub fn new() -> Option {
    -        if utility::prompt_bool("WOULD YOU LIKE TO LOAD PREVIOUS GAME DATA?", false) {
    -            let path = "src/stats.txt";
    -            let mut altitudes = Vec::new();
    -
    -            if let Ok(stats) = fs::read_to_string(path) {
    -                if stats.is_empty() {
    -                    return Some(Stats {
    -                        altitudes: Vec::new(),
    -                    });
    -                }
    -
    -                let stats: Vec<&str> = stats.trim().split(",").collect();
    -
    -                for s in stats {
    -                    if s.is_empty() {
    -                        continue;
    -                    }
    -
    -                    let s = s.parse::().expect("Corrupt stats file!");
    -                    altitudes.push(s);
    -                }
    -
    -                return Some(Stats { altitudes });
    -            } else {
    -                println!("PREVIOUS GAME DATA NOT FOUND!");
    -
    -                if !utility::prompt_bool("WOULD YOU LIKE TO CREATE ONE?", false) {
    -                    return None;
    -                } else {
    -                    let mut file = File::create(path).expect("Invalid file path!");
    -                    file.write_all("".as_bytes())
    -                        .expect("Could not create file!");
    -
    -                    return Some(Stats {
    -                        altitudes: Vec::new(),
    -                    });
    -                }
    -            }
    -        }
    -
    -        println!("\nRESULTS OF THIS SESSION WILL NOT BE SAVED.");
    -        None
    -    }
    -
    -    pub fn add_altitude(&mut self, a: f32) {
    -        let all_jumps = self.altitudes.len() + 1;
    -        let mut placement = all_jumps;
    -
    -        for (i, altitude) in self.altitudes.iter().enumerate() {
    -            if a <= *altitude {
    -                placement = i + 1;
    -                break;
    -            }
    -        }
    -
    -        utility::print_win(all_jumps, placement);
    -
    -        self.altitudes.push(a);
    -        self.altitudes.sort_by(|a, b| a.partial_cmp(b).unwrap());
    -
    -        self.write();
    -    }
    -
    -    fn write(&self) {
    -        let mut file = File::create("src/stats.txt").expect("Error loading stats data!");
    -
    -        let mut altitudes = String::new();
    -
    -        for a in &self.altitudes {
    -            altitudes.push_str(format!("{},", a).as_str());
    -        }
    -
    -        write!(&mut file, "{}", altitudes.trim()).expect("ERROR WRITING Stats FILE!");
    -    }
    -}
    diff --git a/81_Splat/rust/src/utility.rs b/81_Splat/rust/src/utility.rs
    deleted file mode 100644
    index c37a2af31..000000000
    --- a/81_Splat/rust/src/utility.rs
    +++ /dev/null
    @@ -1,168 +0,0 @@
    -use crate::celestial_body;
    -use rand::Rng;
    -use std::io;
    -
    -const DEATH_MESSAGES: [&str; 10] = [
    -    "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.",
    -];
    -
    -pub fn read_line() -> String {
    -    let mut input = String::new();
    -    io::stdin()
    -        .read_line(&mut input)
    -        .expect("Failed to read line.");
    -    input.trim().to_uppercase()
    -}
    -
    -pub fn prompt_bool(msg: &str, template: bool) -> bool {
    -    if template {
    -        println!("{} (YES OR NO)?", msg);
    -    } else {
    -        println!("{}", msg);
    -    }
    -
    -    loop {
    -        let response = read_line();
    -
    -        match response.as_str() {
    -            "YES" => return true,
    -            "NO" => return false,
    -            _ => println!("PLEASE ENTER YES OR NO."),
    -        }
    -    }
    -}
    -
    -pub fn prompt_numeric(msg: &str) -> f32 {
    -    println!("{}", msg);
    -
    -    loop {
    -        let response = read_line();
    -
    -        if let Some(_) = response.chars().find(|c| !c.is_numeric()) {
    -            println!("PLEASE ENTER A NUMBER.");
    -        } else {
    -            return response.parse::().unwrap();
    -        }
    -    }
    -}
    -
    -pub fn get_altitude() -> f32 {
    -    9001. * rand::random::() + 1000.
    -}
    -
    -pub fn get_terminal_velocity(bool_msg: &str, num_msg: &str) -> f32 {
    -    let mut _num = 0.0;
    -
    -    if prompt_bool(bool_msg, true) {
    -        _num = prompt_numeric(num_msg);
    -    } else {
    -        _num = get_random_float(0., 1000.);
    -        println!("OK. TERMINAL VELOCTY = {} MI/HR", _num);
    -    }
    -
    -    (_num * ((5280 / 3600) as f32)) * get_random_float(0.95, 1.05)
    -}
    -
    -pub fn get_acceleration(bool_msg: &str, num_msg: &str) -> f32 {
    -    let mut _num = 0.0;
    -
    -    if prompt_bool(bool_msg, true) {
    -        _num = prompt_numeric(num_msg);
    -    } else {
    -        let b =
    -            celestial_body::random_celestial_body().expect("Fatal Error: Invalid Celestial Body!");
    -
    -        _num = b.get_acceleration();
    -        b.print_acceleration_message();
    -    }
    -
    -    _num * get_random_float(0.95, 1.05)
    -}
    -
    -fn get_random_float(min: f32, max: f32) -> f32 {
    -    rand::thread_rng().gen_range(min..=max)
    -}
    -
    -pub fn print_splat(t: f32) {
    -    print_random(format!("{}\t\tSPLAT!", t).as_str(), &DEATH_MESSAGES);
    -    print!("I'LL GIVE YOU ANOTHER CHANCE.\n");
    -}
    -
    -fn print_random(msg: &str, choices: &[&str]) {
    -    use rand::seq::SliceRandom;
    -    use rand::thread_rng;
    -
    -    let mut rng = thread_rng();
    -
    -    println!("{}", msg);
    -    println!("\n{}\n", choices.choose(&mut rng).unwrap());
    -}
    -
    -pub fn print_win(total: usize, placement: usize) {
    -    if total <= 3 {
    -        let order;
    -
    -        match total {
    -            1 => order = "1ST",
    -            2 => order = "2ND",
    -            3 => order = "3RD",
    -            _ => order = "#INVALID#",
    -        }
    -
    -        println!("AMAZING!!! NOT BAD FOR YOUR {} SUCCESSFUL JUMP!!!", order);
    -        return;
    -    }
    -
    -    let (total, placement) = (total as f32, placement as f32);
    -
    -    let betters = placement - 1.;
    -    let p: f32 = (total - betters) / total;
    -
    -    println!("{}", p);
    -
    -    println!(
    -        "placement: {}, total jumps: {}, percent is: {}",
    -        placement, total, p
    -    );
    -
    -    if p < 0.1 {
    -        println!(
    -            "HEY! YOU PULLED THE RIP CORD MUCH TOO SOON. {} SUCCESSFUL\nJUMPS BEFORE YOURS AND YOU CAME IN NUMBER {}! GET WITH IT!",
    -            total, placement
    -        );
    -    } else if p < 0.25 {
    -        println!(
    -            "HUMPH!  DON'T YOU HAVE ANY SPORTING BLOOD? THERE WERE\n{} SUCCESSFUL JUMPS BEFORE YOURS AND YOU CAME IN {} JUMPS\nBETTER THAN THE WORST. SHAPE UP!!!",
    -            total, placement
    -        );
    -    } else if p < 0.5 {
    -        println!(
    -            "CONSERVATIVE, AREN'T YOU? YOU RANKED ONLY {} IN THE\n{} SUCCESSFUL JUMPS BEFORE YOURS.",
    -            placement, total
    -        );
    -    } else if p < 0.75 {
    -        println!(
    -            "NOT BAD.  THERE HAVE BEEN {} SUCCESSFUL JUMPS BEFORE YOURS.\nYOU WERE BEATEN OUT BY {} OF THEM.",
    -            total, betters
    -        );
    -    } else if p < 0.9 {
    -        println!(
    -            "PRETTY GOOD! {} SUCCESSFUL JUMPS PRECEDED YOURS AND ONLY\n{} OF THEM GOT LOWER THAN YOU DID BEFORE THEIR CHUTES\nOPENED.",
    -            total, betters
    -        )
    -    } else {
    -        println!(
    -            "WOW!  THAT'S SOME JUMPING. OF THE {} SUCCESSFUL JUMPS\nBEFORE YOURS, ONLY {} OPENED THEIR CHUTES LOWER THAN\nYOU DID.",
    -            total, betters
    -        )
    -    }
    -}
    diff --git a/81_Splat/splat.bas b/81_Splat/splat.bas
    index 8561f6345..a3aba0362 100644
    --- a/81_Splat/splat.bas
    +++ b/81_Splat/splat.bas
    @@ -3,122 +3,122 @@
     40 PRINT:PRINT:PRINT
     50 DIM A(42)
     95 PRINT "WELCOME TO 'SPLAT' -- THE GAME THAT SIMULATES A PARACHUTE"
    -96 PRINT "JUMP.  TRY TO OPEN YOUR CHUTE AT THE LAST POSSIBLE"
    +96 PRINT "JUMP.  TRY TO OPEN YOUR CHUTE AT THE LAST POSSIBLE" 
     97 PRINT "MOMENT WITHOUT GOING SPLAT."
     118 PRINT:PRINT:D1=0:V=0:A=0:N=0:M=0:D1=INT(9001*RND(1)+1000)
    -119 PRINT "SELECT YOUR OWN TERMINAL VELOCITY (YES OR NO)";:INPUT A1$
    +119 PRINT "SELECT YOUR OWN TERMINAL VELOCITY (YES OR NO)";:INPUT A1$    
     120 IF A1$="NO" THEN 128
     121 IF A1$<>"YES" THEN PRINT "YES OR NO";:INPUT A1$:GOTO 120
    -123 PRINT "WHAT TERMINAL VELOCITY (MI/HR)";:INPUT V1
    +123 PRINT "WHAT TERMINAL VELOCITY (MI/HR)";:INPUT V1 
     125 V1=V1*(5280/3600):V=V1+((V1*RND(1))/20)-((V1*RND(1))/20):GOTO 135
     128 V1=INT(1000*RND(1))
     130 PRINT "OK.  TERMINAL VELOCITY ="V1"MI/HR"
    -131 V1=V1*(5280/3600):V=V1+((V1*RND(1))/20)-((V1*RND(1))/20)
    -135  PRINT "WANT TO SELECT ACCELERATION DUE TO GRAVITY (YES OR NO)";
    +131 V1=V1*(5280/3600):V=V1+((V1*RND(1))/20)-((V1*RND(1))/20) 
    +135  PRINT "WANT TO SELECT ACCELERATION DUE TO GRAVITY (YES OR NO)"; 
     136 INPUT B1$
     140 IF B1$="NO" THEN 150
     141 IF B1$<>"YES" THEN PRINT "YES OR NO";:INPUT B1$:GOTO 140
    -143 PRINT "WHAT ACCELERATION (FT/SEC/SEC)";:INPUT A2
    +143 PRINT "WHAT ACCELERATION (FT/SEC/SEC)";:INPUT A2 
     145 A=A2+((A2*RND(1))/20)-((A2*RND(1))/20):GOTO 205
    -150 ON INT(1+(10*RND(1)))GOTO 151,152,153,154,155,156,157,158,159,160
    +150 ON INT(1+(10*RND(1)))GOTO 151,152,153,154,155,156,157,158,159,160 
     151 PRINT"FINE. YOU'RE ON MERCURY. ACCELERATION=12.2 FT/SEC/SEC.":GOTO 161
     152 PRINT"ALL RIGHT. YOU'RE ON VENUS. ACCELERATION=28.3 FT/SEC/SEC.":GOTO 162
    -153 PRINT "THEN YOU'RE ON EARTH. ACCELERATION=32.16 FT/SEC/SEC.":GOTO 163
    +153 PRINT "THEN YOU'RE ON EARTH. ACCELERATION=32.16 FT/SEC/SEC.":GOTO 163 
     154 PRINT"FINE. YOU'RE ON THE MOON. ACCELERATION=5.15 FT/SEC/SEC.":GOTO 164
    -155 PRINT"ALL RIGHT. YOU'RE ON MARS. ACCELERATION=12.5 FT/SEC/SEC.":GOTO 165
    +155 PRINT"ALL RIGHT. YOU'RE ON MARS. ACCELERATION=12.5 FT/SEC/SEC.":GOTO 165 
     156 PRINT"THEN YOU'RE ON JUPITER. ACCELERATION=85.2 FT/SEC/SEC.":GOTO 166
     157 PRINT"FINE. YOU'RE ON SATURN. ACCELERATION=37.6 FT/SEC/SEC.":GOTO 167
    -158 PRINT"ALL RIGHT. YOU'RE ON URANUS. ACCELERATION=33.8 FT/SEC/SEC.":GOTO 168
    +158 PRINT"ALL RIGHT. YOU'RE ON URANUS. ACCELERATION=33.8 FT/SEC/SEC.":GOTO 168 
     159 PRINT"THEN YOU'RE ON NEPTUNE. ACCELERATION=39.6 FT/SEC/SEC.":GOTO 169
     160 PRINT"FINE. YOU'RE ON THE SUN. ACCELERATION=896 FT/SEC/SEC.":GOTO 170
    -161 A2=12.2:GOTO 145
    -162 A2=28.3:GOTO 145
    +161 A2=12.2:GOTO 145 
    +162 A2=28.3:GOTO 145 
     163 A2=32.16:GOTO 145
    -164 A2=5.15:GOTO 145
    -165 A2=12.5:GOTO 145
    -166 A2=85.2:GOTO 145
    -167 A2=37.6:GOTO 145
    +164 A2=5.15:GOTO 145 
    +165 A2=12.5:GOTO 145 
    +166 A2=85.2:GOTO 145 
    +167 A2=37.6:GOTO 145 
     168 A2=33.8 :GOTO 145
    -169 A2=39.6:GOTO 145
    +169 A2=39.6:GOTO 145 
     170 A2=896:GOTO 145
     205 PRINT
    -206 PRINT "    ALTITUDE         ="D1"FT"
    +206 PRINT "    ALTITUDE         ="D1"FT" 
     207 PRINT "    TERM. VELOCITY   ="V1"FT/SEC +/-5%"
     208 PRINT "    ACCELERATION     ="A2"FT/SEC/SEC +/-5%"
     210 PRINT "SET THE TIMER FOR YOUR FREEFALL."
     211 PRINT "HOW MANY SECONDS";:INPUT T
     215 PRINT "HERE WE GO."
     217 PRINT
    -218 PRINT "TIME (SEC)","DIST TO FALL (FT)"
    -219 PRINT "==========","================="
    +218 PRINT "TIME (SEC)","DIST TO FALL (FT)" 
    +219 PRINT "==========","=================" 
     300 FOR I=0 TO T STEP (T/8)
     310 IF I>V/A THEN 400
    -320 D=D1-((A/2)*I^2)
    +320 D=D1-((A/2)*I^2) 
     330 IF D<=0 THEN 1000
     340 PRINT I,D
    -350 NEXT I
    -360 GOTO 500
    +350 NEXT I 
    +360 GOTO 500 
     400 PRINT "TERMINAL VELOCITY REACHED AT T PLUS"V/A"SECONDS."
     405 FOR I=I TO T STEP (T/8)
    -410 D=D1-((V^2/(2*A))+(V*(I-(V/A))))
    +410 D=D1-((V^2/(2*A))+(V*(I-(V/A)))) 
     420 IF D<=0 THEN 1010
     430 PRINT I,D
    -440 NEXT I
    +440 NEXT I 
     500 PRINT "CHUTE OPEN"
    -510 K=0:K1=0
    +510 K=0:K1=0 
     550 FOR J=0 TO 42
    -555 IF A(J)=0 THEN 620
    +555 IF A(J)=0 THEN 620 
     560 K=K+1
     570 IF D>=A(J) THEN 600
     580 K1=K1+1
    -600 NEXT J
    -610 GOTO 540
    -620 A(J)=D
    +600 NEXT J 
    +610 GOTO 540 
    +620 A(J)=D 
     630 IF J>2 THEN 650
     635 PRINT "AMAZING!!! NOT BAD FOR YOUR ";
     636 IF J=0 THEN PRINT "1ST ";
     637 IF J=1 THEN PRINT "2ND ";
     638 IF J=2 THEN PRINT "3RD ";
     639 PRINT "SUCCESSFUL JUMP!!!":GOTO 2000
    -650 IF K-K1<=.1*K THEN 700
    +650 IF K-K1<=.1*K THEN 700 
     660 IF K-K1<=.25*K THEN 710
    -670 IF K-K1<=.5*K THEN 720
    +670 IF K-K1<=.5*K THEN 720 
     680 IF K-K1<=.75*K THEN 730
    -690 IF K-K1<=.9*K THEN 740
    -695 GOTO 750
    +690 IF K-K1<=.9*K THEN 740 
    +695 GOTO 750 
     700 PRINT "WOW!  THAT'S SOME JUMPING.  OF THE"K"SUCCESSFUL JUMPS"
    -701 PRINT "BEFORE YOURS, ONLY"K-K1"OPENED THEIR CHUTES LOWER THAN"
    -702 PRINT "YOU DID."
    +701 PRINT "BEFORE YOURS, ONLY"K-K1"OPENED THEIR CHUTES LOWER THAN" 
    +702 PRINT "YOU DID." 
     703 GOTO 2000
     710 PRINT "PRETTY GOOD! " K"SUCCESSFUL JUMPS PRECEDED YOURS AND ONLY"
     711 PRINT K-K1" OF THEM GOT LOWER THAN YOU DID BEFORE THEIR CHUTES"
    -712 PRINT "OPENED." :GOTO 2000
    -720 PRINT "NOT BAD.  THERE HAVE BEEN"K"SUCCESSFUL JUMPS BEFORE YOURS."
    -721 PRINT"YOU WERE BEATEN OUT BY"K-K1"OF THEM.":GOTO 2000
    +712 PRINT "OPENED." :GOTO 2000 
    +720 PRINT "NOT BAD.  THERE HAVE BEEN"K"SUCCESSFUL JUMPS BEFORE YOURS." 
    +721 PRINT"YOU WERE BEATEN OUT BY"K-K1"OF THEM.":GOTO 2000  
     730 PRINT "CONSERVATIVE, AREN'T YOU?  YOU RANKED ONLY"K-K1"IN THE"
     731 PRINT K"SUCCESSFUL JUMPS BEFORE YOURS.":GOTO 2000
    -740 PRINT "HUMPH!  DON'T YOU HAVE ANY SPORTING BLOOD?  THERE WERE"
    +740 PRINT "HUMPH!  DON'T YOU HAVE ANY SPORTING BLOOD?  THERE WERE" 
     741 PRINT K"SUCCESSFUL JUMPS BEFORE YOURS AND YOU CAME IN"K1"JUMPS"
     742 PRINT "BETTER THAN THE WORST.  SHAPE UP!!!":GOTO 2000
     750 PRINT "HEY!  YOU PULLED THE RIP CORD MUCH TOO SOON.  "K"SUCCESSFUL"
    -751 PRINT "JUMPS BEFORE YOURS AND YOU CAME IN NUMBER"K-K1"!  GET WITH IT!"
    +751 PRINT "JUMPS BEFORE YOURS AND YOU CAME IN NUMBER"K-K1"!  GET WITH IT!" 
     752 GOTO 2000
     800 PRINT "REQUIESCAT IN PACE.":GOTO 1950
    -801 PRINT "MAY THE ANGEL OF HEAVEN LEAD YOU INTO PARADISE.":GOTO 1950
    +801 PRINT "MAY THE ANGEL OF HEAVEN LEAD YOU INTO PARADISE.":GOTO 1950 
     802 PRINT "REST IN PEACE.":GOTO 1950
    -803 PRINT "SON-OF-A-GUN.":GOTO 1950
    -804 PRINT "#$%&&%!$":GOTO 1950
    +803 PRINT "SON-OF-A-GUN.":GOTO 1950 
    +804 PRINT "#$%&&%!$":GOTO 1950 
     805 PRINT "A KICK IN THE PANTS IS A BOOST IF YOU'RE HEADED RIGHT.":GOTO 1950
    -806 PRINT "HMMM. SHOULD HAVE PICKED A SHORTER TIME.":GOTO 1950
    +806 PRINT "HMMM. SHOULD HAVE PICKED A SHORTER TIME.":GOTO 1950 
     807 PRINT "MUTTER. MUTTER. MUTTER.":GOTO 1950
    -808 PRINT "PUSHING UP DAISIES.":GOTO 1950
    -809 PRINT "EASY COME, EASY GO.":GOTO 1950
    +808 PRINT "PUSHING UP DAISIES.":GOTO 1950 
    +809 PRINT "EASY COME, EASY GO.":GOTO 1950  
     1000 PRINT SQR(2*D1/A),"SPLAT"
     1005 ON INT(1+(10*RND(1)))GOTO 800,801,802,803,804,805,806,807,808,809
     1010 PRINT (V/A)+((D1-(V^2/(2*A)))/V),"SPLAT"
     1020 GOTO 1005
     1950 PRINT "I'LL GIVE YOU ANOTHER CHANCE.":GOTO 2000
    -2000 PRINT "DO YOU WANT TO PLAY AGAIN";:INPUT Z$
    +2000 PRINT "DO YOU WANT TO PLAY AGAIN";:INPUT Z$  
     2001 IF Z$="YES" THEN 118
     2002 IF Z$="NO" THEN 2005
     2003 PRINT "YES OR NO":GOTO 2000
    diff --git a/81_Splat/vbnet/Splat.sln b/81_Splat/vbnet/Splat.sln
    deleted file mode 100644
    index b132583da..000000000
    --- a/81_Splat/vbnet/Splat.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index daf6de3cb..000000000
    --- a/81_Splat/vbnet/Splat.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Splat
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/82_Stars/README.md b/82_Stars/README.md
    index f4e430d10..ff0679750 100644
    --- a/82_Stars/README.md
    +++ b/82_Stars/README.md
    @@ -14,7 +14,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/82_Stars/csharp/Game.cs b/82_Stars/csharp/Game.cs
    deleted file mode 100644
    index f3944737c..000000000
    --- a/82_Stars/csharp/Game.cs
    +++ /dev/null
    @@ -1,105 +0,0 @@
    -using System;
    -using Games.Common.IO;
    -using Games.Common.Randomness;
    -using Stars.Resources;
    -
    -namespace Stars;
    -
    -internal class Game
    -{
    -    private readonly TextIO _io;
    -    private readonly IRandom _random;
    -    private readonly int _maxNumber;
    -    private readonly int _maxGuessCount;
    -
    -    public Game(TextIO io, IRandom random, int maxNumber, int maxGuessCount)
    -    {
    -        _io = io;
    -        _random = random;
    -        _maxNumber = maxNumber;
    -        _maxGuessCount = maxGuessCount;
    -    }
    -
    -    internal void Play(Func playAgain)
    -    {
    -        DisplayIntroduction();
    -
    -        do
    -        {
    -            Play();
    -        } while (playAgain.Invoke());
    -    }
    -
    -    private void DisplayIntroduction()
    -    {
    -        _io.Write(Resource.Streams.Title);
    -
    -        if (_io.ReadString("Do you want instructions").Equals("N", StringComparison.InvariantCultureIgnoreCase))
    -        {
    -            return;
    -        }
    -
    -        _io.WriteLine(Resource.Formats.Instructions, _maxNumber, _maxGuessCount);
    -    }
    -
    -    private void Play()
    -    {
    -        _io.WriteLine();
    -        _io.WriteLine();
    -
    -        var target = _random.Next(_maxNumber) + 1;
    -
    -        _io.WriteLine("Ok, I am thinking of a number.  Start guessing.");
    -
    -        AcceptGuesses(target);
    -    }
    -
    -    private void AcceptGuesses(int target)
    -    {
    -        for (int guessCount = 1; guessCount <= _maxGuessCount; guessCount++)
    -        {
    -            _io.WriteLine();
    -            var guess = _io.ReadNumber("Your guess");
    -
    -            if (guess == target)
    -            {
    -                DisplayWin(guessCount);
    -                return;
    -            }
    -
    -            DisplayStars(target, guess);
    -        }
    -
    -        DisplayLoss(target);
    -    }
    -
    -    private void DisplayStars(int target, float guess)
    -    {
    -        var stars = Math.Abs(guess - target) switch
    -        {
    -            >= 64 => "*",
    -            >= 32 => "**",
    -            >= 16 => "***",
    -            >= 8  => "****",
    -            >= 4  => "*****",
    -            >= 2  => "******",
    -            _     => "*******"
    -        };
    -
    -        _io.WriteLine(stars);
    -    }
    -
    -    private void DisplayWin(int guessCount)
    -    {
    -        _io.WriteLine();
    -        _io.WriteLine(new string('*', 79));
    -        _io.WriteLine();
    -        _io.WriteLine($"You got it in {guessCount} guesses!!!  Let's play again...");
    -    }
    -
    -    private void DisplayLoss(int target)
    -    {
    -        _io.WriteLine();
    -        _io.WriteLine($"Sorry, that's {_maxGuessCount} guesses. The number was {target}.");
    -    }
    -}
    diff --git a/82_Stars/csharp/Program.cs b/82_Stars/csharp/Program.cs
    deleted file mode 100644
    index cf6e9e4a4..000000000
    --- a/82_Stars/csharp/Program.cs
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -using Games.Common.IO;
    -using Games.Common.Randomness;
    -using Stars;
    -
    -var game = new Game(new ConsoleIO(), new RandomNumberGenerator(), maxNumber: 100, maxGuessCount: 7);
    -
    -game.Play(() => true);
    diff --git a/82_Stars/csharp/Resources/Instructions.txt b/82_Stars/csharp/Resources/Instructions.txt
    deleted file mode 100644
    index 372c7809d..000000000
    --- a/82_Stars/csharp/Resources/Instructions.txt
    +++ /dev/null
    @@ -1,6 +0,0 @@
    -I am thinking of a number between 1 and {0}.
    -Try to guess my number.  After you guess, I
    -will type one or more stars (*).  The more
    -stars I type, the closer you are to my number.
    -One star (*) means far away, seven stars (*******)
    -means really close!  You get {1} guesses.
    \ No newline at end of file
    diff --git a/82_Stars/csharp/Resources/Resource.cs b/82_Stars/csharp/Resources/Resource.cs
    deleted file mode 100644
    index f3a6e47b3..000000000
    --- a/82_Stars/csharp/Resources/Resource.cs
    +++ /dev/null
    @@ -1,28 +0,0 @@
    -using System.IO;
    -using System.Reflection;
    -using System.Runtime.CompilerServices;
    -
    -namespace Stars.Resources;
    -
    -internal static class Resource
    -{
    -    internal static class Streams
    -    {
    -        public static Stream Title => GetStream();
    -    }
    -
    -    internal static class Formats
    -    {
    -        public static string Instructions => GetString();
    -    }
    -
    -    private static string GetString([CallerMemberName] string name = null)
    -    {
    -        using var stream = GetStream(name);
    -        using var reader = new StreamReader(stream);
    -        return reader.ReadToEnd();
    -    }
    -
    -    private static Stream GetStream([CallerMemberName] string name = null)
    -        => Assembly.GetExecutingAssembly().GetManifestResourceStream($"Stars.Resources.{name}.txt");
    -}
    \ No newline at end of file
    diff --git a/82_Stars/csharp/Resources/Title.txt b/82_Stars/csharp/Resources/Title.txt
    deleted file mode 100644
    index 67ccb5452..000000000
    --- a/82_Stars/csharp/Resources/Title.txt
    +++ /dev/null
    @@ -1,5 +0,0 @@
    -                                  Stars
    -               Creative Computing  Morristown, New Jersey
    -
    -
    -
    diff --git a/82_Stars/csharp/Stars.csproj b/82_Stars/csharp/Stars.csproj
    deleted file mode 100644
    index f8fe6e62c..000000000
    --- a/82_Stars/csharp/Stars.csproj
    +++ /dev/null
    @@ -1,16 +0,0 @@
    -
    -
    -  
    -    Exe
    -    net6.0
    -  
    -
    -  
    -    
    -  
    -
    -  
    -    
    -  
    -
    -
    diff --git a/82_Stars/csharp/Stars.sln b/82_Stars/csharp/Stars.sln
    index 19c3a265c..5f85e6b7e 100644
    --- a/82_Stars/csharp/Stars.sln
    +++ b/82_Stars/csharp/Stars.sln
    @@ -1,25 +1,34 @@
     
     Microsoft Visual Studio Solution File, Format Version 12.00
    -# Visual Studio Version 17
    -VisualStudioVersion = 17.0.32014.148
    +# Visual Studio 15
    +VisualStudioVersion = 15.0.26124.0
     MinimumVisualStudioVersion = 15.0.26124.0
    -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stars", "Stars.csproj", "{F03C19DA-0F5D-45F4-B85E-E3ABCA197D4B}"
    +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stars", "Stars\Stars.csproj", "{5832C21C-4DE5-475E-893D-745DA15F1AAC}"
     EndProject
     Global
     	GlobalSection(SolutionConfigurationPlatforms) = preSolution
     		Debug|Any CPU = Debug|Any CPU
    +		Debug|x64 = Debug|x64
    +		Debug|x86 = Debug|x86
     		Release|Any CPU = Release|Any CPU
    -	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
    +		Release|x64 = Release|x64
    +		Release|x86 = Release|x86
     	EndGlobalSection
     	GlobalSection(SolutionProperties) = preSolution
     		HideSolutionNode = FALSE
     	EndGlobalSection
    -	GlobalSection(ExtensibilityGlobals) = postSolution
    -		SolutionGuid = {0752CA22-85F0-43AE-8B79-7A611531CAF7}
    +	GlobalSection(ProjectConfigurationPlatforms) = postSolution
    +		{5832C21C-4DE5-475E-893D-745DA15F1AAC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
    +		{5832C21C-4DE5-475E-893D-745DA15F1AAC}.Debug|Any CPU.Build.0 = Debug|Any CPU
    +		{5832C21C-4DE5-475E-893D-745DA15F1AAC}.Debug|x64.ActiveCfg = Debug|Any CPU
    +		{5832C21C-4DE5-475E-893D-745DA15F1AAC}.Debug|x64.Build.0 = Debug|Any CPU
    +		{5832C21C-4DE5-475E-893D-745DA15F1AAC}.Debug|x86.ActiveCfg = Debug|Any CPU
    +		{5832C21C-4DE5-475E-893D-745DA15F1AAC}.Debug|x86.Build.0 = Debug|Any CPU
    +		{5832C21C-4DE5-475E-893D-745DA15F1AAC}.Release|Any CPU.ActiveCfg = Release|Any CPU
    +		{5832C21C-4DE5-475E-893D-745DA15F1AAC}.Release|Any CPU.Build.0 = Release|Any CPU
    +		{5832C21C-4DE5-475E-893D-745DA15F1AAC}.Release|x64.ActiveCfg = Release|Any CPU
    +		{5832C21C-4DE5-475E-893D-745DA15F1AAC}.Release|x64.Build.0 = Release|Any CPU
    +		{5832C21C-4DE5-475E-893D-745DA15F1AAC}.Release|x86.ActiveCfg = Release|Any CPU
    +		{5832C21C-4DE5-475E-893D-745DA15F1AAC}.Release|x86.Build.0 = Release|Any CPU
     	EndGlobalSection
     EndGlobal
    diff --git a/82_Stars/csharp/Stars/Game.cs b/82_Stars/csharp/Stars/Game.cs
    new file mode 100644
    index 000000000..7045fe4bf
    --- /dev/null
    +++ b/82_Stars/csharp/Stars/Game.cs
    @@ -0,0 +1,94 @@
    +using System;
    +
    +namespace Stars
    +{
    +    internal class Game
    +    {
    +        private readonly int _maxNumber;
    +        private readonly int _maxGuessCount;
    +        private readonly Random _random;
    +
    +        public Game(int maxNumber, int maxGuessCount)
    +        {
    +            _maxNumber = maxNumber;
    +            _maxGuessCount = maxGuessCount;
    +            _random = new Random();
    +        }
    +
    +        internal void DisplayInstructions()
    +        {
    +            if (Input.GetString("Do you want instructions? ").Equals("N", StringComparison.InvariantCultureIgnoreCase))
    +            {
    +                return;
    +            }
    +
    +            Console.WriteLine($"I am thinking of a number between 1 and {_maxNumber}.");
    +            Console.WriteLine("Try to guess my number.  After you guess, I");
    +            Console.WriteLine("will type one or more stars (*).  The more");
    +            Console.WriteLine("stars I type, the close you are to my number.");
    +            Console.WriteLine("One star (*) means far away, seven stars (*******)");
    +            Console.WriteLine($"means really close!  You get {_maxGuessCount} guesses.");
    +        }
    +
    +        internal void Play()
    +        {
    +            Console.WriteLine();
    +            Console.WriteLine();
    +
    +            var target = _random.Next(_maxNumber) + 1;
    +
    +            Console.WriteLine("Ok, I am thinking of a number.  Start guessing.");
    +
    +            AcceptGuesses(target);
    +        }
    +
    +        private void AcceptGuesses(int target)
    +        {
    +            for (int guessCount = 1; guessCount <= _maxGuessCount; guessCount++)
    +            {
    +                Console.WriteLine();
    +                var guess = Input.GetNumber("Your guess? ");
    +
    +                if (guess == target)
    +                {
    +                    DisplayWin(guessCount);
    +                    return;
    +                }
    +
    +                DisplayStars(target, guess);
    +            }
    +
    +            DisplayLoss(target);
    +        }
    +
    +        private static void DisplayStars(int target, float guess)
    +        {
    +            var stars = Math.Abs(guess - target) switch
    +            {
    +                >= 64 => "*",
    +                >= 32 => "**",
    +                >= 16 => "***",
    +                >= 8  => "****",
    +                >= 4  => "*****",
    +                >= 2  => "******",
    +                _     => "*******"
    +            };
    +
    +            Console.WriteLine(stars);
    +        }
    +
    +        private static void DisplayWin(int guessCount)
    +        {
    +            Console.WriteLine();
    +            Console.WriteLine(new string('*', 79));
    +            Console.WriteLine();
    +            Console.WriteLine($"You got it in {guessCount} guesses!!!  Let's play again...");
    +        }
    +
    +        private void DisplayLoss(int target)
    +        {
    +            Console.WriteLine();
    +            Console.WriteLine($"Sorry, that's {_maxGuessCount} guesses. The number was {target}.");
    +        }
    +    }
    +}
    \ No newline at end of file
    diff --git a/82_Stars/csharp/Stars/Input.cs b/82_Stars/csharp/Stars/Input.cs
    new file mode 100644
    index 000000000..6ba6e3a18
    --- /dev/null
    +++ b/82_Stars/csharp/Stars/Input.cs
    @@ -0,0 +1,31 @@
    +using System;
    +
    +namespace Stars
    +{
    +    internal static class Input
    +    {
    +        // Float, because that's what the BASIC input operation returns
    +        internal static float GetNumber(string prompt)
    +        {
    +            Console.Write(prompt);
    +
    +            while (true)
    +            {
    +                var response = Console.ReadLine();
    +                if (float.TryParse(response, out var value))
    +                {
    +                    return value;
    +                }
    +
    +                Console.WriteLine("!Number expected - retry input line");
    +                Console.Write("? ");
    +            }
    +        }
    +
    +        internal static string GetString(string prompt)
    +        {
    +            Console.Write(prompt);
    +            return Console.ReadLine();
    +        }
    +    }
    +}
    diff --git a/82_Stars/csharp/Stars/Program.cs b/82_Stars/csharp/Stars/Program.cs
    new file mode 100644
    index 000000000..b072595c7
    --- /dev/null
    +++ b/82_Stars/csharp/Stars/Program.cs
    @@ -0,0 +1,30 @@
    +using System;
    +
    +namespace Stars
    +{
    +    class Program
    +    {
    +        static void Main(string[] args)
    +        {
    +            DisplayTitle();
    +
    +            var game = new Game(maxNumber: 100, maxGuessCount: 7);
    +
    +            game.DisplayInstructions();
    +
    +            while (true)
    +            {
    +                game.Play();
    +            }
    +        }
    +
    +        private static void DisplayTitle()
    +        {
    +            Console.WriteLine("                                  Stars");
    +            Console.WriteLine("               Creative Computing  Morristown, New Jersey");
    +            Console.WriteLine();
    +            Console.WriteLine();
    +            Console.WriteLine();
    +        }
    +    }
    +}
    diff --git a/51_Hurkle/csharp/Hurkle.csproj b/82_Stars/csharp/Stars/Stars.csproj
    similarity index 100%
    rename from 51_Hurkle/csharp/Hurkle.csproj
    rename to 82_Stars/csharp/Stars/Stars.csproj
    diff --git a/82_Stars/java/src/Stars.java b/82_Stars/java/src/Stars.java
    index b9cf641a1..75e7cdd6a 100644
    --- a/82_Stars/java/src/Stars.java
    +++ b/82_Stars/java/src/Stars.java
    @@ -239,4 +239,4 @@ private int randomNumber() {
             return (int) (Math.random()
                     * (HIGH_NUMBER_RANGE) + 1);
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/82_Stars/javascript/stars.html b/82_Stars/javascript/stars.html
    index 6ca449d25..c63aeb0d2 100644
    --- a/82_Stars/javascript/stars.html
    +++ b/82_Stars/javascript/stars.html
    @@ -1,10 +1,9 @@
     
     
     STARS
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/82_Stars/javascript/stars.js b/82_Stars/javascript/stars.js
    index 15a92ca14..5ffdd761d 100644
    --- a/82_Stars/javascript/stars.js
    +++ b/82_Stars/javascript/stars.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    @@ -71,7 +71,7 @@ async function main()
             var loss = true;
     
             print("\nOK, I AM THINKING OF A NUMBER, START GUESSING.\n\n");
    -
    +        
             for(var guessNum=1; guessNum <= guesses; guessNum++) {
     
                 // Input guess
    @@ -105,4 +105,4 @@ async function main()
         }
     }
     
    -main();
    +main();
    \ No newline at end of file
    diff --git a/82_Stars/kotlin/README.md b/82_Stars/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/82_Stars/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/82_Stars/lua/README.md b/82_Stars/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/82_Stars/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/82_Stars/pascal/README.md b/82_Stars/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/82_Stars/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/82_Stars/python/stars.py b/82_Stars/python/stars.py
    index 5a5f9fed0..7b4cbfa14 100644
    --- a/82_Stars/python/stars.py
    +++ b/82_Stars/python/stars.py
    @@ -1,24 +1,26 @@
    -"""
    -Stars
    -
    -From: BASIC Computer Games (1978)
    -      Edited by David H. Ahl
    -
    -"In this game, the computer selects a random number from 1 to 100
    - (or any value you set [for MAX_NUM]).  You try to guess the number
    - and the computer gives you clues to tell you how close you're
    - getting.  One star (*) means you're far away from the number; seven
    - stars (*******) means you're really close.  You get 7  guesses.
    -
    -"On the surface this game is very similar to GUESS; however, the
    - guessing strategy is quite different.  See if you can come up with
    - one or more approaches to finding the mystery number.
    -
    -"Bob Albrecht of People's Computer Company created this game."
    -
    -
    -Python port by Jeff Jetton, 2019
    -"""
    +######################################################################
    +#
    +# Stars
    +#
    +# From: BASIC Computer Games (1978)
    +#       Edited by David H. Ahl
    +#
    +# "In this game, the computer selects a random number from 1 to 100
    +#  (or any value you set [for MAX_NUM]).  You try to guess the number
    +#  and the computer gives you clues to tell you how close you're
    +#  getting.  One star (*) means you're far away from the number; seven
    +#  stars (*******) means you're really close.  You get 7  guesses.
    +#
    +# "On the surface this game is very similar to GUESS; however, the
    +#  guessing strategy is quite different.  See if you can come up with
    +#  one or more approaches to finding the mystery number.
    +#
    +# "Bob Albrecht of People's Computer Company created this game."
    +#
    +#
    +# Python port by Jeff Jetton, 2019
    +#
    +######################################################################
     
     
     import random
    @@ -28,8 +30,8 @@
     MAX_GUESSES = 7
     
     
    -def print_instructions() -> None:
    -    """Instructions on how to play"""
    +def print_instructions():
    +    # "*** Instructions on how to play"
         print("I am thinking of a whole number from 1 to %d" % MAX_NUM)
         print("Try to guess my number.  After you guess, I")
         print("will type one or more stars (*).  The more")
    @@ -38,69 +40,75 @@ def print_instructions() -> None:
         print("means really close!  You get %d guesses." % MAX_GUESSES)
     
     
    -def print_stars(secret_number, guess) -> None:
    +def print_stars(secret_number, guess):
         diff = abs(guess - secret_number)
    -    stars = "".join("*" for i in range(8) if diff < 2**i)
    +    stars = ""
    +    for i in range(8):
    +        if diff < 2**i:
    +            stars += "*"
         print(stars)
     
     
    -def get_guess(prompt: str) -> int:
    -    while True:
    -        guess_str = input(prompt)
    -        if guess_str.isdigit():
    -            return int(guess_str)
    +def get_guess():
    +    valid_response = False
    +    while not valid_response:
    +        guess = input("Your guess? ")
    +        if guess.isdigit():
    +            valid_response = True
    +            guess = int(guess)
    +    return(guess)
    +    
     
     
    -def main() -> None:
    -    # Display intro text
    -    print("\n                   Stars")
    -    print("Creative Computing  Morristown, New Jersey")
    -    print("\n\n")
    -    # "*** Stars - People's Computer Center, MenloPark, CA"
    +# Display intro text
    +print("\n                   Stars")
    +print("Creative Computing  Morristown, New Jersey")
    +print("\n\n")
    +# "*** Stars - People's Computer Center, MenloPark, CA"
     
    -    response = input("Do you want instructions? ")
    -    if response.upper()[0] == "Y":
    -        print_instructions()
    +response = input("Do you want instructions? ")
    +if response.upper()[0] == "Y":
    +    print_instructions()
    +          
    +still_playing = True
    +while still_playing:
     
    -    still_playing = True
    -    while still_playing:
    +    # "*** Computer thinks of a number"
    +    secret_number = random.randint(1, MAX_NUM)
    +    print("\n\nOK, I am thinking of a number, start guessing.")
     
    -        # "*** Computer thinks of a number"
    -        secret_number = random.randint(1, MAX_NUM)
    -        print("\n\nOK, I am thinking of a number, start guessing.")
    +    # Init/start guess loop
    +    guess_number = 0
    +    player_has_won = False
    +    while (guess_number < MAX_GUESSES) and not player_has_won:
     
    -        # Init/start guess loop
    -        guess_number = 0
    -        player_has_won = False
    -        while (guess_number < MAX_GUESSES) and not player_has_won:
    +         print("")
    +         guess = get_guess()
    +         guess_number += 1
     
    -            print()
    -            guess = get_guess("Your guess? ")
    -            guess_number += 1
    +         if guess == secret_number:
    +             # "*** We have a winner"
    +             player_has_won = True
    +             print("*************************" +
    +                   "*************************!!!")
    +             print("You got it in %d guesses!!!" % guess_number)
     
    -            if guess == secret_number:
    -                # "*** We have a winner"
    -                player_has_won = True
    -                print("**************************************************!!!")
    -                print(f"You got it in {guess_number} guesses!!!")
    +         else:
    +             print_stars(secret_number, guess)
     
    -            else:
    -                print_stars(secret_number, guess)
    +         # End of guess loop
     
    -            # End of guess loop
    +    # "*** Did not guess in [MAX_GUESS] guesses"
    +    if not player_has_won:
    +        print("\nSorry, that's %d guesses, number was %d" %
    +              (guess_number, secret_number))
     
    -        # "*** Did not guess in [MAX_GUESS] guesses"
    -        if not player_has_won:
    -            print(f"\nSorry, that's {guess_number} guesses, number was {secret_number}")
    +    # Keep playing?
    +    response = input("\nPlay again? ")
    +    if response.upper()[0] != "Y":
    +        still_playing = False
     
    -        # Keep playing?
    -        response = input("\nPlay again? ")
    -        if response.upper()[0] != "Y":
    -            still_playing = False
    -
    -
    -if __name__ == "__main__":
    -    main()
    +    
     
     ######################################################################
     #
    @@ -124,3 +132,10 @@ def main() -> None:
     #       Hard   = 6 guesses, 1 to 200
     #
     ######################################################################
    +
    +
    +            
    +        
    +    
    +
    +    
    diff --git a/82_Stars/ruby/stars.rb b/82_Stars/ruby/stars.rb
    deleted file mode 100644
    index d6b31e8ac..000000000
    --- a/82_Stars/ruby/stars.rb
    +++ /dev/null
    @@ -1,90 +0,0 @@
    -class Stars
    -  MAX_NUM = 100
    -  MAX_GUESSES = 7
    -
    -  def start
    -    print "Do you want instructions? (Y/N) "
    -    response = gets.chomp!
    -
    -    if response.upcase[0] == "Y"
    -      print_instructions()
    -    end
    -
    -    still_playing = true
    -    while still_playing
    -      secret_number = rand(1..MAX_NUM)
    -      puts "\n\nOK, I am thinking of a number, start guessing."
    -
    -      guess_number = 0
    -      player_has_won = false
    -
    -      while (guess_number < MAX_GUESSES) and not player_has_won
    -        puts "\n"
    -        guess = get_guess()
    -        guess_number += 1
    -
    -        if guess == secret_number
    -          player_has_won = true
    -            puts "**************************************************!!!"
    -            puts "You got it in #{guess_number} guesses!!!\n\n"
    -        else
    -          print_stars(secret_number, guess)
    -        end
    -      end
    -
    -      if not player_has_won
    -        puts "\nSorry, that's #{guess_number} guesses, number was #{secret_number}\n"
    -      end
    -
    -      print "Play again? (Y/N) "
    -      response = gets.chomp!
    -
    -      if response.upcase[0] != "Y"
    -        still_playing = false
    -      end
    -      
    -    end
    -  end
    -
    -  private
    -    def print_instructions
    -      puts "I am thinking of a whole number from 1 to #{MAX_NUM}"
    -      puts "Try to guess my number.  After you guess, I"
    -      puts "will type one or more stars (*).  The more"
    -      puts "stars I type, the closer you are to my number."
    -      puts "one star (*) means far away, seven stars (*******)"
    -      puts "means really close!  You get #{MAX_GUESSES} guesses."
    -    end
    -
    -    def get_guess
    -      valid_response = false
    -      while not valid_response
    -        print "Your guess? "
    -        guess = gets.chomp!
    -
    -        if guess.match?(/[[:digit:]]/)
    -          valid_response = true
    -          guess = guess.to_i
    -        end
    -      end
    -
    -      return guess
    -    end
    -
    -    def print_stars secret_number, guess
    -      diff = (guess - secret_number).abs
    -      stars = ""
    -      for i in 0..7
    -        if diff < 2**i
    -          stars += "*"
    -        end
    -      end
    -      print(stars)
    -    end
    -end
    -
    -
    -if __FILE__ == $0
    -  stars = Stars.new
    -  stars.start()
    -end
    \ No newline at end of file
    diff --git a/82_Stars/rust/Cargo.lock b/82_Stars/rust/Cargo.lock
    deleted file mode 100644
    index b13b873bb..000000000
    --- a/82_Stars/rust/Cargo.lock
    +++ /dev/null
    @@ -1,75 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.10"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.147"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "stars"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/82_Stars/rust/Cargo.toml b/82_Stars/rust/Cargo.toml
    deleted file mode 100644
    index 8d4e044ff..000000000
    --- a/82_Stars/rust/Cargo.toml
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -[package]
    -name = "stars"
    -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/82_Stars/rust/README.md b/82_Stars/rust/README.md
    deleted file mode 100644
    index fc6468b9f..000000000
    --- a/82_Stars/rust/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Rust](https://www.rust-lang.org/)
    diff --git a/82_Stars/rust/src/main.rs b/82_Stars/rust/src/main.rs
    deleted file mode 100644
    index 429646b39..000000000
    --- a/82_Stars/rust/src/main.rs
    +++ /dev/null
    @@ -1,85 +0,0 @@
    -use rand::Rng;
    -use std::io;
    -
    -fn main() {
    -    println!(
    -        "{: >39}\n{: >57}\n\n\n",
    -        "STARS", "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY"
    -    );
    -    // STARS - PEOPLE'S COMPUTER CENTER, MENLO PARK, CA
    -    // A IS LIMIT ON NUMBER, M IS NUMBER OF GUESSES
    -    let a: u32 = 101;
    -    let m: u32 = 7;
    -    let mut need_instrut = String::new();
    -
    -    println!("DO YOU WANT INSTRUCTIONS?");
    -    io::stdin()
    -        .read_line(&mut need_instrut)
    -        .expect("Failed to get input");
    -
    -    if need_instrut[..1].to_ascii_lowercase().eq("y") {
    -        println!("I AM THINKING OF A WHOLE NUMBER FROM 1 TO {}", a - 1);
    -        println!("TRY TO GUESS MY NUMBER.  AFTER YOU GUESS, I");
    -        println!("WILL TYPE ONE OR MORE STARS (*).  THE MORE");
    -        println!("STARS I TYPE, THE CLOSER YOU ARE TO MY NUMBER.");
    -        println!("ONE STAR (*) MEANS FAR AWAY, SEVEN STARS (*******)");
    -        println!("MEANS REALLY CLOSE!  YOU GET {} GUESSES.\n\n", m);
    -    }
    -
    -    loop {
    -        println!("\nOK, I AM THINKING OF A NUMBER, START GUESSING.\n");
    -        let rand_number: i32 = rand::thread_rng().gen_range(1..a) as i32; // generates a random number between 1 and 100
    -
    -        // GUESSING BEGINS, HUMAN GETS M GUESSES
    -        for i in 0..m {
    -            let mut guess = String::new();
    -            println!("YOUR GUESS?");
    -            io::stdin()
    -                .read_line(&mut guess)
    -                .expect("Failed to get input");
    -            let guess: i32 = match guess.trim().parse() {
    -                Ok(num) => num,
    -                Err(_) => {
    -                    println!("PLEASE ENTER A NUMBER VALUE.\n");
    -                    continue;
    -                }
    -            };
    -            if guess == rand_number {
    -                print!("");
    -                for _i in 0..50 {
    -                    print!("*");
    -                }
    -                println!("!!!");
    -                println!("YOU GOT IT IN {} GUESSES!!!  LET'S PLAY AGAIN...\n", i + 1);
    -                break;
    -            } else {
    -                match_guess(rand_number - guess);
    -            }
    -
    -            if i == 6 {
    -                println!(
    -                    "SORRY, THAT'S {} GUESSES. THE NUMBER WAS {}",
    -                    m, rand_number
    -                );
    -            }
    -        }
    -    }
    -}
    -
    -fn match_guess(diff: i32) {
    -    if diff.abs() >= 64 {
    -        println!("*\n");
    -    } else if diff.abs() >= 32 {
    -        println!("**\n");
    -    } else if diff.abs() >= 16 {
    -        println!("***\n");
    -    } else if diff.abs() >= 8 {
    -        println!("****\n");
    -    } else if diff.abs() >= 4 {
    -        println!("*****\n");
    -    } else if diff.abs() >= 2 {
    -        println!("******\n");
    -    } else {
    -        println!("*******\n");
    -    }
    -}
    diff --git a/82_Stars/rust_JWB/Cargo.toml b/82_Stars/rust_JWB/Cargo.toml
    deleted file mode 100644
    index b35f5d945..000000000
    --- a/82_Stars/rust_JWB/Cargo.toml
    +++ /dev/null
    @@ -1,17 +0,0 @@
    -[package]
    -<<<<<<< HEAD
    -name = "rust"
    -=======
    -name = "stars"
    ->>>>>>> 3e27c70ca800f5efbe6bc1a7d180211decf55b7d
    -version = "0.1.0"
    -edition = "2021"
    -
    -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
    -
    -[dependencies]
    -<<<<<<< HEAD
    -rand = "0.8.5"
    -=======
    -rand = "0.8.3"
    ->>>>>>> 3e27c70ca800f5efbe6bc1a7d180211decf55b7d
    diff --git a/82_Stars/rust_JWB/README.md b/82_Stars/rust_JWB/README.md
    deleted file mode 100644
    index 06139f036..000000000
    --- a/82_Stars/rust_JWB/README.md
    +++ /dev/null
    @@ -1,29 +0,0 @@
    -<<<<<<< HEAD
    -#STARS
    -
    -From: BASIC Computer Games (1978), edited by David H. Ahl
    -
    -In this game, the computer selects a random number from 1 to 100
    -(or any value you set [for MAX_NUM]).  You try to guess the number
    -and the computer gives you clues to tell you how close you're
    -getting.  One star (*) means you're far away from the number; seven
    -stars (*******) means you're really close.  You get 7  guesses.
    -
    -On the surface this game is very similar to GUESS; however, the
    -guessing strategy is quite different.  See if you can come up with
    -one or more approaches to finding the mystery number.
    -
    -Bob Albrecht of People's Computer Company created this game.
    -
    -## NOTES
    -
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Rust](https://www.rust-lang.org/) by JW Bruce
    -
    -thanks to Jeff Jetton for his Python port which provide inspiration
    -=======
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Rust](https://www.rust-lang.org/)
    ->>>>>>> 3e27c70ca800f5efbe6bc1a7d180211decf55b7d
    diff --git a/82_Stars/rust_JWB/src/main.rs b/82_Stars/rust_JWB/src/main.rs
    deleted file mode 100644
    index 162b8b4f6..000000000
    --- a/82_Stars/rust_JWB/src/main.rs
    +++ /dev/null
    @@ -1,236 +0,0 @@
    -<<<<<<< HEAD
    -//
    -// Stars
    -//
    -// From: BASIC Computer Games (1978), edited by David H. Ahl
    -//
    -// In this game, the computer selects a random number from 1 to 100
    -// (or any value you set [for MAX_NUM]).  You try to guess the number
    -// and the computer gives you clues to tell you how close you're
    -// getting.  One star (*) means you're far away from the number; seven
    -// stars (*******) means you're really close.  You get 7  guesses.
    -//
    -// On the surface this game is very similar to GUESS; however, the
    -// guessing strategy is quite different.  See if you can come up with
    -// one or more approaches to finding the mystery number.
    -//
    -// Bob Albrecht of People's Computer Company created this game.
    -//
    -// rust port by JW BRUCE 2022
    -//
    -// ********************************************************************
    -//
    -// Porting Notes (taken for Jeff Jetton's Python version)
    -//
    -//   The original program never exited--it just kept playing rounds
    -//   over and over.  This version asks to continue each time.
    -//
    -// Ideas for Modifications
    -//
    -//   Let the player know how many guesses they have remaining after
    -//   each incorrect guess.
    -//
    -//   Ask the player to select a skill level at the start of the game,
    -//   which will affect the values of MAX_NUM and MAX_GUESSES.
    -//   For example:
    -//
    -//       Easy   = 8 guesses, 1 to 50
    -//       Medium = 7 guesses, 1 to 100
    -//       Hard   = 6 guesses, 1 to 200
    -//
    -// *********************************************************************
    -
    -// I M P O R T S
    -use std::io;
    -use std::io::stdin;
    -//use std::io::{stdin, stdout, Write};
    -use rand::Rng;
    -
    -const   MAX_NUM: u8 = 100;
    -const   MAX_GUESSES: u8 = 7;
    -
    -fn main() -> io::Result<()> {
    -    print_header();
    -    if !read_lowercase_input()?.starts_with('n') {
    -        print_rules();
    -    }
    -    loop {
    -        let secret_number : u8 = rand::thread_rng().gen_range(1..101);
    -        let mut guess_count = 0;
    -        let mut player_won: bool = false;
    -        
    -        println!("\n\nOK, I am thinking of a number, start guessing.");
    -        while guess_count < MAX_GUESSES && !player_won {
    -            
    -            guess_count += 1;        
    -
    -            println!("Your guess? ");
    -            let mut guess = String::new();
    -            io::stdin()
    -                .read_line(&mut guess)
    -                .expect("Failed to read line");
    -
    -            let guess: u8 = match guess.trim().parse() {
    -                Ok(num) => num,
    -                Err(_) => continue,
    -            };
    -            
    -            // USE THIS STATEMENT FOR DEBUG PURPOSES
    -            // println!("Guess #{} is {}. secret number is {}",guess_count, guess, secret_number);
    -            
    -            if guess == secret_number {
    -                // winner winner chicken dinner
    -                player_won = true;
    -                println!("**************************************************!!!");
    -                println!("You got it in {guess_count} guesses!!!");
    -            } else {
    -                print_stars( guess, secret_number) ;
    -            }      
    -        }
    -        
    -        // player exhausted their number of guesses and did not win.
    -        if !player_won {
    -            println!("Sorry, that's {guess_count} guesses, number was {secret_number}");
    -        }
    -
    -        println!("\nPlay again (yes or no)?");
    -        if !read_lowercase_input()?.starts_with('y') {
    -            return Ok(());
    -=======
    -use rand::Rng;
    -use std::io;
    -
    -fn main() {
    -    println!(
    -        "{: >39}\n{: >57}\n\n\n",
    -        "STARS", "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY"
    -    );
    -    // STARS - PEOPLE'S COMPUTER CENTER, MENLO PARK, CA
    -    // A IS LIMIT ON NUMBER, M IS NUMBER OF GUESSES
    -    let a: u32 = 101;
    -    let m: u32 = 7;
    -    let mut need_instrut = String::new();
    -
    -    println!("DO YOU WANT INSTRUCTIONS?");
    -    io::stdin()
    -        .read_line(&mut need_instrut)
    -        .expect("Failed to get input");
    -
    -    if need_instrut[..1].to_ascii_lowercase().eq("y") {
    -        println!("I AM THINKING OF A WHOLE NUMBER FROM 1 TO {}", a - 1);
    -        println!("TRY TO GUESS MY NUMBER.  AFTER YOU GUESS, I");
    -        println!("WILL TYPE ONE OR MORE STARS (*).  THE MORE");
    -        println!("STARS I TYPE, THE CLOSER YOU ARE TO MY NUMBER.");
    -        println!("ONE STAR (*) MEANS FAR AWAY, SEVEN STARS (*******)");
    -        println!("MEANS REALLY CLOSE!  YOU GET {} GUESSES.\n\n", m);
    -    }
    -
    -    loop {
    -        println!("\nOK, I AM THINKING OF A NUMBER, START GUESSING.\n");
    -        let rand_number: i32 = rand::thread_rng().gen_range(1..a) as i32; // generates a random number between 1 and 100
    -
    -        // GUESSING BEGINS, HUMAN GETS M GUESSES
    -        for i in 0..m {
    -            let mut guess = String::new();
    -            println!("YOUR GUESS?");
    -            io::stdin()
    -                .read_line(&mut guess)
    -                .expect("Failed to get input");
    -            let guess: i32 = match guess.trim().parse() {
    -                Ok(num) => num,
    -                Err(_) => {
    -                    println!("PLEASE ENTER A NUMBER VALUE.\n");
    -                    continue;
    -                }
    -            };
    -            if guess == rand_number {
    -                print!("");
    -                for _i in 0..50 {
    -                    print!("*");
    -                }
    -                println!("!!!");
    -                println!("YOU GOT IT IN {} GUESSES!!!  LET'S PLAY AGAIN...\n", i + 1);
    -                break;
    -            } else {
    -                match_guess(rand_number - guess);
    -            }
    -
    -            if i == 6 {
    -                println!(
    -                    "SORRY, THAT'S {} GUESSES. THE NUMBER WAS {}",
    -                    m, rand_number
    -                );
    -            }
    ->>>>>>> 3e27c70ca800f5efbe6bc1a7d180211decf55b7d
    -        }
    -    }
    -}
    -
    -<<<<<<< HEAD
    -// guess is wrong, so print stars to show how far away they are
    -fn print_stars( guess: u8, target: u8) {
    -    // choose to use u8 in main, but currently (1.59.0) does not
    -    //   have abs() defined for u8.  abs() is defined for i16, so
    -    //   this provide an opportunity to demonstrate casting in rust
    -    let diff : i16 = ((guess as i16)-(target as i16)).abs();
    -    
    -    // Since we only print 1-7 stars, this finite set of choices is
    -    //   small enough that we can use rust's match keyword.
    -    // The match "arms" here use the inclusive range notation.
    -    //   The exlusive range notation is not an approved feature of
    -    //   rust, yet.
    -    match diff {
    -        1..=2 => println!("*******"),
    -        3..=4 => println!("******"),
    -        5..=8 => println!("*****"),
    -        9..=16 => println!("****"),
    -        17..=32 => println!("***"),
    -        33..=64 => println!("**"),
    -        _ => println!("*"),
    -    }
    -}
    -
    -//
    -fn read_lowercase_input() -> io::Result {
    -    let mut input = String::new();
    -    stdin().read_line(&mut input)?;
    -    Ok(input.trim().to_lowercase())
    -}
    -
    -// Text to print at the start of the game
    -fn print_header() {
    -    println!("\n                   Stars");
    -    println!("Creative-Computing  Morristown, New Jersey");
    -    println!("\n\n");
    -    println!("Do you want instructions? ");
    -}
    -
    -// Instructions on how to play
    -fn print_rules() {
    -    println!();
    -    println!("I am thinking of a whole number from 1 to {}", MAX_NUM);
    -    println!("Try to guess my number.  After you guess, I");
    -    println!("will type one or more stars (*).  The more");
    -    println!("stars I type, the closer you are to my number.");
    -    println!("one star (*) means far away, seven stars (*******)");
    -    println!("means really close!  You get {} guesses.", MAX_GUESSES);
    -}
    -=======
    -fn match_guess(diff: i32) {
    -    if diff.abs() >= 64 {
    -        println!("*\n");
    -    } else if diff.abs() >= 32 {
    -        println!("**\n");
    -    } else if diff.abs() >= 16 {
    -        println!("***\n");
    -    } else if diff.abs() >= 8 {
    -        println!("****\n");
    -    } else if diff.abs() >= 4 {
    -        println!("*****\n");
    -    } else if diff.abs() >= 2 {
    -        println!("******\n");
    -    } else {
    -        println!("*******\n");
    -    }
    -}
    ->>>>>>> 3e27c70ca800f5efbe6bc1a7d180211decf55b7d
    diff --git a/82_Stars/stars.bas b/82_Stars/stars.bas
    index 0536ed3a7..3290cbbd4 100644
    --- a/82_Stars/stars.bas
    +++ b/82_Stars/stars.bas
    @@ -41,7 +41,7 @@
     520 PRINT
     530 NEXT K
     540 REM *** DID NOT GUESS IN M GUESSES
    -550 PRINT
    +550 PRINT 
     560 PRINT "SORRY, THAT'S";M;"GUESSES. THE NUMBER WAS";X
     580 GOTO 650
     590 REM *** WE HAVE A WINNER
    diff --git a/82_Stars/vbnet/Stars.sln b/82_Stars/vbnet/Stars.sln
    deleted file mode 100644
    index edb5e587c..000000000
    --- a/82_Stars/vbnet/Stars.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index caad7d6eb..000000000
    --- a/82_Stars/vbnet/Stars.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Stars
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/83_Stock_Market/README.md b/83_Stock_Market/README.md
    index 6136b94b6..65447e1f8 100644
    --- a/83_Stock_Market/README.md
    +++ b/83_Stock_Market/README.md
    @@ -14,7 +14,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/83_Stock_Market/csharp/StockMarket.csproj b/83_Stock_Market/csharp/Game.csproj
    similarity index 100%
    rename from 83_Stock_Market/csharp/StockMarket.csproj
    rename to 83_Stock_Market/csharp/Game.csproj
    diff --git a/83_Stock_Market/csharp/StockMarket.sln b/83_Stock_Market/csharp/StockMarket.sln
    index ab159a5b8..5bfb67aa0 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 17
    -VisualStudioVersion = 17.0.32014.148
    +# Visual Studio Version 16
    +VisualStudioVersion = 16.0.31321.278
     MinimumVisualStudioVersion = 10.0.40219.1
    -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StockMarket", "StockMarket.csproj", "{B4C15C31-EB2D-4AAF-8380-5F2EBC0DD9D0}"
    +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Game", "Game.csproj", "{BADD262D-D540-431F-8803-2A6F80C22033}"
     EndProject
     Global
     	GlobalSection(SolutionConfigurationPlatforms) = preSolution
    @@ -11,10 +11,10 @@ Global
     		Release|Any CPU = Release|Any CPU
     	EndGlobalSection
     	GlobalSection(ProjectConfigurationPlatforms) = postSolution
    -		{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
    +		{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
     	EndGlobalSection
     	GlobalSection(SolutionProperties) = preSolution
     		HideSolutionNode = FALSE
    diff --git a/83_Stock_Market/csharp/Assets.cs b/83_Stock_Market/csharp/src/Assets.cs
    similarity index 100%
    rename from 83_Stock_Market/csharp/Assets.cs
    rename to 83_Stock_Market/csharp/src/Assets.cs
    diff --git a/83_Stock_Market/csharp/Broker.cs b/83_Stock_Market/csharp/src/Broker.cs
    similarity index 100%
    rename from 83_Stock_Market/csharp/Broker.cs
    rename to 83_Stock_Market/csharp/src/Broker.cs
    diff --git a/83_Stock_Market/csharp/Company.cs b/83_Stock_Market/csharp/src/Company.cs
    similarity index 100%
    rename from 83_Stock_Market/csharp/Company.cs
    rename to 83_Stock_Market/csharp/src/Company.cs
    diff --git a/83_Stock_Market/csharp/Controller.cs b/83_Stock_Market/csharp/src/Controller.cs
    similarity index 100%
    rename from 83_Stock_Market/csharp/Controller.cs
    rename to 83_Stock_Market/csharp/src/Controller.cs
    diff --git a/83_Stock_Market/csharp/Extensions/EnumerableExtensions.cs b/83_Stock_Market/csharp/src/Extensions/EnumerableExtensions.cs
    similarity index 100%
    rename from 83_Stock_Market/csharp/Extensions/EnumerableExtensions.cs
    rename to 83_Stock_Market/csharp/src/Extensions/EnumerableExtensions.cs
    diff --git a/83_Stock_Market/csharp/Extensions/ImmutableArrayExtensions.cs b/83_Stock_Market/csharp/src/Extensions/ImmutableArrayExtensions.cs
    similarity index 100%
    rename from 83_Stock_Market/csharp/Extensions/ImmutableArrayExtensions.cs
    rename to 83_Stock_Market/csharp/src/Extensions/ImmutableArrayExtensions.cs
    diff --git a/83_Stock_Market/csharp/Extensions/RandomExtensions.cs b/83_Stock_Market/csharp/src/Extensions/RandomExtensions.cs
    similarity index 100%
    rename from 83_Stock_Market/csharp/Extensions/RandomExtensions.cs
    rename to 83_Stock_Market/csharp/src/Extensions/RandomExtensions.cs
    diff --git a/83_Stock_Market/csharp/Program.cs b/83_Stock_Market/csharp/src/Program.cs
    similarity index 100%
    rename from 83_Stock_Market/csharp/Program.cs
    rename to 83_Stock_Market/csharp/src/Program.cs
    diff --git a/83_Stock_Market/csharp/StockMarket.cs b/83_Stock_Market/csharp/src/StockMarket.cs
    similarity index 100%
    rename from 83_Stock_Market/csharp/StockMarket.cs
    rename to 83_Stock_Market/csharp/src/StockMarket.cs
    diff --git a/83_Stock_Market/csharp/TradingDay.cs b/83_Stock_Market/csharp/src/TradingDay.cs
    similarity index 100%
    rename from 83_Stock_Market/csharp/TradingDay.cs
    rename to 83_Stock_Market/csharp/src/TradingDay.cs
    diff --git a/83_Stock_Market/csharp/TransactionResult.cs b/83_Stock_Market/csharp/src/TransactionResult.cs
    similarity index 100%
    rename from 83_Stock_Market/csharp/TransactionResult.cs
    rename to 83_Stock_Market/csharp/src/TransactionResult.cs
    diff --git a/83_Stock_Market/csharp/View.cs b/83_Stock_Market/csharp/src/View.cs
    similarity index 100%
    rename from 83_Stock_Market/csharp/View.cs
    rename to 83_Stock_Market/csharp/src/View.cs
    diff --git a/83_Stock_Market/java/StockMarket.java b/83_Stock_Market/java/StockMarket.java
    deleted file mode 100644
    index 3eb883e91..000000000
    --- a/83_Stock_Market/java/StockMarket.java
    +++ /dev/null
    @@ -1,426 +0,0 @@
    -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 +
    -					'}';
    -		}
    -	}
    -
    -}
    diff --git a/83_Stock_Market/javascript/stockmarket.html b/83_Stock_Market/javascript/stockmarket.html
    index faea6939e..6a6188ef5 100644
    --- a/83_Stock_Market/javascript/stockmarket.html
    +++ b/83_Stock_Market/javascript/stockmarket.html
    @@ -1,10 +1,9 @@
     
     
     STOCKMARKET
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/83_Stock_Market/javascript/stockmarket.js b/83_Stock_Market/javascript/stockmarket.js
    index 69af32f92..fbcbd8a5b 100644
    --- a/83_Stock_Market/javascript/stockmarket.js
    +++ b/83_Stock_Market/javascript/stockmarket.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/83_Stock_Market/kotlin/README.md b/83_Stock_Market/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/83_Stock_Market/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/83_Stock_Market/lua/README.md b/83_Stock_Market/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/83_Stock_Market/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/83_Stock_Market/pascal/README.md b/83_Stock_Market/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/83_Stock_Market/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/83_Stock_Market/python/Stock_Market.py b/83_Stock_Market/python/Stock_Market.py
    index 6ad3f8d1a..98386cc1a 100644
    --- a/83_Stock_Market/python/Stock_Market.py
    +++ b/83_Stock_Market/python/Stock_Market.py
    @@ -1,159 +1,153 @@
     import random
    -from typing import Any, Dict, List
    -
    -
    -class Stock_Market:
    -    def __init__(self) -> None:
    -        # Hard Coded Names
    -        short_names = ["IBM", "RCA", "LBJ", "ABC", "CBS"]
    -        full_names = [
    -            "INT. BALLISTIC MISSLES",
    -            "RED CROSS OF AMERICA",
    -            "LICHTENSTEIN, BUMRAP & JOKE",
    -            "AMERICAN BANKRUPT CO.",
    -            "CENSURED BOOKS STORE",
    -        ]
    -
    -        # Initializing Dictionary to hold all the information systematically
    -        self.data: Dict[str, Any] = {}
    -        for sn, fn in zip(short_names, full_names):
    -            # A dictionary for each stock
    -            temp = {"Name": fn, "Price": None, "Holdings": 0}
    -            # Nested outer dictionary for all stocks
    -            self.data[sn] = temp
    -
    -        # Initializing Randomly generated initial prices
    -        for stock in self.data.values():
    -            stock["Price"] = round(random.uniform(80, 120), 2)  # Price b/w 60 and 120
    -
    -        # Initialize Assets
    -        self.cash_assets = 10000
    -        self.stock_assets = 0
    -
    -    def total_assets(self) -> float:
    -        return self.cash_assets + self.stock_assets
    -
    -    def _generate_day_change(self) -> None:
    -        self.changes: List[float] = []
    -        self.changes.extend(
    -            round(random.uniform(-5, 5), 2) for _ in range(len(self.data))
    -        )
    -
    -    def update_prices(self) -> None:
    -        self._generate_day_change()
    -        for stock, change in zip(self.data.values(), self.changes):
    -            stock["Price"] = round(stock["Price"] + (change / 100) * stock["Price"], 2)
    -
    -    def print_exchange_average(self) -> None:
    -
    -        sum = 0
    -        for stock in self.data.values():
    -            sum += stock["Price"]
    -
    -        print(f"\nNEW YORK STOCK EXCHANGE AVERAGE: ${sum / 5:.2f}")
    -
    -    def get_average_change(self) -> float:
    -        sum: float = 0
    -        for change in self.changes:
    -            sum += change
    -
    -        return round(sum / 5, 2)
    -
    -    def print_first_day(self) -> None:
    -
    -        print("\nSTOCK\t\t\t\t\tINITIALS\tPRICE/SHARE($)")
    -        for stock, data in self.data.items():
    -            if stock != "LBJ":
    -                print(f'{data["Name"]}\t\t\t{stock}\t\t{data["Price"]}')
    -            else:
    -                print(f'{data["Name"]}\t\t{stock}\t\t{data["Price"]}')
    -
    -        self.print_exchange_average()
    -        self.print_assets()
    -
    -    def take_inputs(self) -> List[str]:
    -        print("\nWHAT IS YOUR TRANSACTION IN")
    -        flag = False
    -        while not flag:
    -            new_holdings = []
    -            for stock in self.data.keys():
    -                try:
    -                    new_holdings.append(int(input(f"{stock}? ")))
    -                except Exception:
    -                    print("\nINVALID ENTRY, TRY AGAIN\n")
    -                    break
    -            if len(new_holdings) == 5:
    -                flag = self._check_transaction(new_holdings)
    -
    -        return new_holdings  # type: ignore
    -
    -    def print_trading_day(self) -> None:
    -
    -        print("STOCK\tPRICE/SHARE\tHOLDINGS\tNET. Value\tPRICE CHANGE")
    -        for stock, data, change in zip(
    -            self.data.keys(), self.data.values(), self.changes
    -        ):
    -            value = data["Price"] * data["Holdings"]
    -            print(
    -                "{}\t{}\t\t{}\t\t{:.2f}\t\t{}".format(
    -                    stock, data["Price"], data["Holdings"], value, change
    -                )
    -            )
    -
    -    def update_cash_assets(self, new_holdings) -> None:
    -        sell = 0
    -        buy = 0
    -        for stock, holding in zip(self.data.values(), new_holdings):
    -            if holding > 0:
    -                buy += stock["Price"] * holding
    -
    -            elif holding < 0:
    -                sell += stock["Price"] * abs(holding)
    -
    -        self.cash_assets = self.cash_assets + sell - buy
    -
    -    def update_stock_assets(self) -> None:
    -        sum = 0
    -        for data in self.data.values():
    -            sum += data["Price"] * data["Holdings"]
    -
    -        self.stock_assets = round(sum, 2)
    -
    -    def print_assets(self) -> None:
    -        print(f"\nTOTAL STOCK ASSETS ARE: ${self.stock_assets:.2f}")
    -        print(f"TOTAL CASH ASSETS ARE: ${self.cash_assets:.2f}")
    -        print(f"TOTAL ASSETS ARE: ${self.total_assets():.2f}")
    -
    -    def _check_transaction(self, new_holdings) -> bool:
    -        sum = 0
    -        for stock, holding in zip(self.data.values(), new_holdings):
    -            if holding > 0:
    -                sum += stock["Price"] * holding
    -
    -            elif holding < 0:
    -                if abs(holding) > stock["Holdings"]:
    -                    print("\nYOU HAVE OVERSOLD SOME STOCKS, TRY AGAIN\n")
    -                    return False
    -
    -        if sum > self.cash_assets:
    -            print(
    -                "\nYOU HAVE USED ${:.2f} MORE THAN YOU HAVE, TRY AGAIN\n".format(
    -                    sum - self.cash_assets
    -                )
    -            )
    -            return False
    -
    -        return True
    -
    -    def update_holdings(self, new_holdings) -> None:
    -        for stock, new_holding in zip(self.data.values(), new_holdings):
    -            stock["Holdings"] += new_holding
    -
    -
    -def print_instruction() -> None:
    -
    -    print(
    -        """
    +
    +#Stock_Market
    +class Stock_Market():
    +
    +  def __init__(self):
    +
    +    #Hard Coded Names
    +    short_names = ['IBM', 'RCA', 'LBJ', 'ABC', 'CBS']
    +    full_names = ['INT. BALLISTIC MISSLES', 'RED CROSS OF AMERICA', 
    +                  'LICHTENSTEIN, BUMRAP & JOKE', 'AMERICAN BANKRUPT CO.',
    +                  'CENSURED BOOKS STORE']
    +
    +    #Initializing Dictionary to hold all the information systematically
    +    self.data = {}
    +    for sn, fn in zip(short_names, full_names):
    +      #A dictionary for each stock
    +      temp = {'Name' : fn, 'Price' : None, 'Holdings' : 0}
    +      #Nested outer dictionary for all stocks
    +      self.data[sn] = temp
    +
    +    #Initializing Randomly generated initial prices
    +    for stock in self.data.values():
    +      stock['Price'] = round(random.uniform(80,120),2) #Price b/w 60 and 120
    +
    +    #Initialize Assets
    +    self.cash_assets = 10000
    +    self.stock_assets = 0
    +    
    +  def total_assets(self):
    +    
    +    return self.cash_assets + self.stock_assets
    +
    +  def _generate_day_change(self):
    +
    +    self.changes = []
    +    for _ in range(len(self.data)):
    +      self.changes.append(round(random.uniform(-5,5),2)) #Random % Change b/w -5 and 5
    +
    +  def update_prices(self):
    +
    +    self._generate_day_change()
    +    for stock, change in zip(self.data.values(), self.changes):
    +      stock['Price'] = round(stock['Price'] + (change/100)*stock['Price'], 2)
    +
    +  def print_exchange_average(self):
    +    
    +    sum = 0
    +    for stock in self.data.values():
    +      sum += stock['Price']
    +
    +    print('\nNEW YORK STOCK EXCHANGE AVERAGE: ${:.2f}'.format(sum/5))
    +
    +  def get_average_change(self):
    +
    +    sum = 0
    +    for change in self.changes:
    +      sum += change
    +    
    +    return round(sum/5,2)
    +
    +  def print_first_day(self):
    +
    +    print('\nSTOCK\t\t\t\t\tINITIALS\tPRICE/SHARE($)')
    +    for stock, data in self.data.items():
    +      if stock != 'LBJ':
    +        print('{}\t\t\t{}\t\t{}'.format(data['Name'], stock, data['Price']))
    +      else:
    +        print('{}\t\t{}\t\t{}'.format(data['Name'], stock, data['Price']))
    +
    +    self.print_exchange_average()
    +    self.print_assets()
    +
    +  def take_inputs(self):
    +
    +    print('\nWHAT IS YOUR TRANSACTION IN')
    +    flag = False
    +    while flag != True:
    +      new_holdings = []
    +      for stock in self.data.keys():
    +        try:
    +          new_holdings.append(int(input('{}? '.format(stock))))
    +        except:
    +          print('\nINVALID ENTRY, TRY AGAIN\n')
    +          break
    +      if len(new_holdings) == 5:
    +        flag = self._check_transaction(new_holdings)
    +      
    +    return new_holdings
    +
    +  def print_trading_day(self):
    +
    +    print("STOCK\tPRICE/SHARE\tHOLDINGS\tNET. Value\tPRICE CHANGE")
    +    for stock, data, change in zip(self.data.keys(), self.data.values(),self.changes):
    +      value = data['Price'] * data['Holdings']
    +      print('{}\t{}\t\t{}\t\t{:.2f}\t\t{}'.format(stock, data['Price'], data['Holdings'], value, change))
    +
    +  def update_cash_assets(self, new_holdings):
    +
    +    sell=0
    +    buy=0
    +    for stock, holding in zip(self.data.values(), new_holdings):
    +      if holding > 0:
    +        buy += stock['Price']*holding
    +      
    +      elif holding < 0:
    +        sell += stock['Price']*abs(holding)
    +
    +    self.cash_assets = self.cash_assets + sell - buy
    +
    +  def update_stock_assets(self):
    +
    +    sum=0
    +    for data in self.data.values():
    +      sum += data['Price']*data['Holdings']
    +
    +    self.stock_assets = round(sum,2)
    +
    +  def print_assets(self):
    +
    +    print('\nTOTAL STOCK ASSETS ARE: ${:.2f}'.format(self.stock_assets))
    +    print('TOTAL CASH ASSETS ARE: ${:.2f}'.format(self.cash_assets))
    +    print('TOTAL ASSETS ARE: ${:.2f}'.format(self.total_assets()))
    +
    +  def _check_transaction(self, new_holdings):
    +
    +    sum = 0
    +    for stock, holding in zip(self.data.values(), new_holdings):
    +      if holding > 0:
    +        sum += stock['Price']*holding
    +      
    +      elif holding < 0:
    +        if abs(holding) > stock['Holdings']:
    +          print('\nYOU HAVE OVERSOLD SOME STOCKS, TRY AGAIN\n')
    +          return False
    +
    +    if sum > self.cash_assets:
    +      print('\nYOU HAVE USED ${:.2f} MORE THAN YOU HAVE, TRY AGAIN\n'.format(sum - self.cash_assets))
    +      return False
    +
    +    return True
    +
    +  def update_holdings(self, new_holdings):
    +
    +    for stock, new_holding in zip(self.data.values(), new_holdings):
    +      stock['Holdings'] += new_holding
    +
    +def print_instruction():
    +
    +  print('''
     THIS PROGRAM PLAYS THE STOCK MARKET.  YOU WILL BE GIVEN
     $10,000 AND MAY BUY OR SELL STOCKS.  THE STOCK PRICES WILL
     BE GENERATED RANDOMLY AND THEREFORE THIS MODEL DOES NOT
    @@ -170,50 +164,45 @@ def print_instruction() -> None:
     (NOTE:  TO GET A 'FEEL' FOR THE MARKET RUN FOR AT LEAST
     10 DAYS)
               ------------GOOD LUCK!------------\n
    -    """
    -    )
    -
    -
    -def main() -> None:
    -    print("\t\t      STOCK MARKET")
    -    help = input("\nDO YOU WANT INSTRUCTIONS(YES OR NO)? ")
    -
    -    # Printing Instruction
    -    if help.lower() == "yes":
    -        print_instruction()
    -
    -    # Initialize Game
    -    Game = Stock_Market()
    -
    -    # Do first day
    -    Game.print_first_day()
    +    ''')
    +  
    +if __name__ == "__main__":
    +  
    +  print('\t\t      STOCK MARKET')
    +  help = input('\nDO YOU WANT INSTRUCTIONS(YES OR NO)? ')
    +
    +  #Printing Instruction
    +  if help == 'YES' or help == 'yes' or help == 'Yes':
    +    print_instruction()
    +  
    +  #Initialize Game
    +  Game = Stock_Market()
    +
    +  #Do first day
    +  Game.print_first_day()
    +  new_holdings = Game.take_inputs()
    +  Game.update_holdings(new_holdings)
    +  Game.update_cash_assets(new_holdings)
    +  print('\n------------END OF TRADING DAY--------------\n')
    +
    +  response = 1
    +  while response == 1:
    +
    +    #Simulate a DAY
    +    Game.update_prices()
    +    Game.print_trading_day()
    +    Game.print_exchange_average()
    +    Game.update_stock_assets()
    +    Game.print_assets()
    +
    +    response = int(input('\nDO YOU WISH TO CONTINUE (YES-TYPE 1, NO-TYPE 0)? '))
    +    if response == 0:
    +      break
    +    
         new_holdings = Game.take_inputs()
         Game.update_holdings(new_holdings)
         Game.update_cash_assets(new_holdings)
    -    print("\n------------END OF TRADING DAY--------------\n")
    -
    -    response = 1
    -    while response == 1:
    -
    -        # Simulate a DAY
    -        Game.update_prices()
    -        Game.print_trading_day()
    -        Game.print_exchange_average()
    -        Game.update_stock_assets()
    -        Game.print_assets()
    -
    -        response = int(input("\nDO YOU WISH TO CONTINUE (YES-TYPE 1, NO-TYPE 0)? "))
    -        if response == 0:
    -            break
    +    print('\n------------END OF TRADING DAY--------------\n')
     
    -        new_holdings = Game.take_inputs()
    -        Game.update_holdings(new_holdings)
    -        Game.update_cash_assets(new_holdings)
    -        print("\n------------END OF TRADING DAY--------------\n")
    -
    -    print("\nHOPE YOU HAD FUN!!!!")
    -    input()
    -
    -
    -if __name__ == "__main__":
    -    main()
    +  print('\nHOPE YOU HAD FUN!!!!')
    +  input('')
    diff --git a/83_Stock_Market/stockmarket.bas b/83_Stock_Market/stockmarket.bas
    index 402b6360b..5d81e62f7 100644
    --- a/83_Stock_Market/stockmarket.bas
    +++ b/83_Stock_Market/stockmarket.bas
    @@ -2,107 +2,107 @@
     20 PRINT TAB(15);"CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY"
     30 PRINT: PRINT: PRINT
     100 REM STOCK MARKET SIMULATION     -STOCK-
    -101 REM REVISED 8/18/70 (D. PESSEL, L. BRAUN, C. LOSIK)
    -102 REM IMP VRBLS: A-MRKT TRND SLP; B5-BRKRGE FEE; C-TTL CSH ASSTS;
    +101 REM REVISED 8/18/70 (D. PESSEL, L. BRAUN, C. LOSIK)  
    +102 REM IMP VRBLS: A-MRKT TRND SLP; B5-BRKRGE FEE; C-TTL CSH ASSTS;    
     103 REM C5-TTL CSH ASSTS (TEMP); C(I)-CHNG IN STK VAL; D-TTL ASSTS;
    -104 REM E1,E2-LRG CHNG MISC; I-STCK #; I1,I2-STCKS W LRG CHNG;
    +104 REM E1,E2-LRG CHNG MISC; I-STCK #; I1,I2-STCKS W LRG CHNG; 
     105 REM N1,N2-LRG CHNG DAY CNTS; P5-TTL DAYS PRCHSS; P(I)-PRTFL CNTNTS;
    -106 REM Q9-NEW CYCL?; S4-SGN OF A; S5-TTL DYS SLS; S(I)-VALUE/SHR;
    +106 REM Q9-NEW CYCL?; S4-SGN OF A; S5-TTL DYS SLS; S(I)-VALUE/SHR; 
     107 REM T-TTL STCK ASSTS; T5-TTL VAL OF TRNSCTNS;
     108 REM W3-LRG CHNG; X1-SMLL CHNG(<$1); Z4,Z5,Z6-NYSE AVE.; Z(I)-TRNSCT
    -110 DIM S(5),P(5),Z(5),C(5)
    -112 REM SLOPE OF MARKET TREND:A  (SAME FOR ALL STOCKS)
    +110 DIM S(5),P(5),Z(5),C(5) 
    +112 REM SLOPE OF MARKET TREND:A  (SAME FOR ALL STOCKS) 
     113 LET X=1
    -114 LET A=INT((RND(X)/10)*100+.5)/100
    +114 LET A=INT((RND(X)/10)*100+.5)/100 
     115 LET T5=0
     116 LET X9=0
     117 LET N1=0
     118 LET N2=0
     119 LET E1=0
     120 LET E2=0
    -121 REM INTRODUCTION
    -122 PRINT "DO YOU WANT THE INSTRUCTIONS (YES-TYPE 1, NO-TYPE 0)";
    +121 REM INTRODUCTION 
    +122 PRINT "DO YOU WANT THE INSTRUCTIONS (YES-TYPE 1, NO-TYPE 0)"; 
     123 INPUT Z9
    -124 PRINT
    -125 PRINT
    +124 PRINT 
    +125 PRINT 
     126 IF Z9<1 THEN 200
    -130 PRINT "THIS PROGRAM PLAYS THE STOCK MARKET.  YOU WILL BE GIVEN"
    +130 PRINT "THIS PROGRAM PLAYS THE STOCK MARKET.  YOU WILL BE GIVEN" 
     132 PRINT "$10,000 AND MAY BUY OR SELL STOCKS.  THE STOCK PRICES WILL"
    -134 PRINT "BE GENERATED RANDOMLY AND THEREFORE THIS MODEL DOES NOT"
    +134 PRINT "BE GENERATED RANDOMLY AND THEREFORE THIS MODEL DOES NOT" 
     135 PRINT "REPRESENT EXACTLY WHAT HAPPENS ON THE EXCHANGE.  A TABLE"
     136 PRINT "OF AVAILABLE STOCKS, THEIR PRICES, AND THE NUMBER OF SHARES"
    -137 PRINT "IN YOUR PORTFOLIO WILL BE PRINTED.  FOLLOWING THIS, THE"
    +137 PRINT "IN YOUR PORTFOLIO WILL BE PRINTED.  FOLLOWING THIS, THE" 
     138 PRINT "INITIALS OF EACH STOCK WILL BE PRINTED WITH A QUESTION"
    -139 PRINT "MARK.  HERE YOU INDICATE A TRANSACTION.  TO BUY A STOCK"
    -140 PRINT "TYPE +NNN, TO SELL A STOCK TYPE -NNN, WHERE NNN IS THE"
    +139 PRINT "MARK.  HERE YOU INDICATE A TRANSACTION.  TO BUY A STOCK" 
    +140 PRINT "TYPE +NNN, TO SELL A STOCK TYPE -NNN, WHERE NNN IS THE"  
     141 PRINT "NUMBER OF SHARES.  A BROKERAGE FEE OF 1% WILL BE CHARGED"
     142 PRINT "ON ALL TRANSACTIONS.  NOTE THAT IF A STOCK'S VALUE DROPS"
     143 PRINT "TO ZERO IT MAY REBOUND TO A POSITIVE VALUE AGAIN.  YOU"
     144 PRINT "HAVE $10,000 TO INVEST.  USE INTEGERS FOR ALL YOUR INPUTS."
    -145 PRINT "(NOTE:  TO GET A 'FEEL' FOR THE MARKET RUN FOR AT LEAST"
    +145 PRINT "(NOTE:  TO GET A 'FEEL' FOR THE MARKET RUN FOR AT LEAST" 
     146 PRINT "10 DAYS)"
     147 PRINT "-----GOOD LUCK!-----"
    -200 REM GENERATION OF STOCK TABLE; INPUT REQUESTS
    -210 REM INITIAL STOCK VALUES
    +200 REM GENERATION OF STOCK TABLE; INPUT REQUESTS  
    +210 REM INITIAL STOCK VALUES 
     220 LET S(1)=100
    -230 LET S(2)=85
    +230 LET S(2)=85 
     240 LET S(3)=150
     250 LET S(4)=140
     260 LET S(5)=110
     265 REM INITIAL T8 - # DAYS FOR FIRST TREND SLOPE (A)
    -266 LET T8=INT(4.99*RND(X)+1)
    +266 LET T8=INT(4.99*RND(X)+1) 
     267 REM RANDOMIZE SIGN OF FIRST TREND SLOPE (A)
    -268 IF RND(X)>.5 THEN 270
    +268 IF RND(X)>.5 THEN 270 
     269 LET A=-A
    -270 REM RANDOMIZE INITIAL VALUES
    -280 GOSUB 830
    -285 REM INITIAL PORTFOLIO CONTENTS
    +270 REM RANDOMIZE INITIAL VALUES 
    +280 GOSUB 830 
    +285 REM INITIAL PORTFOLIO CONTENTS 
     290 FOR I=1 TO 5
     300 LET P(I)=0
     305 LET Z(I)=0
     310 NEXT I
    -320 PRINT
    -330 PRINT
    -333 REM INITIALIZE CASH ASSETS:C
    -335 LET C=10000
    +320 PRINT 
    +330 PRINT 
    +333 REM INITIALIZE CASH ASSETS:C 
    +335 LET C=10000 
     338 REM PRINT INITIAL PORTFOLIO
     340 PRINT "STOCK"," ","INITIALS","PRICE/SHARE"
     350 PRINT "INT. BALLISTIC MISSILES","  IBM",S(1)
    -352 PRINT "RED CROSS OF AMERICA","  RCA",S(2)
    +352 PRINT "RED CROSS OF AMERICA","  RCA",S(2) 
     354 PRINT "LICHTENSTEIN, BUMRAP & JOKE","  LBJ",S(3)
     356 PRINT "AMERICAN BANKRUPT CO.","  ABC",S(4)
    -358 PRINT "CENSURED BOOKS STORE","  CBS",S(5)
    -360 PRINT
    -361 REM NYSE AVERAGE:Z5; TEMP. VALUE:Z4; NET CHANGE:Z6
    -363 LET Z4=Z5
    +358 PRINT "CENSURED BOOKS STORE","  CBS",S(5) 
    +360 PRINT 
    +361 REM NYSE AVERAGE:Z5; TEMP. VALUE:Z4; NET CHANGE:Z6 
    +363 LET Z4=Z5 
     364 LET Z5=0
    -365 LET T=0
    +365 LET T=0 
     370 FOR I=1 TO 5
     375 LET Z5=Z5+S(I)
    -380 LET T=T+S(I)*P(I)
    +380 LET T=T+S(I)*P(I) 
     390 NEXT I
    -391 LET Z5=INT(100*(Z5/5)+.5)/100
    +391 LET Z5=INT(100*(Z5/5)+.5)/100 
     392 LET Z6=INT((Z5-Z4)*100+.5)/100
    -393 REM TOTAL ASSETS:D
    -394 LET D=T+C
    +393 REM TOTAL ASSETS:D 
    +394 LET D=T+C 
     395 IF X9>0 THEN 398
    -396 PRINT "NEW YORK STOCK EXCHANGE AVERAGE: "Z5
    -397 GOTO 399
    +396 PRINT "NEW YORK STOCK EXCHANGE AVERAGE: "Z5 
    +397 GOTO 399 
     398 PRINT "NEW YORK STOCK EXCHANGE AVERAGE: "Z5"NET CHANGE"Z6
    -399 PRINT
    -400 LET T=INT(100*T+.5)/100
    +399 PRINT 
    +400 LET T=INT(100*T+.5)/100 
     401 PRINT "TOTAL STOCK ASSETS ARE   $";T
    -403 LET C=INT(100*C+.5)/100
    +403 LET C=INT(100*C+.5)/100 
     405 PRINT "TOTAL CASH ASSETS ARE    $";C
    -407 LET D=INT(100*D+.5)/100
    +407 LET D=INT(100*D+.5)/100 
     408 PRINT "TOTAL ASSETS ARE         $";D
    -410 PRINT
    +410 PRINT 
     411 IF X9=0 THEN 416
     412 PRINT "DO YOU WISH TO CONTINUE (YES-TYPE 1, NO-TYPE 0)";
     413 INPUT Q9
     414 IF Q9<1 THEN 998
    -416 REM INPUT TRANSACTIONS
    -420 PRINT "WHAT IS YOUR TRANSACTION IN"
    +416 REM INPUT TRANSACTIONS 
    +420 PRINT "WHAT IS YOUR TRANSACTION IN" 
     430 PRINT "IBM";
     440 INPUT Z(1)
     450 PRINT "RCA";
    @@ -113,44 +113,44 @@
     500 INPUT Z(4)
     510 PRINT "CBS";
     520 INPUT Z(5)
    -525 PRINT
    +525 PRINT 
     530 REM TOTAL DAY'S PURCHASES IN $:P5
     540 LET P5=0
     550 REM TOTAL DAY'S SALES IN $:S5
     560 LET S5=0
     570 FOR I=1 TO 5
    -575 LET Z(I)=INT(Z(I)+.5)
    -580 IF Z(I)<=0 THEN 610
    -590 LET P5=P5+Z(I)*S(I)
    -600 GOTO 620
    -610 LET S5=S5-Z(I)*S(I)
    -612 IF -Z(I)<=P(I) THEN 620
    -614 PRINT "YOU HAVE OVERSOLD A STOCK; TRY AGAIN."
    -616 GOTO 420
    +575 LET Z(I)=INT(Z(I)+.5) 
    +580 IF Z(I)<=0 THEN 610 
    +590 LET P5=P5+Z(I)*S(I) 
    +600 GOTO 620 
    +610 LET S5=S5-Z(I)*S(I) 
    +612 IF -Z(I)<=P(I) THEN 620 
    +614 PRINT "YOU HAVE OVERSOLD A STOCK; TRY AGAIN." 
    +616 GOTO 420 
     620 NEXT I
    -622 REM TOTAL VALUE OF TRANSACTIONS:T5
    +622 REM TOTAL VALUE OF TRANSACTIONS:T5 
     625 LET T5=P5+S5
    -630 REM BROKERAGE FEE:B5
    -640 LET B5=INT(.01*T5*100+.5)/100
    +630 REM BROKERAGE FEE:B5 
    +640 LET B5=INT(.01*T5*100+.5)/100 
     650 REM CASH ASSETS=OLD CASH ASSETS-TOTAL PURCHASES
    -652 REM -BROKERAGE FEES+TOTAL SALES:C5
    -654 LET C5=C-P5-B5+S5
    -656 IF C5>=0 THEN 674
    -658 PRINT "YOU HAVE USED $"-C5" MORE THAN YOU HAVE."
    +652 REM -BROKERAGE FEES+TOTAL SALES:C5 
    +654 LET C5=C-P5-B5+S5 
    +656 IF C5>=0 THEN 674 
    +658 PRINT "YOU HAVE USED $"-C5" MORE THAN YOU HAVE." 
     660 GOTO 420
     674 LET C=C5
    -675 REM CALCULATE NEW PORTFOLIO
    +675 REM CALCULATE NEW PORTFOLIO  
     680 FOR I=1 TO 5
     690 LET P(I)=P(I)+Z(I)
     700 NEXT I
    -710 REM CALCULATE NEW STOCK VALUES
    -720 GOSUB 830
    +710 REM CALCULATE NEW STOCK VALUES 
    +720 GOSUB 830 
     750 REM PRINT PORTFOLIO
    -751 REM BELL RINGING-DIFFERENT ON MANY COMPUTERS
    -755 PRINT
    +751 REM BELL RINGING-DIFFERENT ON MANY COMPUTERS 
    +755 PRINT 
     756 PRINT "**********     END OF DAY'S TRADING     **********"
    -757 PRINT
    -758 PRINT
    +757 PRINT 
    +758 PRINT 
     759 IF X9<1 THEN 769
     769 PRINT "STOCK","PRICE/SHARE","HOLDINGS", "VALUE", "NET PRICE CHANGE"
     770 PRINT "IBM", S(1), P(1), S(1)*P(1), C(1)
    @@ -159,72 +159,72 @@
     773 PRINT "ABC", S(4), P(4), S(4)*P(4), C(4)
     774 PRINT "CBS", S(5), P(5), S(5)*P(5), C(5)
     775 LET X9=1
    -780 PRINT
    -790 PRINT
    -810 GOTO 360
    +780 PRINT 
    +790 PRINT 
    +810 GOTO 360 
     829 REM NEW STOCK VALUES - SUBROUTINE
     830 REM RANDOMLY PRODUCE NEW STOCK VALUES BASED ON PREVIOUS
    -831 REM DAY'S VALUES
    +831 REM DAY'S VALUES 
     832 REM N1,N2 ARE RANDOM NUMBERS OF DAYS WHICH RESPECTIVELY
     833 REM DETERMINE WHEN STOCK I1 WILL INCREASE 10 PTS. AND STOCK
    -834 REM I2 WILL DECREASE 10 PTS.
    -840 REM IF N1 DAYS HAVE PASSED, PICK AN I1, SET E1, DETERMINE NEW N1
    +834 REM I2 WILL DECREASE 10 PTS. 
    +840 REM IF N1 DAYS HAVE PASSED, PICK AN I1, SET E1, DETERMINE NEW N1 
     841 IF N1>0 THEN 850
    -845 LET I1=INT(4.99*RND(X)+1)
    -846 LET N1=INT(4.99*RND(X)+1)
    +845 LET I1=INT(4.99*RND(X)+1) 
    +846 LET N1=INT(4.99*RND(X)+1) 
     847 LET E1=1
    -850 REM IF N2 DAYS HAVE PASSED, PICK AN I2, SET E2, DETERMINE NEW N2
    +850 REM IF N2 DAYS HAVE PASSED, PICK AN I2, SET E2, DETERMINE NEW N2 
     851 IF N2>0 THEN 860
    -855 LET I2=INT(4.99*RND(X)+1)
    -856 LET N2=INT(4.99*RND(X)+1)
    +855 LET I2=INT(4.99*RND(X)+1) 
    +856 LET N2=INT(4.99*RND(X)+1) 
     857 LET E2=1
     860 REM DEDUCT ONE DAY FROM N1 AND N2
    -861 LET N1=N1-1
    -862 LET N2=N2-1
    +861 LET N1=N1-1 
    +862 LET N2=N2-1 
     890 REM LOOP THROUGH ALL STOCKS
     900 FOR I=1 TO 5
    -910 LET X1=RND(X)
    +910 LET X1=RND(X) 
     915 IF X1>.25 THEN 920
     916 LET X1=.25
    -917 GOTO 935
    +917 GOTO 935 
     920 IF X1>.5 THEN 925
     921 LET X1=.5
    -922 GOTO 935
    +922 GOTO 935 
     925 IF X1>.75 THEN 930
    -926 LET X1=.75
    -927 GOTO 935
    +926 LET X1=.75  
    +927 GOTO 935 
     930 LET X1=0.0
     931 REM BIG CHANGE CONSTANT:W3  (SET TO ZERO INITIALLY)
     935 LET W3=0
     936 IF E1<1 THEN 945
    -937 IF INT(I1+.5)<>INT(I+.5) THEN 945
    -938 REM ADD 10 PTS. TO THIS STOCK;  RESET E1
    -939 LET W3=10
    +937 IF INT(I1+.5)<>INT(I+.5) THEN 945 
    +938 REM ADD 10 PTS. TO THIS STOCK;  RESET E1 
    +939 LET W3=10 
     943 LET E1=0
     945 IF E2<1 THEN 955
    -947 IF INT(I2+.5)<>INT(I+.5) THEN 955
    +947 IF INT(I2+.5)<>INT(I+.5) THEN 955 
     948 REM SUBTRACT 10 PTS. FROM THIS STOCK;  RESET E2
     949 LET W3=W3-10
     953 LET E2=0
     954 REM C(I) IS CHANGE IN STOCK VALUE
    -955 LET C(I)=INT(A*S(I))+X1+INT(3-6*RND(X)+.5)+W3
    -956 LET C(I)=INT(100*C(I)+.5)/100
    +955 LET C(I)=INT(A*S(I))+X1+INT(3-6*RND(X)+.5)+W3 
    +956 LET C(I)=INT(100*C(I)+.5)/100 
     957 LET S(I)=S(I)+C(I)
     960 IF S(I)>0 THEN 967
     964 LET C(I)=0
     965 LET S(I)=0
    -966 GOTO 970
    -967 LET S(I)=INT(100*S(I)+.5)/100
    +966 GOTO 970 
    +967 LET S(I)=INT(100*S(I)+.5)/100 
     970 NEXT I
    -972 REM AFTER T8 DAYS RANDOMLY CHANGE TREND SIGN AND SLOPE
    -973 LET T8=T8-1
    +972 REM AFTER T8 DAYS RANDOMLY CHANGE TREND SIGN AND SLOPE 
    +973 LET T8=T8-1 
     974 IF T8<1 THEN 985
     980 RETURN
    -985 REM RANDOMLY CHANGE TREND SIGN AND SLOPE (A), AND DURATION
    +985 REM RANDOMLY CHANGE TREND SIGN AND SLOPE (A), AND DURATION 
     986 REM OF TREND (T8)
    -990 LET T8=INT(4.99*RND(X)+1)
    -992 LET A=INT((RND(X)/10)*100+.5)/100
    -993 LET S4=RND(X)
    +990 LET T8=INT(4.99*RND(X)+1) 
    +992 LET A=INT((RND(X)/10)*100+.5)/100 
    +993 LET S4=RND(X) 
     994 IF S4<=.5 THEN 997
     995 LET A=-A
     997 RETURN
    diff --git a/83_Stock_Market/vbnet/StockMarket.sln b/83_Stock_Market/vbnet/StockMarket.sln
    deleted file mode 100644
    index 00c392427..000000000
    --- a/83_Stock_Market/vbnet/StockMarket.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 1404eb48d..000000000
    --- a/83_Stock_Market/vbnet/StockMarket.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    StockMarket
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/84_Super_Star_Trek/README.md b/84_Super_Star_Trek/README.md
    index 32f827c67..77fae3d8e 100644
    --- a/84_Super_Star_Trek/README.md
    +++ b/84_Super_Star_Trek/README.md
    @@ -3,12 +3,12 @@
     #### Brief History
     Many versions of Star Trek have been kicking around various college campuses since the late sixties. I recall playing one at Carnegie-Mellon Univ. in 1967 or 68, and a very different one at Berkeley. However, these were a far cry from the one written by Mike Mayfield of Centerline Engineering and/or Custom Data. This was written for an HP2000C and completed in October 1972. It became the “standard” Star Trek in February 1973 when it was put in the HP contributed program library and onto a number of HP Data Center machines.
     
    -In the summer of 1973, I converted the HP version to BASIC-PLUS for DEC’s RSTS-11 compiler and added a few bits and pieces while I was at it. Mary Cole at DEC contributed enormously to this task too. Later that year I published it under the name SPACWR (Space War — in retrospect, an incorrect name) in my book _101 Basic Computer Games_. It is difficult today to find an interactive computer installation that does not have one of these versions of Star Trek available.
    +In the summer of 1973, I converted the HP version to BASIC-PLUS for DEC’s RSTS-11 compiler and added a few bits and pieces while I was at it. Mary Cole at DEC contributed enormously to this task too. Later that year I published it under the name SPACWE (Space War — in retrospect, an incorrect name) in my book _101 Basic Computer Games_.It is difficult today to find an interactive computer installation that does not have one of these versions of Star Trek available.
     
     #### Quadrant Nomenclature
     Recently, certain critics have professed confusion as to the origin on the “quadrant” nomenclature used on all standard CG (Cartesian Galactic) maps. Naturally, for anyone with the remotest knowledge of history, no explanation is necessary; however, the following synopsis should suffice for the critics:
     
    -As every schoolboy knows, most of the intelligent civilizations in the Milky Way had originated galactic designations of their own choosing well before the Third Magellanic Conference, at which the so-called “2⁶ Agreement” was reached. In that historic document, the participant cultures agreed, in all two-dimensional representations of the galaxy, to specify 64 major subdivisions, ordered as an 8 x 8 matrix. This was partially in deference to the Earth culture (which had done much in the initial organization of the Federation), whose century-old galactic maps had always shown 16 major regions named after celestial landmarks divided into four “quadrants,” designated by ancient “Roman Numerals” (the origin of which has been lost).
    +As everybody schoolboy knows, most of the intelligent civilizations in the Milky Way had originated galactic designations of their own choosing well before the Third Magellanic Conference, at which the so-called “2⁶ Agreement” was reached. In that historic document, the participant cultures agreed, in all two-dimensional representations of the galaxy, to specify 64 major subdivisions, ordered as an 8 x 8 matrix. This was partially in deference to the Earth culture (which had done much in the initial organization of the Federation), whose century-old galactic maps had landmarks divided into four “quadrants,” designated by ancient “Roman Numerals” (the origin of which has been lost).
     
     To this day, the official logs of starships originating on near-Earth starbases still refer to the major galactic areas as “quadrants.”
     
    @@ -17,7 +17,7 @@ The relation between the Historical and Standard nomenclatures is shown in the s
     |   | 1            | 2  | 3   | 4  | 5          | 6  | 7   | 8  |
     |---|--------------|----|-----|----|------------|----|-----|----|
     | 1 |    ANTARES   |    |     |    |   SIRIUS   |    |     |    |
    -|   | I            | II | III | IV | I          | II | III | IV |
    +|   | I            | II | III | IV | I          |    | III | IV |
     | 2 |     RIGEL    |    |     |    |    DENEB   |    |     |    |
     |   | I            | II | III | IV | I          | II | III | IV |
     | 3 |    PROCYON   |    |     |    |   CAPELLA  |    |     |    |
    @@ -72,7 +72,7 @@ The relation between the Historical and Standard nomenclatures is shown in the s
         - If you don’t zap a Klingon hard enough (relative to his shield strength) you won’t damage him at all. Your sensors will tell the story.
         - Damage control will let you know when out-of-commission devices have been completely repaired.
     
    -9. Your engines will automatically shut down if you should attempt to leave the galaxy, or if you should try to maneuver through a star, or Starbase, or—heaven help you—a Klingon warship.
    +9. Your engines will automatically shit down if you should attempt to leave the galaxy, or if you should try to maneuver through a star, or Starbase, or—heaven help you—a Klingon warship.
     
     10. In a pinch, or if you should miscalculate slightly, some shield control energy will be automatically diverted to warp engine control (if your shield are operational!).
     
    @@ -88,13 +88,11 @@ 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.
     
    -† Designates trademark of Paramount Pictures Corporation. Used by permission of Paramount Pictures Corporation.
    -
     ---
     
     As published in Basic Computer Games (1978):
     - [Atari Archives](https://www.atariarchives.org/basicgames/showpage.php?page=157)
    -- [Annarchive](https://annarchive.com/files/Basic_Computer_Games_Microcomputer_Edition.pdf#page=172)
    +- [Annarchive](https://annarchive.com/files/Basic_Computer_Games_Microcomputer_Edition.pdf#page=166)
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    @@ -102,15 +100,5 @@ http://www.vintage-basic.net/games.html
     Instructions in this directory at
     instructions.txt
     
    -#### Porting Notes
    -
    -Many of the programs in this book and this collection have bugs in the original code.
    -
    -@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
    -- line `440` : `B9` should be initialised to 0, not 2
    -
     #### External Links
      - C++: https://www.codeproject.com/Articles/28399/The-Object-Oriented-Text-Star-Trek-Game-in-C
    diff --git a/84_Super_Star_Trek/csharp/Commands/Command.cs b/84_Super_Star_Trek/csharp/Commands/Command.cs
    index e6b65db9e..f0d569f8b 100644
    --- a/84_Super_Star_Trek/csharp/Commands/Command.cs
    +++ b/84_Super_Star_Trek/csharp/Commands/Command.cs
    @@ -1,33 +1,34 @@
     using System.ComponentModel;
     
    -namespace SuperStarTrek.Commands;
    -
    -internal enum Command
    +namespace SuperStarTrek.Commands
     {
    -    [Description("To set course")]
    -    NAV,
    +    internal enum Command
    +    {
    +        [Description("To set course")]
    +        NAV,
     
    -    [Description("For short range sensor scan")]
    -    SRS,
    +        [Description("For short range sensor scan")]
    +        SRS,
     
    -    [Description("For long range sensor scan")]
    -    LRS,
    +        [Description("For long range sensor scan")]
    +        LRS,
     
    -    [Description("To fire phasers")]
    -    PHA,
    +        [Description("To fire phasers")]
    +        PHA,
     
    -    [Description("To fire photon torpedoes")]
    -    TOR,
    +        [Description("To fire photon torpedoes")]
    +        TOR,
     
    -    [Description("To raise or lower shields")]
    -    SHE,
    +        [Description("To raise or lower shields")]
    +        SHE,
     
    -    [Description("For damage control reports")]
    -    DAM,
    +        [Description("For damage control reports")]
    +        DAM,
     
    -    [Description("To call on library-computer")]
    -    COM,
    +        [Description("To call on library-computer")]
    +        COM,
     
    -    [Description("To resign your command")]
    -    XXX
    +        [Description("To resign your command")]
    +        XXX
    +    }
     }
    diff --git a/84_Super_Star_Trek/csharp/Commands/CommandExtensions.cs b/84_Super_Star_Trek/csharp/Commands/CommandExtensions.cs
    index e3e2f7aa7..f8f7e9daf 100644
    --- a/84_Super_Star_Trek/csharp/Commands/CommandExtensions.cs
    +++ b/84_Super_Star_Trek/csharp/Commands/CommandExtensions.cs
    @@ -1,13 +1,14 @@
     using System.Reflection;
     using System.ComponentModel;
     
    -namespace SuperStarTrek.Commands;
    -
    -internal static class CommandExtensions
    +namespace SuperStarTrek.Commands
     {
    -    internal static string GetDescription(this Command command) =>
    -        typeof(Command)
    -            .GetField(command.ToString())
    -            .GetCustomAttribute()
    -            .Description;
    +    internal static class CommandExtensions
    +    {
    +        internal static string GetDescription(this Command command) =>
    +            typeof(Command)
    +                .GetField(command.ToString())
    +                .GetCustomAttribute()
    +                .Description;
    +    }
     }
    diff --git a/84_Super_Star_Trek/csharp/Commands/CommandResult.cs b/84_Super_Star_Trek/csharp/Commands/CommandResult.cs
    index be95526f4..1b02780c1 100644
    --- a/84_Super_Star_Trek/csharp/Commands/CommandResult.cs
    +++ b/84_Super_Star_Trek/csharp/Commands/CommandResult.cs
    @@ -1,22 +1,23 @@
    -namespace SuperStarTrek.Commands;
    -
    -internal class CommandResult
    +namespace SuperStarTrek.Commands
     {
    -    public static readonly CommandResult Ok = new(false);
    -    public static readonly CommandResult GameOver = new(true);
    -
    -    private CommandResult(bool isGameOver)
    +    internal class CommandResult
         {
    -        IsGameOver = isGameOver;
    -    }
    +        public static readonly CommandResult Ok = new(false);
    +        public static readonly CommandResult GameOver = new(true);
     
    -    private CommandResult(float timeElapsed)
    -    {
    -        TimeElapsed = timeElapsed;
    -    }
    +        private CommandResult(bool isGameOver)
    +        {
    +            IsGameOver = isGameOver;
    +        }
    +
    +        private CommandResult(float timeElapsed)
    +        {
    +            TimeElapsed = timeElapsed;
    +        }
     
    -    public bool IsGameOver { get; }
    -    public float TimeElapsed { get; }
    +        public bool IsGameOver { get; }
    +        public float TimeElapsed { get; }
     
    -    public static CommandResult Elapsed(float timeElapsed) => new(timeElapsed);
    +        public static CommandResult Elapsed(float timeElapsed) => new(timeElapsed);
    +    }
     }
    diff --git a/84_Super_Star_Trek/csharp/Game.cs b/84_Super_Star_Trek/csharp/Game.cs
    index 918b9f656..274e29488 100644
    --- a/84_Super_Star_Trek/csharp/Game.cs
    +++ b/84_Super_Star_Trek/csharp/Game.cs
    @@ -1,128 +1,131 @@
     using System;
    -using Games.Common.IO;
    -using Games.Common.Randomness;
     using SuperStarTrek.Objects;
     using SuperStarTrek.Resources;
     using SuperStarTrek.Space;
     using SuperStarTrek.Systems;
     using SuperStarTrek.Systems.ComputerFunctions;
     
    -namespace SuperStarTrek;
    -
    -internal class Game
    +namespace SuperStarTrek
     {
    -    private readonly TextIO _io;
    -    private readonly IRandom _random;
    -
    -    private int _initialStardate;
    -    private int _finalStarDate;
    -    private float _currentStardate;
    -    private Coordinates _currentQuadrant;
    -    private Galaxy _galaxy;
    -    private int _initialKlingonCount;
    -    private Enterprise _enterprise;
    -
    -    internal Game(TextIO io, IRandom random)
    -    {
    -        _io = io;
    -        _random = random;
    -    }
    -
    -    internal float Stardate => _currentStardate;
    -
    -    internal float StardatesRemaining => _finalStarDate - _currentStardate;
    -
    -    internal void DoIntroduction()
    +    internal class Game
         {
    -        _io.Write(Strings.Title);
    -
    -        if (_io.GetYesNo("Do you need instructions", IReadWriteExtensions.YesNoMode.FalseOnN))
    +        private readonly Output _output;
    +        private readonly Input _input;
    +        private readonly Random _random;
    +
    +        private int _initialStardate;
    +        private int _finalStarDate;
    +        private float _currentStardate;
    +        private Coordinates _currentQuadrant;
    +        private Galaxy _galaxy;
    +        private int _initialKlingonCount;
    +        private Enterprise _enterprise;
    +
    +        internal Game(Output output, Input input, Random random)
             {
    -            _io.Write(Strings.Instructions);
    -
    -            _io.WaitForAnyKeyButEnter("to continue");
    +            _output = output;
    +            _input = input;
    +            _random = random;
             }
    -    }
     
    -    internal void Play()
    -    {
    -        Initialise();
    -        var gameOver = false;
    +        internal float Stardate => _currentStardate;
     
    -        while (!gameOver)
    +        internal float StardatesRemaining => _finalStarDate - _currentStardate;
    +
    +        internal void DoIntroduction()
             {
    -            var command = _io.ReadCommand();
    +            _output.Write(Strings.Title);
     
    -            var result = _enterprise.Execute(command);
    +            if (_input.GetYesNo("Do you need instructions", Input.YesNoMode.FalseOnN))
    +            {
    +                _output.Write(Strings.Instructions);
     
    -            gameOver = result.IsGameOver || CheckIfStranded();
    -            _currentStardate += result.TimeElapsed;
    -            gameOver |= _currentStardate > _finalStarDate;
    +                _input.WaitForAnyKeyButEnter("to continue");
    +            }
             }
     
    -        if (_galaxy.KlingonCount > 0)
    +        internal void Play()
             {
    -            _io.Write(Strings.EndOfMission, _currentStardate, _galaxy.KlingonCount);
    +            Initialise();
    +            var gameOver = false;
    +
    +            while (!gameOver)
    +            {
    +                var command = _input.GetCommand();
    +
    +                var result = _enterprise.Execute(command);
    +
    +                gameOver = result.IsGameOver || CheckIfStranded();
    +                _currentStardate += result.TimeElapsed;
    +                gameOver |= _currentStardate > _finalStarDate;
    +            }
    +
    +            if (_galaxy.KlingonCount > 0)
    +            {
    +                _output.Write(Strings.EndOfMission, _currentStardate, _galaxy.KlingonCount);
    +            }
    +            else
    +            {
    +                _output.Write(Strings.Congratulations, GetEfficiency());
    +            }
             }
    -        else
    +
    +        private void Initialise()
             {
    -            _io.Write(Strings.Congratulations, CalculateEfficiency());
    +            _currentStardate = _initialStardate = _random.GetInt(20, 40) * 100;
    +            _finalStarDate = _initialStardate + _random.GetInt(25, 35);
    +
    +            _currentQuadrant = _random.GetCoordinate();
    +
    +            _galaxy = new Galaxy(_random);
    +            _initialKlingonCount = _galaxy.KlingonCount;
    +
    +            _enterprise = new Enterprise(3000, _random.GetCoordinate(), _output, _random, _input);
    +            _enterprise
    +                .Add(new WarpEngines(_enterprise, _output, _input))
    +                .Add(new ShortRangeSensors(_enterprise, _galaxy, this, _output))
    +                .Add(new LongRangeSensors(_galaxy, _output))
    +                .Add(new PhaserControl(_enterprise, _output, _input, _random))
    +                .Add(new PhotonTubes(10, _enterprise, _output, _input))
    +                .Add(new ShieldControl(_enterprise, _output, _input))
    +                .Add(new DamageControl(_enterprise, _output))
    +                .Add(new LibraryComputer(
    +                    _output,
    +                    _input,
    +                    new CumulativeGalacticRecord(_output, _galaxy),
    +                    new StatusReport(this, _galaxy, _enterprise, _output),
    +                    new TorpedoDataCalculator(_enterprise, _output),
    +                    new StarbaseDataCalculator(_enterprise, _output),
    +                    new DirectionDistanceCalculator(_enterprise, _output, _input),
    +                    new GalaxyRegionMap(_output, _galaxy)));
    +
    +            _output.Write(Strings.Enterprise);
    +            _output.Write(
    +                Strings.Orders,
    +                _galaxy.KlingonCount,
    +                _finalStarDate,
    +                _finalStarDate - _initialStardate,
    +                _galaxy.StarbaseCount > 1 ? "are" : "is",
    +                _galaxy.StarbaseCount,
    +                _galaxy.StarbaseCount > 1 ? "s" : "");
    +
    +            _input.WaitForAnyKeyButEnter("when ready to accept command");
    +
    +            _enterprise.StartIn(BuildCurrentQuadrant());
             }
    -    }
     
    -    private void Initialise()
    -    {
    -        _currentStardate = _initialStardate = _random.Next(20, 40) * 100;
    -        _finalStarDate = _initialStardate + _random.Next(25, 35);
    -
    -        _currentQuadrant = _random.NextCoordinate();
    -
    -        _galaxy = new Galaxy(_random);
    -        _initialKlingonCount = _galaxy.KlingonCount;
    -
    -        _enterprise = new Enterprise(3000, _random.NextCoordinate(), _io, _random);
    -        _enterprise
    -            .Add(new WarpEngines(_enterprise, _io))
    -            .Add(new ShortRangeSensors(_enterprise, _galaxy, this, _io))
    -            .Add(new LongRangeSensors(_galaxy, _io))
    -            .Add(new PhaserControl(_enterprise, _io, _random))
    -            .Add(new PhotonTubes(10, _enterprise, _io))
    -            .Add(new ShieldControl(_enterprise, _io))
    -            .Add(new DamageControl(_enterprise, _io))
    -            .Add(new LibraryComputer(
    -                _io,
    -                new CumulativeGalacticRecord(_io, _galaxy),
    -                new StatusReport(this, _galaxy, _enterprise, _io),
    -                new TorpedoDataCalculator(_enterprise, _io),
    -                new StarbaseDataCalculator(_enterprise, _io),
    -                new DirectionDistanceCalculator(_enterprise, _io),
    -                new GalaxyRegionMap(_io, _galaxy)));
    -
    -        _io.Write(Strings.Enterprise);
    -        _io.Write(
    -            Strings.Orders,
    -            _galaxy.KlingonCount,
    -            _finalStarDate,
    -            _finalStarDate - _initialStardate,
    -            _galaxy.StarbaseCount > 1 ? "are" : "is",
    -            _galaxy.StarbaseCount,
    -            _galaxy.StarbaseCount > 1 ? "s" : "");
    -
    -        _io.WaitForAnyKeyButEnter("when ready to accept command");
    -
    -        _enterprise.StartIn(BuildCurrentQuadrant());
    -    }
    +        private Quadrant BuildCurrentQuadrant() =>
    +           new Quadrant(_galaxy[_currentQuadrant], _enterprise, _random, _galaxy, _input, _output);
     
    -    private Quadrant BuildCurrentQuadrant() => new(_galaxy[_currentQuadrant], _enterprise, _random, _galaxy, _io);
    +        internal bool Replay() => _galaxy.StarbaseCount > 0 && _input.GetString(Strings.ReplayPrompt, "Aye");
     
    -    internal bool Replay() => _galaxy.StarbaseCount > 0 && _io.ReadExpectedString(Strings.ReplayPrompt, "Aye");
    +        private bool CheckIfStranded()
    +        {
    +            if (_enterprise.IsStranded) { _output.Write(Strings.Stranded); }
    +            return _enterprise.IsStranded;
    +        }
     
    -    private bool CheckIfStranded()
    -    {
    -        if (_enterprise.IsStranded) { _io.Write(Strings.Stranded); }
    -        return _enterprise.IsStranded;
    +        private float GetEfficiency() =>
    +            1000 * (float)Math.Pow(_initialKlingonCount / (_currentStardate - _initialStardate), 2);
         }
    -
    -    private float CalculateEfficiency() =>
    -        1000 * (float)Math.Pow(_initialKlingonCount / (_currentStardate - _initialStardate), 2);
     }
    diff --git a/84_Super_Star_Trek/csharp/IRandomExtensions.cs b/84_Super_Star_Trek/csharp/IRandomExtensions.cs
    deleted file mode 100644
    index f115aeed6..000000000
    --- a/84_Super_Star_Trek/csharp/IRandomExtensions.cs
    +++ /dev/null
    @@ -1,16 +0,0 @@
    -using Games.Common.Randomness;
    -using SuperStarTrek.Space;
    -
    -namespace SuperStarTrek;
    -
    -internal static class IRandomExtensions
    -{
    -    internal static Coordinates NextCoordinate(this IRandom random) =>
    -        new Coordinates(random.Next1To8Inclusive() - 1, random.Next1To8Inclusive() - 1);
    -
    -    // Duplicates the algorithm used in the original code to get an integer value from 1 to 8, inclusive:
    -    //     475 DEF FNR(R)=INT(RND(R)*7.98+1.01)
    -    // Returns a value from 1 to 8, inclusive.
    -    // Note there's a slight bias away from the extreme values, 1 and 8.
    -    internal static int Next1To8Inclusive(this IRandom random) => (int)(random.NextFloat() * 7.98 + 1.01);
    -}
    diff --git a/84_Super_Star_Trek/csharp/IReadWriteExtensions.cs b/84_Super_Star_Trek/csharp/IReadWriteExtensions.cs
    deleted file mode 100644
    index f46e74f76..000000000
    --- a/84_Super_Star_Trek/csharp/IReadWriteExtensions.cs
    +++ /dev/null
    @@ -1,89 +0,0 @@
    -using System;
    -using System.Linq;
    -using Games.Common.IO;
    -using SuperStarTrek.Commands;
    -using SuperStarTrek.Space;
    -using static System.StringComparison;
    -
    -namespace SuperStarTrek;
    -
    -internal static class IReadWriteExtensions
    -{
    -    internal static void WaitForAnyKeyButEnter(this IReadWrite io, string prompt)
    -    {
    -        io.Write($"Hit any key but Enter {prompt} ");
    -        while (io.ReadCharacter() == '\r');
    -    }
    -
    -    internal static (float X, float Y) GetCoordinates(this IReadWrite io, string prompt) =>
    -        io.Read2Numbers($"{prompt} (X,Y)");
    -
    -    internal static bool TryReadNumberInRange(
    -        this IReadWrite io,
    -        string prompt,
    -        float minValue,
    -        float maxValue,
    -        out float value)
    -    {
    -        value = io.ReadNumber($"{prompt} ({minValue}-{maxValue})");
    -
    -        return value >= minValue && value <= maxValue;
    -    }
    -
    -    internal static bool ReadExpectedString(this IReadWrite io, string prompt, string trueValue) =>
    -        io.ReadString(prompt).Equals(trueValue, InvariantCultureIgnoreCase);
    -
    -    internal static Command ReadCommand(this IReadWrite io)
    -    {
    -        while(true)
    -        {
    -            var response = io.ReadString("Command");
    -
    -            if (response.Length >= 3 &&
    -                Enum.TryParse(response.Substring(0, 3), ignoreCase: true, out Command parsedCommand))
    -            {
    -                return parsedCommand;
    -            }
    -
    -            io.WriteLine("Enter one of the following:");
    -            foreach (var command in Enum.GetValues(typeof(Command)).OfType())
    -            {
    -                io.WriteLine($"  {command}  ({command.GetDescription()})");
    -            }
    -            io.WriteLine();
    -        }
    -    }
    -
    -    internal static bool TryReadCourse(this IReadWrite io, string prompt, string officer, out Course course)
    -    {
    -        if (!io.TryReadNumberInRange(prompt, 1, 9, out var direction))
    -        {
    -            io.WriteLine($"{officer} reports, 'Incorrect course data, sir!'");
    -            course = default;
    -            return false;
    -        }
    -
    -        course = new Course(direction);
    -        return true;
    -    }
    -
    -    internal static bool GetYesNo(this IReadWrite io, string prompt, YesNoMode mode)
    -    {
    -        var response = io.ReadString($"{prompt} (Y/N)").ToUpperInvariant();
    -
    -        return (mode, response) switch
    -        {
    -            (YesNoMode.FalseOnN, "N") => false,
    -            (YesNoMode.FalseOnN, _) => true,
    -            (YesNoMode.TrueOnY, "Y") => true,
    -            (YesNoMode.TrueOnY, _) => false,
    -            _ => throw new ArgumentOutOfRangeException(nameof(mode), mode, "Invalid value")
    -        };
    -    }
    -
    -    internal enum YesNoMode
    -    {
    -        TrueOnY,
    -        FalseOnN
    -    }
    -}
    diff --git a/84_Super_Star_Trek/csharp/Input.cs b/84_Super_Star_Trek/csharp/Input.cs
    new file mode 100644
    index 000000000..2b37b2ba6
    --- /dev/null
    +++ b/84_Super_Star_Trek/csharp/Input.cs
    @@ -0,0 +1,159 @@
    +using System;
    +using System.Linq;
    +using SuperStarTrek.Commands;
    +using SuperStarTrek.Space;
    +using static System.StringComparison;
    +
    +namespace SuperStarTrek
    +{
    +    internal class Input
    +    {
    +        private readonly Output _output;
    +
    +        internal Input(Output output)
    +        {
    +            _output = output;
    +        }
    +
    +        internal void WaitForAnyKeyButEnter(string prompt)
    +        {
    +            _output.Write($"Hit any key but Enter {prompt} ");
    +            while (Console.ReadKey(intercept: true).Key == ConsoleKey.Enter);
    +        }
    +
    +        internal string GetString(string prompt)
    +        {
    +            _output.Prompt(prompt);
    +            return Console.ReadLine();
    +        }
    +
    +        internal float GetNumber(string prompt)
    +        {
    +            _output.Prompt(prompt);
    +
    +            while (true)
    +            {
    +                var response = Console.ReadLine();
    +                if (float.TryParse(response, out var value))
    +                {
    +                    return value;
    +                }
    +
    +                _output.WriteLine("!Number expected - retry input line");
    +                _output.Prompt();
    +            }
    +        }
    +
    +        internal (float X, float Y) GetCoordinates(string prompt)
    +        {
    +            _output.Prompt($"{prompt} (X,Y)");
    +            var responses = ReadNumbers(2);
    +            return (responses[0], responses[1]);
    +        }
    +
    +        internal bool TryGetNumber(string prompt, float minValue, float maxValue, out float value)
    +        {
    +            value = GetNumber($"{prompt} ({minValue}-{maxValue})");
    +
    +            return value >= minValue && value <= maxValue;
    +        }
    +
    +        internal bool GetString(string replayPrompt, string trueValue) =>
    +            GetString(replayPrompt).Equals(trueValue, InvariantCultureIgnoreCase);
    +
    +        internal Command GetCommand()
    +        {
    +            while(true)
    +            {
    +                var response = GetString("Command");
    +
    +                if (response.Length >= 3 &&
    +                    Enum.TryParse(response.Substring(0, 3), ignoreCase: true, out Command parsedCommand))
    +                {
    +                    return parsedCommand;
    +                }
    +
    +                _output.WriteLine("Enter one of the following:");
    +                foreach (var command in Enum.GetValues(typeof(Command)).OfType())
    +                {
    +                    _output.WriteLine($"  {command}  ({command.GetDescription()})");
    +                }
    +                _output.WriteLine();
    +            }
    +        }
    +
    +        internal bool TryGetCourse(string prompt, string officer, out Course course)
    +        {
    +            if (!TryGetNumber(prompt, 1, 9, out var direction))
    +            {
    +                _output.WriteLine($"{officer} reports, 'Incorrect course data, sir!'");
    +                course = default;
    +                return false;
    +            }
    +
    +            course = new Course(direction);
    +            return true;
    +        }
    +
    +        internal bool GetYesNo(string prompt, YesNoMode mode)
    +        {
    +            _output.Prompt($"{prompt} (Y/N)");
    +            var response = Console.ReadLine().ToUpperInvariant();
    +
    +            return (mode, response) switch
    +            {
    +                (YesNoMode.FalseOnN, "N") => false,
    +                (YesNoMode.FalseOnN, _) => true,
    +                (YesNoMode.TrueOnY, "Y") => true,
    +                (YesNoMode.TrueOnY, _) => false,
    +                _ => throw new ArgumentOutOfRangeException(nameof(mode), mode, "Invalid value")
    +            };
    +        }
    +
    +        private float[] ReadNumbers(int quantity)
    +        {
    +            var numbers = new float[quantity];
    +            var index = 0;
    +            bool tryAgain;
    +
    +            do
    +            {
    +                tryAgain = false;
    +                var responses = Console.ReadLine().Split(',');
    +                if (responses.Length > quantity)
    +                {
    +                    _output.WriteLine("!Extra input ingored");
    +                }
    +
    +                for (; index < responses.Length; index++)
    +                {
    +                    if (!float.TryParse(responses[index], out numbers[index]))
    +                    {
    +                        _output.WriteLine("!Number expected - retry input line");
    +                        _output.Prompt();
    +                        tryAgain = true;
    +                        break;
    +                    }
    +                }
    +            } while (tryAgain);
    +
    +            if (index < quantity)
    +            {
    +                _output.Prompt("?");
    +                var responses = ReadNumbers(quantity - index);
    +                for (int i = 0; i < responses.Length; i++, index++)
    +                {
    +                    numbers[index] = responses[i];
    +                }
    +            }
    +
    +            return numbers;
    +        }
    +
    +        internal enum YesNoMode
    +        {
    +            TrueOnY,
    +            FalseOnN
    +        }
    +    }
    +}
    diff --git a/84_Super_Star_Trek/csharp/Objects/Enterprise.cs b/84_Super_Star_Trek/csharp/Objects/Enterprise.cs
    index f288e9201..ac9e8112b 100644
    --- a/84_Super_Star_Trek/csharp/Objects/Enterprise.cs
    +++ b/84_Super_Star_Trek/csharp/Objects/Enterprise.cs
    @@ -1,230 +1,231 @@
     using System;
     using System.Collections.Generic;
     using System.Linq;
    -using Games.Common.IO;
    -using Games.Common.Randomness;
     using SuperStarTrek.Commands;
     using SuperStarTrek.Resources;
     using SuperStarTrek.Space;
     using SuperStarTrek.Systems;
     
    -namespace SuperStarTrek.Objects;
    -
    -internal class Enterprise
    +namespace SuperStarTrek.Objects
     {
    -    private readonly int _maxEnergy;
    -    private readonly IReadWrite _io;
    -    private readonly List _systems;
    -    private readonly Dictionary _commandExecutors;
    -    private readonly IRandom _random;
    -    private Quadrant _quadrant;
    -
    -    public Enterprise(int maxEnergy, Coordinates sector, IReadWrite io, IRandom random)
    +    internal class Enterprise
         {
    -        SectorCoordinates = sector;
    -        TotalEnergy = _maxEnergy = maxEnergy;
    -
    -        _systems = new List();
    -        _commandExecutors = new Dictionary();
    -        _io = io;
    -        _random = random;
    -    }
    -
    -    internal Quadrant Quadrant => _quadrant;
    +        private readonly int _maxEnergy;
    +        private readonly Output _output;
    +        private readonly List _systems;
    +        private readonly Dictionary _commandExecutors;
    +        private readonly Random _random;
    +        private readonly Input _input;
    +        private Quadrant _quadrant;
    +
    +        public Enterprise(int maxEnergy, Coordinates sector, Output output, Random random, Input input)
    +        {
    +            SectorCoordinates = sector;
    +            TotalEnergy = _maxEnergy = maxEnergy;
    +
    +            _systems = new List();
    +            _commandExecutors = new Dictionary();
    +            _output = output;
    +            _random = random;
    +            _input = input;
    +        }
     
    -    internal Coordinates QuadrantCoordinates => _quadrant.Coordinates;
    +        internal Quadrant Quadrant => _quadrant;
     
    -    internal Coordinates SectorCoordinates { get; private set; }
    +        internal Coordinates QuadrantCoordinates => _quadrant.Coordinates;
     
    -    internal string Condition => GetCondition();
    +        internal Coordinates SectorCoordinates { get; private set; }
     
    -    internal LibraryComputer Computer => (LibraryComputer)_commandExecutors[Command.COM];
    +        internal string Condition => GetCondition();
     
    -    internal ShieldControl ShieldControl => (ShieldControl)_commandExecutors[Command.SHE];
    +        internal LibraryComputer Computer => (LibraryComputer)_commandExecutors[Command.COM];
     
    -    internal float Energy => TotalEnergy - ShieldControl.ShieldEnergy;
    +        internal ShieldControl ShieldControl => (ShieldControl)_commandExecutors[Command.SHE];
     
    -    internal float TotalEnergy { get; private set; }
    +        internal float Energy => TotalEnergy - ShieldControl.ShieldEnergy;
     
    -    internal int DamagedSystemCount => _systems.Count(s => s.IsDamaged);
    +        internal float TotalEnergy { get; private set; }
     
    -    internal IEnumerable Systems => _systems;
    +        internal int DamagedSystemCount => _systems.Count(s => s.IsDamaged);
     
    -    internal PhotonTubes PhotonTubes => (PhotonTubes)_commandExecutors[Command.TOR];
    +        internal IEnumerable Systems => _systems;
     
    -    internal bool IsDocked => _quadrant.EnterpriseIsNextToStarbase;
    +        internal PhotonTubes PhotonTubes => (PhotonTubes)_commandExecutors[Command.TOR];
     
    -    internal bool IsStranded => TotalEnergy < 10 || Energy < 10 && ShieldControl.IsDamaged;
    +        internal bool IsDocked => _quadrant.EnterpriseIsNextToStarbase;
     
    -    internal Enterprise Add(Subsystem system)
    -    {
    -        _systems.Add(system);
    -        _commandExecutors[system.Command] = system;
    +        internal bool IsStranded => TotalEnergy < 10 || Energy < 10 && ShieldControl.IsDamaged;
     
    -        return this;
    -    }
    +        internal Enterprise Add(Subsystem system)
    +        {
    +            _systems.Add(system);
    +            _commandExecutors[system.Command] = system;
     
    -    internal void StartIn(Quadrant quadrant)
    -    {
    -        _quadrant = quadrant;
    -        quadrant.Display(Strings.StartText);
    -    }
    +            return this;
    +        }
     
    -    private string GetCondition() =>
    -        IsDocked switch
    +        internal void StartIn(Quadrant quadrant)
             {
    -            true => "Docked",
    -            false when _quadrant.HasKlingons => "*Red*",
    -            false when Energy / _maxEnergy < 0.1f => "Yellow",
    -            false => "Green"
    -        };
    -
    -    internal CommandResult Execute(Command command)
    -    {
    -        if (command == Command.XXX) { return CommandResult.GameOver; }
    +            _quadrant = quadrant;
    +            quadrant.Display(Strings.StartText);
    +        }
     
    -        return _commandExecutors[command].ExecuteCommand(_quadrant);
    -    }
    +        private string GetCondition() =>
    +            IsDocked switch
    +            {
    +                true => "Docked",
    +                false when _quadrant.HasKlingons => "*Red*",
    +                false when Energy / _maxEnergy < 0.1f => "Yellow",
    +                false => "Green"
    +            };
     
    -    internal void Refuel() => TotalEnergy = _maxEnergy;
    +        internal CommandResult Execute(Command command)
    +        {
    +            if (command == Command.XXX) { return CommandResult.GameOver; }
     
    -    public override string ToString() => "<*>";
    +            return _commandExecutors[command].ExecuteCommand(_quadrant);
    +        }
     
    -    internal void UseEnergy(float amountUsed)
    -    {
    -        TotalEnergy -= amountUsed;
    -    }
    +        internal void Refuel() => TotalEnergy = _maxEnergy;
     
    -    internal CommandResult TakeHit(Coordinates sector, int hitStrength)
    -    {
    -        _io.WriteLine($"{hitStrength} unit hit on Enterprise from sector {sector}");
    -        ShieldControl.AbsorbHit(hitStrength);
    +        public override string ToString() => "<*>";
     
    -        if (ShieldControl.ShieldEnergy <= 0)
    +        internal void UseEnergy(float amountUsed)
             {
    -            _io.WriteLine(Strings.Destroyed);
    -            return CommandResult.GameOver;
    +            TotalEnergy -= amountUsed;
             }
     
    -        _io.WriteLine($"      ");
    -
    -        if (hitStrength >= 20)
    +        internal CommandResult TakeHit(Coordinates sector, int hitStrength)
             {
    -            TakeDamage(hitStrength);
    -        }
    +            _output.WriteLine($"{hitStrength} unit hit on Enterprise from sector {sector}");
    +            ShieldControl.AbsorbHit(hitStrength);
     
    -        return CommandResult.Ok;
    -    }
    +            if (ShieldControl.ShieldEnergy <= 0)
    +            {
    +                _output.WriteLine(Strings.Destroyed);
    +                return CommandResult.GameOver;
    +            }
     
    -    private void TakeDamage(float hitStrength)
    -    {
    -        var hitShieldRatio = hitStrength / ShieldControl.ShieldEnergy;
    -        if (_random.NextFloat() > 0.6 || hitShieldRatio <= 0.02f)
    -        {
    -            return;
    -        }
    +            _output.WriteLine($"      ");
     
    -        var system = _systems[_random.Next1To8Inclusive() - 1];
    -        system.TakeDamage(hitShieldRatio + 0.5f * _random.NextFloat());
    -        _io.WriteLine($"Damage Control reports, '{system.Name} damaged by the hit.'");
    -    }
    +            if (hitStrength >= 20)
    +            {
    +                TakeDamage(hitStrength);
    +            }
     
    -    internal void RepairSystems(float repairWorkDone)
    -    {
    -        var repairedSystems = new List();
    +            return CommandResult.Ok;
    +        }
     
    -        foreach (var system in _systems.Where(s => s.IsDamaged))
    +        private void TakeDamage(float hitStrength)
             {
    -            if (system.Repair(repairWorkDone))
    +            var hitShieldRatio = hitStrength / ShieldControl.ShieldEnergy;
    +            if (_random.GetFloat() > 0.6 || hitShieldRatio <= 0.02f)
                 {
    -                repairedSystems.Add(system.Name);
    +                return;
                 }
    +
    +            var system = _systems[_random.Get1To8Inclusive() - 1];
    +            system.TakeDamage(hitShieldRatio + 0.5f * _random.GetFloat());
    +            _output.WriteLine($"Damage Control reports, '{system.Name} damaged by the hit.'");
             }
     
    -        if (repairedSystems.Any())
    +        internal void RepairSystems(float repairWorkDone)
             {
    -            _io.WriteLine("Damage Control report:");
    -            foreach (var systemName in repairedSystems)
    +            var repairedSystems = new List();
    +
    +            foreach (var system in _systems.Where(s => s.IsDamaged))
                 {
    -                _io.WriteLine($"        {systemName} repair completed.");
    +                if (system.Repair(repairWorkDone))
    +                {
    +                    repairedSystems.Add(system.Name);
    +                }
                 }
    -        }
    -    }
     
    -    internal void VaryConditionOfRandomSystem()
    -    {
    -        if (_random.NextFloat() > 0.2f) { return; }
    +            if (repairedSystems.Any())
    +            {
    +                _output.WriteLine("Damage Control report:");
    +                foreach (var systemName in repairedSystems)
    +                {
    +                    _output.WriteLine($"        {systemName} repair completed.");
    +                }
    +            }
    +        }
     
    -        var system = _systems[_random.Next1To8Inclusive() - 1];
    -        _io.Write($"Damage Control report:  {system.Name} ");
    -        if (_random.NextFloat() >= 0.6)
    +        internal void VaryConditionOfRandomSystem()
             {
    -            system.Repair(_random.NextFloat() * 3 + 1);
    -            _io.WriteLine("state of repair improved");
    +            if (_random.GetFloat() > 0.2f) { return; }
    +
    +            var system = _systems[_random.Get1To8Inclusive() - 1];
    +            _output.Write($"Damage Control report:  {system.Name} ");
    +            if (_random.GetFloat() >= 0.6)
    +            {
    +                system.Repair(_random.GetFloat() * 3 + 1);
    +                _output.WriteLine("state of repair improved");
    +            }
    +            else
    +            {
    +                system.TakeDamage(_random.GetFloat() * 5 + 1);
    +                _output.WriteLine("damaged");
    +            }
             }
    -        else
    +
    +        internal float Move(Course course, float warpFactor, int distance)
             {
    -            system.TakeDamage(_random.NextFloat() * 5 + 1);
    -            _io.WriteLine("damaged");
    -        }
    -    }
    +            var (quadrant, sector) = MoveWithinQuadrant(course, distance) ?? MoveBeyondQuadrant(course, distance);
     
    -    internal float Move(Course course, float warpFactor, int distance)
    -    {
    -        var (quadrant, sector) = MoveWithinQuadrant(course, distance) ?? MoveBeyondQuadrant(course, distance);
    +            if (quadrant != _quadrant.Coordinates)
    +            {
    +                _quadrant = new Quadrant(_quadrant.Galaxy[quadrant], this, _random, _quadrant.Galaxy, _input, _output);
    +            }
    +            _quadrant.SetEnterpriseSector(sector);
    +            SectorCoordinates = sector;
     
    -        if (quadrant != _quadrant.Coordinates)
    -        {
    -            _quadrant = new Quadrant(_quadrant.Galaxy[quadrant], this, _random, _quadrant.Galaxy, _io);
    -        }
    -        _quadrant.SetEnterpriseSector(sector);
    -        SectorCoordinates = sector;
    +            TotalEnergy -= distance + 10;
    +            if (Energy < 0)
    +            {
    +                _output.WriteLine("Shield Control supplies energy to complete the maneuver.");
    +                ShieldControl.ShieldEnergy = Math.Max(0, TotalEnergy);
    +            }
     
    -        TotalEnergy -= distance + 10;
    -        if (Energy < 0)
    -        {
    -            _io.WriteLine("Shield Control supplies energy to complete the maneuver.");
    -            ShieldControl.ShieldEnergy = Math.Max(0, TotalEnergy);
    +            return GetTimeElapsed(quadrant, warpFactor);
             }
     
    -        return GetTimeElapsed(quadrant, warpFactor);
    -    }
    -
    -    private (Coordinates, Coordinates)? MoveWithinQuadrant(Course course, int distance)
    -    {
    -        var currentSector = SectorCoordinates;
    -        foreach (var (sector, index) in course.GetSectorsFrom(SectorCoordinates).Select((s, i) => (s, i)))
    +        private (Coordinates, Coordinates)? MoveWithinQuadrant(Course course, int distance)
             {
    -            if (distance == 0) { break; }
    -
    -            if (_quadrant.HasObjectAt(sector))
    +            var currentSector = SectorCoordinates;
    +            foreach (var (sector, index) in course.GetSectorsFrom(SectorCoordinates).Select((s, i) => (s, i)))
                 {
    -                _io.WriteLine($"Warp engines shut down at sector {currentSector} dues to bad navigation");
    -                distance = 0;
    -                break;
    +                if (distance == 0) { break; }
    +
    +                if (_quadrant.HasObjectAt(sector))
    +                {
    +                    _output.WriteLine($"Warp engines shut down at sector {currentSector} dues to bad navigation");
    +                    distance = 0;
    +                    break;
    +                }
    +
    +                currentSector = sector;
    +                distance -= 1;
                 }
     
    -            currentSector = sector;
    -            distance -= 1;
    +            return distance == 0 ? (_quadrant.Coordinates, currentSector) : null;
             }
     
    -        return distance == 0 ? (_quadrant.Coordinates, currentSector) : null;
    -    }
    +        private (Coordinates, Coordinates) MoveBeyondQuadrant(Course course, int distance)
    +        {
    +            var (complete, quadrant, sector) = course.GetDestination(QuadrantCoordinates, SectorCoordinates, distance);
     
    -    private (Coordinates, Coordinates) MoveBeyondQuadrant(Course course, int distance)
    -    {
    -        var (complete, quadrant, sector) = course.GetDestination(QuadrantCoordinates, SectorCoordinates, distance);
    +            if (!complete)
    +            {
    +                _output.Write(Strings.PermissionDenied, sector, quadrant);
    +            }
     
    -        if (!complete)
    -        {
    -            _io.Write(Strings.PermissionDenied, sector, quadrant);
    +            return (quadrant, sector);
             }
     
    -        return (quadrant, sector);
    +        private float GetTimeElapsed(Coordinates finalQuadrant, float warpFactor) =>
    +            finalQuadrant == _quadrant.Coordinates
    +                ? Math.Min(1, (float)Math.Round(warpFactor, 1, MidpointRounding.ToZero))
    +                : 1;
         }
    -
    -    private float GetTimeElapsed(Coordinates finalQuadrant, float warpFactor) =>
    -        finalQuadrant == _quadrant.Coordinates
    -            ? Math.Min(1, (float)Math.Round(warpFactor, 1, MidpointRounding.ToZero))
    -            : 1;
     }
    diff --git a/84_Super_Star_Trek/csharp/Objects/Klingon.cs b/84_Super_Star_Trek/csharp/Objects/Klingon.cs
    index 7e84ae567..1b55940ad 100644
    --- a/84_Super_Star_Trek/csharp/Objects/Klingon.cs
    +++ b/84_Super_Star_Trek/csharp/Objects/Klingon.cs
    @@ -1,43 +1,43 @@
    -using Games.Common.Randomness;
     using SuperStarTrek.Commands;
     using SuperStarTrek.Space;
     
    -namespace SuperStarTrek.Objects;
    -
    -internal class Klingon
    +namespace SuperStarTrek.Objects
     {
    -    private readonly IRandom _random;
    -
    -    internal Klingon(Coordinates sector, IRandom random)
    +    internal class Klingon
         {
    -        Sector = sector;
    -        _random = random;
    -        Energy = _random.NextFloat(100, 300);
    -    }
    +        private readonly Random _random;
     
    -    internal float Energy { get; private set; }
    +        internal Klingon(Coordinates sector, Random random)
    +        {
    +            Sector = sector;
    +            _random = random;
    +            Energy = _random.GetFloat(100, 300);
    +        }
     
    -    internal Coordinates Sector { get; private set; }
    +        internal float Energy { get; private set; }
     
    -    public override string ToString() => "+K+";
    +        internal Coordinates Sector { get; private set; }
     
    -    internal CommandResult FireOn(Enterprise enterprise)
    -    {
    -        var attackStrength = _random.NextFloat();
    -        var distanceToEnterprise = Sector.GetDistanceTo(enterprise.SectorCoordinates);
    -        var hitStrength = (int)(Energy * (2 + attackStrength) / distanceToEnterprise);
    -        Energy /= 3 + attackStrength;
    +        public override string ToString() => "+K+";
     
    -        return enterprise.TakeHit(Sector, hitStrength);
    -    }
    +        internal CommandResult FireOn(Enterprise enterprise)
    +        {
    +            var attackStrength = _random.GetFloat();
    +            var distanceToEnterprise = Sector.GetDistanceTo(enterprise.SectorCoordinates);
    +            var hitStrength = (int)(Energy * (2 + attackStrength) / distanceToEnterprise);
    +            Energy /= 3 + attackStrength;
     
    -    internal bool TakeHit(int hitStrength)
    -    {
    -        if (hitStrength < 0.15 * Energy) { return false; }
    +            return enterprise.TakeHit(Sector, hitStrength);
    +        }
     
    -        Energy -= hitStrength;
    -        return true;
    -    }
    +        internal bool TakeHit(int hitStrength)
    +        {
    +            if (hitStrength < 0.15 * Energy) { return false; }
     
    -    internal void MoveTo(Coordinates newSector) => Sector = newSector;
    +            Energy -= hitStrength;
    +            return true;
    +        }
    +
    +        internal void MoveTo(Coordinates newSector) => Sector = newSector;
    +    }
     }
    diff --git a/84_Super_Star_Trek/csharp/Objects/Star.cs b/84_Super_Star_Trek/csharp/Objects/Star.cs
    index 8676d3c31..1d9eef6f4 100644
    --- a/84_Super_Star_Trek/csharp/Objects/Star.cs
    +++ b/84_Super_Star_Trek/csharp/Objects/Star.cs
    @@ -1,6 +1,7 @@
    -namespace SuperStarTrek.Objects;
    -
    -internal class Star
    +namespace SuperStarTrek.Objects
     {
    -    public override string ToString() => " * ";
    +    internal class Star
    +    {
    +        public override string ToString() => " * ";
    +    }
     }
    diff --git a/84_Super_Star_Trek/csharp/Objects/Starbase.cs b/84_Super_Star_Trek/csharp/Objects/Starbase.cs
    index f9e5eaecb..c9abb8707 100644
    --- a/84_Super_Star_Trek/csharp/Objects/Starbase.cs
    +++ b/84_Super_Star_Trek/csharp/Objects/Starbase.cs
    @@ -1,44 +1,45 @@
    -using Games.Common.IO;
    -using Games.Common.Randomness;
     using SuperStarTrek.Resources;
     using SuperStarTrek.Space;
     
    -namespace SuperStarTrek.Objects;
    -
    -internal class Starbase
    +namespace SuperStarTrek.Objects
     {
    -    private readonly IReadWrite _io;
    -    private readonly float _repairDelay;
    -
    -    internal Starbase(Coordinates sector, IRandom random, IReadWrite io)
    +    internal class Starbase
         {
    -        Sector = sector;
    -        _repairDelay = random.NextFloat(0.5f);
    -        _io = io;
    -    }
    +        private readonly Input _input;
    +        private readonly Output _output;
    +        private readonly float _repairDelay;
     
    -    internal Coordinates Sector { get; }
    +        internal Starbase(Coordinates sector, Random random, Input input, Output output)
    +        {
    +            Sector = sector;
    +            _repairDelay = random.GetFloat() * 0.5f;
    +            _input = input;
    +            _output = output;
    +        }
     
    -    public override string ToString() => ">!<";
    +        internal Coordinates Sector { get; }
     
    -    internal bool TryRepair(Enterprise enterprise, out float repairTime)
    -    {
    -        repairTime = enterprise.DamagedSystemCount * 0.1f + _repairDelay;
    -        if (repairTime >= 1) { repairTime = 0.9f; }
    +        public override string ToString() => ">!<";
     
    -        _io.Write(Strings.RepairEstimate, repairTime);
    -        if (_io.GetYesNo(Strings.RepairPrompt, IReadWriteExtensions.YesNoMode.TrueOnY))
    +        internal bool TryRepair(Enterprise enterprise, out float repairTime)
             {
    -            foreach (var system in enterprise.Systems)
    +            repairTime = enterprise.DamagedSystemCount * 0.1f + _repairDelay;
    +            if (repairTime >= 1) { repairTime = 0.9f; }
    +
    +            _output.Write(Strings.RepairEstimate, repairTime);
    +            if (_input.GetYesNo(Strings.RepairPrompt, Input.YesNoMode.TrueOnY))
                 {
    -                system.Repair();
    +                foreach (var system in enterprise.Systems)
    +                {
    +                    system.Repair();
    +                }
    +                return true;
                 }
    -            return true;
    +
    +            repairTime = 0;
    +            return false;
             }
     
    -        repairTime = 0;
    -        return false;
    +        internal void ProtectEnterprise() => _output.WriteLine(Strings.Protected);
         }
    -
    -    internal void ProtectEnterprise() => _io.WriteLine(Strings.Protected);
     }
    diff --git a/84_Super_Star_Trek/csharp/Output.cs b/84_Super_Star_Trek/csharp/Output.cs
    new file mode 100644
    index 000000000..6a377bcef
    --- /dev/null
    +++ b/84_Super_Star_Trek/csharp/Output.cs
    @@ -0,0 +1,40 @@
    +using System;
    +
    +namespace SuperStarTrek
    +{
    +    internal class Output
    +    {
    +        internal Output Write(string text)
    +        {
    +            Console.Write(text);
    +            return this;
    +        }
    +
    +        internal Output Write(string format, params object[] args)
    +        {
    +            Console.Write(format, args);
    +            return this;
    +        }
    +
    +        internal Output WriteLine(string text = "")
    +        {
    +            Console.WriteLine(text);
    +            return this;
    +        }
    +
    +
    +        internal Output NextLine()
    +        {
    +            Console.WriteLine();
    +            return this;
    +        }
    +
    +
    +        internal Output Prompt(string text = "")
    +        {
    +            Console.Write($"{text}? ");
    +            return this;
    +        }
    +
    +    }
    +}
    diff --git a/84_Super_Star_Trek/csharp/Program.cs b/84_Super_Star_Trek/csharp/Program.cs
    index 730d56d4e..7080df29d 100644
    --- a/84_Super_Star_Trek/csharp/Program.cs
    +++ b/84_Super_Star_Trek/csharp/Program.cs
    @@ -23,18 +23,24 @@
     // ****  CONVERTED TO MICROSOFT C# 2/20/21 BY ANDREW COOPER
     // ****
     
    -using Games.Common.IO;
    -using Games.Common.Randomness;
    -using SuperStarTrek;
    -
    -var io = new ConsoleIO();
    -var random = new RandomNumberGenerator();
    +namespace SuperStarTrek
    +{
    +    internal class Program
    +    {
    +        static void Main()
    +        {
    +            var output = new Output();
    +            var input = new Input(output);
    +            var random = new Random();
     
    -var game = new Game(io, random);
    +            var game = new Game(output, input, random);
     
    -game.DoIntroduction();
    +            game.DoIntroduction();
     
    -do
    -{
    -    game.Play();
    -} while (game.Replay());
    +            do
    +            {
    +                game.Play();
    +            } while (game.Replay());
    +        }
    +    }
    +}
    diff --git a/84_Super_Star_Trek/csharp/Random.cs b/84_Super_Star_Trek/csharp/Random.cs
    new file mode 100644
    index 000000000..cd0ef2304
    --- /dev/null
    +++ b/84_Super_Star_Trek/csharp/Random.cs
    @@ -0,0 +1,25 @@
    +using SuperStarTrek.Space;
    +
    +namespace SuperStarTrek
    +{
    +    internal class Random
    +    {
    +        private readonly System.Random _random = new();
    +
    +        internal Coordinates GetCoordinate() => new Coordinates(Get1To8Inclusive() - 1, Get1To8Inclusive() - 1);
    +
    +        // Duplicates the algorithm used in the original code to get an integer value from 1 to 8, inclusive:
    +        //     475 DEF FNR(R)=INT(RND(R)*7.98+1.01)
    +        // Returns a value from 1 to 8, inclusive.
    +        // Note there's a slight bias away from the extreme values, 1 and 8.
    +        internal int Get1To8Inclusive() => (int)(GetFloat() * 7.98 + 1.01);
    +
    +        internal int GetInt(int inclusiveMinValue, int exclusiveMaxValue) =>
    +            _random.Next(inclusiveMinValue, exclusiveMaxValue);
    +
    +        internal float GetFloat() => (float)_random.NextDouble();
    +
    +        internal float GetFloat(float inclusiveMinValue, float exclusiveMaxValue)
    +            => GetFloat() * (exclusiveMaxValue - inclusiveMinValue) + inclusiveMinValue;
    +    }
    +}
    diff --git a/84_Super_Star_Trek/csharp/Space/Coordinates.cs b/84_Super_Star_Trek/csharp/Space/Coordinates.cs
    index adfda6dea..7aec927f2 100644
    --- a/84_Super_Star_Trek/csharp/Space/Coordinates.cs
    +++ b/84_Super_Star_Trek/csharp/Space/Coordinates.cs
    @@ -1,69 +1,70 @@
     using System;
     using SuperStarTrek.Utils;
     
    -namespace SuperStarTrek.Space;
    -
    -// Represents the corrdintate of a quadrant in the galaxy, or a sector in a quadrant.
    -// Note that the origin is top-left, x increase downwards, and y increases to the right.
    -internal record Coordinates
    +namespace SuperStarTrek.Space
     {
    -    internal Coordinates(int x, int y)
    +    // Represents the corrdintate of a quadrant in the galaxy, or a sector in a quadrant.
    +    // Note that the origin is top-left, x increase downwards, and y increases to the right.
    +    internal record Coordinates
         {
    -        X = Validated(x, nameof(x));
    -        Y = Validated(y, nameof(y));
    -
    -        RegionIndex = (X << 1) + (Y >> 2);
    -        SubRegionIndex = Y % 4;
    -    }
    +        internal Coordinates(int x, int y)
    +        {
    +            X = Validated(x, nameof(x));
    +            Y = Validated(y, nameof(y));
     
    -    internal int X { get; }
    +            RegionIndex = (X << 1) + (Y >> 2);
    +            SubRegionIndex = Y % 4;
    +        }
     
    -    internal int Y { get; }
    +        internal int X { get; }
    +        
    +        internal int Y { get; }
    +        
    +        internal int RegionIndex { get; }
    +        
    +        internal int SubRegionIndex { get; }
     
    -    internal int RegionIndex { get; }
    +        private static int Validated(int value, string argumentName)
    +        {
    +            if (value >= 0 && value <= 7) { return value; }
     
    -    internal int SubRegionIndex { get; }
    +            throw new ArgumentOutOfRangeException(argumentName, value, "Must be 0 to 7 inclusive");
    +        }
     
    -    private static int Validated(int value, string argumentName)
    -    {
    -        if (value >= 0 && value <= 7) { return value; }
    +        private static bool IsValid(int value) => value >= 0 && value <= 7;
     
    -        throw new ArgumentOutOfRangeException(argumentName, value, "Must be 0 to 7 inclusive");
    -    }
    +        public override string ToString() => $"{X+1} , {Y+1}";
     
    -    private static bool IsValid(int value) => value >= 0 && value <= 7;
    +        internal void Deconstruct(out int x, out int y)
    +        {
    +            x = X;
    +            y = Y;
    +        }
     
    -    public override string ToString() => $"{X+1} , {Y+1}";
    +        internal static bool TryCreate(float x, float y, out Coordinates coordinates)
    +        {
    +            var roundedX = Round(x);
    +            var roundedY = Round(y);
     
    -    internal void Deconstruct(out int x, out int y)
    -    {
    -        x = X;
    -        y = Y;
    -    }
    +            if (IsValid(roundedX) && IsValid(roundedY))
    +            {
    +                coordinates = new Coordinates(roundedX, roundedY);
    +                return true;
    +            }
     
    -    internal static bool TryCreate(float x, float y, out Coordinates coordinates)
    -    {
    -        var roundedX = Round(x);
    -        var roundedY = Round(y);
    +            coordinates = default;
    +            return false;
     
    -        if (IsValid(roundedX) && IsValid(roundedY))
    -        {
    -            coordinates = new Coordinates(roundedX, roundedY);
    -            return true;
    +            static int Round(float value) => (int)Math.Round(value, MidpointRounding.AwayFromZero);
             }
     
    -        coordinates = default;
    -        return false;
    +        internal (float Direction, float Distance) GetDirectionAndDistanceTo(Coordinates destination) =>
    +            DirectionAndDistance.From(this).To(destination);
     
    -        static int Round(float value) => (int)Math.Round(value, MidpointRounding.AwayFromZero);
    -    }
    -
    -    internal (float Direction, float Distance) GetDirectionAndDistanceTo(Coordinates destination) =>
    -        DirectionAndDistance.From(this).To(destination);
    -
    -    internal float GetDistanceTo(Coordinates destination)
    -    {
    -        var (_, distance) = GetDirectionAndDistanceTo(destination);
    -        return distance;
    +        internal float GetDistanceTo(Coordinates destination)
    +        {
    +            var (_, distance) = GetDirectionAndDistanceTo(destination);
    +            return distance;
    +        }
         }
     }
    diff --git a/84_Super_Star_Trek/csharp/Space/Course.cs b/84_Super_Star_Trek/csharp/Space/Course.cs
    index f411976aa..b316e4b38 100644
    --- a/84_Super_Star_Trek/csharp/Space/Course.cs
    +++ b/84_Super_Star_Trek/csharp/Space/Course.cs
    @@ -1,97 +1,98 @@
     using System;
     using System.Collections.Generic;
     
    -namespace SuperStarTrek.Space;
    -
    -// Implements the course calculations from the original code:
    -//     530 FORI=1TO9:C(I,1)=0:C(I,2)=0:NEXTI
    -//     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
    -//
    -//     3110 X1=C(C1,1)+(C(C1+1,1)-C(C1,1))*(C1-INT(C1))
    -//     3140 X2=C(C1,2)+(C(C1+1,2)-C(C1,2))*(C1-INT(C1))
    -internal class Course
    +namespace SuperStarTrek.Space
     {
    -    private static readonly (int DeltaX, int DeltaY)[] cardinals = new[]
    -    {
    -        (0, 1),
    -        (-1, 1),
    -        (-1, 0),
    -        (-1, -1),
    -        (0, -1),
    -        (1, -1),
    -        (1, 0),
    -        (1, 1),
    -        (0, 1)
    -    };
    -
    -    internal Course(float direction)
    +    // Implements the course calculations from the original code:
    +    //     530 FORI=1TO9:C(I,1)=0:C(I,2)=0:NEXTI
    +    //     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
    +    //
    +    //     3110 X1=C(C1,1)+(C(C1+1,1)-C(C1,1))*(C1-INT(C1))
    +    //     3140 X2=C(C1,2)+(C(C1+1,2)-C(C1,2))*(C1-INT(C1))
    +    internal class Course
         {
    -        if (direction < 1 || direction > 9)
    +        private static readonly (int DeltaX, int DeltaY)[] cardinals = new[]
             {
    -            throw new ArgumentOutOfRangeException(
    -                nameof(direction),
    -                direction,
    -                "Must be between 1 and 9, inclusive.");
    -        }
    -
    -        var cardinalDirection = (int)(direction - 1) % 8;
    -        var fractionalDirection = direction - (int)direction;
    +            (0, 1),
    +            (-1, 1),
    +            (-1, 0),
    +            (-1, -1),
    +            (0, -1),
    +            (1, -1),
    +            (1, 0),
    +            (1, 1),
    +            (0, 1)
    +        };
     
    -        var baseCardinal = cardinals[cardinalDirection];
    -        var nextCardinal = cardinals[cardinalDirection + 1];
    +        internal Course(float direction)
    +        {
    +            if (direction < 1 || direction > 9)
    +            {
    +                throw new ArgumentOutOfRangeException(
    +                    nameof(direction),
    +                    direction,
    +                    "Must be between 1 and 9, inclusive.");
    +            }
     
    -        DeltaX = baseCardinal.DeltaX + (nextCardinal.DeltaX - baseCardinal.DeltaX) * fractionalDirection;
    -        DeltaY = baseCardinal.DeltaY + (nextCardinal.DeltaY - baseCardinal.DeltaY) * fractionalDirection;
    -    }
    +            var cardinalDirection = (int)(direction - 1) % 8;
    +            var fractionalDirection = direction - (int)direction;
     
    -    internal float DeltaX { get; }
    +            var baseCardinal = cardinals[cardinalDirection];
    +            var nextCardinal = cardinals[cardinalDirection + 1];
     
    -    internal float DeltaY { get; }
    +            DeltaX = baseCardinal.DeltaX + (nextCardinal.DeltaX - baseCardinal.DeltaX) * fractionalDirection;
    +            DeltaY = baseCardinal.DeltaY + (nextCardinal.DeltaY - baseCardinal.DeltaY) * fractionalDirection;
    +        }
     
    -    internal IEnumerable GetSectorsFrom(Coordinates start)
    -    {
    -        (float x, float y) = start;
    +        internal float DeltaX { get; }
    +        
    +        internal float DeltaY { get; }
     
    -        while(true)
    +        internal IEnumerable GetSectorsFrom(Coordinates start)
             {
    -            x += DeltaX;
    -            y += DeltaY;
    +            (float x, float y) = start;
     
    -            if (!Coordinates.TryCreate(x, y, out var coordinates))
    +            while(true)
                 {
    -                yield break;
    -            }
    -
    -            yield return coordinates;
    -        }
    -    }
    -
    -    internal (bool, Coordinates, Coordinates) GetDestination(Coordinates quadrant, Coordinates sector, int distance)
    -    {
    -        var (xComplete, quadrantX, sectorX) = GetNewCoordinate(quadrant.X, sector.X, DeltaX * distance);
    -        var (yComplete, quadrantY, sectorY) = GetNewCoordinate(quadrant.Y, sector.Y, DeltaY * distance);
    +                x += DeltaX;
    +                y += DeltaY;
     
    -        return (xComplete && yComplete, new Coordinates(quadrantX, quadrantY), new Coordinates(sectorX, sectorY));
    -    }
    +                if (!Coordinates.TryCreate(x, y, out var coordinates))
    +                {
    +                    yield break;
    +                }
     
    -    private static (bool, int, int) GetNewCoordinate(int quadrant, int sector, float sectorsTravelled)
    -    {
    -        var galacticCoordinate = quadrant * 8 + sector + sectorsTravelled;
    -        var newQuadrant = (int)(galacticCoordinate / 8);
    -        var newSector = (int)(galacticCoordinate - newQuadrant * 8);
    +                yield return coordinates;
    +            }
    +        }
     
    -        if (newSector < 0)
    +        internal (bool, Coordinates, Coordinates) GetDestination(Coordinates quadrant, Coordinates sector, int distance)
             {
    -            newQuadrant -= 1;
    -            newSector += 8;
    +            var (xComplete, quadrantX, sectorX) = GetNewCoordinate(quadrant.X, sector.X, DeltaX * distance);
    +            var (yComplete, quadrantY, sectorY) = GetNewCoordinate(quadrant.Y, sector.Y, DeltaY * distance);
    +
    +            return (xComplete && yComplete, new Coordinates(quadrantX, quadrantY), new Coordinates(sectorX, sectorY));
             }
     
    -        return newQuadrant switch
    +        private static (bool, int, int) GetNewCoordinate(int quadrant, int sector, float sectorsTravelled)
             {
    -            < 0 => (false, 0, 0),
    -            > 7 => (false, 7, 7),
    -            _ => (true, newQuadrant, newSector)
    -        };
    +            var galacticCoordinate = quadrant * 8 + sector + sectorsTravelled;
    +            var newQuadrant = (int)(galacticCoordinate / 8);
    +            var newSector = (int)(galacticCoordinate - newQuadrant * 8);
    +
    +            if (newSector < 0)
    +            {
    +                newQuadrant -= 1;
    +                newSector += 8;
    +            }
    +
    +            return newQuadrant switch
    +            {
    +                < 0 => (false, 0, 0),
    +                > 7 => (false, 7, 7),
    +                _ => (true, newQuadrant, newSector)
    +            };
    +        }
         }
     }
    diff --git a/84_Super_Star_Trek/csharp/Space/Galaxy.cs b/84_Super_Star_Trek/csharp/Space/Galaxy.cs
    index d8e990b4b..0b348b06a 100644
    --- a/84_Super_Star_Trek/csharp/Space/Galaxy.cs
    +++ b/84_Super_Star_Trek/csharp/Space/Galaxy.cs
    @@ -1,64 +1,64 @@
     using System.Collections.Generic;
     using System.Linq;
    -using Games.Common.Randomness;
     using SuperStarTrek.Resources;
     
     using static System.StringSplitOptions;
     
    -namespace SuperStarTrek.Space;
    -
    -internal class Galaxy
    +namespace SuperStarTrek.Space
     {
    -    private static readonly string[] _regionNames;
    -    private static readonly string[] _subRegionIdentifiers;
    -    private readonly QuadrantInfo[][] _quadrants;
    -
    -    static Galaxy()
    +    internal class Galaxy
         {
    -        _regionNames = Strings.RegionNames.Split(new[] { ' ', '\n' }, RemoveEmptyEntries | TrimEntries);
    -        _subRegionIdentifiers = new[] { "I", "II", "III", "IV" };
    -    }
    +        private static readonly string[] _regionNames;
    +        private static readonly string[] _subRegionIdentifiers;
    +        private readonly QuadrantInfo[][] _quadrants;
     
    -    internal Galaxy(IRandom random)
    -    {
    -        _quadrants = Enumerable
    -            .Range(0, 8)
    -            .Select(x => Enumerable
    -                .Range(0, 8)
    -                .Select(y => new Coordinates(x, y))
    -                .Select(c => QuadrantInfo.Create(c, GetQuadrantName(c), random))
    -                .ToArray())
    -            .ToArray();
    +        static Galaxy()
    +        {
    +            _regionNames = Strings.RegionNames.Split(new[] { ' ', '\n' }, RemoveEmptyEntries | TrimEntries);
    +            _subRegionIdentifiers = new[] { "I", "II", "III", "IV" };
    +        }
     
    -        if (StarbaseCount == 0)
    +        internal Galaxy(Random random)
             {
    -            var randomQuadrant = this[random.NextCoordinate()];
    -            randomQuadrant.AddStarbase();
    +            _quadrants = Enumerable
    +                .Range(0, 8)
    +                .Select(x => Enumerable
    +                    .Range(0, 8)
    +                    .Select(y => new Coordinates(x, y))
    +                    .Select(c => QuadrantInfo.Create(c, GetQuadrantName(c), random))
    +                    .ToArray())
    +                .ToArray();
     
    -            if (randomQuadrant.KlingonCount < 2)
    +            if (StarbaseCount == 0)
                 {
    -                randomQuadrant.AddKlingon();
    +                var randomQuadrant = this[random.GetCoordinate()];
    +                randomQuadrant.AddStarbase();
    +
    +                if (randomQuadrant.KlingonCount < 2)
    +                {
    +                    randomQuadrant.AddKlingon();
    +                }
                 }
             }
    -    }
     
    -    internal QuadrantInfo this[Coordinates coordinate] => _quadrants[coordinate.X][coordinate.Y];
    +        internal QuadrantInfo this[Coordinates coordinate] => _quadrants[coordinate.X][coordinate.Y];
     
    -    internal int KlingonCount => _quadrants.SelectMany(q => q).Sum(q => q.KlingonCount);
    +        internal int KlingonCount => _quadrants.SelectMany(q => q).Sum(q => q.KlingonCount);
     
    -    internal int StarbaseCount => _quadrants.SelectMany(q => q).Count(q => q.HasStarbase);
    +        internal int StarbaseCount => _quadrants.SelectMany(q => q).Count(q => q.HasStarbase);
     
    -    internal IEnumerable> Quadrants => _quadrants;
    +        internal IEnumerable> Quadrants => _quadrants;
     
    -    private static string GetQuadrantName(Coordinates coordinates) =>
    -        $"{_regionNames[coordinates.RegionIndex]} {_subRegionIdentifiers[coordinates.SubRegionIndex]}";
    +        private static string GetQuadrantName(Coordinates coordinates) =>
    +            $"{_regionNames[coordinates.RegionIndex]} {_subRegionIdentifiers[coordinates.SubRegionIndex]}";
     
    -    internal IEnumerable> GetNeighborhood(Quadrant quadrant) =>
    -        Enumerable.Range(-1, 3)
    -            .Select(dx => dx + quadrant.Coordinates.X)
    -            .Select(x => GetNeighborhoodRow(quadrant, x));
    -    private IEnumerable GetNeighborhoodRow(Quadrant quadrant, int x) =>
    -        Enumerable.Range(-1, 3)
    -            .Select(dy => dy + quadrant.Coordinates.Y)
    -            .Select(y => y < 0 || y > 7 || x < 0 || x > 7 ? null : _quadrants[x][y]);
    +        internal IEnumerable> GetNeighborhood(Quadrant quadrant) =>
    +            Enumerable.Range(-1, 3)
    +                .Select(dx => dx + quadrant.Coordinates.X)
    +                .Select(x => GetNeighborhoodRow(quadrant, x));
    +        private IEnumerable GetNeighborhoodRow(Quadrant quadrant, int x) =>
    +            Enumerable.Range(-1, 3)
    +                .Select(dy => dy + quadrant.Coordinates.Y)
    +                .Select(y => y < 0 || y > 7 || x < 0 || x > 7 ? null : _quadrants[x][y]);
    +    }
     }
    diff --git a/84_Super_Star_Trek/csharp/Space/Quadrant.cs b/84_Super_Star_Trek/csharp/Space/Quadrant.cs
    index ba8f9a99d..694f7fc87 100644
    --- a/84_Super_Star_Trek/csharp/Space/Quadrant.cs
    +++ b/84_Super_Star_Trek/csharp/Space/Quadrant.cs
    @@ -1,192 +1,192 @@
     using System;
     using System.Collections.Generic;
     using System.Linq;
    -using Games.Common.IO;
    -using Games.Common.Randomness;
     using SuperStarTrek.Commands;
     using SuperStarTrek.Objects;
     using SuperStarTrek.Resources;
     
    -namespace SuperStarTrek.Space;
    -
    -internal class Quadrant
    +namespace SuperStarTrek.Space
     {
    -    private readonly QuadrantInfo _info;
    -    private readonly IRandom _random;
    -    private readonly Dictionary _sectors;
    -    private readonly Enterprise _enterprise;
    -    private readonly IReadWrite _io;
    -    private bool _entered = false;
    -
    -    internal Quadrant(
    -        QuadrantInfo info,
    -        Enterprise enterprise,
    -        IRandom random,
    -        Galaxy galaxy,
    -        IReadWrite io)
    +    internal class Quadrant
         {
    -        _info = info;
    -        _random = random;
    -        _io = io;
    -        Galaxy = galaxy;
    -
    -        info.MarkAsKnown();
    -        _sectors = new() { [enterprise.SectorCoordinates] = _enterprise = enterprise };
    -        PositionObject(sector => new Klingon(sector, _random), _info.KlingonCount);
    -        if (_info.HasStarbase)
    +        private readonly QuadrantInfo _info;
    +        private readonly Random _random;
    +        private readonly Dictionary _sectors;
    +        private readonly Enterprise _enterprise;
    +        private readonly Output _output;
    +        private bool _entered = false;
    +
    +        internal Quadrant(
    +            QuadrantInfo info,
    +            Enterprise enterprise,
    +            Random random,
    +            Galaxy galaxy,
    +            Input input,
    +            Output output)
             {
    -            Starbase = PositionObject(sector => new Starbase(sector, _random, io));
    +            _info = info;
    +            _random = random;
    +            _output = output;
    +            Galaxy = galaxy;
    +
    +            info.MarkAsKnown();
    +            _sectors = new() { [enterprise.SectorCoordinates] = _enterprise = enterprise };
    +            PositionObject(sector => new Klingon(sector, _random), _info.KlingonCount);
    +            if (_info.HasStarbase)
    +            {
    +                Starbase = PositionObject(sector => new Starbase(sector, _random, input, output));
    +            }
    +            PositionObject(_ => new Star(), _info.StarCount);
             }
    -        PositionObject(_ => new Star(), _info.StarCount);
    -    }
     
    -    internal Coordinates Coordinates => _info.Coordinates;
    +        internal Coordinates Coordinates => _info.Coordinates;
     
    -    internal bool HasKlingons => _info.KlingonCount > 0;
    +        internal bool HasKlingons => _info.KlingonCount > 0;
     
    -    internal int KlingonCount => _info.KlingonCount;
    +        internal int KlingonCount => _info.KlingonCount;
     
    -    internal bool HasStarbase => _info.HasStarbase;
    +        internal bool HasStarbase => _info.HasStarbase;
     
    -    internal Starbase Starbase { get; }
    +        internal Starbase Starbase { get; }
     
    -    internal Galaxy Galaxy { get; }
    +        internal Galaxy Galaxy { get; }
     
    -    internal bool EnterpriseIsNextToStarbase =>
    -        _info.HasStarbase &&
    -        Math.Abs(_enterprise.SectorCoordinates.X - Starbase.Sector.X) <= 1 &&
    -        Math.Abs(_enterprise.SectorCoordinates.Y - Starbase.Sector.Y) <= 1;
    +        internal bool EnterpriseIsNextToStarbase =>
    +            _info.HasStarbase &&
    +            Math.Abs(_enterprise.SectorCoordinates.X - Starbase.Sector.X) <= 1 &&
    +            Math.Abs(_enterprise.SectorCoordinates.Y - Starbase.Sector.Y) <= 1;
     
    -    internal IEnumerable Klingons => _sectors.Values.OfType();
    +        internal IEnumerable Klingons => _sectors.Values.OfType();
     
    -    public override string ToString() => _info.Name;
    -
    -    private T PositionObject(Func objectFactory)
    -    {
    -        var sector = GetRandomEmptySector();
    -        _sectors[sector] = objectFactory.Invoke(sector);
    -        return (T)_sectors[sector];
    -    }
    +        public override string ToString() => _info.Name;
     
    -    private void PositionObject(Func objectFactory, int count)
    -    {
    -        for (int i = 0; i < count; i++)
    +        private T PositionObject(Func objectFactory)
             {
    -            PositionObject(objectFactory);
    +            var sector = GetRandomEmptySector();
    +            _sectors[sector] = objectFactory.Invoke(sector);
    +            return (T)_sectors[sector];
             }
    -    }
     
    -    internal void Display(string textFormat)
    -    {
    -        if (!_entered)
    +        private void PositionObject(Func objectFactory, int count)
             {
    -            _io.Write(textFormat, this);
    -            _entered = true;
    +            for (int i = 0; i < count; i++)
    +            {
    +                PositionObject(objectFactory);
    +            }
             }
     
    -        if (_info.KlingonCount > 0)
    +        internal void Display(string textFormat)
             {
    -            _io.Write(Strings.CombatArea);
    -            if (_enterprise.ShieldControl.ShieldEnergy <= 200) { _io.Write(Strings.LowShields); }
    -        }
    +            if (!_entered)
    +            {
    +                _output.Write(textFormat, this);
    +                _entered = true;
    +            }
     
    -        _enterprise.Execute(Command.SRS);
    -    }
    +            if (_info.KlingonCount > 0)
    +            {
    +                _output.Write(Strings.CombatArea);
    +                if (_enterprise.ShieldControl.ShieldEnergy <= 200) { _output.Write(Strings.LowShields); }
    +            }
     
    -    internal bool HasObjectAt(Coordinates coordinates) => _sectors.ContainsKey(coordinates);
    +            _enterprise.Execute(Command.SRS);
    +        }
     
    -    internal bool TorpedoCollisionAt(Coordinates coordinates, out string message, out bool gameOver)
    -    {
    -        gameOver = false;
    -        message = default;
    +        internal bool HasObjectAt(Coordinates coordinates) => _sectors.ContainsKey(coordinates);
     
    -        switch (_sectors.GetValueOrDefault(coordinates))
    +        internal bool TorpedoCollisionAt(Coordinates coordinates, out string message, out bool gameOver)
             {
    -            case Klingon klingon:
    -                message = Remove(klingon);
    -                gameOver = Galaxy.KlingonCount == 0;
    -                return true;
    -
    -            case Star _:
    -                message = $"Star at {coordinates} absorbed torpedo energy.";
    -                return true;
    -
    -            case Starbase _:
    -                _sectors.Remove(coordinates);
    -                _info.RemoveStarbase();
    -                message = "*** Starbase destroyed ***" +
    -                    (Galaxy.StarbaseCount > 0 ? Strings.CourtMartial : Strings.RelievedOfCommand);
    -                gameOver = Galaxy.StarbaseCount == 0;
    -                return true;
    -
    -            default:
    -                return false;
    -        }
    -    }
    +            gameOver = false;
    +            message = default;
     
    -    internal string Remove(Klingon klingon)
    -    {
    -        _sectors.Remove(klingon.Sector);
    -        _info.RemoveKlingon();
    -        return "*** Klingon destroyed ***";
    -    }
    +            switch (_sectors.GetValueOrDefault(coordinates))
    +            {
    +                case Klingon klingon:
    +                    message = Remove(klingon);
    +                    gameOver = Galaxy.KlingonCount == 0;
    +                    return true;
    +
    +                case Star _:
    +                    message = $"Star at {coordinates} absorbed torpedo energy.";
    +                    return true;
    +
    +                case Starbase _:
    +                    _sectors.Remove(coordinates);
    +                    _info.RemoveStarbase();
    +                    message = "*** Starbase destroyed ***" +
    +                        (Galaxy.StarbaseCount > 0 ? Strings.CourtMartial : Strings.RelievedOfCommand);
    +                    gameOver = Galaxy.StarbaseCount == 0;
    +                    return true;
    +
    +                default:
    +                    return false;
    +            }
    +        }
     
    -    internal CommandResult KlingonsMoveAndFire()
    -    {
    -        foreach (var klingon in Klingons.ToList())
    +        internal string Remove(Klingon klingon)
             {
    -            var newSector = GetRandomEmptySector();
                 _sectors.Remove(klingon.Sector);
    -            _sectors[newSector] = klingon;
    -            klingon.MoveTo(newSector);
    +            _info.RemoveKlingon();
    +            return "*** Klingon destroyed ***";
             }
     
    -        return KlingonsFireOnEnterprise();
    -    }
    -
    -    internal CommandResult KlingonsFireOnEnterprise()
    -    {
    -        if (EnterpriseIsNextToStarbase && Klingons.Any())
    +        internal CommandResult KlingonsMoveAndFire()
             {
    -            Starbase.ProtectEnterprise();
    -            return CommandResult.Ok;
    +            foreach (var klingon in Klingons.ToList())
    +            {
    +                var newSector = GetRandomEmptySector();
    +                _sectors.Remove(klingon.Sector);
    +                _sectors[newSector] = klingon;
    +                klingon.MoveTo(newSector);
    +            }
    +
    +            return KlingonsFireOnEnterprise();
             }
     
    -        foreach (var klingon in Klingons)
    +        internal CommandResult KlingonsFireOnEnterprise()
             {
    -            var result = klingon.FireOn(_enterprise);
    -            if (result.IsGameOver) { return result; }
    -        }
    +            if (EnterpriseIsNextToStarbase && Klingons.Any())
    +            {
    +                Starbase.ProtectEnterprise();
    +                return CommandResult.Ok;
    +            }
     
    -        return CommandResult.Ok;
    -    }
    +            foreach (var klingon in Klingons)
    +            {
    +                var result = klingon.FireOn(_enterprise);
    +                if (result.IsGameOver) { return result; }
    +            }
     
    -    private Coordinates GetRandomEmptySector()
    -    {
    -        while (true)
    +            return CommandResult.Ok;
    +        }
    +
    +        private Coordinates GetRandomEmptySector()
             {
    -            var sector = _random.NextCoordinate();
    -            if (!_sectors.ContainsKey(sector))
    +            while (true)
                 {
    -                return sector;
    +                var sector = _random.GetCoordinate();
    +                if (!_sectors.ContainsKey(sector))
    +                {
    +                    return sector;
    +                }
                 }
             }
    -    }
     
    -    internal IEnumerable GetDisplayLines() => Enumerable.Range(0, 8).Select(x => GetDisplayLine(x));
    +        internal IEnumerable GetDisplayLines() => Enumerable.Range(0, 8).Select(x => GetDisplayLine(x));
     
    -    private string GetDisplayLine(int x) =>
    -        string.Join(
    -            " ",
    -            Enumerable
    -                .Range(0, 8)
    -                .Select(y => new Coordinates(x, y))
    -                .Select(c => _sectors.GetValueOrDefault(c))
    -                .Select(o => o?.ToString() ?? "   "));
    +        private string GetDisplayLine(int x) =>
    +            string.Join(
    +                " ",
    +                Enumerable
    +                    .Range(0, 8)
    +                    .Select(y => new Coordinates(x, y))
    +                    .Select(c => _sectors.GetValueOrDefault(c))
    +                    .Select(o => o?.ToString() ?? "   "));
     
    -    internal void SetEnterpriseSector(Coordinates sector)
    -    {
    -        _sectors.Remove(_enterprise.SectorCoordinates);
    -        _sectors[sector] = _enterprise;
    +        internal void SetEnterpriseSector(Coordinates sector)
    +        {
    +            _sectors.Remove(_enterprise.SectorCoordinates);
    +            _sectors[sector] = _enterprise;
    +        }
         }
     }
    diff --git a/84_Super_Star_Trek/csharp/Space/QuadrantInfo.cs b/84_Super_Star_Trek/csharp/Space/QuadrantInfo.cs
    index 0c0b65a02..6a403c2e2 100644
    --- a/84_Super_Star_Trek/csharp/Space/QuadrantInfo.cs
    +++ b/84_Super_Star_Trek/csharp/Space/QuadrantInfo.cs
    @@ -1,66 +1,65 @@
    -using Games.Common.Randomness;
    -
    -namespace SuperStarTrek.Space;
    -
    -internal class QuadrantInfo
    +namespace SuperStarTrek.Space
     {
    -    private bool _isKnown;
    -
    -    private QuadrantInfo(Coordinates coordinates, string name, int klingonCount, int starCount, bool hasStarbase)
    +    internal class QuadrantInfo
         {
    -        Coordinates = coordinates;
    -        Name = name;
    -        KlingonCount = klingonCount;
    -        StarCount = starCount;
    -        HasStarbase = hasStarbase;
    -    }
    +        private bool _isKnown;
     
    -    internal Coordinates Coordinates { get; }
    +        private QuadrantInfo(Coordinates coordinates, string name, int klingonCount, int starCount, bool hasStarbase)
    +        {
    +            Coordinates = coordinates;
    +            Name = name;
    +            KlingonCount = klingonCount;
    +            StarCount = starCount;
    +            HasStarbase = hasStarbase;
    +        }
     
    -    internal string Name { get; }
    +        internal Coordinates Coordinates { get; }
     
    -    internal int KlingonCount { get; private set; }
    +        internal string Name { get; }
     
    -    internal bool HasStarbase { get; private set; }
    +        internal int KlingonCount { get; private set; }
     
    -    internal int StarCount { get; }
    +        internal bool HasStarbase { get; private set; }
     
    -    internal static QuadrantInfo Create(Coordinates coordinates, string name, IRandom random)
    -    {
    -        var klingonCount = random.NextFloat() switch
    -        {
    -            > 0.98f => 3,
    -            > 0.95f => 2,
    -            > 0.80f => 1,
    -            _ => 0
    -        };
    -        var hasStarbase = random.NextFloat() > 0.96f;
    -        var starCount = random.Next1To8Inclusive();
    +        internal int StarCount { get; }
     
    -        return new QuadrantInfo(coordinates, name, klingonCount, starCount, hasStarbase);
    -    }
    +        internal static QuadrantInfo Create(Coordinates coordinates, string name, Random random)
    +        {
    +            var klingonCount = random.GetFloat() switch
    +            {
    +                > 0.98f => 3,
    +                > 0.95f => 2,
    +                > 0.80f => 1,
    +                _ => 0
    +            };
    +            var hasStarbase = random.GetFloat() > 0.96f;
    +            var starCount = random.Get1To8Inclusive();
    +
    +            return new QuadrantInfo(coordinates, name, klingonCount, starCount, hasStarbase);
    +        }
     
    -    internal void AddKlingon() => KlingonCount += 1;
    +        internal void AddKlingon() => KlingonCount += 1;
     
    -    internal void AddStarbase() => HasStarbase = true;
    +        internal void AddStarbase() => HasStarbase = true;
     
    -    internal void MarkAsKnown() => _isKnown = true;
    +        internal void MarkAsKnown() => _isKnown = true;
     
    -    internal string Scan()
    -    {
    -        _isKnown = true;
    -        return ToString();
    -    }
    +        internal string Scan()
    +        {
    +            _isKnown = true;
    +            return ToString();
    +        }
     
    -    public override string ToString() => _isKnown ? $"{KlingonCount}{(HasStarbase ? 1 : 0)}{StarCount}" : "***";
    +        public override string ToString() => _isKnown ? $"{KlingonCount}{(HasStarbase ? 1 : 0)}{StarCount}" : "***";
     
    -    internal void RemoveKlingon()
    -    {
    -        if (KlingonCount > 0)
    +        internal void RemoveKlingon()
             {
    -            KlingonCount -= 1;
    +            if (KlingonCount > 0)
    +            {
    +                KlingonCount -= 1;
    +            }
             }
    -    }
     
    -    internal void RemoveStarbase() => HasStarbase = false;
    +        internal void RemoveStarbase() => HasStarbase = false;
    +    }
     }
    diff --git a/84_Super_Star_Trek/csharp/StringExtensions.cs b/84_Super_Star_Trek/csharp/StringExtensions.cs
    index 4706e9cb8..02e9794fe 100644
    --- a/84_Super_Star_Trek/csharp/StringExtensions.cs
    +++ b/84_Super_Star_Trek/csharp/StringExtensions.cs
    @@ -1,6 +1,7 @@
    -namespace SuperStarTrek;
    -
    -internal static class StringExtensions
    +namespace SuperStarTrek
     {
    -    internal static string Pluralize(this string singular, int quantity) => singular + (quantity > 1 ? "s" : "");
    -}
    +    internal static class StringExtensions
    +    {
    +        internal static string Pluralize(this string singular, int quantity) => singular + (quantity > 1 ? "s" : "");
    +    }
    +}
    \ No newline at end of file
    diff --git a/84_Super_Star_Trek/csharp/SuperStarTrek.csproj b/84_Super_Star_Trek/csharp/SuperStarTrek.csproj
    index de228ec6e..c0de0594a 100644
    --- a/84_Super_Star_Trek/csharp/SuperStarTrek.csproj
    +++ b/84_Super_Star_Trek/csharp/SuperStarTrek.csproj
    @@ -2,15 +2,11 @@
     
       
         Exe
    -    net6.0
    +    net5.0
       
     
       
         
       
     
    -  
    -    
    -  
    -
     
    diff --git a/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/ComputerFunction.cs b/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/ComputerFunction.cs
    index 4356b8593..36d9127b4 100644
    --- a/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/ComputerFunction.cs
    +++ b/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/ComputerFunction.cs
    @@ -1,19 +1,19 @@
    -using Games.Common.IO;
     using SuperStarTrek.Space;
     
    -namespace SuperStarTrek.Systems.ComputerFunctions;
    -
    -internal abstract class ComputerFunction
    +namespace SuperStarTrek.Systems.ComputerFunctions
     {
    -    protected ComputerFunction(string description, IReadWrite io)
    +    internal abstract class ComputerFunction
         {
    -        Description = description;
    -        IO = io;
    -    }
    +        protected ComputerFunction(string description, Output output)
    +        {
    +            Description = description;
    +            Output = output;
    +        }
     
    -    internal string Description { get; }
    +        internal string Description { get; }
     
    -    protected IReadWrite IO { get; }
    +        protected Output Output { get; }
     
    -    internal abstract void Execute(Quadrant quadrant);
    -}
    +        internal abstract void Execute(Quadrant quadrant);
    +    }
    +}
    \ No newline at end of file
    diff --git a/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/CumulativeGalacticRecord.cs b/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/CumulativeGalacticRecord.cs
    index f7c93f2ba..f02677ca2 100644
    --- a/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/CumulativeGalacticRecord.cs
    +++ b/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/CumulativeGalacticRecord.cs
    @@ -1,24 +1,21 @@
    +using System;
     using System.Collections.Generic;
     using System.Linq;
    -using Games.Common.IO;
     using SuperStarTrek.Space;
     
    -namespace SuperStarTrek.Systems.ComputerFunctions;
    -
    -internal class CumulativeGalacticRecord : GalacticReport
    +namespace SuperStarTrek.Systems.ComputerFunctions
     {
    -    internal CumulativeGalacticRecord(IReadWrite io, Galaxy galaxy)
    -        : base("Cumulative galactic record", io, galaxy)
    +    internal class CumulativeGalacticRecord : GalacticReport
         {
    -    }
    +        internal CumulativeGalacticRecord(Output output, Galaxy galaxy)
    +            : base("Cumulative galactic record", output, galaxy)
    +        {
    +        }
     
    -    protected override void WriteHeader(Quadrant quadrant)
    -    {
    -        IO.WriteLine();
    -        IO.WriteLine($"Computer record of galaxy for quadrant {quadrant.Coordinates}");
    -        IO.WriteLine();
    -    }
    +        protected override void WriteHeader(Quadrant quadrant) =>
    +            Output.NextLine().WriteLine($"Computer record of galaxy for quadrant {quadrant.Coordinates}").NextLine();
     
    -    protected override IEnumerable GetRowData() =>
    -        Galaxy.Quadrants.Select(row => " " + string.Join("   ", row));
    -}
    +        protected override IEnumerable GetRowData() =>
    +            Galaxy.Quadrants.Select(row => " " + string.Join("   ", row));
    +    }
    +}
    \ No newline at end of file
    diff --git a/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/DirectionDistanceCalculator.cs b/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/DirectionDistanceCalculator.cs
    index e3402ab2d..a3679ada9 100644
    --- a/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/DirectionDistanceCalculator.cs
    +++ b/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/DirectionDistanceCalculator.cs
    @@ -1,30 +1,30 @@
    -using Games.Common.IO;
     using SuperStarTrek.Objects;
     using SuperStarTrek.Space;
     
    -namespace SuperStarTrek.Systems.ComputerFunctions;
    -
    -internal class DirectionDistanceCalculator : NavigationCalculator
    +namespace SuperStarTrek.Systems.ComputerFunctions
     {
    -    private readonly Enterprise _enterprise;
    -    private readonly IReadWrite _io;
    -
    -    internal DirectionDistanceCalculator(Enterprise enterprise, IReadWrite io)
    -        : base("Direction/distance calculator", io)
    +    internal class DirectionDistanceCalculator : NavigationCalculator
         {
    -        _enterprise = enterprise;
    -        _io = io;
    -    }
    +        private readonly Enterprise _enterprise;
    +        private readonly Input _input;
     
    -    internal override void Execute(Quadrant quadrant)
    -    {
    -        IO.WriteLine("Direction/distance calculator:");
    -        IO.Write($"You are at quadrant {_enterprise.QuadrantCoordinates}");
    -        IO.WriteLine($" sector {_enterprise.SectorCoordinates}");
    -        IO.WriteLine("Please enter");
    +        internal DirectionDistanceCalculator(Enterprise enterprise, Output output, Input input)
    +            : base("Direction/distance calculator", output)
    +        {
    +            _enterprise = enterprise;
    +            _input = input;
    +        }
    +
    +        internal override void Execute(Quadrant quadrant)
    +        {
    +            Output.WriteLine("Direction/distance calculator:")
    +                .Write($"You are at quadrant {_enterprise.QuadrantCoordinates}")
    +                .WriteLine($" sector {_enterprise.SectorCoordinates}")
    +                .WriteLine("Please enter");
     
    -        WriteDirectionAndDistance(
    -            _io.GetCoordinates("  Initial coordinates"),
    -            _io.GetCoordinates("  Final coordinates"));
    +            WriteDirectionAndDistance(
    +                _input.GetCoordinates("  Initial coordinates"),
    +                _input.GetCoordinates("  Final coordinates"));
    +        }
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/GalacticReport.cs b/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/GalacticReport.cs
    index 49f7363de..8be29baf5 100644
    --- a/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/GalacticReport.cs
    +++ b/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/GalacticReport.cs
    @@ -1,34 +1,34 @@
     using System.Collections.Generic;
     using System.Linq;
    -using Games.Common.IO;
     using SuperStarTrek.Space;
     
    -namespace SuperStarTrek.Systems.ComputerFunctions;
    -
    -internal abstract class GalacticReport : ComputerFunction
    +namespace SuperStarTrek.Systems.ComputerFunctions
     {
    -    internal GalacticReport(string description, IReadWrite io, Galaxy galaxy)
    -        : base(description, io)
    +    internal abstract class GalacticReport : ComputerFunction
         {
    -        Galaxy = galaxy;
    -    }
    -
    -    protected Galaxy Galaxy { get; }
    +        internal GalacticReport(string description, Output output, Galaxy galaxy)
    +            : base(description, output)
    +        {
    +            Galaxy = galaxy;
    +        }
     
    -    protected abstract void WriteHeader(Quadrant quadrant);
    +        protected Galaxy Galaxy { get; }
     
    -    protected abstract IEnumerable GetRowData();
    +        protected abstract void WriteHeader(Quadrant quadrant);
     
    -    internal sealed override void Execute(Quadrant quadrant)
    -    {
    -        WriteHeader(quadrant);
    -        IO.WriteLine("       1     2     3     4     5     6     7     8");
    -        IO.WriteLine("     ----- ----- ----- ----- ----- ----- ----- -----");
    +        protected abstract IEnumerable GetRowData();
     
    -        foreach (var (row, index) in GetRowData().Select((r, i) => (r, i)))
    +        internal sealed override void Execute(Quadrant quadrant)
             {
    -            IO.WriteLine($" {index+1}   {row}");
    -            IO.WriteLine("     ----- ----- ----- ----- ----- ----- ----- -----");
    +            WriteHeader(quadrant);
    +            Output.WriteLine("       1     2     3     4     5     6     7     8")
    +                .WriteLine("     ----- ----- ----- ----- ----- ----- ----- -----");
    +
    +            foreach (var (row, index) in GetRowData().Select((r, i) => (r, i)))
    +            {
    +                Output.WriteLine($" {index+1}   {row}")
    +                    .WriteLine("     ----- ----- ----- ----- ----- ----- ----- -----");
    +            }
             }
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/GalaxyRegionMap.cs b/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/GalaxyRegionMap.cs
    index c4850e1c5..f6fe0305a 100644
    --- a/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/GalaxyRegionMap.cs
    +++ b/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/GalaxyRegionMap.cs
    @@ -1,21 +1,21 @@
     using System.Collections.Generic;
     using System.Linq;
    -using Games.Common.IO;
     using SuperStarTrek.Resources;
     using SuperStarTrek.Space;
     
    -namespace SuperStarTrek.Systems.ComputerFunctions;
    -
    -internal class GalaxyRegionMap : GalacticReport
    +namespace SuperStarTrek.Systems.ComputerFunctions
     {
    -    internal GalaxyRegionMap(IReadWrite io, Galaxy galaxy)
    -        : base("Galaxy 'region name' map", io, galaxy)
    +    internal class GalaxyRegionMap : GalacticReport
         {
    -    }
    +        internal GalaxyRegionMap(Output output, Galaxy galaxy)
    +            : base("Galaxy 'region name' map", output, galaxy)
    +        {
    +        }
     
    -    protected override void WriteHeader(Quadrant quadrant) =>
    -        IO.WriteLine("                        The Galaxy");
    +        protected override void WriteHeader(Quadrant quadrant) =>
    +            Output.WriteLine("                        The Galaxy");
     
    -    protected override IEnumerable GetRowData() =>
    -        Strings.RegionNames.Split('\n').Select(n => n.TrimEnd('\r'));
    -}
    +        protected override IEnumerable GetRowData() =>
    +            Strings.RegionNames.Split('\n').Select(n => n.TrimEnd('\r'));
    +    }
    +}
    \ No newline at end of file
    diff --git a/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/NavigationCalculator.cs b/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/NavigationCalculator.cs
    index bddb00d2b..680f3d18e 100644
    --- a/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/NavigationCalculator.cs
    +++ b/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/NavigationCalculator.cs
    @@ -1,31 +1,29 @@
    -using Games.Common.IO;
     using SuperStarTrek.Space;
     using SuperStarTrek.Utils;
     
    -namespace SuperStarTrek.Systems.ComputerFunctions;
    -
    -internal abstract class NavigationCalculator : ComputerFunction
    +namespace SuperStarTrek.Systems.ComputerFunctions
     {
    -    protected NavigationCalculator(string description, IReadWrite io)
    -        : base(description, io)
    +    internal abstract class NavigationCalculator : ComputerFunction
         {
    -    }
    +        protected NavigationCalculator(string description, Output output)
    +            : base(description, output)
    +        {
    +        }
     
    -    protected void WriteDirectionAndDistance(Coordinates from, Coordinates to)
    -    {
    -        var (direction, distance) = from.GetDirectionAndDistanceTo(to);
    -        Write(direction, distance);
    -    }
    +        protected void WriteDirectionAndDistance(Coordinates from, Coordinates to)
    +        {
    +            var (direction, distance) = from.GetDirectionAndDistanceTo(to);
    +            Write(direction, distance);
    +        }
     
    -    protected void WriteDirectionAndDistance((float X, float Y) from, (float X, float Y) to)
    -    {
    -        var (direction, distance) = DirectionAndDistance.From(from.X, from.Y).To(to.X, to.Y);
    -        Write(direction, distance);
    -    }
    +        protected void WriteDirectionAndDistance((float X, float Y) from, (float X, float Y) to)
    +        {
    +            var (direction, distance) = DirectionAndDistance.From(from.X, from.Y).To(to.X, to.Y);
    +            Write(direction, distance);
    +        }
     
    -    private void Write(float direction, float distance)
    -    {
    -        IO.WriteLine($"Direction = {direction}");
    -        IO.WriteLine($"Distance = {distance}");
    +        private void Write(float direction, float distance) =>
    +            Output.WriteLine($"Direction = {direction}")
    +                .WriteLine($"Distance = {distance}");
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/StarbaseDataCalculator.cs b/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/StarbaseDataCalculator.cs
    index 08e7eda38..7a87f9708 100644
    --- a/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/StarbaseDataCalculator.cs
    +++ b/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/StarbaseDataCalculator.cs
    @@ -1,30 +1,30 @@
    -using Games.Common.IO;
     using SuperStarTrek.Objects;
     using SuperStarTrek.Resources;
     using SuperStarTrek.Space;
     
    -namespace SuperStarTrek.Systems.ComputerFunctions;
    -
    -internal class StarbaseDataCalculator : NavigationCalculator
    +namespace SuperStarTrek.Systems.ComputerFunctions
     {
    -    private readonly Enterprise _enterprise;
    -
    -    internal StarbaseDataCalculator(Enterprise enterprise, IReadWrite io)
    -        : base("Starbase nav data", io)
    +    internal class StarbaseDataCalculator : NavigationCalculator
         {
    -        _enterprise = enterprise;
    -    }
    +        private readonly Enterprise _enterprise;
     
    -    internal override void Execute(Quadrant quadrant)
    -    {
    -        if (!quadrant.HasStarbase)
    +        internal StarbaseDataCalculator(Enterprise enterprise, Output output)
    +            : base("Starbase nav data", output)
             {
    -            IO.WriteLine(Strings.NoStarbase);
    -            return;
    +            _enterprise = enterprise;
             }
     
    -        IO.WriteLine("From Enterprise to Starbase:");
    +        internal override void Execute(Quadrant quadrant)
    +        {
    +            if (!quadrant.HasStarbase)
    +            {
    +                Output.WriteLine(Strings.NoStarbase);
    +                return;
    +            }
    +
    +            Output.WriteLine("From Enterprise to Starbase:");
     
    -        WriteDirectionAndDistance(_enterprise.SectorCoordinates, quadrant.Starbase.Sector);
    +            WriteDirectionAndDistance(_enterprise.SectorCoordinates, quadrant.Starbase.Sector);
    +        }
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/StatusReport.cs b/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/StatusReport.cs
    index b0d6bc1d7..26a299a81 100644
    --- a/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/StatusReport.cs
    +++ b/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/StatusReport.cs
    @@ -1,43 +1,41 @@
    -using Games.Common.IO;
     using SuperStarTrek.Commands;
     using SuperStarTrek.Objects;
     using SuperStarTrek.Space;
     
    -namespace SuperStarTrek.Systems.ComputerFunctions;
    -
    -internal class StatusReport : ComputerFunction
    +namespace SuperStarTrek.Systems.ComputerFunctions
     {
    -    private readonly Game _game;
    -    private readonly Galaxy _galaxy;
    -    private readonly Enterprise _enterprise;
    -
    -    internal StatusReport(Game game, Galaxy galaxy, Enterprise enterprise, IReadWrite io)
    -        : base("Status report", io)
    -    {
    -        _game = game;
    -        _galaxy = galaxy;
    -        _enterprise = enterprise;
    -    }
    -
    -    internal override void Execute(Quadrant quadrant)
    +    internal class StatusReport : ComputerFunction
         {
    -        IO.WriteLine("   Status report:");
    -        IO.Write("Klingon".Pluralize(_galaxy.KlingonCount));
    -        IO.WriteLine($" left:  {_galaxy.KlingonCount}");
    -        IO.WriteLine($"Mission must be completed in {_game.StardatesRemaining:0.#} stardates.");
    +        private readonly Game _game;
    +        private readonly Galaxy _galaxy;
    +        private readonly Enterprise _enterprise;
     
    -        if (_galaxy.StarbaseCount > 0)
    +        internal StatusReport(Game game, Galaxy galaxy, Enterprise enterprise, Output output)
    +            : base("Status report", output)
             {
    -            IO.Write($"The Federation is maintaining {_galaxy.StarbaseCount} ");
    -            IO.Write("starbase".Pluralize(_galaxy.StarbaseCount));
    -            IO.WriteLine(" in the galaxy.");
    +            _game = game;
    +            _galaxy = galaxy;
    +            _enterprise = enterprise;
             }
    -        else
    +
    +        internal override void Execute(Quadrant quadrant)
             {
    -            IO.WriteLine("Your stupidity has left you on your own in");
    -            IO.WriteLine("  the galaxy -- you have no starbases left!");
    -        }
    +            Output.WriteLine("   Status report:")
    +                .Write("Klingon".Pluralize(_galaxy.KlingonCount)).WriteLine($" left:  {_galaxy.KlingonCount}")
    +                .WriteLine($"Mission must be completed in {_game.StardatesRemaining:0.#} stardates.");
     
    -        _enterprise.Execute(Command.DAM);
    +            if (_galaxy.StarbaseCount > 0)
    +            {
    +                Output.Write($"The Federation is maintaining {_galaxy.StarbaseCount} ")
    +                   .Write("starbase".Pluralize(_galaxy.StarbaseCount)).WriteLine(" in the galaxy.");
    +            }
    +            else
    +            {
    +                Output.WriteLine("Your stupidity has left you on your own in")
    +                    .WriteLine("  the galaxy -- you have no starbases left!");
    +            }
    +
    +            _enterprise.Execute(Command.DAM);
    +        }
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/TorpedoDataCalculator.cs b/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/TorpedoDataCalculator.cs
    index d1de3eb77..ec837fc42 100644
    --- a/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/TorpedoDataCalculator.cs
    +++ b/84_Super_Star_Trek/csharp/Systems/ComputerFunctions/TorpedoDataCalculator.cs
    @@ -1,33 +1,33 @@
    -using Games.Common.IO;
     using SuperStarTrek.Objects;
     using SuperStarTrek.Resources;
     using SuperStarTrek.Space;
     
    -namespace SuperStarTrek.Systems.ComputerFunctions;
    -
    -internal class TorpedoDataCalculator : NavigationCalculator
    +namespace SuperStarTrek.Systems.ComputerFunctions
     {
    -    private readonly Enterprise _enterprise;
    -
    -    internal TorpedoDataCalculator(Enterprise enterprise, IReadWrite io)
    -        : base("Photon torpedo data", io)
    +    internal class TorpedoDataCalculator : NavigationCalculator
         {
    -        _enterprise = enterprise;
    -    }
    +        private readonly Enterprise _enterprise;
     
    -    internal override void Execute(Quadrant quadrant)
    -    {
    -        if (!quadrant.HasKlingons)
    +        internal TorpedoDataCalculator(Enterprise enterprise, Output output)
    +            : base("Photon torpedo data", output)
             {
    -            IO.WriteLine(Strings.NoEnemyShips);
    -            return;
    +            _enterprise = enterprise;
             }
     
    -        IO.WriteLine("From Enterprise to Klingon battle cruiser".Pluralize(quadrant.KlingonCount));
    -
    -        foreach (var klingon in quadrant.Klingons)
    +        internal override void Execute(Quadrant quadrant)
             {
    -            WriteDirectionAndDistance(_enterprise.SectorCoordinates, klingon.Sector);
    +            if (!quadrant.HasKlingons)
    +            {
    +                Output.WriteLine(Strings.NoEnemyShips);
    +                return;
    +            }
    +
    +            Output.WriteLine("From Enterprise to Klingon battle cruiser".Pluralize(quadrant.KlingonCount));
    +
    +            foreach (var klingon in quadrant.Klingons)
    +            {
    +                WriteDirectionAndDistance(_enterprise.SectorCoordinates, klingon.Sector);
    +            }
             }
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/84_Super_Star_Trek/csharp/Systems/DamageControl.cs b/84_Super_Star_Trek/csharp/Systems/DamageControl.cs
    index 53dc586e1..8fbf21d34 100644
    --- a/84_Super_Star_Trek/csharp/Systems/DamageControl.cs
    +++ b/84_Super_Star_Trek/csharp/Systems/DamageControl.cs
    @@ -1,55 +1,54 @@
    -using Games.Common.IO;
     using SuperStarTrek.Commands;
     using SuperStarTrek.Objects;
     using SuperStarTrek.Space;
     
    -namespace SuperStarTrek.Systems;
    -
    -internal class DamageControl : Subsystem
    +namespace SuperStarTrek.Systems
     {
    -    private readonly Enterprise _enterprise;
    -    private readonly IReadWrite _io;
    -
    -    internal DamageControl(Enterprise enterprise, IReadWrite io)
    -        : base("Damage Control", Command.DAM, io)
    +    internal class DamageControl : Subsystem
         {
    -        _enterprise = enterprise;
    -        _io = io;
    -    }
    +        private readonly Enterprise _enterprise;
    +        private readonly Output _output;
     
    -    protected override CommandResult ExecuteCommandCore(Quadrant quadrant)
    -    {
    -        if (IsDamaged)
    +        internal DamageControl(Enterprise enterprise, Output output)
    +            : base("Damage Control", Command.DAM, output)
             {
    -            _io.WriteLine("Damage Control report not available");
    -        }
    -        else
    -        {
    -            _io.WriteLine();
    -            WriteDamageReport();
    +            _enterprise = enterprise;
    +            _output = output;
             }
     
    -        if (_enterprise.DamagedSystemCount > 0 && _enterprise.IsDocked)
    +        protected override CommandResult ExecuteCommandCore(Quadrant quadrant)
             {
    -            if (quadrant.Starbase.TryRepair(_enterprise, out var repairTime))
    +            if (IsDamaged)
    +            {
    +                _output.WriteLine("Damage Control report not available");
    +            }
    +            else
                 {
    +                _output.NextLine();
                     WriteDamageReport();
    -                return CommandResult.Elapsed(repairTime);
                 }
    -        }
     
    -        return CommandResult.Ok;
    -    }
    +            if (_enterprise.DamagedSystemCount > 0 && _enterprise.IsDocked)
    +            {
    +                if (quadrant.Starbase.TryRepair(_enterprise, out var repairTime))
    +                {
    +                    WriteDamageReport();
    +                    return CommandResult.Elapsed(repairTime);
    +                }
    +            }
     
    -    internal void WriteDamageReport()
    -    {
    -        _io.WriteLine();
    -        _io.WriteLine("Device             State of Repair");
    -        foreach (var system in _enterprise.Systems)
    +            return CommandResult.Ok;
    +        }
    +
    +        internal void WriteDamageReport()
             {
    -            _io.Write(system.Name.PadRight(25));
    -            _io.WriteLine((int)(system.Condition * 100) * 0.01F);
    +            _output.NextLine().WriteLine("Device             State of Repair");
    +            foreach (var system in _enterprise.Systems)
    +            {
    +                _output.Write(system.Name.PadRight(25))
    +                    .WriteLine(((int)(system.Condition * 100) * 0.01).ToString(" 0.##;-0.##"));
    +            }
    +            _output.NextLine();
             }
    -        _io.WriteLine();
         }
     }
    diff --git a/84_Super_Star_Trek/csharp/Systems/LibraryComputer.cs b/84_Super_Star_Trek/csharp/Systems/LibraryComputer.cs
    index 4a56909ee..df5c68686 100644
    --- a/84_Super_Star_Trek/csharp/Systems/LibraryComputer.cs
    +++ b/84_Super_Star_Trek/csharp/Systems/LibraryComputer.cs
    @@ -1,44 +1,46 @@
    -using Games.Common.IO;
     using SuperStarTrek.Commands;
     using SuperStarTrek.Space;
     using SuperStarTrek.Systems.ComputerFunctions;
     
    -namespace SuperStarTrek.Systems;
    -
    -internal class LibraryComputer : Subsystem
    +namespace SuperStarTrek.Systems
     {
    -    private readonly IReadWrite _io;
    -    private readonly ComputerFunction[] _functions;
    -
    -    internal LibraryComputer(IReadWrite io, params ComputerFunction[] functions)
    -        : base("Library-Computer", Command.COM, io)
    +    internal class LibraryComputer : Subsystem
         {
    -        _io = io;
    -        _functions = functions;
    -    }
    +        private readonly Output _output;
    +        private readonly Input _input;
    +        private readonly ComputerFunction[] _functions;
     
    -    protected override bool CanExecuteCommand() => IsOperational("Computer disabled");
    +        internal LibraryComputer(Output output, Input input, params ComputerFunction[] functions)
    +            : base("Library-Computer", Command.COM, output)
    +        {
    +            _output = output;
    +            _input = input;
    +            _functions = functions;
    +        }
     
    -    protected override CommandResult ExecuteCommandCore(Quadrant quadrant)
    -    {
    -        var index = GetFunctionIndex();
    -        _io.WriteLine();
    +        protected override bool CanExecuteCommand() => IsOperational("Computer disabled");
     
    -        _functions[index].Execute(quadrant);
    +        protected override CommandResult ExecuteCommandCore(Quadrant quadrant)
    +        {
    +            var index = GetFunctionIndex();
    +            _output.NextLine();
     
    -        return CommandResult.Ok;
    -    }
    +            _functions[index].Execute(quadrant);
     
    -    private int GetFunctionIndex()
    -    {
    -        while (true)
    -        {
    -            var index = (int)_io.ReadNumber("Computer active and waiting command");
    -            if (index >= 0 && index <= 5) { return index; }
    +            return CommandResult.Ok;
    +        }
     
    -            for (int i = 0; i < _functions.Length; i++)
    +        private int GetFunctionIndex()
    +        {
    +            while (true)
                 {
    -                _io.WriteLine($"   {i} = {_functions[i].Description}");
    +                var index = (int)_input.GetNumber("Computer active and waiting command");
    +                if (index >= 0 && index <= 5) { return index; }
    +
    +                for (int i = 0; i < _functions.Length; i++)
    +                {
    +                    _output.WriteLine($"   {i} = {_functions[i].Description}");
    +                }
                 }
             }
         }
    diff --git a/84_Super_Star_Trek/csharp/Systems/LongRangeSensors.cs b/84_Super_Star_Trek/csharp/Systems/LongRangeSensors.cs
    index 2e21b63c8..a873eeba6 100644
    --- a/84_Super_Star_Trek/csharp/Systems/LongRangeSensors.cs
    +++ b/84_Super_Star_Trek/csharp/Systems/LongRangeSensors.cs
    @@ -1,35 +1,34 @@
     using System.Linq;
    -using Games.Common.IO;
     using SuperStarTrek.Commands;
     using SuperStarTrek.Space;
     
    -namespace SuperStarTrek.Systems;
    -
    -internal class LongRangeSensors : Subsystem
    +namespace SuperStarTrek.Systems
     {
    -    private readonly Galaxy _galaxy;
    -    private readonly IReadWrite _io;
    -
    -    internal LongRangeSensors(Galaxy galaxy, IReadWrite io)
    -        : base("Long Range Sensors", Command.LRS, io)
    +    internal class LongRangeSensors : Subsystem
         {
    -        _galaxy = galaxy;
    -        _io = io;
    -    }
    +        private readonly Galaxy _galaxy;
    +        private readonly Output _output;
     
    -    protected override bool CanExecuteCommand() => IsOperational("{name} are inoperable");
    -
    -    protected override CommandResult ExecuteCommandCore(Quadrant quadrant)
    -    {
    -        _io.WriteLine($"Long range scan for quadrant {quadrant.Coordinates}");
    -        _io.WriteLine("-------------------");
    -        foreach (var quadrants in _galaxy.GetNeighborhood(quadrant))
    +        internal LongRangeSensors(Galaxy galaxy, Output output)
    +            : base("Long Range Sensors", Command.LRS, output)
             {
    -            _io.WriteLine(": " + string.Join(" : ", quadrants.Select(q => q?.Scan() ?? "***")) + " :");
    -            _io.WriteLine("-------------------");
    +            _galaxy = galaxy;
    +            _output = output;
             }
     
    -        return CommandResult.Ok;
    +        protected override bool CanExecuteCommand() => IsOperational("{name} are inoperable");
    +
    +        protected override CommandResult ExecuteCommandCore(Quadrant quadrant)
    +        {
    +            _output.WriteLine($"Long range scan for quadrant {quadrant.Coordinates}");
    +            _output.WriteLine("-------------------");
    +            foreach (var quadrants in _galaxy.GetNeighborhood(quadrant))
    +            {
    +                _output.WriteLine(": " + string.Join(" : ", quadrants.Select(q => q?.Scan() ?? "***")) + " :");
    +                _output.WriteLine("-------------------");
    +            }
    +
    +            return CommandResult.Ok;
    +        }
         }
     }
    -
    diff --git a/84_Super_Star_Trek/csharp/Systems/PhaserControl.cs b/84_Super_Star_Trek/csharp/Systems/PhaserControl.cs
    index 61249d510..9207ad940 100644
    --- a/84_Super_Star_Trek/csharp/Systems/PhaserControl.cs
    +++ b/84_Super_Star_Trek/csharp/Systems/PhaserControl.cs
    @@ -1,96 +1,97 @@
     using System.Linq;
    -using Games.Common.IO;
    -using Games.Common.Randomness;
     using SuperStarTrek.Commands;
     using SuperStarTrek.Objects;
     using SuperStarTrek.Resources;
     using SuperStarTrek.Space;
     
    -namespace SuperStarTrek.Systems;
    -
    -internal class PhaserControl : Subsystem
    +namespace SuperStarTrek.Systems
     {
    -    private readonly Enterprise _enterprise;
    -    private readonly IReadWrite _io;
    -    private readonly IRandom _random;
    -
    -    internal PhaserControl(Enterprise enterprise, IReadWrite io, IRandom random)
    -        : base("Phaser Control", Command.PHA, io)
    +    internal class PhaserControl : Subsystem
         {
    -        _enterprise = enterprise;
    -        _io = io;
    -        _random = random;
    -    }
    +        private readonly Enterprise _enterprise;
    +        private readonly Output _output;
    +        private readonly Input _input;
    +        private readonly Random _random;
     
    -    protected override bool CanExecuteCommand() => IsOperational("Phasers inoperative");
    -
    -    protected override CommandResult ExecuteCommandCore(Quadrant quadrant)
    -    {
    -        if (!quadrant.HasKlingons)
    +        internal PhaserControl(Enterprise enterprise, Output output, Input input, Random random)
    +            : base("Phaser Control", Command.PHA, output)
             {
    -            _io.WriteLine(Strings.NoEnemyShips);
    -            return CommandResult.Ok;
    +            _enterprise = enterprise;
    +            _output = output;
    +            _input = input;
    +            _random = random;
             }
     
    -        if (_enterprise.Computer.IsDamaged)
    -        {
    -            _io.WriteLine("Computer failure hampers accuracy");
    -        }
    +        protected override bool CanExecuteCommand() => IsOperational("Phasers inoperative");
     
    -        _io.Write($"Phasers locked on target;  ");
    +        protected override CommandResult ExecuteCommandCore(Quadrant quadrant)
    +        {
    +            if (!quadrant.HasKlingons)
    +            {
    +                _output.WriteLine(Strings.NoEnemyShips);
    +                return CommandResult.Ok;
    +            }
     
    -        var phaserStrength = GetPhaserStrength();
    -        if (phaserStrength < 0) { return CommandResult.Ok; }
    +            if (_enterprise.Computer.IsDamaged)
    +            {
    +                _output.WriteLine("Computer failure hampers accuracy");
    +            }
     
    -        _enterprise.UseEnergy(phaserStrength);
    +            _output.Write($"Phasers locked on target;  ");
     
    -        var perEnemyStrength = GetPerTargetPhaserStrength(phaserStrength, quadrant.KlingonCount);
    +            var phaserStrength = GetPhaserStrength();
    +            if (phaserStrength < 0) { return CommandResult.Ok; }
     
    -        foreach (var klingon in quadrant.Klingons.ToList())
    -        {
    -            ResolveHitOn(klingon, perEnemyStrength, quadrant);
    -        }
    +            _enterprise.UseEnergy(phaserStrength);
     
    -        return quadrant.KlingonsFireOnEnterprise();
    -    }
    +            var perEnemyStrength = GetPerTargetPhaserStrength(phaserStrength, quadrant.KlingonCount);
     
    -    private float GetPhaserStrength()
    -    {
    -        while (true)
    -        {
    -            _io.WriteLine($"Energy available = {_enterprise.Energy} units");
    -            var phaserStrength = _io.ReadNumber("Number of units to fire");
    +            foreach (var klingon in quadrant.Klingons.ToList())
    +            {
    +                ResolveHitOn(klingon, perEnemyStrength, quadrant);
    +            }
     
    -            if (phaserStrength <= _enterprise.Energy) { return phaserStrength; }
    +            return quadrant.KlingonsFireOnEnterprise();
             }
    -    }
     
    -    private float GetPerTargetPhaserStrength(float phaserStrength, int targetCount)
    -    {
    -        if (_enterprise.Computer.IsDamaged)
    +        private float GetPhaserStrength()
             {
    -            phaserStrength *= _random.NextFloat();
    -        }
    +            while (true)
    +            {
    +                _output.WriteLine($"Energy available = {_enterprise.Energy} units");
    +                var phaserStrength = _input.GetNumber("Number of units to fire");
     
    -        return phaserStrength / targetCount;
    -    }
    -
    -    private void ResolveHitOn(Klingon klingon, float perEnemyStrength, Quadrant quadrant)
    -    {
    -        var distance = _enterprise.SectorCoordinates.GetDistanceTo(klingon.Sector);
    -        var hitStrength = (int)(perEnemyStrength / distance * (2 + _random.NextFloat()));
    +                if (phaserStrength <= _enterprise.Energy) { return phaserStrength; }
    +            }
    +        }
     
    -        if (klingon.TakeHit(hitStrength))
    +        private float GetPerTargetPhaserStrength(float phaserStrength, int targetCount)
             {
    -            _io.WriteLine($"{hitStrength} unit hit on Klingon at sector {klingon.Sector}");
    -            _io.WriteLine(
    -                klingon.Energy <= 0
    -                    ? quadrant.Remove(klingon)
    -                    : $"   (sensors show {klingon.Energy} units remaining)");
    +            if (_enterprise.Computer.IsDamaged)
    +            {
    +                phaserStrength *= _random.GetFloat();
    +            }
    +
    +            return phaserStrength / targetCount;
             }
    -        else
    +
    +        private void ResolveHitOn(Klingon klingon, float perEnemyStrength, Quadrant quadrant)
             {
    -            _io.WriteLine($"Sensors show no damage to enemy at {klingon.Sector}");
    +            var distance = _enterprise.SectorCoordinates.GetDistanceTo(klingon.Sector);
    +            var hitStrength = (int)(perEnemyStrength / distance * (2 + _random.GetFloat()));
    +
    +            if (klingon.TakeHit(hitStrength))
    +            {
    +                _output.WriteLine($"{hitStrength} unit hit on Klingon at sector {klingon.Sector}");
    +                _output.WriteLine(
    +                    klingon.Energy <= 0
    +                        ? quadrant.Remove(klingon)
    +                        : $"   (sensors show {klingon.Energy} units remaining)");
    +            }
    +            else
    +            {
    +                _output.WriteLine($"Sensors show no damage to enemy at {klingon.Sector}");
    +            }
             }
         }
     }
    diff --git a/84_Super_Star_Trek/csharp/Systems/PhotonTubes.cs b/84_Super_Star_Trek/csharp/Systems/PhotonTubes.cs
    index 597ae3a03..37613037d 100644
    --- a/84_Super_Star_Trek/csharp/Systems/PhotonTubes.cs
    +++ b/84_Super_Star_Trek/csharp/Systems/PhotonTubes.cs
    @@ -1,64 +1,66 @@
    -using Games.Common.IO;
     using SuperStarTrek.Commands;
     using SuperStarTrek.Objects;
     using SuperStarTrek.Space;
     
    -namespace SuperStarTrek.Systems;
    -
    -internal class PhotonTubes : Subsystem
    +namespace SuperStarTrek.Systems
     {
    -    private readonly int _tubeCount;
    -    private readonly Enterprise _enterprise;
    -    private readonly IReadWrite _io;
    -
    -    internal PhotonTubes(int tubeCount, Enterprise enterprise, IReadWrite io)
    -        : base("Photon Tubes", Command.TOR, io)
    +    internal class PhotonTubes : Subsystem
         {
    -        TorpedoCount = _tubeCount = tubeCount;
    -        _enterprise = enterprise;
    -        _io = io;
    -    }
    +        private readonly int _tubeCount;
    +        private readonly Enterprise _enterprise;
    +        private readonly Output _output;
    +        private readonly Input _input;
     
    -    internal int TorpedoCount { get; private set; }
    -
    -    protected override bool CanExecuteCommand() => HasTorpedoes() && IsOperational("{name} are not operational");
    +        internal PhotonTubes(int tubeCount, Enterprise enterprise, Output output, Input input)
    +            : base("Photon Tubes", Command.TOR, output)
    +        {
    +            TorpedoCount = _tubeCount = tubeCount;
    +            _enterprise = enterprise;
    +            _output = output;
    +            _input = input;
    +        }
     
    -    private bool HasTorpedoes()
    -    {
    -        if (TorpedoCount > 0) { return true; }
    +        internal int TorpedoCount { get; private set; }
     
    -        _io.WriteLine("All photon torpedoes expended");
    -        return false;
    -    }
    +        protected override bool CanExecuteCommand() => HasTorpedoes() && IsOperational("{name} are not operational");
     
    -    protected override CommandResult ExecuteCommandCore(Quadrant quadrant)
    -    {
    -        if (!_io.TryReadCourse("Photon torpedo course", "Ensign Chekov", out var course))
    +        private bool HasTorpedoes()
             {
    -            return CommandResult.Ok;
    -        }
    +            if (TorpedoCount > 0) { return true; }
     
    -        TorpedoCount -= 1;
    +            _output.WriteLine("All photon torpedoes expended");
    +            return false;
    +        }
     
    -        var isHit = false;
    -        _io.WriteLine("Torpedo track:");
    -        foreach (var sector in course.GetSectorsFrom(_enterprise.SectorCoordinates))
    +        protected override CommandResult ExecuteCommandCore(Quadrant quadrant)
             {
    -            _io.WriteLine($"                {sector}");
    +            if (!_input.TryGetCourse("Photon torpedo course", "Ensign Chekov", out var course))
    +            {
    +                return CommandResult.Ok;
    +            }
     
    -            if (quadrant.TorpedoCollisionAt(sector, out var message, out var gameOver))
    +            TorpedoCount -= 1;
    +
    +            var isHit = false;
    +            _output.WriteLine("Torpedo track:");
    +            foreach (var sector in course.GetSectorsFrom(_enterprise.SectorCoordinates))
                 {
    -                _io.WriteLine(message);
    -                isHit = true;
    -                if (gameOver) { return CommandResult.GameOver; }
    -                break;
    +                _output.WriteLine($"                {sector}");
    +
    +                if (quadrant.TorpedoCollisionAt(sector, out var message, out var gameOver))
    +                {
    +                    _output.WriteLine(message);
    +                    isHit = true;
    +                    if (gameOver) { return CommandResult.GameOver; }
    +                    break;
    +                }
                 }
    -        }
     
    -        if (!isHit) { _io.WriteLine("Torpedo missed!"); }
    +            if (!isHit) { _output.WriteLine("Torpedo missed!"); }
     
    -        return quadrant.KlingonsFireOnEnterprise();
    -    }
    +            return quadrant.KlingonsFireOnEnterprise();
    +        }
     
    -    internal void ReplenishTorpedoes() => TorpedoCount = _tubeCount;
    +        internal void ReplenishTorpedoes() => TorpedoCount = _tubeCount;
    +    }
     }
    diff --git a/84_Super_Star_Trek/csharp/Systems/ShieldControl.cs b/84_Super_Star_Trek/csharp/Systems/ShieldControl.cs
    index 9d781b235..de4f44d92 100644
    --- a/84_Super_Star_Trek/csharp/Systems/ShieldControl.cs
    +++ b/84_Super_Star_Trek/csharp/Systems/ShieldControl.cs
    @@ -1,57 +1,59 @@
    -using Games.Common.IO;
     using SuperStarTrek.Commands;
     using SuperStarTrek.Objects;
     using SuperStarTrek.Resources;
     using SuperStarTrek.Space;
     
    -namespace SuperStarTrek.Systems;
    -
    -internal class ShieldControl : Subsystem
    +namespace SuperStarTrek.Systems
     {
    -    private readonly Enterprise _enterprise;
    -    private readonly IReadWrite _io;
    -
    -    internal ShieldControl(Enterprise enterprise, IReadWrite io)
    -        : base("Shield Control", Command.SHE, io)
    +    internal class ShieldControl : Subsystem
         {
    -        _enterprise = enterprise;
    -        _io = io;
    -    }
    +        private readonly Enterprise _enterprise;
    +        private readonly Output _output;
    +        private readonly Input _input;
     
    -    internal float ShieldEnergy { get; set; }
    +        internal ShieldControl(Enterprise enterprise, Output output, Input input)
    +            : base("Shield Control", Command.SHE, output)
    +        {
    +            _enterprise = enterprise;
    +            _output = output;
    +            _input = input;
    +        }
     
    -    protected override bool CanExecuteCommand() => IsOperational("{name} inoperable");
    +        internal float ShieldEnergy { get; set; }
     
    -    protected override CommandResult ExecuteCommandCore(Quadrant quadrant)
    -    {
    -        _io.WriteLine($"Energy available = {_enterprise.TotalEnergy}");
    -        var requested = _io.ReadNumber($"Number of units to shields");
    +        protected override bool CanExecuteCommand() => IsOperational("{name} inoperable");
     
    -        if (Validate(requested))
    -        {
    -            ShieldEnergy = requested;
    -            _io.Write(Strings.ShieldsSet, requested);
    -        }
    -        else
    +        protected override CommandResult ExecuteCommandCore(Quadrant quadrant)
             {
    -            _io.WriteLine("");
    +            _output.WriteLine($"Energy available = {_enterprise.TotalEnergy}");
    +            var requested = _input.GetNumber($"Number of units to shields");
    +
    +            if (Validate(requested))
    +            {
    +                ShieldEnergy = requested;
    +                _output.Write(Strings.ShieldsSet, requested);
    +            }
    +            else
    +            {
    +                _output.WriteLine("");
    +            }
    +
    +            return CommandResult.Ok;
             }
     
    -        return CommandResult.Ok;
    -    }
    -
    -    private bool Validate(float requested)
    -    {
    -        if (requested > _enterprise.TotalEnergy)
    +        private bool Validate(float requested)
             {
    -            _io.WriteLine("Shield Control reports, 'This is not the Federation Treasury.'");
    -            return false;
    -        }
    +            if (requested > _enterprise.TotalEnergy)
    +            {
    +                _output.WriteLine("Shield Control reports, 'This is not the Federation Treasury.'");
    +                return false;
    +            }
     
    -        return requested >= 0 && requested != ShieldEnergy;
    -    }
    +            return requested >= 0 && requested != ShieldEnergy;
    +        }
     
    -    internal void AbsorbHit(int hitStrength) => ShieldEnergy -= hitStrength;
    +        internal void AbsorbHit(int hitStrength) => ShieldEnergy -= hitStrength;
     
    -    internal void DropShields() => ShieldEnergy = 0;
    +        internal void DropShields() => ShieldEnergy = 0;
    +    }
     }
    diff --git a/84_Super_Star_Trek/csharp/Systems/ShortRangeSensors.cs b/84_Super_Star_Trek/csharp/Systems/ShortRangeSensors.cs
    index 406af6b80..c37028cb6 100644
    --- a/84_Super_Star_Trek/csharp/Systems/ShortRangeSensors.cs
    +++ b/84_Super_Star_Trek/csharp/Systems/ShortRangeSensors.cs
    @@ -2,61 +2,61 @@
     using System;
     using System.Collections.Generic;
     using System.Linq;
    -using Games.Common.IO;
     using SuperStarTrek.Commands;
     using SuperStarTrek.Objects;
     using SuperStarTrek.Resources;
     using SuperStarTrek.Space;
     
    -namespace SuperStarTrek.Systems;
    -
    -internal class ShortRangeSensors : Subsystem
    +namespace SuperStarTrek.Systems
     {
    -    private readonly Enterprise _enterprise;
    -    private readonly Galaxy _galaxy;
    -    private readonly Game _game;
    -    private readonly IReadWrite _io;
    -
    -    internal ShortRangeSensors(Enterprise enterprise, Galaxy galaxy, Game game, IReadWrite io)
    -        : base("Short Range Sensors", Command.SRS, io)
    +    internal class ShortRangeSensors : Subsystem
         {
    -        _enterprise = enterprise;
    -        _galaxy = galaxy;
    -        _game = game;
    -        _io = io;
    -    }
    +        private readonly Enterprise _enterprise;
    +        private readonly Galaxy _galaxy;
    +        private readonly Game _game;
    +        private readonly Output _output;
     
    -    protected override CommandResult ExecuteCommandCore(Quadrant quadrant)
    -    {
    -        if (_enterprise.IsDocked)
    +        internal ShortRangeSensors(Enterprise enterprise, Galaxy galaxy, Game game, Output output)
    +            : base("Short Range Sensors", Command.SRS, output)
             {
    -            _io.WriteLine(Strings.ShieldsDropped);
    +            _enterprise = enterprise;
    +            _galaxy = galaxy;
    +            _game = game;
    +            _output = output;
             }
     
    -        if (Condition < 0)
    +        protected override CommandResult ExecuteCommandCore(Quadrant quadrant)
             {
    -            _io.WriteLine(Strings.ShortRangeSensorsOut);
    +            if (_enterprise.IsDocked)
    +            {
    +                _output.WriteLine(Strings.ShieldsDropped);
    +            }
    +
    +            if (Condition < 0)
    +            {
    +                _output.WriteLine(Strings.ShortRangeSensorsOut);
    +            }
    +
    +            _output.WriteLine("---------------------------------");
    +            quadrant.GetDisplayLines()
    +                .Zip(GetStatusLines(), (sectors, status) => $" {sectors}         {status}")
    +                .ToList()
    +                .ForEach(l => _output.WriteLine(l));
    +            _output.WriteLine("---------------------------------");
    +
    +            return CommandResult.Ok;
             }
     
    -        _io.WriteLine("---------------------------------");
    -        quadrant.GetDisplayLines()
    -            .Zip(GetStatusLines(), (sectors, status) => $" {sectors}         {status}")
    -            .ToList()
    -            .ForEach(l => _io.WriteLine(l));
    -        _io.WriteLine("---------------------------------");
    -
    -        return CommandResult.Ok;
    -    }
    -
    -    internal IEnumerable GetStatusLines()
    -    {
    -        yield return $"Stardate           {_game.Stardate}";
    -        yield return $"Condition          {_enterprise.Condition}";
    -        yield return $"Quadrant           {_enterprise.QuadrantCoordinates}";
    -        yield return $"Sector             {_enterprise.SectorCoordinates}";
    -        yield return $"Photon torpedoes   {_enterprise.PhotonTubes.TorpedoCount}";
    -        yield return $"Total energy       {Math.Ceiling(_enterprise.TotalEnergy)}";
    -        yield return $"Shields            {(int)_enterprise.ShieldControl.ShieldEnergy}";
    -        yield return $"Klingons remaining {_galaxy.KlingonCount}";
    +        internal IEnumerable GetStatusLines()
    +        {
    +            yield return $"Stardate           {_game.Stardate}";
    +            yield return $"Condition          {_enterprise.Condition}";
    +            yield return $"Quadrant           {_enterprise.QuadrantCoordinates}";
    +            yield return $"Sector             {_enterprise.SectorCoordinates}";
    +            yield return $"Photon torpedoes   {_enterprise.PhotonTubes.TorpedoCount}";
    +            yield return $"Total energy       {Math.Ceiling(_enterprise.TotalEnergy)}";
    +            yield return $"Shields            {(int)_enterprise.ShieldControl.ShieldEnergy}";
    +            yield return $"Klingons remaining {_galaxy.KlingonCount}";
    +        }
         }
     }
    diff --git a/84_Super_Star_Trek/csharp/Systems/Subsystem.cs b/84_Super_Star_Trek/csharp/Systems/Subsystem.cs
    index 5a3711035..5c11e6567 100644
    --- a/84_Super_Star_Trek/csharp/Systems/Subsystem.cs
    +++ b/84_Super_Star_Trek/csharp/Systems/Subsystem.cs
    @@ -1,68 +1,68 @@
    -using Games.Common.IO;
     using SuperStarTrek.Commands;
     using SuperStarTrek.Space;
     
    -namespace SuperStarTrek.Systems;
    -
    -internal abstract class Subsystem
    +namespace SuperStarTrek.Systems
     {
    -    private readonly IReadWrite _io;
    -
    -    protected Subsystem(string name, Command command, IReadWrite io)
    +    internal abstract class Subsystem
         {
    -        Name = name;
    -        Command = command;
    -        Condition = 0;
    -        _io = io;
    -    }
    +        private readonly Output _output;
     
    -    internal string Name { get; }
    +        protected Subsystem(string name, Command command, Output output)
    +        {
    +            Name = name;
    +            Command = command;
    +            Condition = 0;
    +            _output = output;
    +        }
     
    -    internal float Condition { get; private set; }
    +        internal string Name { get; }
     
    -    internal bool IsDamaged => Condition < 0;
    +        internal float Condition { get; private set; }
     
    -    internal Command Command { get; }
    +        internal bool IsDamaged => Condition < 0;
     
    -    protected virtual bool CanExecuteCommand() => true;
    +        internal Command Command { get; }
     
    -    protected bool IsOperational(string notOperationalMessage)
    -    {
    -        if (IsDamaged)
    +        protected virtual bool CanExecuteCommand() => true;
    +
    +        protected bool IsOperational(string notOperationalMessage)
             {
    -            _io.WriteLine(notOperationalMessage.Replace("{name}", Name));
    -            return false;
    -        }
    +            if (IsDamaged)
    +            {
    +                _output.WriteLine(notOperationalMessage.Replace("{name}", Name));
    +                return false;
    +            }
     
    -        return true;
    -    }
    +            return true;
    +        }
     
    -    internal CommandResult ExecuteCommand(Quadrant quadrant)
    -        => CanExecuteCommand() ? ExecuteCommandCore(quadrant) : CommandResult.Ok;
    +        internal CommandResult ExecuteCommand(Quadrant quadrant)
    +            => CanExecuteCommand() ? ExecuteCommandCore(quadrant) : CommandResult.Ok;
     
    -    protected abstract CommandResult ExecuteCommandCore(Quadrant quadrant);
    +        protected abstract CommandResult ExecuteCommandCore(Quadrant quadrant);
     
    -    internal virtual void Repair()
    -    {
    -        if (IsDamaged)
    +        internal virtual void Repair()
             {
    -            Condition = 0;
    +            if (IsDamaged)
    +            {
    +                Condition = 0;
    +            }
             }
    -    }
     
    -    internal virtual bool Repair(float repairWorkDone)
    -    {
    -        if (IsDamaged)
    +        internal virtual bool Repair(float repairWorkDone)
             {
    -            Condition += repairWorkDone;
    -            if (Condition > -0.1f && Condition < 0)
    +            if (IsDamaged)
                 {
    -                Condition = -0.1f;
    +                Condition += repairWorkDone;
    +                if (Condition > -0.1f && Condition < 0)
    +                {
    +                    Condition = -0.1f;
    +                }
                 }
    +
    +            return !IsDamaged;
             }
     
    -        return !IsDamaged;
    +        internal void TakeDamage(float damage) => Condition -= damage;
         }
    -
    -    internal void TakeDamage(float damage) => Condition -= damage;
     }
    diff --git a/84_Super_Star_Trek/csharp/Systems/WarpEngines.cs b/84_Super_Star_Trek/csharp/Systems/WarpEngines.cs
    index a9651abfb..096d0e43a 100644
    --- a/84_Super_Star_Trek/csharp/Systems/WarpEngines.cs
    +++ b/84_Super_Star_Trek/csharp/Systems/WarpEngines.cs
    @@ -1,5 +1,4 @@
     using System;
    -using Games.Common.IO;
     using SuperStarTrek.Commands;
     using SuperStarTrek.Objects;
     using SuperStarTrek.Resources;
    @@ -10,18 +9,20 @@ namespace SuperStarTrek.Systems
         internal class WarpEngines : Subsystem
         {
             private readonly Enterprise _enterprise;
    -        private readonly IReadWrite _io;
    +        private readonly Output _output;
    +        private readonly Input _input;
     
    -        internal WarpEngines(Enterprise enterprise, IReadWrite io)
    -            : base("Warp Engines", Command.NAV, io)
    +        internal WarpEngines(Enterprise enterprise, Output output, Input input)
    +            : base("Warp Engines", Command.NAV, output)
             {
                 _enterprise = enterprise;
    -            _io = io;
    +            _output = output;
    +            _input = input;
             }
     
             protected override CommandResult ExecuteCommandCore(Quadrant quadrant)
             {
    -            if (_io.TryReadCourse("Course", "   Lt. Sulu", out var course) &&
    +            if (_input.TryGetCourse("Course", "   Lt. Sulu", out var course) &&
                     TryGetWarpFactor(out var warpFactor) &&
                     TryGetDistanceToMove(warpFactor, out var distanceToMove))
                 {
    @@ -50,12 +51,12 @@ protected override CommandResult ExecuteCommandCore(Quadrant quadrant)
             private bool TryGetWarpFactor(out float warpFactor)
             {
                 var maximumWarp = IsDamaged ? 0.2f : 8;
    -            if (_io.TryReadNumberInRange("Warp Factor", 0, maximumWarp, out warpFactor))
    +            if (_input.TryGetNumber("Warp Factor", 0, maximumWarp, out warpFactor))
                 {
                     return warpFactor > 0;
                 }
     
    -            _io.WriteLine(
    +            _output.WriteLine(
                     IsDamaged && warpFactor > maximumWarp
                         ? "Warp engines are damaged.  Maximum speed = warp 0.2"
                         : $"  Chief Engineer Scott reports, 'The engines won't take warp {warpFactor} !'");
    @@ -68,14 +69,14 @@ private bool TryGetDistanceToMove(float warpFactor, out int distanceToTravel)
                 distanceToTravel = (int)Math.Round(warpFactor * 8, MidpointRounding.AwayFromZero);
                 if (distanceToTravel <= _enterprise.Energy) { return true; }
     
    -            _io.WriteLine("Engineering reports, 'Insufficient energy available");
    -            _io.WriteLine($"                      for maneuvering at warp {warpFactor} !'");
    +            _output.WriteLine("Engineering reports, 'Insufficient energy available")
    +                .WriteLine($"                      for maneuvering at warp {warpFactor} !'");
     
                 if (distanceToTravel <= _enterprise.TotalEnergy && !_enterprise.ShieldControl.IsDamaged)
                 {
    -                _io.Write($"Deflector control room acknowledges {_enterprise.ShieldControl.ShieldEnergy} ");
    -                _io.WriteLine("units of energy");
    -                _io.WriteLine("                         presently deployed to shields.");
    +                _output.Write($"Deflector control room acknowledges {_enterprise.ShieldControl.ShieldEnergy} ")
    +                    .WriteLine("units of energy")
    +                    .WriteLine("                         presently deployed to shields.");
                 }
     
                 return false;
    diff --git a/84_Super_Star_Trek/csharp/Utils/DirectionAndDistance.cs b/84_Super_Star_Trek/csharp/Utils/DirectionAndDistance.cs
    index a2d3f09bc..e4b1a2faa 100644
    --- a/84_Super_Star_Trek/csharp/Utils/DirectionAndDistance.cs
    +++ b/84_Super_Star_Trek/csharp/Utils/DirectionAndDistance.cs
    @@ -62,4 +62,4 @@ private static float GetDirection(float deltaX, float deltaY)
             private static float GetDistance(float deltaX, float deltaY) =>
                 (float)Math.Sqrt(Math.Pow(deltaX, 2) + Math.Pow(deltaY, 2));
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/84_Super_Star_Trek/instructions.txt b/84_Super_Star_Trek/instructions.txt
    index 59124d9d6..91f26b42b 100644
    --- a/84_Super_Star_Trek/instructions.txt
    +++ b/84_Super_Star_Trek/instructions.txt
    @@ -54,9 +54,9 @@ OF THE STARSHIP ENTERPRISE:
          WAY BETWEEN 1 AND 2                      ...
                                                  . . .
          VALUES MAY APPROACH 9.0, WHICH         6  7  8
    -     ITSELF IS EQUIVALENT TO 1.0"
    +     ITSELF IS EQUIVALENT TO 1.0"        
                                                 COURSE
    -     ONE WARP FACTOR IS THE SIZE OF
    +     ONE WARP FACTOR IS THE SIZE OF 
          ONE QUADTANT.  THEREFORE, TO GET
          FROM QUADRANT 6,5 TO 5,5, YOU WOULD
          USE COURSE 3, WARP FACTOR 1.
    @@ -83,7 +83,7 @@ OF THE STARSHIP ENTERPRISE:
          EXAMPLE - 207 = 2 KLINGONS, NO STARBASES, & 7 STARS.
     
     \PHA\ COMMAND = PHASER CONTROL.
    -     ALLOWS YOU TO DESTROY THE KLINGON BATTLE CRUISERS BY
    +     ALLOWS YOU TO DESTROY THE KLINGON BATTLE CRUISERS BY 
          ZAPPING THEM WITH SUITABLY LARGE UNITS OF ENERGY TO
          DEPLETE THEIR SHIELD POWER.  (REMEMBER, KLINGONS HAVE
          PHASERS TOO!)
    @@ -92,10 +92,10 @@ OF THE STARSHIP ENTERPRISE:
          TORPEDO COURSE IS THE SAME AS USED IN WARP ENGINE CONTROL
          IF YOU HIT THE KLINGON VESSEL, HE IS DESTROYED AND
          CANNOT FIRE BACK AT YOU.  IF YOU MISS, YOU ARE SUBJECT TO
    -     HIS PHASER FIRE.  IN EITHER CASE, YOU ARE ALSO SUBJECT TO
    +     HIS PHASER FIRE.  IN EITHER CASE, YOU ARE ALSO SUBJECT TO 
          THE PHASER FIRE OF ALL OTHER KLINGONS IN THE QUADRANT.
     
    -     THE LIBRARY-COMPUTER (\COM\ COMMAND) HAS AN OPTION TO
    +     THE LIBRARY-COMPUTER (\COM\ COMMAND) HAS AN OPTION TO 
          COMPUTE TORPEDO TRAJECTORY FOR YOU (OPTION 2)
     
     \SHE\ COMMAND = SHIELD CONTROL
    @@ -120,11 +120,12 @@ OF THE STARSHIP ENTERPRISE:
             WHICH GIVES DIRECTIONS AND DISTANCE FROM THE ENTERPRISE
             TO ALL KLINGONS IN YOUR QUADRANT
          OPTION 3 = STARBASE NAV DATA
    -        THIS OPTION GIVES DIRECTION AND DISTANCE TO ANY
    +        THIS OPTION GIVES DIRECTION AND DISTANCE TO ANY 
             STARBASE WITHIN YOUR QUADRANT
          OPTION 4 = DIRECTION/DISTANCE CALCULATOR
             THIS OPTION ALLOWS YOU TO ENTER COORDINATES FOR
             DIRECTION/DISTANCE CALCULATIONS
          OPTION 5 = GALACTIC /REGION NAME/ MAP
    -        THIS OPTION PRINTS THE NAMES OF THE SIXTEEN MAJOR
    +        THIS OPTION PRINTS THE NAMES OF THE SIXTEEN MAJOR 
             GALACTIC REGIONS REFERRED TO IN THE GAME.
    + 
    diff --git a/84_Super_Star_Trek/java/Enterprise.java b/84_Super_Star_Trek/java/Enterprise.java
    deleted file mode 100644
    index d362769e3..000000000
    --- a/84_Super_Star_Trek/java/Enterprise.java
    +++ /dev/null
    @@ -1,331 +0,0 @@
    -import java.util.stream.IntStream;
    -
    -/**
    - * The starship Enterprise.
    - */
    -public class Enterprise {
    -
    -    public static final int COORD_X = 0;
    -    public static final int COORD_Y = 1;
    -
    -    // 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;
    -    final double[] deviceStatus = new double[9];   // 8  device damage stats
    -
    -    // position
    -    final int[][] cardinalDirections = new int[10][3];   // 9x2 vectors in cardinal directions
    -    int quadrantX;
    -    int quadrantY;
    -    int sectorX;
    -    int sectorY;
    -
    -    // ship status
    -    boolean docked = false;
    -    int energy = 3000;
    -    int torpedoes = 10;
    -    int shields = 0;
    -    double repairCost;
    -
    -    final int initialEnergy = energy;
    -    final int initialTorpedoes = torpedoes;
    -
    -    public Enterprise() {
    -        // random initial position
    -        this.setQuadrant(new int[]{ Util.fnr(), Util.fnr() });
    -        this.setSector(new int[]{ Util.fnr(), Util.fnr() });
    -        // init cardinal directions
    -        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;
    -        // init devices
    -        IntStream.range(1, 8).forEach(i -> deviceStatus[i] = 0);
    -    }
    -
    -    public int getShields() {
    -        return shields;
    -    }
    -
    -    /**
    -     * Enterprise is hit by enemies.
    -     * @param hits the number of hit points
    -     */
    -    public void sufferHitPoints(int hits) {
    -        this.shields = shields - hits;
    -    }
    -
    -    public int getEnergy() {
    -        return energy;
    -    }
    -
    -    public void replenishSupplies() {
    -        this.energy = this.initialEnergy;
    -        this.torpedoes = this.initialTorpedoes;
    -    }
    -
    -    public void decreaseEnergy(final double amount) {
    -        this.energy -= amount;
    -    }
    -
    -    public void decreaseTorpedoes(final int amount) {
    -        torpedoes -= amount;
    -    }
    -
    -    public void dropShields() {
    -        this.shields = 0;
    -    }
    -
    -    public int getTotalEnergy() {
    -        return (shields + energy);
    -    }
    -
    -    public int getInitialEnergy() {
    -        return initialEnergy;
    -    }
    -
    -    public int getTorpedoes() {
    -        return torpedoes;
    -    }
    -
    -    public double[] getDeviceStatus() {
    -        return deviceStatus;
    -    }
    -
    -    public int[][] getCardinalDirections() {
    -        return cardinalDirections;
    -    }
    -
    -    public void setDeviceStatus(final int device, final double status) {
    -        this.deviceStatus[device] = status;
    -    }
    -
    -    public boolean isDocked() {
    -        return docked;
    -    }
    -
    -    public void setDocked(boolean docked) {
    -        this.docked = docked;
    -    }
    -
    -    public int[] getQuadrant() {
    -        return new int[] {quadrantX, quadrantY};
    -    }
    -
    -    public void setQuadrant(final int[] quadrant) {
    -        this.quadrantX = quadrant[COORD_X];
    -        this.quadrantY = quadrant[COORD_Y];
    -    }
    -
    -    public int[] getSector() {
    -        return new int[] {sectorX, sectorY};
    -    }
    -
    -    public void setSector(final int[] sector) {
    -        this.sectorX = sector[COORD_X];
    -        this.sectorY = sector[COORD_Y];
    -    }
    -
    -    public int[] moveShip(final float course, final int n, final String quadrantMap, final double stardate, final double initialStardate, final int missionDuration, final GameCallback callback) {
    -        int ic1 = Util.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 = Util.toInt(x / 8);
    -                quadrantY = Util.toInt(y / 8);
    -                sectorX = Util.toInt(x - quadrantX * 8);
    -                sectorY = Util.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) {
    -                    Util.println("LT. UHURA REPORTS MESSAGE FROM STARFLEET COMMAND:");
    -                    Util.println("  'PERMISSION TO ATTEMPT CROSSING OF GALACTIC PERIMETER");
    -                    Util.println("  IS HEREBY *DENIED*.  SHUT DOWN YOUR ENGINES.'");
    -                    Util.println("CHIEF ENGINEER SCOTT REPORTS  'WARP ENGINES SHUT DOWN");
    -                    Util.println("  AT SECTOR " + sectorX + "," + sectorY + " OF QUADRANT " + quadrantX + "," + quadrantY + ".'");
    -                    if (stardate > initialStardate + missionDuration) callback.endGameFail(false);
    -                }
    -                if (8 * quadrantX + quadrantY == 8 * initialQuadrantX + initialQuadrantY) {
    -                    break;
    -                }
    -                callback.incrementStardate(1);
    -                maneuverEnergySR(n);
    -                callback.enterNewQuadrant();
    -                return this.getSector();
    -            } else {
    -                int S8 = Util.toInt(sectorX) * 24 + Util.toInt(sectorY) * 3 - 26; // S8 = pos
    -                if (!("  ".equals(Util.midStr(quadrantMap, S8, 2)))) {
    -                    sectorX = Util.toInt(sectorX - x1);
    -                    sectorY = Util.toInt(sectorY - x2);
    -                    Util.println("WARP ENGINES SHUT DOWN AT ");
    -                    Util.println("SECTOR " + sectorX + "," + sectorY + " DUE TO BAD NAVIGATION");
    -                    break;
    -                }
    -            }
    -        }
    -        sectorX = Util.toInt(sectorX);
    -        sectorY = Util.toInt(sectorY);
    -        return this.getSector();
    -    }
    -
    -    void randomRepairCost() {
    -        repairCost = .5 * Util.random();
    -    }
    -
    -    public void repairDamagedDevices(final float warp) {
    -        // 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) {
    -                    Util.println("DAMAGE CONTROL REPORT:  ");
    -                    Util.println(Util.tab(8) + printDeviceName(i) + " REPAIR COMPLETED.");
    -                }
    -            }
    -        }
    -    }
    -
    -    public void maneuverEnergySR(final int N) {
    -        energy = energy - N - 10;
    -        if (energy >= 0) return;
    -        Util.println("SHIELD CONTROL SUPPLIES ENERGY TO COMPLETE THE MANEUVER.");
    -        shields = shields + energy;
    -        energy = 0;
    -        if (shields <= 0) shields = 0;
    -    }
    -
    -    void shieldControl() {
    -        if (deviceStatus[DEVICE_SHIELD_CONTROL] < 0) {
    -            Util.println("SHIELD CONTROL INOPERABLE");
    -            return;
    -        }
    -        Util.println("ENERGY AVAILABLE = " + (energy + shields));
    -        int energyToShields = Util.toInt(Util.inputFloat("NUMBER OF UNITS TO SHIELDS"));
    -        if (energyToShields < 0 || shields == energyToShields) {
    -            Util.println("");
    -            return;
    -        }
    -        if (energyToShields > energy + energyToShields) {
    -            Util.println("SHIELD CONTROL REPORTS  'THIS IS NOT THE FEDERATION TREASURY.'");
    -            Util.println("");
    -            return;
    -        }
    -        energy = energy + shields - energyToShields;
    -        shields = energyToShields;
    -        Util.println("DEFLECTOR CONTROL ROOM REPORT:");
    -        Util.println("  'SHIELDS NOW AT " + Util.toInt(shields) + " UNITS PER YOUR COMMAND.'");
    -    }
    -
    -    void damageControl(GameCallback callback) {
    -        if (deviceStatus[DEVICE_DAMAGE_CONTROL] < 0) {
    -            Util.println("DAMAGE CONTROL REPORT NOT AVAILABLE");
    -        } else {
    -            Util.println("\nDEVICE             STATE OF REPAIR");
    -            for (int deviceNr = 1; deviceNr <= 8; deviceNr++) {
    -                Util.print(printDeviceName(deviceNr) + Util.leftStr(GalaxyMap.QUADRANT_ROW, 25 - Util.strlen(printDeviceName(deviceNr))) + " " + Util.toInt(deviceStatus[deviceNr] * 100) * .01 + "\n");
    -            }
    -        }
    -        if (!docked) 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;
    -            Util.println("TECHNICIANS STANDING BY TO EFFECT REPAIRS TO YOUR SHIP;");
    -            Util.println("ESTIMATED TIME TO REPAIR:'" + .01 * Util.toInt(100 * deltaToRepair) + " STARDATES");
    -            final String reply = Util.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;
    -                }
    -                callback.incrementStardate(deltaToRepair + .1);
    -            }
    -        }
    -    }
    -
    -    public static 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 "";
    -    }
    -
    -}
    diff --git a/84_Super_Star_Trek/java/GalaxyMap.java b/84_Super_Star_Trek/java/GalaxyMap.java
    deleted file mode 100644
    index 77541ec90..000000000
    --- a/84_Super_Star_Trek/java/GalaxyMap.java
    +++ /dev/null
    @@ -1,649 +0,0 @@
    -import java.util.stream.IntStream;
    -
    -/**
    - * Map of the galaxy divided in Quadrants and Sectors,
    - * populated with stars, starbases, klingons, and the Enterprise.
    - */
    -public class GalaxyMap {
    -
    -    // 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 = " * ";
    -
    -    static final int AVG_KLINGON_SHIELD_ENERGY = 200;
    -
    -    // galaxy map
    -    public static final String QUADRANT_ROW = "                         ";
    -    String quadrantMap = QUADRANT_ROW + QUADRANT_ROW + QUADRANT_ROW + QUADRANT_ROW + QUADRANT_ROW + QUADRANT_ROW + QUADRANT_ROW + Util.leftStr(QUADRANT_ROW, 17);       // current quadrant map
    -    final int[][] galaxy = new int[9][9];    // 8x8 galaxy map G
    -    final int[][] klingonQuadrants = new int[4][4];    // 3x3 position of klingons K
    -    final int[][] chartedGalaxy = new int[9][9];    // 8x8 charted galaxy map Z
    -
    -    // galaxy state
    -    int basesInGalaxy = 0;
    -    int remainingKlingons;
    -    int klingonsInGalaxy = 0;
    -    final Enterprise enterprise = new Enterprise();
    -
    -    // quadrant state
    -    int klingons = 0;
    -    int starbases = 0;
    -    int stars = 0;
    -    int starbaseX = 0; // X coordinate of starbase
    -    int starbaseY = 0; // Y coord of starbase
    -
    -    public Enterprise getEnterprise() {
    -        return enterprise;
    -    }
    -
    -    public int getBasesInGalaxy() {
    -        return basesInGalaxy;
    -    }
    -
    -    public int getRemainingKlingons() {
    -        return remainingKlingons;
    -    }
    -
    -    public int getKlingonsInGalaxy() {
    -        return klingonsInGalaxy;
    -    }
    -
    -    double fnd(int i) {
    -        return Math.sqrt((klingonQuadrants[i][1] - enterprise.getSector()[Enterprise.COORD_X]) ^ 2 + (klingonQuadrants[i][2] - enterprise.getSector()[Enterprise.COORD_Y]) ^ 2);
    -    }
    -
    -    public GalaxyMap() {
    -        int quadrantX = enterprise.getQuadrant()[Enterprise.COORD_X];
    -        int quadrantY = enterprise.getQuadrant()[Enterprise.COORD_Y];
    -        // populate Klingons, Starbases, Stars
    -        IntStream.range(1, 8).forEach(x -> {
    -            IntStream.range(1, 8).forEach(y -> {
    -                klingons = 0;
    -                chartedGalaxy[x][y] = 0;
    -                float random = Util.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 (Util.random() > .96) {
    -                    starbases = 1;
    -                    basesInGalaxy = +1;
    -                }
    -                galaxy[x][y] = klingons * 100 + starbases * 10 + Util.fnr();
    -            });
    -        });
    -        if (basesInGalaxy == 0) {
    -            if (galaxy[quadrantX][quadrantY] < 200) {
    -                galaxy[quadrantX][quadrantY] = galaxy[quadrantX][quadrantY] + 120;
    -                klingonsInGalaxy = +1;
    -            }
    -            basesInGalaxy = 1;
    -            galaxy[quadrantX][quadrantY] = +10;
    -            enterprise.setQuadrant(new int[]{ Util.fnr(), Util.fnr() });
    -        }
    -        remainingKlingons = klingonsInGalaxy;
    -    }
    -
    -    void newQuadrant(final double stardate, final double initialStardate) {   // 1320
    -        final int quadrantX = enterprise.getQuadrant()[Enterprise.COORD_X];
    -        final int quadrantY = enterprise.getQuadrant()[Enterprise.COORD_Y];
    -        klingons = 0;
    -        starbases = 0;
    -        stars = 0;
    -        enterprise.randomRepairCost();
    -        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) {
    -                Util.println("YOUR MISSION BEGINS WITH YOUR STARSHIP LOCATED\n" +
    -                        "IN THE GALACTIC QUADRANT, '" + quadrantName + "'.");
    -            } else {
    -                Util.println("NOW ENTERING " + quadrantName + " QUADRANT . . .");
    -            }
    -            Util.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) {
    -                Util.println("COMBAT AREA      CONDITION RED");
    -                if (enterprise.getShields() <= 200) {
    -                    Util.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, enterprise.getSector()[Enterprise.COORD_X], enterprise.getSector()[Enterprise.COORD_Y]);
    -        // 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(AVG_KLINGON_SHIELD_ENERGY * (0.5 + Util.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]);
    -        }
    -    }
    -
    -    public void klingonsMoveAndFire(GameCallback callback) {
    -        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(callback);
    -    }
    -
    -    void klingonsShoot(GameCallback callback) {
    -        if (klingons <= 0) return; // no klingons
    -        if (enterprise.isDocked()) {
    -            Util.println("STARBASE SHIELDS PROTECT THE ENTERPRISE");
    -            return;
    -        }
    -        for (int i = 1; i <= 3; i++) {
    -            if (klingonQuadrants[i][3] <= 0) continue;
    -            int hits = Util.toInt((klingonQuadrants[i][3] / fnd(1)) * (2 + Util.random()));
    -            enterprise.sufferHitPoints(hits);
    -            klingonQuadrants[i][3] = Util.toInt(klingonQuadrants[i][3] / (3 + Util.random()));
    -            Util.println(hits + " UNIT HIT ON ENTERPRISE FROM SECTOR " + klingonQuadrants[i][1] + "," + klingonQuadrants[i][2]);
    -            if (enterprise.getShields() <= 0) callback.endGameFail(true);
    -            Util.println("      ");
    -            if (hits < 20) continue;
    -            if ((Util.random() > .6) || (hits / enterprise.getShields() <= .02)) continue;
    -            int randomDevice = Util.fnr();
    -            enterprise.setDeviceStatus(randomDevice, enterprise.getDeviceStatus()[randomDevice]- hits / enterprise.getShields() - .5 * Util.random());
    -            Util.println("DAMAGE CONTROL REPORTS " + Enterprise.printDeviceName(randomDevice) + " DAMAGED BY THE HIT'");
    -        }
    -    }
    -
    -    public void moveEnterprise(final float course, final float warp, final int n, final double stardate, final double initialStardate, final int missionDuration, final GameCallback callback) {
    -        insertMarker(MARKER_EMPTY, Util.toInt(enterprise.getSector()[Enterprise.COORD_X]), Util.toInt(enterprise.getSector()[Enterprise.COORD_Y]));
    -        final int[] sector = enterprise.moveShip(course, n, quadrantMap, stardate, initialStardate, missionDuration, callback);
    -        int sectorX = sector[Enterprise.COORD_X];
    -        int sectorY = sector[Enterprise.COORD_Y];
    -        insertMarker(MARKER_ENTERPRISE, Util.toInt(sectorX), Util.toInt(sectorY));
    -        enterprise.maneuverEnergySR(n);
    -        double stardateDelta = 1;
    -        if (warp < 1) stardateDelta = .1 * Util.toInt(10 * warp);
    -        callback.incrementStardate(stardateDelta);
    -        if (stardate > initialStardate + missionDuration) callback.endGameFail(false);
    -    }
    -
    -    void shortRangeSensorScan(final double stardate) {
    -        final int sectorX = enterprise.getSector()[Enterprise.COORD_X];
    -        final int sectorY = enterprise.getSector()[Enterprise.COORD_Y];
    -        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 ((Util.toInt(i) >= 1) && (Util.toInt(i) <= 8) && (Util.toInt(j) >= 1) && (Util.toInt(j) <= 8)) {
    -                    if (compareMarker(quadrantMap, MARKER_STARBASE, i, j)) {
    -                        docked = true;
    -                    }
    -                }
    -            }
    -        }
    -        if (!docked) {
    -            enterprise.setDocked(false);
    -            if (klingons > 0) {
    -                shipCondition = "*RED*";
    -            } else {
    -                shipCondition = "GREEN";
    -                if (enterprise.getEnergy() < enterprise.getInitialEnergy() * .1) {
    -                    shipCondition = "YELLOW";
    -                }
    -            }
    -        } else {
    -            enterprise.setDocked(true);
    -            shipCondition = "DOCKED";
    -            enterprise.replenishSupplies();
    -            Util.println("SHIELDS DROPPED FOR DOCKING PURPOSES");
    -            enterprise.dropShields();
    -        }
    -        if (enterprise.getDeviceStatus()[Enterprise.DEVICE_SHORT_RANGE_SENSORS] < 0) { // are short range sensors out?
    -            Util.println("\n*** SHORT RANGE SENSORS ARE OUT ***\n");
    -            return;
    -        }
    -        final String row = "---------------------------------";
    -        Util.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 += " " + Util.midStr(quadrantMap, j, 3);
    -            }
    -            switch (i) {
    -                case 1:
    -                    Util.println(sectorMapRow + "        STARDATE           " + Util.toInt(stardate * 10) * .1);
    -                    break;
    -                case 2:
    -                    Util.println(sectorMapRow + "        CONDITION          " + shipCondition);
    -                    break;
    -                case 3:
    -                    Util.println(sectorMapRow + "        QUADRANT           " + enterprise.getQuadrant()[Enterprise.COORD_X] + "," + enterprise.getQuadrant()[Enterprise.COORD_Y]);
    -                    break;
    -                case 4:
    -                    Util.println(sectorMapRow + "        SECTOR             " + sectorX + "," + sectorY);
    -                    break;
    -                case 5:
    -                    Util.println(sectorMapRow + "        PHOTON TORPEDOES   " + Util.toInt(enterprise.getTorpedoes()));
    -                    break;
    -                case 6:
    -                    Util.println(sectorMapRow + "        TOTAL ENERGY       " + Util.toInt(enterprise.getTotalEnergy()));
    -                    break;
    -                case 7:
    -                    Util.println(sectorMapRow + "        SHIELDS            " + Util.toInt(enterprise.getShields()));
    -                    break;
    -                case 8:
    -                    Util.println(sectorMapRow + "        KLINGONS REMAINING " + Util.toInt(klingonsInGalaxy));
    -            }
    -        }
    -        Util.println(row);
    -    }
    -
    -    void longRangeSensorScan() {
    -        final int quadrantX = enterprise.getQuadrant()[Enterprise.COORD_X];
    -        final int quadrantY = enterprise.getQuadrant()[Enterprise.COORD_Y];
    -        if (enterprise.getDeviceStatus()[Enterprise.DEVICE_LONG_RANGE_SENSORS] < 0) {
    -            Util.println("LONG RANGE SENSORS ARE INOPERABLE");
    -            return;
    -        }
    -        Util.println("LONG RANGE SCAN FOR QUADRANT " + quadrantX + "," + quadrantY);
    -        final String rowStr = "-------------------";
    -        Util.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++) {
    -                Util.print(": ");
    -                if (n[l] < 0) {
    -                    Util.print("*** ");
    -                    continue;
    -                }
    -                Util.print(Util.rightStr(Integer.toString(n[l] + 1000), 3) + " ");
    -            }
    -            Util.println(": \n" + rowStr);
    -        }
    -    }
    -
    -    void firePhasers(GameCallback callback) {
    -        final double[] deviceStatus = enterprise.getDeviceStatus();
    -        final int quadrantX = enterprise.getQuadrant()[Enterprise.COORD_X];
    -        final int quadrantY = enterprise.getQuadrant()[Enterprise.COORD_Y];
    -        if (deviceStatus[Enterprise.DEVICE_PHASER_CONTROL] < 0) {
    -            Util.println("PHASERS INOPERATIVE");
    -            return;
    -        }
    -        if (klingons <= 0) {
    -            printNoEnemyShipsMessage();
    -            return;
    -        }
    -        if (deviceStatus[Enterprise.DEVICE_LIBRARY_COMPUTER] < 0) Util.println("COMPUTER FAILURE HAMPERS ACCURACY");
    -        Util.println("PHASERS LOCKED ON TARGET;  ");
    -        int nrUnitsToFire;
    -        while (true) {
    -            Util.println("ENERGY AVAILABLE = " + enterprise.getEnergy() + " UNITS");
    -            nrUnitsToFire = Util.toInt(Util.inputFloat("NUMBER OF UNITS TO FIRE"));
    -            if (nrUnitsToFire <= 0) return;
    -            if (enterprise.getEnergy() - nrUnitsToFire >= 0) break;
    -        }
    -        enterprise.decreaseEnergy(nrUnitsToFire);
    -        if (deviceStatus[Enterprise.DEVICE_SHIELD_CONTROL] < 0) nrUnitsToFire = Util.toInt(nrUnitsToFire * Util.random());
    -        int h1 = Util.toInt(nrUnitsToFire / klingons);
    -        for (int i = 1; i <= 3; i++) {
    -            if (klingonQuadrants[i][3] <= 0) break;
    -            int hitPoints = Util.toInt((h1 / fnd(0)) * (Util.random() + 2));
    -            if (hitPoints <= .15 * klingonQuadrants[i][3]) {
    -                Util.println("SENSORS SHOW NO DAMAGE TO ENEMY AT " + klingonQuadrants[i][1] + "," + klingonQuadrants[i][2]);
    -                continue;
    -            }
    -            klingonQuadrants[i][3] = klingonQuadrants[i][3] - hitPoints;
    -            Util.println(hitPoints + " UNIT HIT ON KLINGON AT SECTOR " + klingonQuadrants[i][1] + "," + klingonQuadrants[i][2]);
    -            if (klingonQuadrants[i][3] <= 0) {
    -                Util.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) callback.endGameSuccess();
    -            } else {
    -                Util.println("   (SENSORS SHOW " + klingonQuadrants[i][3] + " UNITS REMAINING)");
    -            }
    -        }
    -        klingonsShoot(callback);
    -    }
    -
    -    void firePhotonTorpedo(final double stardate, final double initialStardate, final double missionDuration, GameCallback callback) {
    -        if (enterprise.getTorpedoes() <= 0) {
    -            Util.println("ALL PHOTON TORPEDOES EXPENDED");
    -            return;
    -        }
    -        if (enterprise.getDeviceStatus()[Enterprise.DEVICE_PHOTON_TUBES] < 0) {
    -            Util.println("PHOTON TUBES ARE NOT OPERATIONAL");
    -        }
    -        float c1 = Util.inputFloat("PHOTON TORPEDO COURSE (1-9)");
    -        if (c1 == 9) c1 = 1;
    -        if (c1 < 1 && c1 >= 9) {
    -            Util.println("ENSIGN CHEKOV REPORTS,  'INCORRECT COURSE DATA, SIR!'");
    -            return;
    -        }
    -        int ic1 = Util.toInt(c1);
    -        final int[][] cardinalDirections = enterprise.getCardinalDirections();
    -        float x1 = cardinalDirections[ic1][1] + (cardinalDirections[ic1 + 1][1] - cardinalDirections[ic1][1]) * (c1 - ic1);
    -        enterprise.decreaseEnergy(2);
    -        enterprise.decreaseTorpedoes(1);
    -        float x2 = cardinalDirections[ic1][2] + (cardinalDirections[ic1 + 1][2] - cardinalDirections[ic1][2]) * (c1 - ic1);
    -        float x = enterprise.getSector()[Enterprise.COORD_X];
    -        float y = enterprise.getSector()[Enterprise.COORD_Y];
    -        Util.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) {
    -                Util.println("TORPEDO MISSED"); // 5490
    -                klingonsShoot(callback);
    -                return;
    -            }
    -            Util.println("               " + x3 + "," + y3);
    -            if (compareMarker(quadrantMap, MARKER_EMPTY, Util.toInt(x), Util.toInt(y)))  {
    -                continue;
    -            } else if (compareMarker(quadrantMap, MARKER_KLINGON, Util.toInt(x), Util.toInt(y))) {
    -                Util.println("*** KLINGON DESTROYED ***");
    -                klingons = klingons - 1;
    -                klingonsInGalaxy = klingonsInGalaxy - 1;
    -                if (klingonsInGalaxy <= 0) callback.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, Util.toInt(x), Util.toInt(y))) {
    -                Util.println("STAR AT " + x3 + "," + y3 + " ABSORBED TORPEDO ENERGY.");
    -                klingonsShoot(callback);
    -                return;
    -            } else if (compareMarker(quadrantMap, MARKER_STARBASE, Util.toInt(x), Util.toInt(y))) {
    -                Util.println("*** STARBASE DESTROYED ***");
    -                starbases = starbases - 1;
    -                basesInGalaxy = basesInGalaxy - 1;
    -                if (basesInGalaxy == 0 && klingonsInGalaxy <= stardate - initialStardate - missionDuration) {
    -                    Util.println("THAT DOES IT, CAPTAIN!!  YOU ARE HEREBY RELIEVED OF COMMAND");
    -                    Util.println("AND SENTENCED TO 99 STARDATES AT HARD LABOR ON CYGNUS 12!!");
    -                    callback.endGameFail(false);
    -                } else {
    -                    Util.println("STARFLEET COMMAND REVIEWING YOUR RECORD TO CONSIDER");
    -                    Util.println("COURT MARTIAL!");
    -                    enterprise.setDocked(false);
    -                }
    -            }
    -            insertMarker(MARKER_EMPTY, Util.toInt(x), Util.toInt(y));
    -            final int quadrantX = enterprise.getQuadrant()[Enterprise.COORD_X];
    -            final int quadrantY = enterprise.getQuadrant()[Enterprise.COORD_Y];
    -            galaxy[quadrantX][quadrantY] = klingons * 100 + starbases * 10 + stars;
    -            chartedGalaxy[quadrantX][quadrantY] = galaxy[quadrantX][quadrantY];
    -            klingonsShoot(callback);
    -        }
    -    }
    -
    -    public void cumulativeGalacticRecord(final boolean cumulativeReport) {
    -        final int quadrantX = enterprise.getQuadrant()[Enterprise.COORD_X];
    -        final int quadrantY = enterprise.getQuadrant()[Enterprise.COORD_Y];
    -        if (cumulativeReport) {
    -            Util.println("");
    -            Util.println("        ");
    -            Util.println("COMPUTER RECORD OF GALAXY FOR QUADRANT " + quadrantX + "," + quadrantY);
    -            Util.println("");
    -        } else {
    -            Util.println("                        THE GALAXY");
    -        }
    -        Util.println("       1     2     3     4     5     6     7     8");
    -        final String rowDivider = "     ----- ----- ----- ----- ----- ----- ----- -----";
    -        Util.println(rowDivider);
    -        for (int i = 1; i <= 8; i++) {
    -            Util.print(i + "  ");
    -            if (cumulativeReport) {
    -                int y = 1;
    -                String quadrantName = getQuadrantName(false, i, y);
    -                int tabLen = Util.toInt(15 - .5 * Util.strlen(quadrantName));
    -                Util.println(Util.tab(tabLen) + quadrantName);
    -                y = 5;
    -                quadrantName = getQuadrantName(false, i, y);
    -                tabLen = Util.toInt(39 - .5 * Util.strlen(quadrantName));
    -                Util.println(Util.tab(tabLen) + quadrantName);
    -            } else {
    -                for (int j = 1; j <= 8; j++) {
    -                    Util.print("   ");
    -                    if (chartedGalaxy[i][j] == 0) {
    -                        Util.print("***");
    -                    } else {
    -                        Util.print(Util.rightStr(Integer.toString(chartedGalaxy[i][j] + 1000), 3));
    -                    }
    -                }
    -            }
    -            Util.println("");
    -            Util.println(rowDivider);
    -        }
    -        Util.println("");
    -    }
    -
    -    public void photonTorpedoData() {
    -        int sectorX = enterprise.getSector()[Enterprise.COORD_X];
    -        int sectorY = enterprise.getSector()[Enterprise.COORD_Y];
    -        if (klingons <= 0) {
    -            printNoEnemyShipsMessage();
    -            return;
    -        }
    -        Util.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() {
    -        int quadrantX = enterprise.getQuadrant()[Enterprise.COORD_X];
    -        int quadrantY = enterprise.getQuadrant()[Enterprise.COORD_Y];
    -        int sectorX = enterprise.getSector()[Enterprise.COORD_X];
    -        int sectorY = enterprise.getSector()[Enterprise.COORD_Y];
    -        Util.println("DIRECTION/DISTANCE CALCULATOR:");
    -        Util.println("YOU ARE AT QUADRANT " + quadrantX + "," + quadrantY + " SECTOR " + sectorX + "," + sectorY);
    -        Util.print("PLEASE ENTER ");
    -        int[] initialCoords = Util.inputCoords("  INITIAL COORDINATES (X,Y)");
    -        int[] finalCoords = Util.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) {
    -        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) {
    -                Util.println("DIRECTION = " + (from_x + to_y / from_y));
    -            } else {
    -                Util.println("DIRECTION = " + (from_x + 2 - to_y / from_y));
    -            }
    -        }
    -        Util.println("DISTANCE = " + Util.round(Math.sqrt(to_y ^ 2 + from_y ^ 2), 6));
    -    }
    -
    -    void starbaseNavData() {
    -        int sectorX = enterprise.getSector()[Enterprise.COORD_X];
    -        int sectorY = enterprise.getSector()[Enterprise.COORD_Y];
    -        if (starbases != 0) {
    -            Util.println("FROM ENTERPRISE TO STARBASE:");
    -            printDirection(sectorX, sectorY, starbaseX, starbaseY);
    -        } else {
    -            Util.println("MR. SPOCK REPORTS,  'SENSORS SHOW NO STARBASES IN THIS");
    -            Util.println(" QUADRANT.'");
    -        }
    -    }
    -
    -    void printNoEnemyShipsMessage() {
    -        Util.println("SCIENCE OFFICER SPOCK REPORTS  'SENSORS SHOW NO ENEMY SHIPS");
    -        Util.println("                                IN THIS QUADRANT'");
    -    }
    -
    -    String getRegionName(final boolean regionNameOnly, final int y) {
    -        if (!regionNameOnly) {
    -            switch (y % 4) {
    -                case 0:
    -                    return " I";
    -                case 1:
    -                    return " II";
    -                case 2:
    -                    return " III";
    -                case 3:
    -                    return " IV";
    -            }
    -        }
    -        return "";
    -    }
    -
    -    String getQuadrantName(final boolean regionNameOnly, final int x, final int y) {
    -        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 insertMarker(final String marker, final int x, final int y) {
    -        final int pos = Util.toInt(y) * 3 + Util.toInt(x) * 24 + 1;
    -        if (marker.length() != 3) {
    -            System.err.println("ERROR");
    -            System.exit(-1);
    -        }
    -        if (pos == 1) {
    -            quadrantMap = marker + Util.rightStr(quadrantMap, 189);
    -        }
    -        if (pos == 190) {
    -            quadrantMap = Util.leftStr(quadrantMap, 189) + marker;
    -        }
    -        quadrantMap = Util.leftStr(quadrantMap, (pos - 1)) + marker + Util.rightStr(quadrantMap, (190 - pos));
    -    }
    -
    -    /**
    -     * Finds random empty coordinates in a quadrant.
    -     *
    -     * @param quadrantString
    -     * @return an array with a pair of coordinates x, y
    -     */
    -    int[] findEmptyPlaceInQuadrant(final String quadrantString) {
    -        final int x = Util.fnr();
    -        final int y = Util.fnr();
    -        if (!compareMarker(quadrantString, MARKER_EMPTY, x, y)) {
    -            return findEmptyPlaceInQuadrant(quadrantString);
    -        }
    -        return new int[]{x, y};
    -    }
    -
    -    boolean compareMarker(final String quadrantString, final String marker, final int x, final int y) {
    -        final int markerRegion = (y - 1) * 3 + (x - 1) * 24 + 1;
    -        if (Util.midStr(quadrantString, markerRegion, 3).equals(marker)) {
    -            return true;
    -        }
    -        return false;
    -    }
    -
    -}
    diff --git a/84_Super_Star_Trek/java/GameCallback.java b/84_Super_Star_Trek/java/GameCallback.java
    deleted file mode 100644
    index 1d4530a36..000000000
    --- a/84_Super_Star_Trek/java/GameCallback.java
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -/**
    - * Interface for decoupling inversion of control from GalaxyMap and Enterprise towards the game class.
    - */
    -public interface GameCallback {
    -    void enterNewQuadrant();
    -    void incrementStardate(double increment);
    -    void endGameSuccess();
    -    void endGameFail(boolean enterpriseDestroyed);
    -}
    diff --git a/84_Super_Star_Trek/java/README.md b/84_Super_Star_Trek/java/README.md
    index c4f8a30ad..51edd8d4f 100644
    --- a/84_Super_Star_Trek/java/README.md
    +++ b/84_Super_Star_Trek/java/README.md
    @@ -1,13 +1,3 @@
     Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
     
    -Conversion to [Oracle Java](https://openjdk.java.net/) by [Taciano Dreckmann Perez](https://github.com/taciano-perez).
    -
    -Overview of Java classes:
    -- SuperStarTrekInstructions: displays game instructions
    -- SuperStarTrekGame: main game class
    -- GalaxyMap: map of the galaxy divided in quadrants and sectors, containing stars, bases, klingons, and the Enterprise
    -- Enterprise: the starship Enterprise
    -- GameCallback: interface allowing other classes to interact with the game class without circular dependencies 
    -- Util: utility methods
    -
    -[This video](https://www.youtube.com/watch?v=cU3NKOnRNCI) describes the approach and the different steps followed to translate the game.
    \ No newline at end of file
    +Conversion to [Oracle Java](https://openjdk.java.net/)
    diff --git a/84_Super_Star_Trek/java/SuperStarTrekGame.java b/84_Super_Star_Trek/java/SuperStarTrekGame.java
    deleted file mode 100644
    index c1778cda9..000000000
    --- a/84_Super_Star_Trek/java/SuperStarTrekGame.java
    +++ /dev/null
    @@ -1,341 +0,0 @@
    -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-Mar 2022 by
    - * Taciano Dreckmann Perez (taciano.perez@gmail.com)
    - */
    -public class SuperStarTrekGame implements GameCallback {
    -
    -    // 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;
    -
    -    // other constants
    -    static final String COMMANDS = "NAVSRSLRSPHATORSHEDAMCOMXXX";
    -
    -    // game state
    -    final GalaxyMap galaxyMap = new GalaxyMap();
    -    double stardate = Util.toInt(Util.random() * 20 + 20);
    -    int missionDuration = Math.max((25 + Util.toInt(Util.random() * 10)), galaxyMap.getKlingonsInGalaxy()+1);    // T9 (mission duration in stardates)
    -    boolean restart = false;
    -
    -    // initial values
    -    final double initialStardate = stardate;
    -
    -    public static void main(String[] args) {
    -        final SuperStarTrekGame game = new SuperStarTrekGame();
    -        printBanner();
    -        while (true) {
    -            game.orders();
    -            game.enterNewQuadrant();
    -            game.restart = false;
    -            game.commandLoop();
    -        }
    -    }
    -
    -    static void printBanner() {
    -        IntStream.range(1, 10).forEach(i -> {
    -            Util.println("");
    -        });
    -        Util.println(
    -                """
    -                                                            ,------*------,
    -                                            ,-------------   '---  ------'
    -                                             '-------- --'      / /
    -                                                 ,---' '-------/ /--,
    -                                                  '----------------'
    -
    -                                            THE USS ENTERPRISE --- NCC-1701"
    -
    -                        """
    -        );
    -    }
    -
    -    void orders() {
    -        Util.println("YOUR ORDERS ARE AS FOLLOWS:\n" +
    -                "     DESTROY THE " + galaxyMap.getKlingonsInGalaxy() + " KLINGON WARSHIP" + ((galaxyMap.getKlingonsInGalaxy() == 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 " + ((galaxyMap.getBasesInGalaxy() == 1) ? "IS" : "ARE") + "\n" +
    -                "  " + galaxyMap.getBasesInGalaxy() + " STARBASE" + ((galaxyMap.getBasesInGalaxy() == 1) ? "" : "S") + " IN THE GALAXY FOR RESUPPLYING YOUR SHIP");
    -    }
    -
    -    public void enterNewQuadrant() {
    -        galaxyMap.newQuadrant(stardate, initialStardate);
    -        shortRangeSensorScan();
    -    }
    -
    -    void commandLoop() {
    -        while (!this.restart) {
    -            checkShipEnergy();
    -            String cmdStr = "";
    -            while ("".equals(cmdStr)) cmdStr = Util.inputStr("COMMAND");
    -            boolean foundCommand = false;
    -            for (int i = 1; i <= 9; i++) {
    -                if (Util.leftStr(cmdStr, 3).equals(Util.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:
    -                            galaxyMap.getEnterprise().damageControl(this);
    -                            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() {
    -        final Enterprise enterprise = galaxyMap.getEnterprise();
    -        if (enterprise.getTotalEnergy() < 10 && (enterprise.getEnergy() <= 10 || enterprise.getDeviceStatus()[Enterprise.DEVICE_SHIELD_CONTROL] != 0)) {
    -            Util.println("\n** FATAL ERROR **   YOU'VE JUST STRANDED YOUR SHIP IN ");
    -            Util.println("SPACE");
    -            Util.println("YOU HAVE INSUFFICIENT MANEUVERING ENERGY,");
    -            Util.println(" AND SHIELD CONTROL");
    -            Util.println("IS PRESENTLY INCAPABLE OF CROSS");
    -            Util.println("-CIRCUITING TO ENGINE ROOM!!");
    -            endGameFail(false);
    -        }
    -    }
    -
    -    void printCommandOptions() {
    -        Util.println("ENTER ONE OF THE FOLLOWING:");
    -        Util.println("  NAV  (TO SET COURSE)");
    -        Util.println("  SRS  (FOR SHORT RANGE SENSOR SCAN)");
    -        Util.println("  LRS  (FOR LONG RANGE SENSOR SCAN)");
    -        Util.println("  PHA  (TO FIRE PHASERS)");
    -        Util.println("  TOR  (TO FIRE PHOTON TORPEDOES)");
    -        Util.println("  SHE  (TO RAISE OR LOWER SHIELDS)");
    -        Util.println("  DAM  (FOR DAMAGE CONTROL REPORTS)");
    -        Util.println("  COM  (TO CALL ON LIBRARY-COMPUTER)");
    -        Util.println("  XXX  (TO RESIGN YOUR COMMAND)\n");
    -    }
    -
    -    void navigation() {
    -        float course = Util.toInt(Util.inputFloat("COURSE (0-9)"));
    -        if (course == 9) course = 1;
    -        if (course < 1 || course >= 9) {
    -            Util.println("   LT. SULU REPORTS, 'INCORRECT COURSE DATA, SIR!'");
    -            return;
    -        }
    -        final Enterprise enterprise = galaxyMap.getEnterprise();
    -        final double[] deviceStatus = enterprise.getDeviceStatus();
    -        Util.println("WARP FACTOR (0-" + ((deviceStatus[Enterprise.DEVICE_WARP_ENGINES] < 0) ? "0.2" : "8") + ")");
    -        float warp = Util.inputFloat("");
    -        if (deviceStatus[Enterprise.DEVICE_WARP_ENGINES] < 0 && warp > .2) {
    -            Util.println("WARP ENGINES ARE DAMAGED.  MAXIMUM SPEED = WARP 0.2");
    -            return;
    -        }
    -        if (warp == 0) return;
    -        if (warp > 0 && warp <= 8) {
    -            int n = Util.toInt(warp * 8);
    -            if (enterprise.getEnergy() - n >= 0) {
    -                galaxyMap.klingonsMoveAndFire(this);
    -                repairDamagedDevices(course, warp, n);
    -                galaxyMap.moveEnterprise(course, warp, n, stardate, initialStardate, missionDuration, this);
    -            } else {
    -                Util.println("ENGINEERING REPORTS   'INSUFFICIENT ENERGY AVAILABLE");
    -                Util.println("                       FOR MANEUVERING AT WARP " + warp + "!'");
    -                if (enterprise.getShields() < n - enterprise.getEnergy() || deviceStatus[Enterprise.DEVICE_SHIELD_CONTROL] < 0) return;
    -                Util.println("DEFLECTOR CONTROL ROOM ACKNOWLEDGES " + enterprise.getShields() + " UNITS OF ENERGY");
    -                Util.println("                         PRESENTLY DEPLOYED TO SHIELDS.");
    -            }
    -        } else {
    -            Util.println("   CHIEF ENGINEER SCOTT REPORTS 'THE ENGINES WON'T TAKE");
    -            Util.println(" WARP " + warp + "!'");
    -        }
    -    }
    -
    -    void repairDamagedDevices(final float course, final float warp, final int N) {
    -        final Enterprise enterprise = galaxyMap.getEnterprise();
    -        // repair damaged devices and print damage report
    -        enterprise.repairDamagedDevices(warp);
    -        if (Util.random() > .2) return;  // 80% chance no damage nor repair
    -        int randomDevice = Util.fnr();    // random device
    -        final double[] deviceStatus = enterprise.getDeviceStatus();
    -        if (Util.random() >= .6) {   // 40% chance of repair of random device
    -            enterprise.setDeviceStatus(randomDevice, deviceStatus[randomDevice] + Util.random() * 3 + 1);
    -            Util.println("DAMAGE CONTROL REPORT:  " + Enterprise.printDeviceName(randomDevice) + " STATE OF REPAIR IMPROVED\n");
    -        } else {            // 60% chance of damage of random device
    -            enterprise.setDeviceStatus(randomDevice, deviceStatus[randomDevice] - (Util.random() * 5 + 1));
    -            Util.println("DAMAGE CONTROL REPORT:  " + Enterprise.printDeviceName(randomDevice) + " DAMAGED");
    -        }
    -    }
    -
    -    void longRangeSensorScan() {
    -        // LONG RANGE SENSOR SCAN CODE
    -        galaxyMap.longRangeSensorScan();
    -    }
    -
    -    void firePhasers() {
    -        galaxyMap.firePhasers(this);
    -    }
    -
    -    void firePhotonTorpedo() {
    -        galaxyMap.firePhotonTorpedo(stardate, initialStardate, missionDuration, this);
    -    }
    -
    -    void shieldControl() {
    -        galaxyMap.getEnterprise().shieldControl();
    -    }
    -
    -    void shortRangeSensorScan() {
    -        // SHORT RANGE SENSOR SCAN & STARTUP SUBROUTINE
    -        galaxyMap.shortRangeSensorScan(stardate);
    -    }
    -
    -    void libraryComputer() {
    -        // REM LIBRARY COMPUTER CODE
    -        if (galaxyMap.getEnterprise().getDeviceStatus()[Enterprise.DEVICE_LIBRARY_COMPUTER] < 0) {
    -            Util.println("COMPUTER DISABLED");
    -            return;
    -        }
    -        while (true) {
    -            final float commandInput = Util.inputFloat("COMPUTER ACTIVE AND AWAITING COMMAND");
    -            if (commandInput < 0) return;
    -            Util.println("");
    -            int command = Util.toInt(commandInput) + 1;
    -            if (command >= COMPUTER_COMMAND_CUMULATIVE_GALACTIC_RECORD && command <= COMPUTER_COMMAND_GALAXY_MAP) {
    -                switch (command) {
    -                    case COMPUTER_COMMAND_CUMULATIVE_GALACTIC_RECORD:
    -                        galaxyMap.cumulativeGalacticRecord(true);
    -                        return;
    -                    case COMPUTER_COMMAND_STATUS_REPORT:
    -                        statusReport();
    -                        return;
    -                    case COMPUTER_COMMAND_PHOTON_TORPEDO_DATA:
    -                        galaxyMap.photonTorpedoData();
    -                        return;
    -                    case COMPUTER_COMMAND_STARBASE_NAV_DATA:
    -                        galaxyMap.starbaseNavData();
    -                        return;
    -                    case COMPUTER_COMMAND_DIR_DIST_CALC:
    -                        galaxyMap.directionDistanceCalculator();
    -                        return;
    -                    case COMPUTER_COMMAND_GALAXY_MAP:
    -                        galaxyMap.cumulativeGalacticRecord(false);
    -                        return;
    -                }
    -            } else {
    -                // invalid command
    -                Util.println("FUNCTIONS AVAILABLE FROM LIBRARY-COMPUTER:");
    -                Util.println("   0 = CUMULATIVE GALACTIC RECORD");
    -                Util.println("   1 = STATUS REPORT");
    -                Util.println("   2 = PHOTON TORPEDO DATA");
    -                Util.println("   3 = STARBASE NAV DATA");
    -                Util.println("   4 = DIRECTION/DISTANCE CALCULATOR");
    -                Util.println("   5 = GALAXY 'REGION NAME' MAP");
    -                Util.println("");
    -            }
    -        }
    -    }
    -
    -    void statusReport() {
    -        Util.println("   STATUS REPORT:");
    -        Util.println("KLINGON" + ((galaxyMap.getKlingonsInGalaxy() > 1)? "S" : "")  + " LEFT: " + galaxyMap.getKlingonsInGalaxy());
    -        Util.println("MISSION MUST BE COMPLETED IN " + .1 * Util.toInt((initialStardate + missionDuration - stardate) * 10) + " STARDATES");
    -        if (galaxyMap.getBasesInGalaxy() >= 1) {
    -            Util.println("THE FEDERATION IS MAINTAINING " + galaxyMap.getBasesInGalaxy() + " STARBASE" + ((galaxyMap.getBasesInGalaxy() > 1)? "S" : "") + " IN THE GALAXY");
    -        } else {
    -            Util.println("YOUR STUPIDITY HAS LEFT YOU ON YOUR OWN IN");
    -            Util.println("  THE GALAXY -- YOU HAVE NO STARBASES LEFT!");
    -        }
    -        galaxyMap.getEnterprise().damageControl(this);
    -    }
    -
    -    public void incrementStardate(double increment) {
    -        this.stardate += increment;
    -    }
    -
    -    public void endGameFail(final boolean enterpriseDestroyed) {    // 6220
    -        if (enterpriseDestroyed) {
    -            Util.println("\nTHE ENTERPRISE HAS BEEN DESTROYED.  THEN FEDERATION ");
    -            Util.println("WILL BE CONQUERED");
    -        }
    -        Util.println("\nIT IS STARDATE " + stardate);
    -        Util.println("THERE WERE " + galaxyMap.getKlingonsInGalaxy() + " KLINGON BATTLE CRUISERS LEFT AT");
    -        Util.println("THE END OF YOUR MISSION.");
    -        repeatGame();
    -    }
    -
    -    public void endGameSuccess() {
    -        Util.println("CONGRATULATION, CAPTAIN!  THE LAST KLINGON BATTLE CRUISER");
    -        Util.println("MENACING THE FEDERATION HAS BEEN DESTROYED.\n");
    -        Util.println("YOUR EFFICIENCY RATING IS " + (Math.sqrt(1000 * (galaxyMap.getRemainingKlingons() / (stardate - initialStardate)))));
    -        repeatGame();
    -    }
    -
    -    void repeatGame() {
    -        Util.println("\n");
    -        if (galaxyMap.getBasesInGalaxy() != 0) {
    -            Util.println("THE FEDERATION IS IN NEED OF A NEW STARSHIP COMMANDER");
    -            Util.println("FOR A SIMILAR MISSION -- IF THERE IS A VOLUNTEER,");
    -            final String reply = Util.inputStr("LET HIM STEP FORWARD AND ENTER 'AYE'");
    -            if ("AYE".equals(reply)) {
    -                this.restart = true;
    -            } else {
    -                System.exit(0);
    -            }
    -        }
    -    }
    -
    -}
    diff --git a/84_Super_Star_Trek/java/SuperStarTrekInstructions.java b/84_Super_Star_Trek/java/SuperStarTrekInstructions.java
    deleted file mode 100644
    index 16f730dad..000000000
    --- a/84_Super_Star_Trek/java/SuperStarTrekInstructions.java
    +++ /dev/null
    @@ -1,162 +0,0 @@
    -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 "";
    -        }
    -    }
    -
    -}
    diff --git a/84_Super_Star_Trek/java/Util.java b/84_Super_Star_Trek/java/Util.java
    deleted file mode 100644
    index 17c07ecd9..000000000
    --- a/84_Super_Star_Trek/java/Util.java
    +++ /dev/null
    @@ -1,113 +0,0 @@
    -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;
    -
    -/**
    - * Convenience utility methods for the Super Star Trek game.
    - */
    -public class Util {
    -
    -    static final Random random = new Random();
    -
    -    public static float random() {
    -        return random.nextFloat();
    -    }
    -
    -    public static int fnr() {    // 475
    -        // Generate a random integer from 1 to 8 inclusive.
    -        return toInt(random() * 7 + 1);
    -    }
    -
    -    public static int toInt(final double num) {
    -        int x = (int) Math.floor(num);
    -        if (x < 0) x *= -1;
    -        return x;
    -    }
    -
    -    public static void println(final String s) {
    -        System.out.println(s);
    -    }
    -
    -    public static void print(final String s) {
    -        System.out.print(s);
    -    }
    -
    -    public static String tab(final int n) {
    -        return IntStream.range(1, n).mapToObj(num -> " ").collect(Collectors.joining());
    -    }
    -
    -    public static int strlen(final String s) {
    -        return s.length();
    -    }
    -
    -    public 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 "";
    -        }
    -    }
    -
    -    public 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();
    -            }
    -        }
    -    }
    -
    -    public 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();
    -            }
    -        }
    -    }
    -
    -    public static String leftStr(final String input, final int len) {
    -        if (input == null || input.length() < len) return input;
    -        return input.substring(0, len);
    -    }
    -
    -    public 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);
    -    }
    -
    -    public static String rightStr(final String input, final int len) {
    -        if (input == null || input.length() < len) return "";
    -        return input.substring(input.length() - len);
    -    }
    -
    -    public 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/javascript/README.md b/84_Super_Star_Trek/javascript/README.md
    index 06f53f122..49b7ece64 100644
    --- a/84_Super_Star_Trek/javascript/README.md
    +++ b/84_Super_Star_Trek/javascript/README.md
    @@ -1,6 +1,3 @@
    -Original source downloaded [from Vintage Basic][def]
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
     
    -Conversion to [****J****avaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Shells)
    -
    -
    -[def]: http://www.vintage-basic.net/games.html
    \ No newline at end of file
    +Conversion to [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Shells)
    diff --git a/84_Super_Star_Trek/javascript/cli.mjs b/84_Super_Star_Trek/javascript/cli.mjs
    index 4277c2323..bacceff85 100644
    --- a/84_Super_Star_Trek/javascript/cli.mjs
    +++ b/84_Super_Star_Trek/javascript/cli.mjs
    @@ -2,9 +2,12 @@ import {
       onExit,
       onPrint,
       onInput,
    +  setGameOptions,
    +  getGameState,
       gameMain,
     } from "./superstartrek.mjs";
     
    +import util from "util";
     import readline from "readline";
     
     onExit(function exit() {
    diff --git a/84_Super_Star_Trek/javascript/index.html b/84_Super_Star_Trek/javascript/index.html
    index d2e31b8f3..fd3a7e091 100644
    --- a/84_Super_Star_Trek/javascript/index.html
    +++ b/84_Super_Star_Trek/javascript/index.html
    @@ -96,9 +96,9 @@ 

    Super Star Trek

    WAY BETWEEN 1 AND 2 ... . . . VALUES MAY APPROACH 9.0, WHICH 6 7 8 - ITSELF IS EQUIVALENT TO 1.0" + ITSELF IS EQUIVALENT TO 1.0" COURSE - ONE WARP FACTOR IS THE SIZE OF + ONE WARP FACTOR IS THE SIZE OF ONE QUADTANT. THEREFORE, TO GET FROM QUADRANT 6,5 TO 5,5, YOU WOULD USE COURSE 3, WARP FACTOR 1. @@ -122,7 +122,7 @@

    Super Star Trek

    EXAMPLE - 207 = 2 KLINGONS, NO STARBASES, & 7 STARS. \PHA\ COMMAND = PHASER CONTROL. - ALLOWS YOU TO DESTROY THE KLINGON BATTLE CRUISERS BY + ALLOWS YOU TO DESTROY THE KLINGON BATTLE CRUISERS BY ZAPPING THEM WITH SUITABLY LARGE UNITS OF ENERGY TO DEPLETE THEIR SHIELD POWER. (REMBER, KLINGONS HAVE PHASERS TOO!) @@ -150,7 +150,7 @@

    Super Star Trek

    THE LIBRARY-COMPUTER CONTAINS SIX OPTIONS: OPTION 0 = CUMULATIVE GALACTIC RECORD THIS OPTION SHOWES COMPUTER MEMORY OF THE RESULTS OF ALL - PREVIOUS SHORT AND LONG RANGE SENSOR SCANS + PREVIOUS SHORT AND LONG RANGE SENSOR SCANS OPTION 1 = STATUS REPORT THIS OPTION SHOWS THE NUMBER OF KLINGONS, STARDATES, AND STARBASES REMAINING IN THE GAME. diff --git a/84_Super_Star_Trek/kotlin/README.md b/84_Super_Star_Trek/kotlin/README.md deleted file mode 100644 index f43a5b700..000000000 --- a/84_Super_Star_Trek/kotlin/README.md +++ /dev/null @@ -1,3 +0,0 @@ -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) - -Conversion to [Kotlin](https://kotlinlang.org/) diff --git a/84_Super_Star_Trek/lua/README.md b/84_Super_Star_Trek/lua/README.md deleted file mode 100644 index c063f42fd..000000000 --- a/84_Super_Star_Trek/lua/README.md +++ /dev/null @@ -1,3 +0,0 @@ -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) - -Conversion to [Lua](https://www.lua.org/) diff --git a/84_Super_Star_Trek/pascal/README.md b/84_Super_Star_Trek/pascal/README.md new file mode 100644 index 000000000..aa1b3ae5d --- /dev/null +++ b/84_Super_Star_Trek/pascal/README.md @@ -0,0 +1,3 @@ +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) + +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language)) diff --git a/84_Super_Star_Trek/python/superstartrek.py b/84_Super_Star_Trek/python/superstartrek.py index 892988c76..f6898c0d2 100644 --- a/84_Super_Star_Trek/python/superstartrek.py +++ b/84_Super_Star_Trek/python/superstartrek.py @@ -1,1117 +1,692 @@ -""" -**** **** 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 . . . - Output is identical to BASIC version except for a few - fixes (as noted, search `bug`) and minor cleanup. -""" +# **** **** 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 . . . +# +# Python translation by Jack Boyce - February 2021 +# Output is identical to BASIC version except for a few +# fixes (as noted, search `bug`) and minor cleanup. import random -import sys -from dataclasses import dataclass -from enum import Enum from math import sqrt -from typing import Callable, Dict, Final, List, Optional, Tuple -def get_user_float(prompt: str) -> float: - """Get input from user and return it.""" +# ------------------------------------------------------------------------- +# Utility functions +# ------------------------------------------------------------------------- + + +def fnr(): + # Generate a random integer from 0 to 7 inclusive. + return random.randint(0, 7) + + +def quadrant_name(row, col, region_only=False): + # Return quadrant name visible on scans, etc. + region1 = ['ANTARES', 'RIGEL', 'PROCYON', 'VEGA', 'CANOPUS', 'ALTAIR', + 'SAGITTARIUS', 'POLLUX'] + region2 = ['SIRIUS', 'DENEB', 'CAPELLA', 'BETELGEUSE', 'ALDEBARAN', + 'REGULUS', 'ARCTURUS', 'SPICA'] + modifier = ['I', 'II', 'III', 'IV'] + + quadrant = region1[row] if col < 4 else region2[row] + + if not region_only: + quadrant += ' ' + modifier[col % 4] + + return quadrant + + +def insert_marker(row, col, marker): + # Insert a marker into a given position in the quadrant string `qs`. The + # contents of a quadrant (Enterprise, stars, etc.) are stored in `qs`. + global qs + + if len(marker) != 3: + print('ERROR') + exit() + + pos = round(col) * 3 + round(row) * 24 + qs = qs[0:pos] + marker + qs[(pos + 3):192] + + +def compare_marker(row, col, test_marker): + # Check whether the position in the current quadrant is occupied with a + # given marker. + pos = round(col) * 3 + round(row) * 24 + return qs[pos:(pos + 3)] == test_marker + + +def find_empty_place(): + # Find an empty location in the current quadrant. while True: - answer = input(prompt) - try: - return float(answer) - except ValueError: - pass - - -class Entity(Enum): - klingon = "+K+" - ship = "<*>" - empty = "***" - starbase = ">!<" - star = " * " - void = " " - - -@dataclass -class Point: - x: int - y: int - - def __str__(self) -> str: - return f"{self.x + 1} , {self.y + 1}" - - -@dataclass -class Position: - """ - Every quadrant has 8 sectors - - Hence the position could also be represented as: - x = quadrant.x * 8 + sector.x - y = quadrant.y * 8 + sector.y - """ - - quadrant: Point - sector: Point - - -@dataclass -class QuadrantData: - klingons: int - bases: int - stars: int - - def num(self) -> int: - return 100 * self.klingons + 10 * self.bases + self.stars - - -@dataclass -class KlingonShip: - sector: Point - shield: float - - -class Ship: - energy_capacity: int = 3000 - torpedo_capacity: int = 10 - - def __init__(self) -> None: - self.position = Position(Point(fnr(), fnr()), Point(fnr(), fnr())) - self.energy: int = Ship.energy_capacity - self.devices: Tuple[str, ...] = ( - "WARP ENGINES", - "SHORT RANGE SENSORS", - "LONG RANGE SENSORS", - "PHASER CONTROL", - "PHOTON TUBES", - "DAMAGE CONTROL", - "SHIELD CONTROL", - "LIBRARY-COMPUTER", - ) - self.damage_stats: List[float] = [0] * len(self.devices) - self.shields = 0 - self.torpedoes = Ship.torpedo_capacity - self.docked: bool = False # true when docked at starbase - - def refill(self) -> None: - self.energy = Ship.energy_capacity - self.torpedoes = Ship.torpedo_capacity - - def maneuver_energy(self, n: int) -> None: - """Deduct the energy for navigation from energy/shields.""" - self.energy -= n + 10 - - if self.energy <= 0: - print("SHIELD CONTROL SUPPLIES ENERGY TO COMPLETE THE MANEUVER.") - self.shields += self.energy - self.energy = 0 - self.shields = max(0, self.shields) - - def shield_control(self) -> None: - """Raise or lower the shields.""" - if self.damage_stats[6] < 0: - print("SHIELD CONTROL INOPERABLE") - return + row, col = fnr(), fnr() + if compare_marker(row, col, ' '): + return row, col - while True: - energy_to_shield = input( - f"ENERGY AVAILABLE = {self.energy + self.shields} NUMBER OF UNITS TO SHIELDS? " - ) - if len(energy_to_shield) > 0: - x = int(energy_to_shield) - break - if x < 0 or self.shields == x: - print("") - return +# ------------------------------------------------------------------------- +# Functions for individual player commands +# ------------------------------------------------------------------------- - if x > self.energy + self.shields: - print( - "SHIELD CONTROL REPORTS 'THIS IS NOT THE FEDERATION " - "TREASURY.'\n" - "" - ) - return - self.energy += self.shields - x - self.shields = x - print("DEFLECTOR CONTROL ROOM REPORT:") - print(f" 'SHIELDS NOW AT {self.shields} UNITS PER YOUR COMMAND.'") - - -class Quadrant: - def __init__( - self, - point: Point, # position of the quadrant - population: QuadrantData, - ship_position: Position, - ) -> None: - """Populate quadrant map""" - assert 0 <= point.x <= 7 and 0 <= point.y <= 7 - self.name = Quadrant.quadrant_name(point.x, point.y, False) - - self.nb_klingons = population.klingons - self.nb_bases = population.bases - self.nb_stars = population.stars - - # extra delay in repairs at base - self.delay_in_repairs_at_base: float = 0.5 * random.random() - - # Klingons in current quadrant - self.klingon_ships: List[KlingonShip] = [] - - # Initialize empty: save what is at which position - self.data = [[Entity.void for _ in range(8)] for _ in range(8)] - - self.populate_quadrant(ship_position) - - @classmethod - def quadrant_name(cls, row: int, col: int, region_only: bool = False) -> str: - """Return quadrant name visible on scans, etc.""" - region1 = [ - "ANTARES", - "RIGEL", - "PROCYON", - "VEGA", - "CANOPUS", - "ALTAIR", - "SAGITTARIUS", - "POLLUX", - ] - region2 = [ - "SIRIUS", - "DENEB", - "CAPELLA", - "BETELGEUSE", - "ALDEBARAN", - "REGULUS", - "ARCTURUS", - "SPICA", - ] - modifier = ["I", "II", "III", "IV"] - - quadrant = region1[row] if col < 4 else region2[row] - - if not region_only: - quadrant += f" {modifier[col % 4]}" - - return quadrant - - def set_value(self, x: float, y: float, entity: Entity) -> None: - self.data[round(x)][round(y)] = entity - - def get_value(self, x: float, y: float) -> Entity: - return self.data[round(x)][round(y)] - - def find_empty_place(self) -> Tuple[int, int]: - """Find an empty location in the current quadrant.""" - while True: - row, col = fnr(), fnr() - if self.get_value(row, col) == Entity.void: - return row, col - - def populate_quadrant(self, ship_position: Position) -> None: - self.set_value(ship_position.sector.x, ship_position.sector.y, Entity.ship) - for _ in range(self.nb_klingons): - x, y = self.find_empty_place() - self.set_value(x, y, Entity.klingon) - self.klingon_ships.append( - KlingonShip( - Point(x, y), klingon_shield_strength * (0.5 + random.random()) - ) - ) - if self.nb_bases > 0: - # Position of starbase in current sector - starbase_x, starbase_y = self.find_empty_place() - self.starbase = Point(starbase_x, starbase_y) - self.set_value(starbase_x, starbase_y, Entity.starbase) - for _ in range(self.nb_stars): - x, y = self.find_empty_place() - self.set_value(x, y, Entity.star) - - def __str__(self) -> str: - quadrant_string = "" - for row in self.data: - for entity in row: - quadrant_string += entity.value - return quadrant_string - - -class World: - def __init__( - self, - total_klingons: int = 0, # Klingons at start of game - bases_in_galaxy: int = 0, - ) -> None: - self.ship = Ship() - self.initial_stardate = 100 * random.randint(20, 39) - self.stardate: float = self.initial_stardate - self.mission_duration = random.randint(25, 34) - - # Enemy - self.remaining_klingons = total_klingons - - # Player starbases - self.bases_in_galaxy = bases_in_galaxy - - self.galaxy_map: List[List[QuadrantData]] = [ - [QuadrantData(0, 0, 0) for _ in range(8)] for _ in range(8) - ] - self.charted_galaxy_map: List[List[QuadrantData]] = [ - [QuadrantData(0, 0, 0) for _ in range(8)] for _ in range(8) - ] - - # initialize contents of galaxy - for x in range(8): - for y in range(8): - r1 = random.random() - - if r1 > 0.98: - quadrant_klingons = 3 - elif r1 > 0.95: - quadrant_klingons = 2 - elif r1 > 0.80: - quadrant_klingons = 1 - else: - quadrant_klingons = 0 - self.remaining_klingons += quadrant_klingons - - quadrant_bases = 0 - if random.random() > 0.96: - quadrant_bases = 1 - self.bases_in_galaxy += 1 - self.galaxy_map[x][y] = QuadrantData( - quadrant_klingons, quadrant_bases, 1 + fnr() - ) - - if self.remaining_klingons > self.mission_duration: - self.mission_duration = self.remaining_klingons + 1 - - if self.bases_in_galaxy == 0: # original has buggy extra code here - self.bases_in_galaxy = 1 - self.galaxy_map[self.ship.position.quadrant.x][ - self.ship.position.quadrant.y - ].bases += 1 - - curr = self.ship.position.quadrant - self.quadrant = Quadrant( - self.ship.position.quadrant, - self.galaxy_map[curr.x][curr.y], - self.ship.position, - ) - - def remaining_time(self) -> float: - return self.initial_stardate + self.mission_duration - self.stardate - - def has_mission_ended(self) -> bool: - return self.remaining_time() < 0 - - -class Game: - """Handle user actions""" - - def __init__(self) -> None: - self.restart = False - self.world = World() - - def startup(self) -> None: - """Initialize the game variables and map, and print startup messages.""" - print( - "\n\n\n\n\n\n\n\n\n\n\n" - " ,------*------,\n" - " ,------------- '--- ------'\n" - " '-------- --' / /\n" - " ,---' '-------/ /--,\n" - " '----------------'\n\n" - " THE USS ENTERPRISE --- NCC-1701\n" - "\n\n\n\n" - ) - world = self.world - print( - "YOUR ORDERS ARE AS FOLLOWS:\n" - f" DESTROY THE {world.remaining_klingons} KLINGON WARSHIPS WHICH HAVE INVADED\n" - " THE GALAXY BEFORE THEY CAN ATTACK FEDERATION HEADQUARTERS\n" - f" ON STARDATE {world.initial_stardate+world.mission_duration}. " - f" THIS GIVES YOU {world.mission_duration} DAYS. THERE " - f"{'IS' if world.bases_in_galaxy == 1 else 'ARE'}\n" - f" {world.bases_in_galaxy} " - f"STARBASE{'' if world.bases_in_galaxy == 1 else 'S'} IN THE GALAXY FOR " - "RESUPPLYING YOUR SHIP.\n" - ) - - def new_quadrant(self) -> None: - """Enter a new quadrant: populate map and print a short range scan.""" - world = self.world - ship = world.ship - q = ship.position.quadrant - - world.quadrant = Quadrant( - q, - world.galaxy_map[q.x][q.y], - ship.position, - ) - - world.charted_galaxy_map[q.x][q.y] = world.galaxy_map[q.x][q.y] - - if world.stardate == world.initial_stardate: - print("\nYOUR MISSION BEGINS WITH YOUR STARSHIP LOCATED") - print(f"IN THE GALACTIC QUADRANT, '{world.quadrant.name}'.\n") +def navigation(): + # Take navigation input and move the Enterprise. + global d, s, e, k, qs, t, q1, q2, s1, s2 + + while True: + c1s = input("COURSE (1-9)? ") + if len(c1s) > 0: + c1 = float(c1s) + break + if c1 == 9: + c1 = 1 + if c1 < 1 or c1 >= 9: + print(" LT. SULU REPORTS, 'INCORRECT COURSE DATA, SIR!'") + return + + while True: + warps = input(f"WARP FACTOR (0-{'0.2' if d[0] < 0 else '8'})? ") + if len(warps) > 0: + warp = float(warps) + break + if d[0] < 0 and warp > 0.2: + print("WARP ENGINES ARE DAMAGED. MAXIMUM SPEED = WARP 0.2") + return + if warp == 0: + return + if warp < 0 or warp > 8: + print(" CHIEF ENGINEER SCOTT REPORTS 'THE ENGINES WON'T TAKE " + f"WARP {warp}!'") + return + + n = round(warp * 8) + if e < n: + print("ENGINEERING REPORTS 'INSUFFICIENT ENERGY AVAILABLE") + print(f" FOR MANEUVERING AT WARP {warp}!'") + if s >= n - e and d[6] >= 0: + print(f"DEFLECTOR CONTROL ROOM ACKNOWLEDGES {s} UNITS OF ENERGY") + print(" PRESENTLY DEPLOYED TO SHIELDS.") + return + + # klingons move and fire + for i in range(3): + if k[i][2] != 0: + insert_marker(k[i][0], k[i][1], ' ') + k[i][0], k[i][1] = find_empty_place() + insert_marker(k[i][0], k[i][1], '+K+') + + klingons_fire() + + # repair damaged devices and print damage report + line = '' + for i in range(8): + if d[i] < 0: + d[i] += min(warp, 1) + if -0.1 < d[i] < 0: + d[i] = -0.1 + elif d[i] >= 0: + if len(line) == 0: + line = "DAMAGE CONTROL REPORT:" + line += ' ' + devices[i] + ' REPAIR COMPLETED\n' + if len(line) > 0: + print(line) + if random.random() <= 0.2: + r1 = fnr() + if random.random() < 0.6: + d[r1] -= random.random() * 5 + 1 + print(f"DAMAGE CONTROL REPORT: {devices[r1]} DAMAGED\n") else: - print(f"\nNOW ENTERING {world.quadrant.name} QUADRANT . . .\n") + d[r1] += random.random() * 3 + 1 + print(f"DAMAGE CONTROL REPORT: {devices[r1]} STATE OF " + "REPAIR IMPROVED\n") + + # begin moving starship + insert_marker(int(s1), int(s2), ' ') + ic1 = int(c1) + x1 = c[ic1 - 1][0] + (c[ic1][0] - c[ic1 - 1][0]) * (c1 - ic1) + x2 = c[ic1 - 1][1] + (c[ic1][1] - c[ic1 - 1][1]) * (c1 - ic1) + q1_start, q2_start = q1, q2 + x, y = s1, s2 + + for _ in range(n): + s1 += x1 + s2 += x2 + + if s1 < 0 or s1 > 7 or s2 < 0 or s2 > 7: + # exceeded quadrant limits; calculate final position + x += 8 * q1 + n * x1 + y += 8 * q2 + n * x2 + q1, q2 = int(x / 8), int(y / 8) + s1, s2 = int(x - q1 * 8), int(y - q2 * 8) + if s1 < 0: + q1 -= 1 + s1 = 7 + if s2 < 0: + q2 -= 1 + s2 = 7 + + hit_edge = False + if q1 < 0: + hit_edge = True + q1 = s1 = 0 + if q1 > 7: + hit_edge = True + q1 = s1 = 7 + if q2 < 0: + hit_edge = True + q2 = s2 = 0 + if q2 > 7: + hit_edge = True + q2 = s2 = 7 + if hit_edge: + print("LT. UHURA REPORTS MESSAGE FROM STARFLEET COMMAND:") + print(" 'PERMISSION TO ATTEMPT CROSSING OF GALACTIC " + "PERIMETER") + print(" IS HEREBY *DENIED*. SHUT DOWN YOUR ENGINES.'") + print("CHIEF ENGINEER SCOTT REPORTS 'WARP ENGINES SHUT DOWN") + print(f" AT SECTOR {s1 + 1} , {s2 + 1} OF QUADRANT " + f"{q1 + 1} , {q2 + 1}.'") + if t > t0 + t9: + end_game(won=False, quit=False) + return - if world.quadrant.nb_klingons != 0: - print("COMBAT AREA CONDITION RED") - if ship.shields <= 200: - print(" SHIELDS DANGEROUSLY LOW") - self.short_range_scan() + if q1 == q1_start and q2 == q2_start: + break + t += 1 + maneuver_energy(n) + new_quadrant() + return + else: + pos = int(s1) * 24 + int(s2) * 3 + if qs[pos:(pos + 2)] != ' ': + s1, s2 = int(s1 - x1), int(s2 - x2) + print("WARP ENGINES SHUT DOWN AT SECTOR " + f"{s1 + 1} , {s2 + 1} DUE TO BAD NAVAGATION") + break + else: + s1, s2 = int(s1), int(s2) - def fnd(self, i: int) -> float: - """Find distance between Enterprise and i'th Klingon warship.""" - ship = self.world.ship.position.sector - klingons = self.world.quadrant.klingon_ships[i].sector - return sqrt((klingons.x - ship.x) ** 2 + (klingons.y - ship.y) ** 2) + insert_marker(int(s1), int(s2), '<*>') + maneuver_energy(n) - def klingons_fire(self) -> None: - """Process nearby Klingons firing on Enterprise.""" - ship = self.world.ship + t += 0.1 * int(10 * warp) if warp < 1 else 1 + if t > t0 + t9: + end_game(won=False, quit=False) + return - if self.world.quadrant.nb_klingons <= 0: - return - if ship.docked: - print("STARBASE SHIELDS PROTECT THE ENTERPRISE") - return + short_range_scan() - for i, klingon_ship in enumerate(self.world.quadrant.klingon_ships): - if klingon_ship.shield <= 0: - continue - h = int((klingon_ship.shield / self.fnd(i)) * (random.random() + 2)) - ship.shields -= h - klingon_ship.shield /= random.random() + 3 - print(f" {h} UNIT HIT ON ENTERPRISE FROM SECTOR {klingon_ship.sector} ") - if ship.shields <= 0: - self.end_game(won=False, quit=False, enterprise_killed=True) - return - print(f" ") - if h >= 20 and random.random() < 0.60 and h / ship.shields > 0.02: - device = fnr() - ship.damage_stats[device] -= h / ship.shields + 0.5 * random.random() - print( - f"DAMAGE CONTROL REPORTS '{ship.devices[device]} DAMAGED BY THE HIT'" - ) - - def phaser_control(self) -> None: - """Take phaser control input and fire phasers.""" - world = self.world - klingon_ships = world.quadrant.klingon_ships - ship = world.ship - - if ship.damage_stats[3] < 0: - print("PHASERS INOPERATIVE") - return +def maneuver_energy(n): + # Deduct the energy for navigation from energy/shields. + global e, s - if self.world.quadrant.nb_klingons <= 0: - print("SCIENCE OFFICER SPOCK REPORTS 'SENSORS SHOW NO ENEMY SHIPS") - print(" IN THIS QUADRANT'") - return + e -= n + 10 - if ship.damage_stats[7] < 0: - print("COMPUTER FAILURE HAMPERS ACCURACY") + if e <= 0: + print("SHIELD CONTROL SUPPLIES ENERGY TO COMPLETE THE MANEUVER.") + s += e + e = 0 + s = max(0, s) - print(f"PHASERS LOCKED ON TARGET; ENERGY AVAILABLE = {ship.energy} UNITS") - phaser_firepower: float = 0 - while True: - while True: - units_to_fire = input("NUMBER OF UNITS TO FIRE? ") - if len(units_to_fire) > 0: - phaser_firepower = int(units_to_fire) + +def short_range_scan(): + # Print a short range scan. + global docked, e, p, s + + docked = False + for i in (s1 - 1, s1, s1 + 1): + for j in (s2 - 1, s2, s2 + 1): + if 0 <= i <= 7 and 0 <= j <= 7: + if compare_marker(i, j, '>!<'): + docked = True + cs = 'DOCKED' + e, p = e0, p0 + print("SHIELDS DROPPED FOR DOCKING PURPOSES") + s = 0 break - if phaser_firepower <= 0: - return - if ship.energy >= phaser_firepower: - break - print(f"ENERGY AVAILABLE = {ship.energy} UNITS") + else: + continue + break + else: + if k3 > 0: + cs = '*RED*' + elif e < e0 * 0.1: + cs = 'YELLOW' + else: + cs = 'GREEN' - ship.energy -= phaser_firepower - if ship.damage_stats[7] < 0: # bug in original, was d[6] - phaser_firepower *= random.random() + if d[1] < 0: + print("\n*** SHORT RANGE SENSORS ARE OUT ***\n") + return - phaser_per_klingon = int(phaser_firepower / self.world.quadrant.nb_klingons) - for i, klingon_ship in enumerate(klingon_ships): - if klingon_ship.shield <= 0: - continue + sep = '---------------------------------' + print(sep) + for i in range(8): + line = '' + for j in range(8): + pos = i * 24 + j * 3 + line = line + ' ' + qs[pos:(pos + 3)] + + if i == 0: + line += f' STARDATE {round(int(t * 10) * 0.1, 1)}' + elif i == 1: + line += f' CONDITION {cs}' + elif i == 2: + line += f' QUADRANT {q1 + 1} , {q2 + 1}' + elif i == 3: + line += f' SECTOR {s1 + 1} , {s2 + 1}' + elif i == 4: + line += f' PHOTON TORPEDOES {int(p)}' + elif i == 5: + line += f' TOTAL ENERGY {int(e + s)}' + elif i == 6: + line += f' SHIELDS {int(s)}' + else: + line += f' KLINGONS REMAINING {k9}' - h = int((phaser_per_klingon / self.fnd(i)) * (random.random() + 2)) - if h <= 0.15 * klingon_ship.shield: - print(f"SENSORS SHOW NO DAMAGE TO ENEMY AT {klingon_ship.sector}") - else: - klingon_ship.shield -= h - print(f" {h} UNIT HIT ON KLINGON AT SECTOR {klingon_ship.sector}") - if klingon_ship.shield <= 0: - print("*** KLINGON DESTROYED ***") - self.world.quadrant.nb_klingons -= 1 - world.remaining_klingons -= 1 - world.quadrant.set_value( - klingon_ship.sector.x, klingon_ship.sector.y, Entity.void - ) - klingon_ship.shield = 0 - world.galaxy_map[ship.position.quadrant.x][ - ship.position.quadrant.y - ].klingons -= 1 - world.charted_galaxy_map[ship.position.quadrant.x][ - ship.position.quadrant.y - ] = world.galaxy_map[ship.position.quadrant.x][ - ship.position.quadrant.y - ] - if world.remaining_klingons <= 0: - self.end_game(won=True, quit=False) - return - else: - print( - f" (SENSORS SHOW {round(klingon_ship.shield,6)} UNITS REMAINING)" - ) + print(line) + print(sep) - self.klingons_fire() - def photon_torpedoes(self) -> None: - """Take photon torpedo input and process firing of torpedoes.""" - world = self.world - klingon_ships = world.quadrant.klingon_ships - ship = world.ship +def long_range_scan(): + # Print a long range scan. + global z - if ship.torpedoes <= 0: - print("ALL PHOTON TORPEDOES EXPENDED") - return - if ship.damage_stats[4] < 0: - print("PHOTON TUBES ARE NOT OPERATIONAL") - return + if d[2] < 0: + print("LONG RANGE SENSORS ARE INOPERABLE") + return - cd = get_user_float("PHOTON TORPEDO COURSE (1-9)? ") - if cd == 9: - cd = 1 - if cd < 1 or cd >= 9: - print("ENSIGN CHEKOV REPORTS, 'INCORRECT COURSE DATA, SIR!'") - return + print(f"LONG RANGE SCAN FOR QUADRANT {q1 + 1} , {q2 + 1}") + sep = '-------------------' + print(sep) + for i in (q1 - 1, q1, q1 + 1): + n = [-1, -2, -3] + + for j in (q2 - 1, q2, q2 + 1): + if 0 <= i <= 7 and 0 <= j <= 7: + n[j - q2 + 1] = g[i][j] + z[i][j] = g[i][j] + + line = ': ' + for l in range(3): + if n[l] < 0: + line += '*** : ' + else: + line += str(n[l] + 1000).rjust(4, ' ')[-3:] + ' : ' + print(line) + print(sep) - cdi = int(cd) - # Interpolate direction: - dx = dirs[cdi - 1][0] + (dirs[cdi][0] - dirs[cdi - 1][0]) * (cd - cdi) - dy = dirs[cdi - 1][1] + (dirs[cdi][1] - dirs[cdi - 1][1]) * (cd - cdi) +def phaser_control(): + # Take phaser control input and fire phasers. + global e, k, g, z, k3, k9 - ship.energy -= 2 - ship.torpedoes -= 1 + if d[3] < 0: + print("PHASERS INOPERATIVE") + return - # Exact position - x: float = ship.position.sector.x - y: float = ship.position.sector.y + if k3 <= 0: + print("SCIENCE OFFICER SPOCK REPORTS 'SENSORS SHOW NO ENEMY SHIPS") + print(" IN THIS QUADRANT'") + return - # Rounded position (to coordinates) - torpedo_x, torpedo_y = x, y - print("TORPEDO TRACK:") + if d[7] < 0: + print("COMPUTER FAILURE HAMPERS ACCURACY") + + print(f"PHASERS LOCKED ON TARGET; ENERGY AVAILABLE = {e} UNITS") + x = 0 + while True: while True: - x += dx - y += dy - torpedo_x, torpedo_y = round(x), round(y) - if torpedo_x < 0 or torpedo_x > 7 or torpedo_y < 0 or torpedo_y > 7: - print("TORPEDO MISSED") - self.klingons_fire() - return - print(f" {torpedo_x + 1} , {torpedo_y + 1}") - if world.quadrant.get_value(torpedo_x, torpedo_y) != Entity.void: + xs = input("NUMBER OF UNITS TO FIRE? ") + if len(xs) > 0: + x = int(xs) break - - if world.quadrant.get_value(torpedo_x, torpedo_y) == Entity.klingon: - print("*** KLINGON DESTROYED ***") - self.world.quadrant.nb_klingons -= 1 - world.remaining_klingons -= 1 - if world.remaining_klingons <= 0: - self.end_game(won=True, quit=False) - return - for klingon_ship in klingon_ships: - if ( - torpedo_x == klingon_ship.sector.x - and torpedo_y == klingon_ship.sector.y - ): - klingon_ship.shield = 0 - elif world.quadrant.get_value(torpedo_x, torpedo_y) == Entity.star: - print(f"STAR AT {torpedo_x + 1} , {torpedo_y + 1} ABSORBED TORPEDO ENERGY.") - self.klingons_fire() + if x <= 0: return - elif world.quadrant.get_value(torpedo_x, torpedo_y) == Entity.starbase: - print("*** STARBASE DESTROYED ***") - self.world.quadrant.nb_bases -= 1 - world.bases_in_galaxy -= 1 - if ( - world.bases_in_galaxy == 0 - and world.remaining_klingons - <= world.stardate - world.initial_stardate - world.mission_duration - ): - print("THAT DOES IT, CAPTAIN!! YOU ARE HEREBY RELIEVED OF COMMAND") - print("AND SENTENCED TO 99 STARDATES AT HARD LABOR ON CYGNUS 12!!") - self.end_game(won=False) - return - print("STARFLEET COMMAND REVIEWING YOUR RECORD TO CONSIDER") - print("COURT MARTIAL!") - ship.docked = False - - world.quadrant.set_value(torpedo_x, torpedo_y, Entity.void) - world.galaxy_map[ship.position.quadrant.x][ - ship.position.quadrant.y - ] = QuadrantData( - self.world.quadrant.nb_klingons, - self.world.quadrant.nb_bases, - self.world.quadrant.nb_stars, - ) - world.charted_galaxy_map[ship.position.quadrant.x][ - ship.position.quadrant.y - ] = world.galaxy_map[ship.position.quadrant.x][ship.position.quadrant.y] - self.klingons_fire() - - def short_range_scan(self) -> None: - """Print a short range scan.""" - self.world.ship.docked = False - ship = self.world.ship - for x in ( - ship.position.sector.x - 1, - ship.position.sector.x, - ship.position.sector.x + 1, - ): - for y in ( - ship.position.sector.y - 1, - ship.position.sector.y, - ship.position.sector.y + 1, - ): - if ( - 0 <= x <= 7 - and 0 <= y <= 7 - and self.world.quadrant.get_value(x, y) == Entity.starbase - ): - ship.docked = True - cs = "DOCKED" - ship.refill() - print("SHIELDS DROPPED FOR DOCKING PURPOSES") - ship.shields = 0 - break - else: - continue + if e >= x: break + print(f"ENERGY AVAILABLE = {e} UNITS") + + e -= x + if d[7] < 0: # bug in original, was d[6] + x *= random.random() + + h1 = int(x / k3) + for i in range(3): + if k[i][2] <= 0: + continue + + h = int((h1 / fnd(i)) * (random.random() + 2)) + if h <= 0.15 * k[i][2]: + print("SENSORS SHOW NO DAMAGE TO ENEMY AT " + f"{k[i][0] + 1} , {k[i][1] + 1}") else: - if self.world.quadrant.nb_klingons > 0: - cs = "*RED*" - elif ship.energy < Ship.energy_capacity * 0.1: - cs = "YELLOW" + k[i][2] -= h + print(f" {h} UNIT HIT ON KLINGON AT SECTOR " + f"{k[i][0] + 1} , {k[i][1] + 1}") + if k[i][2] <= 0: + print("*** KLINGON DESTROYED ***") + k3 -= 1 + k9 -= 1 + insert_marker(k[i][0], k[i][1], ' ') + k[i][2] = 0 + g[q1][q2] -= 100 + z[q1][q2] = g[q1][q2] + if k9 <= 0: + end_game(won=True, quit=False) + return else: - cs = "GREEN" + print(f" (SENSORS SHOW {round(k[i][2],6)} UNITS REMAINING)") - if ship.damage_stats[1] < 0: - print("\n*** SHORT RANGE SENSORS ARE OUT ***\n") - return + klingons_fire() - sep = "---------------------------------" - print(sep) - for x in range(8): - line = "" - for y in range(8): - line = f"{line} {self.world.quadrant.data[x][y].value}" - - if x == 0: - line += f" STARDATE {round(int(self.world.stardate * 10) * 0.1, 1)}" - elif x == 1: - line += f" CONDITION {cs}" - elif x == 2: - line += f" QUADRANT {ship.position.quadrant}" - elif x == 3: - line += f" SECTOR {ship.position.sector}" - elif x == 4: - line += f" PHOTON TORPEDOES {int(ship.torpedoes)}" - elif x == 5: - line += f" TOTAL ENERGY {int(ship.energy + ship.shields)}" - elif x == 6: - line += f" SHIELDS {int(ship.shields)}" - else: - line += f" KLINGONS REMAINING {self.world.remaining_klingons}" - print(line) - print(sep) +def photon_torpedoes(): + # Take photon torpedo input and process firing of torpedoes. + global e, p, k3, k9, k, b3, b9, docked, g, z - def long_range_scan(self) -> None: - """Print a long range scan.""" - if self.world.ship.damage_stats[2] < 0: - print("LONG RANGE SENSORS ARE INOPERABLE") - return + if p <= 0: + print("ALL PHOTON TORPEDOES EXPENDED") + return + if d[4] < 0: + print("PHOTON TUBES ARE NOT OPERATIONAL") + return - print(f"LONG RANGE SCAN FOR QUADRANT {self.world.ship.position.quadrant}") - print_scan_results( - self.world.ship.position.quadrant, - self.world.galaxy_map, - self.world.charted_galaxy_map, - ) - - def navigation(self) -> None: - """ - Take navigation input and move the Enterprise. - - 1/8 warp goes 1 sector in the direction dirs[course] - """ - world = self.world - ship = world.ship - - cd = get_user_float("COURSE (1-9)? ") - 1 # Convert to 0-8 - if cd == len(dirs) - 1: - cd = 0 - if cd < 0 or cd >= len(dirs): - print(" LT. SULU REPORTS, 'INCORRECT COURSE DATA, SIR!'") + while True: + c1s = input("PHOTON TORPEDO COURSE (1-9)? ") + if len(c1s) > 0: + c1 = float(c1s) + break + if c1 == 9: + c1 = 1 + if c1 < 1 or c1 >= 9: + print("ENSIGN CHEKOV REPORTS, 'INCORRECT COURSE DATA, SIR!'") + return + + ic1 = int(c1) + x1 = c[ic1 - 1][0] + (c[ic1][0] - c[ic1 - 1][0]) * (c1 - ic1) + e -= 2 + p -= 1 + x2 = c[ic1 - 1][1] + (c[ic1][1] - c[ic1 - 1][1]) * (c1 - ic1) + x, y = s1, s2 + x3, y3 = x, y + print("TORPEDO TRACK:") + while True: + x += x1 + y += x2 + x3, y3 = round(x), round(y) + if x3 < 0 or x3 > 7 or y3 < 0 or y3 > 7: + print("TORPEDO MISSED") + klingons_fire() return + print(f" {x3 + 1} , {y3 + 1}") + if not compare_marker(x3, y3, ' '): + break - warp = get_user_float( - f"WARP FACTOR (0-{'0.2' if ship.damage_stats[0] < 0 else '8'})? " - ) - if ship.damage_stats[0] < 0 and warp > 0.2: - print("WARP ENGINES ARE DAMAGED. MAXIMUM SPEED = WARP 0.2") + if compare_marker(x3, y3, '+K+'): + print("*** KLINGON DESTROYED ***") + k3 -= 1 + k9 -= 1 + if k9 <= 0: + end_game(won=True, quit=False) return - if warp == 0: - return - if warp < 0 or warp > 8: - print( - f" CHIEF ENGINEER SCOTT REPORTS 'THE ENGINES WON'T TAKE WARP {warp}!'" - ) + for i in range(3): + if x3 == k[i][0] and y3 == k[i][1]: + k[i][2] = 0 + elif compare_marker(x3, y3, ' * '): + print(f"STAR AT {x3 + 1} , {y3 + 1} ABSORBED TORPEDO ENERGY.") + klingons_fire() + return + elif compare_marker(x3, y3, '>!<'): + print("*** STARBASE DESTROYED ***") + b3 -= 1 + b9 -= 1 + if b9 == 0 and k9 <= t - t0 - t9: + print("THAT DOES IT, CAPTAIN!! YOU ARE HEREBY RELIEVED OF COMMAND") + print("AND SENTENCED TO 99 STARDATES AT HARD LABOR ON CYGNUS 12!!") + end_game(won=False) return + else: + print("STARFLEET COMMAND REVIEWING YOUR RECORD TO CONSIDER") + print("COURT MARTIAL!") + docked = False - warp_rounds = round(warp * 8) - if ship.energy < warp_rounds: - print("ENGINEERING REPORTS 'INSUFFICIENT ENERGY AVAILABLE") - print(f" FOR MANEUVERING AT WARP {warp}!'") - if ship.shields >= warp_rounds - ship.energy and ship.damage_stats[6] >= 0: - print( - f"DEFLECTOR CONTROL ROOM ACKNOWLEDGES {ship.shields} UNITS OF ENERGY" - ) - print(" PRESENTLY DEPLOYED TO SHIELDS.") - return + insert_marker(x3, y3, ' ') + g[q1][q2] = k3 * 100 + b3 * 10 + s3 + z[q1][q2] = g[q1][q2] + klingons_fire() - # klingons move and fire - for klingon_ship in self.world.quadrant.klingon_ships: - if klingon_ship.shield != 0: - world.quadrant.set_value( - klingon_ship.sector.x, klingon_ship.sector.y, Entity.void - ) - ( - klingon_ship.sector.x, - klingon_ship.sector.y, - ) = world.quadrant.find_empty_place() - world.quadrant.set_value( - klingon_ship.sector.x, klingon_ship.sector.y, Entity.klingon - ) - - self.klingons_fire() - - # repair damaged devices and print damage report - line = "" - for i in range(8): - if ship.damage_stats[i] < 0: - ship.damage_stats[i] += min(warp, 1) - if -0.1 < ship.damage_stats[i] < 0: - ship.damage_stats[i] = -0.1 - elif ship.damage_stats[i] >= 0: - if len(line) == 0: - line = "DAMAGE CONTROL REPORT:" - line += f" {ship.devices[i]} REPAIR COMPLETED\n" - if len(line) > 0: - print(line) - if random.random() <= 0.2: - device = fnr() - if random.random() < 0.6: - ship.damage_stats[device] -= random.random() * 5 + 1 - print(f"DAMAGE CONTROL REPORT: {ship.devices[device]} DAMAGED\n") - else: - ship.damage_stats[device] += random.random() * 3 + 1 - print( - f"DAMAGE CONTROL REPORT: {ship.devices[device]} STATE OF REPAIR IMPROVED\n" - ) - - self.move_ship(warp_rounds, cd) - world.stardate += 0.1 * int(10 * warp) if warp < 1 else 1 - if world.has_mission_ended(): - self.end_game(won=False, quit=False) - return - self.short_range_scan() - - def move_ship(self, warp_rounds: int, cd: float) -> None: - assert cd >= 0 - assert cd < len(dirs) - 1 - # cd is the course data which points to 'dirs' - world = self.world - ship = self.world.ship - world.quadrant.set_value( - int(ship.position.sector.x), int(ship.position.sector.y), Entity.void - ) - cdi = int(cd) - - # Interpolate direction: - dx = dirs[cdi][0] + (dirs[cdi + 1][0] - dirs[cdi][0]) * (cd - cdi) - dy = dirs[cdi][1] + (dirs[cdi + 1][1] - dirs[cdi][1]) * (cd - cdi) - - start_quadrant = Point(ship.position.quadrant.x, ship.position.quadrant.y) - sector_start_x: float = ship.position.sector.x - sector_start_y: float = ship.position.sector.y - - for _ in range(warp_rounds): - ship.position.sector.x += dx # type: ignore - ship.position.sector.y += dy # type: ignore - - if ( - ship.position.sector.x < 0 - or ship.position.sector.x > 7 - or ship.position.sector.y < 0 - or ship.position.sector.y > 7 - ): - # exceeded quadrant limits; calculate final position - sector_start_x += ship.position.quadrant.x * 8 + warp_rounds * dx - sector_start_y += ship.position.quadrant.y * 8 + warp_rounds * dy - ship.position.quadrant.x = int(sector_start_x / 8) - ship.position.quadrant.y = int(sector_start_y / 8) - ship.position.sector.x = int( - sector_start_x - ship.position.quadrant.x * 8 - ) - ship.position.sector.y = int( - sector_start_y - ship.position.quadrant.y * 8 - ) - if ship.position.sector.x < 0: - ship.position.quadrant.x -= 1 - ship.position.sector.x = 7 - if ship.position.sector.y < 0: - ship.position.quadrant.y -= 1 - ship.position.sector.y = 7 - - hit_edge = False - if ship.position.quadrant.x < 0: - hit_edge = True - ship.position.quadrant.x = ship.position.sector.x = 0 - if ship.position.quadrant.x > 7: - hit_edge = True - ship.position.quadrant.x = ship.position.sector.x = 7 - if ship.position.quadrant.y < 0: - hit_edge = True - ship.position.quadrant.y = ship.position.sector.y = 0 - if ship.position.quadrant.y > 7: - hit_edge = True - ship.position.quadrant.y = ship.position.sector.y = 7 - if hit_edge: - print("LT. UHURA REPORTS MESSAGE FROM STARFLEET COMMAND:") - print(" 'PERMISSION TO ATTEMPT CROSSING OF GALACTIC PERIMETER") - print(" IS HEREBY *DENIED*. SHUT DOWN YOUR ENGINES.'") - print("CHIEF ENGINEER SCOTT REPORTS 'WARP ENGINES SHUT DOWN") - print( - f" AT SECTOR {ship.position.sector} OF " - f"QUADRANT {ship.position.quadrant}.'" - ) - if world.has_mission_ended(): - self.end_game(won=False, quit=False) - return - - stayed_in_quadrant = ( - ship.position.quadrant.x == start_quadrant.x - and ship.position.quadrant.y == start_quadrant.y - ) - if stayed_in_quadrant: - break - world.stardate += 1 - ship.maneuver_energy(warp_rounds) - self.new_quadrant() - return - ship_sector = self.world.ship.position.sector - ship_x = int(ship_sector.x) - ship_y = int(ship_sector.y) - if self.world.quadrant.data[ship_x][ship_y] != Entity.void: - ship_sector.x = int(ship_sector.x - dx) - ship_sector.y = int(ship_sector.y - dy) - print( - "WARP ENGINES SHUT DOWN AT SECTOR " - f"{ship_sector} DUE TO BAD NAVIGATION" - ) - break - else: - ship.position.sector.x, ship.position.sector.y = int( - ship.position.sector.x - ), int(ship.position.sector.y) +def fnd(i): + # Find distance between Enterprise and i'th Klingon warship. + return sqrt((k[i][0] - s1)**2 + (k[i][1] - s2)**2) - world.quadrant.set_value( - int(ship.position.sector.x), int(ship.position.sector.y), Entity.ship - ) - ship.maneuver_energy(warp_rounds) - def damage_control(self) -> None: - """Print a damage control report.""" - ship = self.world.ship +def klingons_fire(): + # Process nearby Klingons firing on Enterprise. + global s, k, d - if ship.damage_stats[5] < 0: - print("DAMAGE CONTROL REPORT NOT AVAILABLE") - else: - print("\nDEVICE STATE OF REPAIR") - for r1 in range(8): - print( - f"{ship.devices[r1].ljust(26, ' ')}{int(ship.damage_stats[r1] * 100) * 0.01:g}" - ) - print() + if k3 <= 0: + return + if docked: + print("STARBASE SHIELDS PROTECT THE ENTERPRISE") + return - if not ship.docked: - return + for i in range(3): + if k[i][2] <= 0: + continue - damage_sum = sum(0.1 for i in range(8) if ship.damage_stats[i] < 0) - if damage_sum == 0: + h = int((k[i][2] / fnd(i)) * (random.random() + 2)) + s -= h + k[i][2] /= (random.random() + 3) + print(f" {h} UNIT HIT ON ENTERPRISE FROM SECTOR " + f"{k[i][0] + 1} , {k[i][1] + 1}") + if s <= 0: + end_game(won=False, quit=False, enterprise_killed=True) return + print(f" ") + if h >= 20 and random.random() < 0.60 and h / s > 0.02: + r1 = fnr() + d[r1] -= h / s + 0.5 * random.random() + print(f"DAMAGE CONTROL REPORTS '{devices[r1]} DAMAGED " + "BY THE HIT'") - damage_sum += self.world.quadrant.delay_in_repairs_at_base - if damage_sum >= 1: - damage_sum = 0.9 - print("\nTECHNICIANS STANDING BY TO EFFECT REPAIRS TO YOUR SHIP;") - print( - f"ESTIMATED TIME TO REPAIR: {round(0.01 * int(100 * damage_sum), 2)} STARDATES" - ) - if input("WILL YOU AUTHORIZE THE REPAIR ORDER (Y/N)? ").upper().strip() != "Y": - return - for i in range(8): - ship.damage_stats[i] = max(ship.damage_stats[i], 0) - self.world.stardate += damage_sum + 0.1 +def shield_control(): + # Raise or lower the shields. + global e, s + + if d[6] < 0: + print("SHIELD CONTROL INOPERABLE") + return + + while True: + xs = input(f"ENERGY AVAILABLE = {e + s} NUMBER OF UNITS TO SHIELDS? ") + if len(xs) > 0: + x = int(xs) + break + + if x < 0 or s == x: + print("") + return + + if x > e + s: + print("SHIELD CONTROL REPORTS 'THIS IS NOT THE FEDERATION " + "TREASURY.'\n" + "") + return + + e += s - x + s = x + print("DEFLECTOR CONTROL ROOM REPORT:") + print(f" 'SHIELDS NOW AT {s} UNITS PER YOUR COMMAND.'") - def computer(self) -> None: - """Perform the various functions of the library computer.""" - world = self.world - ship = world.ship - if ship.damage_stats[7] < 0: - print("COMPUTER DISABLED") +def damage_control(): + # Print a damage control report. + global d, t + + if d[5] < 0: + print('DAMAGE CONTROL REPORT NOT AVAILABLE') + else: + print('\nDEVICE STATE OF REPAIR') + for r1 in range(8): + print(f"{devices[r1].ljust(26, ' ')}{int(d[r1] * 100) * 0.01:g}") + print() + + if not docked: + return + + d3 = sum(0.1 for i in range(8) if d[i] < 0) + if d3 == 0: + return + + d3 += d4 + if d3 >= 1: + d3 = 0.9 + print("\nTECHNICIANS STANDING BY TO EFFECT REPAIRS TO YOUR SHIP;") + print("ESTIMATED TIME TO REPAIR: " + f"{round(0.01 * int(100 * d3), 2)} STARDATES") + if input("WILL YOU AUTHORIZE THE " + "REPAIR ORDER (Y/N)? ").upper().strip() != 'Y': + return + + for i in range(8): + if d[i] < 0: + d[i] = 0 + t += d3 + 0.1 + + +def computer(): + # Perform the various functions of the library computer. + global d, z, k9, t0, t9, t, b9, s1, s2, b4, b5 + + if d[7] < 0: + print("COMPUTER DISABLED") + return + + while True: + coms = input("COMPUTER ACTIVE AND AWAITING COMMAND? ") + if len(coms) == 0: + com = 6 + else: + com = int(coms) + if com < 0: return - while True: - command = input("COMPUTER ACTIVE AND AWAITING COMMAND? ") - if len(command) == 0: - com = 6 + print() + + if com == 0 or com == 5: + if com == 5: + print(" THE GALAXY") else: - try: - com = int(command) - except ValueError: - com = 6 - if com < 0: - return + print("\n COMPUTER RECORD OF GALAXY FOR " + f"QUADRANT {q1 + 1} , {q2 + 1}\n") - print() + print(" 1 2 3 4 5 6 7 8") + sep = " ----- ----- ----- ----- ----- ----- ----- -----" + print(sep) + + for i in range(8): + line = ' ' + str(i + 1) + ' ' - if com in {0, 5}: if com == 5: - print(" THE GALAXY") + g2s = quadrant_name(i, 0, True) + line += (' ' * int(12 - 0.5 * len(g2s))) + g2s + g2s = quadrant_name(i, 4, True) + line += (' ' * int(39 - 0.5 * len(g2s) - len(line))) + g2s else: - print( - "\n COMPUTER RECORD OF GALAXY FOR " - f"QUADRANT {ship.position.quadrant}\n" - ) - - print(" 1 2 3 4 5 6 7 8") - sep = " ----- ----- ----- ----- ----- ----- ----- -----" + for j in range(8): + line += ' ' + if z[i][j] == 0: + line += '***' + else: + line += str(z[i][j] + 1000)[-3:] + + print(line) print(sep) - for i in range(8): - line = f" {str(i + 1)} " - - if com == 5: - g2s = Quadrant.quadrant_name(i, 0, True) - line += (" " * int(12 - 0.5 * len(g2s))) + g2s - g2s = Quadrant.quadrant_name(i, 4, True) - line += (" " * int(39 - 0.5 * len(g2s) - len(line))) + g2s - else: - for j in range(8): - line += " " - if world.charted_galaxy_map[i][j].num() == 0: - line += "***" - else: - line += str( - world.charted_galaxy_map[i][j].num() + 1000 - )[-3:] - - print(line) - print(sep) - - print() - elif com == 1: - print(" STATUS REPORT:") - print( - f"KLINGON{'S' if world.remaining_klingons > 1 else ''} LEFT: {world.remaining_klingons}" - ) - print( - "MISSION MUST BE COMPLETED IN " - f"{round(0.1 * int(world.remaining_time() * 10), 1)} STARDATES" - ) - - if world.bases_in_galaxy == 0: - print("YOUR STUPIDITY HAS LEFT YOU ON YOUR OWN IN") - print(" THE GALAXY -- YOU HAVE NO STARBASES LEFT!") - else: - print( - f"THE FEDERATION IS MAINTAINING {world.bases_in_galaxy} " - f"STARBASE{'S' if world.bases_in_galaxy > 1 else ''} IN THE GALAXY" - ) - - self.damage_control() - elif com == 2: - if self.world.quadrant.nb_klingons <= 0: - print( - "SCIENCE OFFICER SPOCK REPORTS 'SENSORS SHOW NO ENEMY " - "SHIPS\n" - " IN THIS QUADRANT'" - ) - return + print() + return + elif com == 1: + print(" STATUS REPORT:") + print(f"KLINGON{'S' if k9 > 1 else ''} LEFT: {k9}") + print("MISSION MUST BE COMPLETED IN " + f"{round(0.1 * int((t0+t9-t) * 10), 1)} STARDATES") + + if b9 == 0: + print("YOUR STUPIDITY HAS LEFT YOU ON YOUR OWN IN") + print(" THE GALAXY -- YOU HAVE NO STARBASES LEFT!") + else: + print(f"THE FEDERATION IS MAINTAINING {b9} " + f"STARBASE{'S' if b9 > 1 else ''} IN THE GALAXY") - print( - f"FROM ENTERPRISE TO KLINGON BATTLE CRUISER{'S' if self.world.quadrant.nb_klingons > 1 else ''}" - ) - - for klingon_ship in self.world.quadrant.klingon_ships: - if klingon_ship.shield > 0: - print_direction( - Point(ship.position.sector.x, ship.position.sector.y), - Point( - int(klingon_ship.sector.x), - int(klingon_ship.sector.y), - ), - ) - elif com == 3: - if self.world.quadrant.nb_bases == 0: - print( - "MR. SPOCK REPORTS, 'SENSORS SHOW NO STARBASES IN THIS " - "QUADRANT.'" - ) - return + damage_control() + return + elif com == 2: + if k3 <= 0: + print("SCIENCE OFFICER SPOCK REPORTS 'SENSORS SHOW NO ENEMY " + "SHIPS\n" + " IN THIS QUADRANT'") + return - print("FROM ENTERPRISE TO STARBASE:") - print_direction( - Point(ship.position.sector.x, ship.position.sector.y), - self.world.quadrant.starbase, - ) - elif com == 4: - print("DIRECTION/DISTANCE CALCULATOR:") - print( - f"YOU ARE AT QUADRANT {ship.position.quadrant} " - f"SECTOR {ship.position.sector}" - ) - print("PLEASE ENTER") - while True: - coordinates = input(" INITIAL COORDINATES (X,Y)? ").split(",") - if len(coordinates) == 2: - from1, from2 = int(coordinates[0]) - 1, int(coordinates[1]) - 1 - if 0 <= from1 <= 7 and 0 <= from2 <= 7: - break - while True: - coordinates = input(" FINAL COORDINATES (X,Y)? ").split(",") - if len(coordinates) == 2: - to1, to2 = int(coordinates[0]) - 1, int(coordinates[1]) - 1 - if 0 <= to1 <= 7 and 0 <= to2 <= 7: - break - print_direction(Point(from1, from2), Point(to1, to2)) - else: - print( - "FUNCTIONS AVAILABLE FROM LIBRARY-COMPUTER:\n" - " 0 = CUMULATIVE GALACTIC RECORD\n" - " 1 = STATUS REPORT\n" - " 2 = PHOTON TORPEDO DATA\n" - " 3 = STARBASE NAV DATA\n" - " 4 = DIRECTION/DISTANCE CALCULATOR\n" - " 5 = GALAXY 'REGION NAME' MAP\n" - ) - - def end_game( - self, won: bool = False, quit: bool = True, enterprise_killed: bool = False - ) -> None: - """Handle end-of-game situations.""" - if won: - print("CONGRATULATIONS, CAPTAIN! THE LAST KLINGON BATTLE CRUISER") - print("MENACING THE FEDERATION HAS BEEN DESTROYED.\n") - print( - f"YOUR EFFICIENCY RATING IS {round(1000 * (self.world.remaining_klingons / (self.world.stardate - self.world.initial_stardate))**2, 4)}\n\n" - ) - else: - if not quit: - if enterprise_killed: - print( - "\nTHE ENTERPRISE HAS BEEN DESTROYED. THE FEDERATION " - "WILL BE CONQUERED." - ) - print(f"IT IS STARDATE {round(self.world.stardate, 1)}") - - print( - f"THERE WERE {self.world.remaining_klingons} KLINGON BATTLE CRUISERS LEFT AT" - ) - print("THE END OF YOUR MISSION.\n\n") - - if self.world.bases_in_galaxy == 0: - sys.exit() - - print("THE FEDERATION IS IN NEED OF A NEW STARSHIP COMMANDER") - print("FOR A SIMILAR MISSION -- IF THERE IS A VOLUNTEER,") - if input("LET HIM STEP FORWARD AND ENTER 'AYE'? ").upper().strip() != "AYE": - sys.exit() - self.restart = True - - -klingon_shield_strength: Final = 200 -# 8 sectors = 1 quadrant -dirs: Final = [ # (down-up, left,right) - [0, 1], # 1: go right (same as #9) - [-1, 1], # 2: go up-right - [-1, 0], # 3: go up (lower x-coordines; north) - [-1, -1], # 4: go up-left (north-west) - [0, -1], # 5: go left (west) - [1, -1], # 6: go down-left (south-west) - [1, 0], # 7: go down (higher x-coordines; south) - [1, 1], # 8: go down-right - [0, 1], # 9: go right (east) -] # vectors in cardinal directions - - -def fnr() -> int: - """Generate a random integer from 0 to 7 inclusive.""" - return random.randint(0, 7) + print("FROM ENTERPRISE TO KLINGON BATTLE " + f"CRUISER{'S' if k3 > 1 else ''}") + for i in range(3): + if k[i][2] > 0: + print_direction(s1, s2, k[i][0], k[i][1]) + return + elif com == 3: + if b3 == 0: + print("MR. SPOCK REPORTS, 'SENSORS SHOW NO STARBASES IN THIS " + "QUADRANT.'") + return -def print_scan_results( - quadrant: Point, - galaxy_map: List[List[QuadrantData]], - charted_galaxy_map: List[List[QuadrantData]], -) -> None: - sep = "-------------------" - print(sep) - for x in (quadrant.x - 1, quadrant.x, quadrant.x + 1): - n: List[Optional[int]] = [None, None, None] - - # Reveal parts of the current map - for y in (quadrant.y - 1, quadrant.y, quadrant.y + 1): - if 0 <= x <= 7 and 0 <= y <= 7: - n[y - quadrant.y + 1] = galaxy_map[x][y].num() - charted_galaxy_map[x][y] = galaxy_map[x][y] - - line = ": " - for line_col in n: - if line_col is None: - line += "*** : " - else: - line += str(line_col + 1000).rjust(4, " ")[-3:] + " : " - print(line) - print(sep) + print("FROM ENTERPRISE TO STARBASE:") + print_direction(s1, s2, b4, b5) + return + elif com == 4: + print("DIRECTION/DISTANCE CALCULATOR:") + print(f"YOU ARE AT QUADRANT {q1+1} , {q2+1} SECTOR " + f"{s1+1} , {s2+1}") + print("PLEASE ENTER") + while True: + ins = input(" INITIAL COORDINATES (X,Y)? ").split(',') + if len(ins) == 2: + from1, from2 = int(ins[0]) - 1, int(ins[1]) - 1 + if 0 <= from1 <= 7 and 0 <= from2 <= 7: + break + while True: + ins = input(" FINAL COORDINATES (X,Y)? ").split(',') + if len(ins) == 2: + to1, to2 = int(ins[0]) - 1, int(ins[1]) - 1 + if 0 <= to1 <= 7 and 0 <= to2 <= 7: + break + print_direction(from1, from2, to1, to2) + return + else: + print("FUNCTIONS AVAILABLE FROM LIBRARY-COMPUTER:\n" + " 0 = CUMULATIVE GALACTIC RECORD\n" + " 1 = STATUS REPORT\n" + " 2 = PHOTON TORPEDO DATA\n" + " 3 = STARBASE NAV DATA\n" + " 4 = DIRECTION/DISTANCE CALCULATOR\n" + " 5 = GALAXY 'REGION NAME' MAP\n") -def print_direction(source: Point, to: Point) -> None: - """Print direction and distance between two locations in the grid.""" - delta1 = -(to.x - source.x) # flip so positive is up (heading = 3) - delta2 = to.y - source.y +def print_direction(from1, from2, to1, to2): + # Print direction and distance between two locations in the grid. + delta1 = -(to1 - from1) # flip so positive is up (heading = 3) + delta2 = to2 - from2 if delta2 > 0: if delta1 < 0: @@ -1119,11 +694,12 @@ def print_direction(source: Point, to: Point) -> None: else: base = 1 delta1, delta2 = delta2, delta1 - elif delta1 > 0: - base = 3 else: - base = 5 - delta1, delta2 = delta2, delta1 + if delta1 > 0: + base = 3 + else: + base = 5 + delta1, delta2 = delta2, delta1 delta1, delta2 = abs(delta1), abs(delta2) @@ -1136,56 +712,202 @@ def print_direction(source: Point, to: Point) -> None: print(f"DISTANCE = {round(sqrt(delta1 ** 2 + delta2 ** 2), 6)}") -def main() -> None: - game = Game() - world = game.world - ship = world.ship +# ------------------------------------------------------------------------- +# Game transitions +# ------------------------------------------------------------------------- + + +def startup(): + # Initialize the game variables and map, and print startup messages. + global g, z, d, t, t0, t9, docked, e, e0, p, p0, s, k9, b9, s9, c + global devices, q1, q2, s1, s2, k7 + + print("\n\n\n\n\n\n\n\n\n\n\n" + " ,------*------,\n" + " ,------------- '--- ------'\n" + " '-------- --' / /\n" + " ,---' '-------/ /--,\n" + " '----------------'\n\n" + " THE USS ENTERPRISE --- NCC-1701\n" + "\n\n\n\n") + + # set up global game variables + g = [[0] * 8 for _ in range(8)] # galaxy map + z = [[0] * 8 for _ in range(8)] # charted galaxy map + d = [0] * 8 # damage stats for devices + t = t0 = 100 * random.randint(20, 39) # stardate (current, initial) + t9 = random.randint(25, 34) # mission duration (stardates) + docked = False # true when docked at starbase + e = e0 = 3000 # energy (current, initial) + p = p0 = 10 # torpedoes (current, initial) + s = 0 # shields + k9, b9 = 0, 0 # total Klingons, bases in galaxy + # ^ bug in original, was b9 = 2 + s9 = 200 # avg. Klingon shield strength + + c = [[0, 1], [-1, 1], [-1, 0], [-1, -1], [0, -1], [1, -1], + [1, 0], [1, 1], [0, 1]] # vectors in cardinal directions + + devices = ['WARP ENGINES', 'SHORT RANGE SENSORS', 'LONG RANGE SENSORS', + 'PHASER CONTROL', 'PHOTON TUBES', 'DAMAGE CONTROL', + 'SHIELD CONTROL', 'LIBRARY-COMPUTER'] + + # initialize Enterprise's position + q1, q2 = fnr(), fnr() # Enterprise's quadrant + s1, s2 = fnr(), fnr() # ...and sector + + # initialize contents of galaxy + for i in range(8): + for j in range(8): + k3 = 0 + r1 = random.random() + + if r1 > 0.98: + k3 = 3 + elif r1 > 0.95: + k3 = 2 + elif r1 > 0.80: + k3 = 1 + k9 += k3 + + b3 = 0 + if random.random() > 0.96: + b3 = 1 + b9 += 1 + g[i][j] = k3 * 100 + b3 * 10 + fnr() + 1 + + if k9 > t9: + t9 = k9 + 1 + + if b9 == 0: # original has buggy extra code here + b9 = 1 + g[q1][q2] += 10 + q1, q2 = fnr(), fnr() + + k7 = k9 # Klingons at start of game + + print("YOUR ORDERS ARE AS FOLLOWS:\n" + f" DESTROY THE {k9} KLINGON WARSHIPS WHICH HAVE INVADED\n" + " THE GALAXY BEFORE THEY CAN ATTACK FEDERATION HEADQUARTERS\n" + f" ON STARDATE {t0+t9}. THIS GIVES YOU {t9} DAYS. THERE " + f"{'IS' if b9 == 1 else 'ARE'}\n" + f" {b9} STARBASE{'' if b9 == 1 else 'S'} IN THE GALAXY FOR " + "RESUPPLYING YOUR SHIP.\n") + + +def new_quadrant(): + # Enter a new quadrant: populate map and print a short range scan. + global z, k3, b3, s3, d4, k, qs, b4, b5 + + k3 = b3 = s3 = 0 # Klingons, bases, stars in quad. + d4 = 0.5 * random.random() # extra delay in repairs at base + z[q1][q2] = g[q1][q2] + + if 0 <= q1 <= 7 and 0 <= q2 <= 7: + quad = quadrant_name(q1, q2, False) + if t == t0: + print("\nYOUR MISSION BEGINS WITH YOUR STARSHIP LOCATED") + print(f"IN THE GALACTIC QUADRANT, '{quad}'.\n") + else: + print(f"\nNOW ENTERING {quad} QUADRANT . . .\n") + + k3 = g[q1][q2] // 100 + b3 = g[q1][q2] // 10 - 10 * k3 + s3 = g[q1][q2] - 100 * k3 - 10 * b3 + + if k3 != 0: + print("COMBAT AREA CONDITION RED") + if s <= 200: + print(" SHIELDS DANGEROUSLY LOW") + + k = [[0, 0, 0], [0, 0, 0], [0, 0, 0]] # Klingons in current quadrant + qs = ' ' * 192 # quadrant string + + # build quadrant string + insert_marker(s1, s2, '<*>') + for i in range(k3): + r1, r2 = find_empty_place() + insert_marker(r1, r2, '+K+') + k[i] = [r1, r2, s9 * (0.5 + random.random())] + if b3 > 0: + b4, b5 = find_empty_place() # position of starbase (sector) + insert_marker(b4, b5, '>!<') + for i in range(s3): + r1, r2 = find_empty_place() + insert_marker(r1, r2, ' * ') + + short_range_scan() + + +def end_game(won=False, quit=True, enterprise_killed=False): + # Handle end-of-game situations. + global restart + + if won: + print("CONGRATULATIONS, CAPTAIN! THE LAST KLINGON BATTLE CRUISER") + print("MENACING THE FEDERATION HAS BEEN DESTROYED.\n") + print("YOUR EFFICIENCY RATING IS " + f"{round(1000 * (k7 / (t - t0))**2, 4)}\n\n") + else: + if not quit: + if enterprise_killed: + print("\nTHE ENTERPRISE HAS BEEN DESTROYED. THE FEDERATION " + "WILL BE CONQUERED.") + print(f"IT IS STARDATE {round(t, 1)}") + + print(f"THERE WERE {k9} KLINGON BATTLE CRUISERS LEFT AT") + print(f"THE END OF YOUR MISSION.\n\n") + + if b9 == 0: + exit() + + print("THE FEDERATION IS IN NEED OF A NEW STARSHIP COMMANDER") + print("FOR A SIMILAR MISSION -- IF THERE IS A VOLUNTEER,") + if input("LET HIM STEP FORWARD AND " + "ENTER 'AYE'? ").upper().strip() != 'AYE': + exit() + restart = True - f: Dict[str, Callable[[], None]] = { - "NAV": game.navigation, - "SRS": game.short_range_scan, - "LRS": game.long_range_scan, - "PHA": game.phaser_control, - "TOR": game.photon_torpedoes, - "SHE": ship.shield_control, - "DAM": game.damage_control, - "COM": game.computer, - "XXX": game.end_game, - } + +# ------------------------------------------------------------------------- +# Entry point and main game loop +# ------------------------------------------------------------------------- + + +def main(): + global restart + + f = {'NAV': navigation, 'SRS': short_range_scan, 'LRS': long_range_scan, + 'PHA': phaser_control, 'TOR': photon_torpedoes, 'SHE': shield_control, + 'DAM': damage_control, 'COM': computer, 'XXX': end_game} while True: - game.startup() - game.new_quadrant() + startup() + new_quadrant() restart = False while not restart: - if ship.shields + ship.energy <= 10 or ( - ship.energy <= 10 and ship.damage_stats[6] != 0 - ): - print( - "\n** FATAL ERROR ** YOU'VE JUST STRANDED YOUR SHIP " - "IN SPACE.\nYOU HAVE INSUFFICIENT MANEUVERING ENERGY, " - "AND SHIELD CONTROL\nIS PRESENTLY INCAPABLE OF CROSS-" - "CIRCUITING TO ENGINE ROOM!!" - ) - - command = input("COMMAND? ").upper().strip() + if s + e <= 10 or (e <= 10 and d[6] != 0): + print("\n** FATAL ERROR ** YOU'VE JUST STRANDED YOUR SHIP " + "IN SPACE.\nYOU HAVE INSUFFICIENT MANEUVERING ENERGY, " + "AND SHIELD CONTROL\nIS PRESENTLY INCAPABLE OF CROSS-" + "CIRCUITING TO ENGINE ROOM!!") + + command = input('COMMAND? ').upper().strip() if command in f: f[command]() else: - print( - "ENTER ONE OF THE FOLLOWING:\n" - " NAV (TO SET COURSE)\n" - " SRS (FOR SHORT RANGE SENSOR SCAN)\n" - " LRS (FOR LONG RANGE SENSOR SCAN)\n" - " PHA (TO FIRE PHASERS)\n" - " TOR (TO FIRE PHOTON TORPEDOES)\n" - " SHE (TO RAISE OR LOWER SHIELDS)\n" - " DAM (FOR DAMAGE CONTROL REPORTS)\n" - " COM (TO CALL ON LIBRARY-COMPUTER)\n" - " XXX (TO RESIGN YOUR COMMAND)\n" - ) + print("ENTER ONE OF THE FOLLOWING:\n" + " NAV (TO SET COURSE)\n" + " SRS (FOR SHORT RANGE SENSOR SCAN)\n" + " LRS (FOR LONG RANGE SENSOR SCAN)\n" + " PHA (TO FIRE PHASERS)\n" + " TOR (TO FIRE PHOTON TORPEDOES)\n" + " SHE (TO RAISE OR LOWER SHIELDS)\n" + " DAM (FOR DAMAGE CONTROL REPORTS)\n" + " COM (TO CALL ON LIBRARY-COMPUTER)\n" + " XXX (TO RESIGN YOUR COMMAND)\n") if __name__ == "__main__": diff --git a/84_Super_Star_Trek/python/superstartrekins.py b/84_Super_Star_Trek/python/superstartrekins.py index 6060ad9d4..2260c8072 100644 --- a/84_Super_Star_Trek/python/superstartrekins.py +++ b/84_Super_Star_Trek/python/superstartrekins.py @@ -7,28 +7,25 @@ Ported by Dave LeCompte """ - -def get_yes_no(prompt: str) -> bool: +def get_yes_no(prompt): response = input(prompt).upper() - return response[0] != "N" - + return response[0] != 'N' -def print_header() -> None: - for _ in range(12): +def print_header(): + for i in range(12): print() t10 = " " * 10 - print(f"{t10}*************************************") - print(f"{t10}* *") - print(f"{t10}* *") - print(f"{t10}* * * SUPER STAR TREK * * *") - print(f"{t10}* *") - print(f"{t10}* *") - print(f"{t10}*************************************") - for _ in range(8): + print(t10 + "*************************************") + print(t10 + "* *") + print(t10 + "* *") + print(t10 + "* * * SUPER STAR TREK * * *") + print(t10 + "* *") + print(t10 + "* *") + print(t10 + "*************************************") + for i in range(8): print() - -def print_instructions() -> None: +def print_instructions(): # Back in the 70s, at this point, the user would be prompted to # turn on their (printing) TTY to capture the output to hard copy. @@ -63,7 +60,7 @@ def print_instructions() -> None: 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(" ITSELF IS EQUIVALENT TO 1.0" ) print(" COURSE") print(" ONE WARP FACTOR IS THE SIZE OF ") print(" ONE QUADTANT. THEREFORE, TO GET") @@ -137,14 +134,14 @@ def print_instructions() -> None: 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.") + + - -def main() -> None: +def main(): print_header() if not get_yes_no("DO YOU NEED INSTRUCTIONS (Y/N)? "): return print_instructions() - if __name__ == "__main__": main() diff --git a/84_Super_Star_Trek/rust/Cargo.lock b/84_Super_Star_Trek/rust/Cargo.lock deleted file mode 100644 index 71bbf0c8c..000000000 --- a/84_Super_Star_Trek/rust/Cargo.lock +++ /dev/null @@ -1,169 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "bitflags" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "ctrlc" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a011bbe2c35ce9c1f143b7af6f94f29a167beb4cd1d29e6740ce836f723120e" -dependencies = [ - "nix", - "windows-sys", -] - -[[package]] -name = "getrandom" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "libc" -version = "0.2.147" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" - -[[package]] -name = "nix" -version = "0.26.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abbbc55ad7b13aac85f9401c796dcda1b864e07fcad40ad47792eaa8932ea502" -dependencies = [ - "bitflags", - "cfg-if", - "libc", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rust" -version = "0.1.0" -dependencies = [ - "ctrlc", - "rand", -] - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" diff --git a/84_Super_Star_Trek/rust/Cargo.toml b/84_Super_Star_Trek/rust/Cargo.toml deleted file mode 100644 index 01457249b..000000000 --- a/84_Super_Star_Trek/rust/Cargo.toml +++ /dev/null @@ -1,10 +0,0 @@ -[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] -ctrlc = "3.2.5" -rand = "0.8.5" diff --git a/84_Super_Star_Trek/rust/readme.md b/84_Super_Star_Trek/rust/readme.md deleted file mode 100644 index ae2f58dc3..000000000 --- a/84_Super_Star_Trek/rust/readme.md +++ /dev/null @@ -1,19 +0,0 @@ -# Super Star Trek - Rust version - -Explanation of modules: - -- [main.rs](./src/main.rs) - creates the galaxy (generation functions are in model.rs as impl methods) then loops listening for commands. after each command checks for victory or defeat condtions. -- [model.rs](./src/model.rs) - all the structs and enums that represent the galaxy. key methods in here (as impl methods) are generation functions on galaxy and quadrant, and various comparison methods on the 'Pos' tuple type. -- [commands.rs](./src/commands.rs) - most of the code that implements instructions given by the player (some code logic is in the model impls, and some in view.rs if its view only). -- [view.rs](./src/view.rs) - all text printed to the output, mostly called by command.rs (like view::bad_nav for example). also contains the prompts printed to the user (e.g. view::prompts::COMMAND). -- [input.rs](./src/input.rs) - utility methods for getting input from the user, including logic for parsing numbers, repeating prompts until a correct value is provided etc. - -Basically the user is asked for the next command, this runs a function that usually checks if the command system is working, and if so will gather additional input (see next note for a slight change here), then either the model is read and info printed, or its mutated in some way (e.g. firing a torpedo, which reduces the torpedo count on the enterprise and can destroy klingons and star bases; finally the klingons fire back and can destroy the enterprise). Finally the win/lose conditions are checked before the loop repeats. - -## Changes from the original - -I have tried to keep it as close as possible. Notable changes are: - -- commands can be given with parameters in line. e.g. while 'nav' will ask for course and then warp speed in the original, here you can *optionally* also do this as one line, e.g. `nav 1 0.1` to move one sector east. I'm sorry - it was driving me insane in its original form (which is still sorted, as is partial application e.g. nav 1 to preset direction and then provide speed). -- text is mostly not uppercase, as text was in the basic version. this would be easy to change however as all text is in view.rs, but I chose not to. -- the navigation system (plotting direction, paths and collision detection) is as close as I could make it to the basic version (by using other language conversions as specification sources) but I suspect is not perfect. seems to work well enough however. \ No newline at end of file diff --git a/84_Super_Star_Trek/rust/src/commands.rs b/84_Super_Star_Trek/rust/src/commands.rs deleted file mode 100644 index 599327cac..000000000 --- a/84_Super_Star_Trek/rust/src/commands.rs +++ /dev/null @@ -1,584 +0,0 @@ -use rand::Rng; - -use crate::{model::*, view, input::{self, param_or_prompt_value, prompt_two_values}}; - -pub fn perform_short_range_scan(galaxy: &Galaxy) { - if galaxy.enterprise.damaged.contains_key(systems::SHORT_RANGE_SCAN) { - view::scanners_out(); - return; - } - - view::short_range_scan(&galaxy) -} - -pub fn get_amount_and_set_shields(galaxy: &mut Galaxy, provided: Vec) { - - if galaxy.enterprise.damaged.contains_key(systems::SHIELD_CONTROL) { - view::inoperable(&systems::name_for(systems::SHIELD_CONTROL)); - return; - } - - view::energy_available(galaxy.enterprise.total_energy); - let value = input::param_or_prompt_value(&provided, 0, view::prompts::SHIELDS, 0, i32::MAX); - if value.is_none() { - view::shields_unchanged(); - return; - } - - let value = value.unwrap() as u16; - if value > galaxy.enterprise.total_energy { - view::ridiculous(); - view::shields_unchanged(); - return; - } - - galaxy.enterprise.shields = value; - view::shields_set(value); -} - -pub fn gather_dir_and_speed_then_move(galaxy: &mut Galaxy, provided: Vec) { - - let course = input::param_or_prompt_value(&provided, 0, view::prompts::COURSE, 1.0, 9.0); - if course.is_none() { - view::bad_course_data(); - return; - } - - let course = course.unwrap(); - - let mut max_warp = 8.0; - if galaxy.enterprise.damaged.contains_key(systems::WARP_ENGINES) { - max_warp = 0.2; - } - - let speed = input::param_or_prompt_value(&provided, 1, &view::prompts::warp_factor(max_warp), 0.0, 8.0); - if speed.is_none() { - view::bad_course_data(); - return; - } - - let speed = speed.unwrap(); - - if speed > max_warp { - view::damaged_engines(max_warp, speed); - return; - } - - klingons_move(galaxy); - klingons_fire(galaxy); - - if galaxy.enterprise.destroyed { - return; - } - - repair_systems(&mut galaxy.enterprise, speed); - repair_or_damage_random_system(&mut galaxy.enterprise); - - move_enterprise(course, speed, galaxy); -} - -fn repair_systems(enterprise: &mut Enterprise, amount: f32) { - - let keys: Vec = enterprise.damaged.keys().map(|k| k.to_string()).collect(); - let mut repaired = Vec::new(); - for key in keys { - let fully_fixed = enterprise.repair_system(&key, amount); - if fully_fixed { - repaired.push(systems::name_for(&key)); - } - } - - if repaired.len() <= 0 { - return; - } - - view::damage_control_report(); - for name in repaired { - view::system_repair_completed(name); - } -} - -fn repair_or_damage_random_system(enterprise: &mut Enterprise) { - let mut rng = rand::thread_rng(); - - if rng.gen::() > 0.2 { - return; - } - - if rng.gen::() >= 0.6 { - if enterprise.damaged.len() == 0 { - return; - } - - let damaged: Vec = enterprise.damaged.keys().map(|k| k.to_string()).collect(); - let system = damaged[rng.gen_range(0..damaged.len())].to_string(); - let system_name = &systems::name_for(&system); - - enterprise.repair_system(&system, rng.gen::() * 3.0 + 1.0); - view::random_repair_report_for(system_name, false); - return; - } - - let system = systems::KEYS[rng.gen_range(0..systems::KEYS.len())].to_string(); - let system_name = &systems::name_for(&system); - - enterprise.damage_system(&system, rng.gen::() * 5.0 + 1.0); - view::random_repair_report_for(system_name, true); -} - -fn move_enterprise(course: f32, warp_speed: f32, galaxy: &mut Galaxy) { - - let ship = &mut galaxy.enterprise; - - let (mut path, mut hit_edge) = find_nav_path(ship.quadrant, ship.sector, course, warp_speed); - for i in 0..path.len() { - let (quadrant, sector) = path[i].to_local_quadrant_sector(); - if quadrant != ship.quadrant { - break; // have left current quadrant, so collision checks removed. if there is a collision at the dest... /shrug? - } - let quadrant = &galaxy.quadrants[quadrant.as_index()]; - if quadrant.sector_status(sector) != SectorStatus::Empty { - path = path[..i].into(); - hit_edge = false; - if i > 0 { - let (_, last_sector) = path[path.len() - 1].to_local_quadrant_sector(); - view::bad_nav(last_sector); - } else { - view::bad_nav(ship.sector); - return; - } - break; - } - } - - if path.len() == 0 { - if hit_edge { - view::hit_edge(ship.quadrant, ship.sector); - } - return; - } - - let energy_cost = path.len() as u16 + 10; - - if energy_cost > ship.total_energy { - view::insuffient_warp_energy(warp_speed); - return - } - - let (end_quadrant, end_sector) = path[path.len() - 1].to_local_quadrant_sector(); - if hit_edge { - view::hit_edge(end_quadrant, end_sector); - } - - if ship.quadrant != end_quadrant { - view::enter_quadrant(end_quadrant); - galaxy.scanned.insert(end_quadrant); - - if galaxy.quadrants[end_quadrant.as_index()].klingons.len() > 0 { - view::condition_red(); - if ship.shields <= 200 { - view::danger_shields(); - } - } - } - - ship.quadrant = end_quadrant; - ship.sector = end_sector; - - let quadrant = &galaxy.quadrants[end_quadrant.as_index()]; - if quadrant.docked_at_starbase(ship.sector) { - ship.shields = 0; - ship.photon_torpedoes = MAX_PHOTON_TORPEDOES; - ship.total_energy = MAX_ENERGY; - } else { - ship.total_energy = ship.total_energy - energy_cost; - if ship.shields > ship.total_energy { - view::divert_energy_from_shields(); - ship.shields = ship.total_energy; - } - } - - view::short_range_scan(&galaxy) -} - -fn find_nav_path(start_quadrant: Pos, start_sector: Pos, course: f32, warp_speed: f32) -> (Vec, bool) { - - let (dx, dy) = calculate_delta(course); - - let mut distance = (warp_speed * 8.0) as i8; - if distance == 0 { - distance = 1; - } - - let mut last_sector = start_sector.as_galactic_sector(start_quadrant); - let mut path = Vec::new(); - let mut hit_edge; - - loop { - let nx = (last_sector.0 as f32 + dx) as i8; - let ny = (last_sector.1 as f32 + dy) as i8; - hit_edge = nx < 0 || ny < 0 || nx >= 64 || ny >= 64; - if hit_edge { - break; - } - last_sector = Pos(nx as u8, ny as u8); - path.push(last_sector); - - distance -= 1; - if distance == 0 { - break; - } - } - - (path, hit_edge) -} - -fn calculate_delta(course: f32) -> (f32, f32) { - // this course delta stuff is a translation (of a translation, of a translation...) of the original basic calcs - let dir = (course - 1.0) % 8.0; - let (dx1, dy1) = COURSES[dir as usize]; - let (dx2, dy2) = COURSES[(dir + 1.0) as usize]; - let frac = dir - (dir as i32) as f32; - - let dx = dx1 + (dx2 - dx1) * frac; - let dy = dy1 + (dy2 - dy1) * frac; - - (dx, dy) -} - -fn klingons_move(galaxy: &mut Galaxy) { - let quadrant = &mut galaxy.quadrants[galaxy.enterprise.quadrant.as_index()]; - for k in 0..quadrant.klingons.len() { - let new_sector: Pos; - loop { - let candidate = quadrant.find_empty_sector(); - if candidate != galaxy.enterprise.sector { - new_sector = candidate; - break; - } - } - quadrant.klingons[k].sector = new_sector; - } -} - -fn klingons_fire(galaxy: &mut Galaxy) { - let quadrant = &mut galaxy.quadrants[galaxy.enterprise.quadrant.as_index()]; - if quadrant.docked_at_starbase(galaxy.enterprise.sector) { - view::starbase_shields(); - return; - } - - for k in 0..quadrant.klingons.len() { - quadrant.klingons[k].fire_on(&mut galaxy.enterprise); - } -} - -pub fn run_damage_control(galaxy: &Galaxy) { - if galaxy.enterprise.damaged.contains_key(systems::DAMAGE_CONTROL) { - view::inoperable(&systems::name_for(systems::DAMAGE_CONTROL)); - return; - } - - view::damage_control(&galaxy.enterprise); -} - -pub fn try_starbase_ship_repair(galaxy: &mut Galaxy) { - let ship = &mut galaxy.enterprise; - let quadrant = &galaxy.quadrants[ship.quadrant.as_index()]; - if ship.damaged.len() == 0 || !quadrant.docked_at_starbase(ship.sector) { - return; - } - - let repair_delay = quadrant.star_base.as_ref().unwrap().repair_delay; - let repair_time = (ship.damaged.len() as f32 * 0.1 + repair_delay).max(0.9); - - view::repair_estimate(repair_time); - if !input::prompt_yes_no(view::prompts::REPAIR) { - return; - } - - ship.damaged.clear(); - galaxy.stardate += repair_time; - view::damage_control(&ship); -} - -pub fn perform_long_range_scan(galaxy: &mut Galaxy) { - if galaxy.enterprise.damaged.contains_key(systems::LONG_RANGE_SCAN) { - view::inoperable(&systems::name_for(systems::LONG_RANGE_SCAN)); - return; - } - - let seen = view::long_range_scan(galaxy); - for pos in seen { - galaxy.scanned.insert(pos); - } -} - -pub fn access_computer(galaxy: &Galaxy, provided: Vec) { - if galaxy.enterprise.damaged.contains_key(systems::COMPUTER) { - view::inoperable(&systems::name_for(systems::COMPUTER)); - return; - } - - let operation : i32; - loop { - let entered = input::param_or_prompt_value(&provided, 0, view::prompts::COMPUTER, 0, 5); - if entered.is_none() { - view::computer_options(); - } else { - operation = entered.unwrap(); - break; - } - } - - match operation { - 0 => view::galaxy_scanned_map(galaxy), - 1 => { - view::status_report(galaxy); - run_damage_control(galaxy); - }, - 2 => show_klingon_direction_data(galaxy), - 3 => show_starbase_direction_data(galaxy), - 4 => direction_dist_calculator(galaxy), - 5 => view::galaxy_region_map(), - _ => () // unreachable - } -} - -fn show_klingon_direction_data(galaxy: &Galaxy) { - let quadrant = &galaxy.quadrants[galaxy.enterprise.quadrant.as_index()]; - if quadrant.klingons.len() == 0 { - view::no_local_enemies(); - return; - } - - view::klingon_report(quadrant.klingons.len() > 1); - let origin = galaxy.enterprise.sector; - for k in &quadrant.klingons { - let target = k.sector; - view::direction_distance(origin.direction(target), origin.dist(target)) - } -} - -fn show_starbase_direction_data(galaxy: &Galaxy) { - let quadrant = &galaxy.quadrants[galaxy.enterprise.quadrant.as_index()]; - match &quadrant.star_base { - None => { - view::no_local_starbase(); - return; - }, - Some(s) => { - view::starbase_report(); - let origin = galaxy.enterprise.sector; - let target = s.sector; - view::direction_distance(origin.direction(target), origin.dist(target)) - } - } -} - -fn direction_dist_calculator(galaxy: &Galaxy) { - view::direction_dist_intro(&galaxy.enterprise); - loop { - let coords1 = prompt_two_values(view::prompts::INITIAL_COORDS, 1, 8).map(|(x, y)| Pos(x, y)); - if coords1.is_none() { - continue; - } - let coords2 = prompt_two_values(view::prompts::TARGET_COORDS, 1, 8).map(|(x, y)| Pos(x, y)); - if coords2.is_none() { - continue; - } - let dir = coords1.unwrap().direction(coords2.unwrap()); - let dist = coords1.unwrap().dist(coords2.unwrap()); - view::direction_distance(dir, dist); - break; - } -} - -pub fn get_power_and_fire_phasers(galaxy: &mut Galaxy, provided: Vec) { - if galaxy.enterprise.damaged.contains_key(systems::PHASERS) { - view::inoperable(&systems::name_for(systems::PHASERS)); - return; - } - - let quadrant = &mut galaxy.quadrants[galaxy.enterprise.quadrant.as_index()]; - if quadrant.klingons.len() == 0 { - view::no_local_enemies(); - return; - } - - let computer_damaged = galaxy.enterprise.damaged.contains_key(systems::COMPUTER); - if computer_damaged { - view::computer_accuracy_issue(); - } - - let available_energy = galaxy.enterprise.total_energy - galaxy.enterprise.shields; - view::phasers_locked(available_energy); - let mut power: f32; - loop { - let setting = param_or_prompt_value(&provided, 0, view::prompts::PHASERS, 0, available_energy); - if setting.is_some() { - power = setting.unwrap() as f32; - break; - } - } - - if power == 0.0 { - return; - } - - galaxy.enterprise.total_energy -= power as u16; - - let mut rng = rand::thread_rng(); - if computer_damaged { - power *= rng.gen::(); - } - - let per_enemy = power / quadrant.klingons.len() as f32; - - for k in &mut quadrant.klingons { - let dist = k.sector.abs_diff(galaxy.enterprise.sector) as f32; - let hit_strength = per_enemy / dist * (2.0 + rng.gen::()); - if hit_strength < 0.15 * k.energy { - view::no_damage(k.sector); - } else { - k.energy -= hit_strength; - view::hit_on_klingon(hit_strength, k.sector); - if k.energy > 0.0 { - view::klingon_remaining_energy(k.energy); - } else { - view::klingon_destroyed(); - } - } - } - - quadrant.klingons.retain(|k| k.energy > 0.0); - - klingons_fire(galaxy); -} - -pub fn gather_dir_and_launch_torpedo(galaxy: &mut Galaxy, provided: Vec) { - let star_bases = galaxy.remaining_starbases(); - let ship = &mut galaxy.enterprise; - - if ship.damaged.contains_key(systems::TORPEDOES) { - view::inoperable(&systems::name_for(systems::TORPEDOES)); - return; - } - - if ship.photon_torpedoes == 0 { - view::no_torpedoes_remaining(); - return; - } - - let course = input::param_or_prompt_value(&provided, 0, view::prompts::TORPEDO_COURSE, 1.0, 9.0); - if course.is_none() { - view::bad_torpedo_course(); - return; - } - - ship.photon_torpedoes -= 1; - view::torpedo_track(); - - let path = find_torpedo_path(ship.sector, course.unwrap()); - let quadrant = &mut galaxy.quadrants[ship.quadrant.as_index()]; - let mut hit = false; - for p in path { - view::torpedo_path(p); - match quadrant.sector_status(p) { - SectorStatus::Empty => continue, - SectorStatus::Star => { - hit = true; - view::star_absorbed_torpedo(p); - break; - }, - SectorStatus::Klingon => { - hit = true; - quadrant.get_klingon(p).unwrap().energy = 0.0; - quadrant.klingons.retain(|k| k.energy > 0.0); - view::klingon_destroyed(); - break; - }, - SectorStatus::StarBase => { - hit = true; - quadrant.star_base = None; - let remaining = star_bases - 1; - view::destroyed_starbase(remaining > 0); - if remaining == 0 { - ship.destroyed = true; - } - break; - } - } - } - - if ship.destroyed { // if you wiped out the last starbase, trigger game over - return; - } - - if !hit { - view::torpedo_missed(); - } - - klingons_fire(galaxy); -} - -fn find_torpedo_path(start_sector: Pos, course: f32) -> Vec { - - let (dx, dy) = calculate_delta(course); - - let mut last_sector = start_sector; - let mut path = Vec::new(); - - let mut nx = last_sector.0 as f32; - let mut ny = last_sector.1 as f32; - - loop { - nx += dx; - ny += dy; - if nx < 0.0 || ny < 0.0 || nx >= 8.0 || ny >= 8.0 { - break; - } - let step = Pos(nx.round() as u8, ny.round() as u8); - if step != last_sector { - last_sector = step; - path.push(last_sector); - } - } - - path -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_find_torpedo_path() { - let path = find_torpedo_path(Pos(0, 0), 7.45); - assert_eq!( - *path.last().unwrap(), - Pos(7, 3), - ); - assert_eq!( - path, - vec!(Pos(1, 0), Pos(2, 1), Pos(3, 1), Pos(4, 2), Pos(5, 2), Pos(6, 3), Pos(7, 3)) - ); - - assert_eq!( - find_torpedo_path(Pos(4, 7), 4.5), - vec!(Pos(4, 6), Pos(3, 5), Pos(3, 4), Pos(2, 3), Pos(2, 2), Pos(1, 1), Pos(1, 0)) - ); - - let enterprise = Pos(3, 3); - for y in 0..=7 { - for x in 0..=7 { - let pos = Pos(y, x); - if pos != enterprise { - let course = enterprise.direction(pos); - let path = find_torpedo_path(enterprise, course); - assert!(path.contains(&pos)); - }; - }; - }; - } -} diff --git a/84_Super_Star_Trek/rust/src/input.rs b/84_Super_Star_Trek/rust/src/input.rs deleted file mode 100644 index 62d4daee9..000000000 --- a/84_Super_Star_Trek/rust/src/input.rs +++ /dev/null @@ -1,73 +0,0 @@ -use std::{io::{stdin, stdout, Write}, str::FromStr}; - -pub fn prompt(prompt_text: &str) -> Vec { - let stdin = stdin(); - let mut stdout = stdout(); - - print!("{prompt_text} "); - let _ = stdout.flush(); - - let mut buffer = String::new(); - if let Ok(_) = stdin.read_line(&mut buffer) { - return buffer.trim_end().split([' ', ',']).map(|s| s.to_string()).collect(); - } - Vec::new() -} - -pub fn prompt_yes_no(prompt_text: &str) -> bool { - loop { - let response = prompt(&format!("{prompt_text} (Y/N)")); - if response.len() == 0 { - continue; - } - let first_word = response[0].to_uppercase(); - if first_word.starts_with("Y") { - return true; - } - if first_word.starts_with("N") { - return false; - } - } -} - -pub fn prompt_value(prompt_text: &str, min: T, max: T) -> Option { - let passed = prompt(prompt_text); - if passed.len() != 1 { - return None - } - match passed[0].parse::() { - Ok(n) if (n >= min && n <= max) => Some(n), - _ => None - } -} - -pub fn param_or_prompt_value(params: &Vec, param_pos: usize, prompt_text: &str, min: T, max: T) -> Option { - let mut res: Option = None; - if params.len() > param_pos { - match params[param_pos].parse::() { - Ok(n) if (n >= min && n <= max) => res = Some(n), - _ => () - } - } - if res.is_some() { - return res; - } - return prompt_value::(prompt_text, min, max); -} - -pub fn prompt_two_values(prompt_text: &str, min: T, max: T) -> Option<(T, T)> { - let passed = prompt(prompt_text); - if passed.len() != 2 { - return None - } - match passed[0].parse::() { - Ok(n1) if (n1 >= min && n1 <= max) => { - match passed[1].parse::() { - Ok(n2) if (n2 >= min && n2 <= max) => - Some((n1, n2)), - _ => None - } - } - _ => None - } -} \ No newline at end of file diff --git a/84_Super_Star_Trek/rust/src/main.rs b/84_Super_Star_Trek/rust/src/main.rs deleted file mode 100644 index 4c1a277ef..000000000 --- a/84_Super_Star_Trek/rust/src/main.rs +++ /dev/null @@ -1,70 +0,0 @@ -use std::process::exit; - -use input::{prompt, prompt_yes_no}; -use model::{Galaxy, systems}; - -mod input; -mod model; -mod commands; -mod view; - -fn main() { - ctrlc::set_handler(move || { exit(0) }) - .expect("Error setting Ctrl-C handler"); - - view::title(); - if prompt_yes_no(view::prompts::INSTRUCTIONS) { - view::full_instructions(); - let _ = input::prompt(view::prompts::WHEN_READY); - } - - let mut galaxy = Galaxy::generate_new(); - let initial_klingons = galaxy.remaining_klingons(); - let initial_stardate = galaxy.stardate; - - view::enterprise(); - view::intro(&galaxy); - let _ = input::prompt(view::prompts::WHEN_READY); - - view::starting_quadrant(galaxy.enterprise.quadrant); - view::short_range_scan(&galaxy); - - loop { - let command = input::prompt(view::prompts::COMMAND); - if command.len() == 0 { - continue; - } - match command[0].to_uppercase().as_str() { // order is weird because i built it in this order :) - systems::SHORT_RANGE_SCAN => commands::perform_short_range_scan(&galaxy), - systems::WARP_ENGINES => commands::gather_dir_and_speed_then_move(&mut galaxy, command[1..].into()), - systems::SHIELD_CONTROL => commands::get_amount_and_set_shields(&mut galaxy, command[1..].into()), - systems::DAMAGE_CONTROL => { - commands::run_damage_control(&galaxy); - commands::try_starbase_ship_repair(&mut galaxy); - } - systems::LONG_RANGE_SCAN => commands::perform_long_range_scan(&mut galaxy), - systems::COMPUTER => commands::access_computer(&galaxy, command[1..].into()), - systems::PHASERS => commands::get_power_and_fire_phasers(&mut galaxy, command[1..].into()), - systems::TORPEDOES => commands::gather_dir_and_launch_torpedo(&mut galaxy, command[1..].into()), - systems::RESIGN => galaxy.enterprise.destroyed = true, - _ => view::print_command_help() - } - - if galaxy.enterprise.destroyed || galaxy.enterprise.is_stranded() || galaxy.stardate >= galaxy.final_stardate { - view::end_game_failure(&galaxy); - if galaxy.remaining_klingons() > 0 && galaxy.remaining_starbases() > 0 && galaxy.stardate < galaxy.final_stardate { - view::replay(); - let result = prompt(""); - if result.len() > 0 && result[0].to_uppercase() == "AYE" { - galaxy.enterprise = Galaxy::new_captain(&galaxy.quadrants); - continue; - } - } - break; - } else if galaxy.remaining_klingons() == 0 { - let efficiency = 1000.0 * f32::powi(initial_klingons as f32 / (galaxy.stardate - initial_stardate), 2); - view::congratulations(efficiency); - break; - } - } -} diff --git a/84_Super_Star_Trek/rust/src/model.rs b/84_Super_Star_Trek/rust/src/model.rs deleted file mode 100644 index aa08d7345..000000000 --- a/84_Super_Star_Trek/rust/src/model.rs +++ /dev/null @@ -1,355 +0,0 @@ -use std::{ops::{Mul, Add}, fmt::Display, collections::{HashMap, HashSet}}; - -use rand::Rng; - -use crate::view; - -pub struct Galaxy { - pub stardate: f32, - pub final_stardate: f32, - pub quadrants: Vec, - pub scanned: HashSet, - pub enterprise: Enterprise -} - -pub struct Quadrant { - pub stars: Vec, - pub star_base: Option, - pub klingons: Vec -} - -pub struct StarBase { - pub sector: Pos, - pub repair_delay: f32, -} - -pub struct Klingon { - pub sector: Pos, - pub energy: f32 -} - -impl Klingon { - pub fn fire_on(&mut self, enterprise: &mut Enterprise) { - let mut rng = rand::thread_rng(); - let attack_strength = rng.gen::(); - let dist_to_enterprise = self.sector.abs_diff(enterprise.sector) as f32; - let hit_strength = self.energy * (2.0 + attack_strength) / dist_to_enterprise; - - self.energy /= 3.0 + attack_strength; - - enterprise.take_hit(self.sector, hit_strength as u16); - } -} - -pub struct Enterprise { - pub destroyed: bool, - pub damaged: HashMap, - pub quadrant: Pos, - pub sector: Pos, - pub photon_torpedoes: u8, - pub total_energy: u16, - pub shields: u16, -} -impl Enterprise { - fn take_hit(&mut self, sector: Pos, hit_strength: u16) { - if self.destroyed { - return; - } - - view::enterprise_hit(&hit_strength, sector); - - if self.shields <= hit_strength { - view::enterprise_destroyed(); - self.destroyed = true; - return; - } - - self.shields -= hit_strength; - - view::shields_hit(self.shields); - - if hit_strength >= 20 { - self.take_damage(hit_strength) - } - } - - fn take_damage(&mut self, hit_strength: u16) { - let mut rng = rand::thread_rng(); - - let hit_past_shield = hit_strength as f32 / self.shields as f32; - if rng.gen::() > 0.6 || hit_past_shield < 0.02 { - return - } - - let system = systems::KEYS[rng.gen_range(0..systems::KEYS.len())].to_string(); - let damage = hit_past_shield + rng.gen::() * 0.5; - self.damage_system(&system, damage); - } - - pub fn damage_system(&mut self, system: &str, damage: f32) { - self.damaged.entry(system.to_string()).and_modify(|d| *d -= damage).or_insert(-damage); - } - - pub fn repair_system(&mut self, system: &str, amount: f32) -> bool { - let existing_damage = self.damaged[system]; - if existing_damage + amount >= -0.1 { - self.damaged.remove(system); - return true; - } - - self.damaged.entry(system.to_string()).and_modify(|d| *d += amount); - return false; - } - - pub fn is_stranded(&self) -> bool { - if self.total_energy < 10 || (self.shields + 10 > self.total_energy && self.damaged.contains_key(systems::SHIELD_CONTROL)) { - view::stranded(); - return true; - } - return false; - } -} - -pub mod systems { - - pub const SHORT_RANGE_SCAN: &str = "SRS"; - pub const WARP_ENGINES: &str = "NAV"; - pub const SHIELD_CONTROL: &str = "SHE"; - pub const DAMAGE_CONTROL: &str = "DAM"; - pub const LONG_RANGE_SCAN: &str = "LRS"; - pub const COMPUTER: &str = "COM"; - pub const PHASERS: &str = "PHA"; - pub const TORPEDOES: &str = "TOR"; - - pub const RESIGN: &str = "XXX"; - - pub const KEYS: [&str; 8] = [ - SHORT_RANGE_SCAN, WARP_ENGINES, SHIELD_CONTROL, DAMAGE_CONTROL, LONG_RANGE_SCAN, COMPUTER, PHASERS, TORPEDOES - ]; - - pub fn name_for(key: &str) -> String { - match key { - SHORT_RANGE_SCAN => "Short Range Scanners".into(), - WARP_ENGINES => "Warp Engines".into(), - SHIELD_CONTROL => "Shield Control".into(), - DAMAGE_CONTROL => "Damage Control".into(), - LONG_RANGE_SCAN => "Long Range Scanners".into(), - COMPUTER => "Library-Computer".into(), - PHASERS => "Phaser Control".into(), - TORPEDOES => "Photon Tubes".into(), - _ => "Unknown".into() - } - } -} - -#[derive(PartialEq, Clone, Copy, Debug, Hash, Eq)] -pub struct Pos(pub u8, pub u8); - -impl Pos { - pub fn as_index(&self) -> usize { - (self.0 * 8 + self.1).into() - } - - pub fn abs_diff(&self, other: Pos) -> u8 { - self.0.abs_diff(other.0) + self.1.abs_diff(other.1) - } - - pub fn dist(&self, other: Pos) -> u8 { - let dx = other.0 as f32 - self.0 as f32; - let dy = other.1 as f32 - self.1 as f32; - (f32::powi(dx, 2) + f32::powi(dy, 2)).sqrt() as u8 - } - - pub fn direction(&self, other: Pos) -> f32 { - // this is a replication of the original BASIC code - let dx = other.0 as f32 - self.0 as f32; - let dy = other.1 as f32 - self.1 as f32; - let dx_dominant = dx.abs() > dy.abs(); - - let frac = if dx_dominant { dy / dx } else { -dx / dy }; - let nearest_cardinal = - if dx_dominant { - if dx > 0. { 7. } else { 3. } - } else { - if dy > 0. { 1. } else { 5. } - }; - - let mut dir = nearest_cardinal + frac; - if dir < 1. { - dir += 8. - } - dir - } - - pub fn as_galactic_sector(&self, containing_quadrant: Pos) -> Self { - Pos(containing_quadrant.0 * 8 + self.0, containing_quadrant.1 * 8 + self.1) - } - - pub fn to_local_quadrant_sector(&self) -> (Self, Self) { - (Pos(self.0 / 8, self.1 / 8), Pos(self.0 % 8, self.1 % 8)) - } -} - -impl Mul for Pos { - type Output = Self; - - fn mul(self, rhs: u8) -> Self::Output { - Pos(self.0 * rhs, self.1 * rhs) - } -} - -impl Add for Pos { - type Output = Self; - - fn add(self, rhs: Pos) -> Self::Output { - Pos(self.0 + rhs.0, self.1 + rhs.1) - } -} - -impl Display for Pos { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{} , {}", self.0 + 1, self.1 + 1) - } -} - -pub const COURSES : [(f32, f32); 9] = [ - (0., 1.), - (-1., 1.), - (-1., 0.), - (-1., -1.), - (0., -1.), - (1., -1.), - (1., 0.), - (1., 1.), - (0., 1.), // course 9 is equal to course 1 -]; - -#[derive(PartialEq)] -pub enum SectorStatus { - Empty, Star, StarBase, Klingon -} - -pub const MAX_PHOTON_TORPEDOES: u8 = 28; -pub const MAX_ENERGY: u16 = 3000; - -impl Galaxy { - pub fn remaining_klingons(&self) -> u8 { - let quadrants = &self.quadrants; - quadrants.into_iter().map(|q| { q.klingons.len() as u8 }).sum::() - } - - pub fn remaining_starbases(&self) -> u8 { - let quadrants = &self.quadrants; - quadrants.into_iter().filter(|q| q.star_base.is_some()).count() as u8 - } - - pub fn generate_new() -> Self { - let quadrants = Self::generate_quadrants(); - - let mut rng = rand::thread_rng(); - let stardate = rng.gen_range(20..=40) as f32 * 100.0; - - let enterprise = Self::new_captain(&quadrants); - - let mut scanned = HashSet::new(); - scanned.insert(enterprise.quadrant); - - Galaxy { - stardate, - final_stardate: stardate + rng.gen_range(25..=35) as f32, - quadrants, - scanned, - enterprise - } - } - - pub fn new_captain(quadrants: &Vec) -> Enterprise { - let mut rng = rand::thread_rng(); - let enterprise_quadrant = Pos(rng.gen_range(0..8), rng.gen_range(0..8)); - let enterprise_sector = quadrants[enterprise_quadrant.as_index()].find_empty_sector(); - Enterprise { - destroyed: false, - damaged: HashMap::new(), - quadrant: enterprise_quadrant, - sector: enterprise_sector, - photon_torpedoes: MAX_PHOTON_TORPEDOES, - total_energy: MAX_ENERGY, - shields: 0 } - } - - fn generate_quadrants() -> Vec { - let mut rng = rand::thread_rng(); - let mut result = Vec::new(); - for _ in 0..64 { - - let mut quadrant = Quadrant { stars: Vec::new(), star_base: None, klingons: Vec::new() }; - let star_count = rng.gen_range(0..=7); - for _ in 0..star_count { - quadrant.stars.push(quadrant.find_empty_sector()); - } - - if rng.gen::() > 0.96 { - quadrant.star_base = Some(StarBase { sector: quadrant.find_empty_sector(), repair_delay: rng.gen::() * 0.5 }); - } - - let klingon_count = - match rng.gen::() { - n if n > 0.98 => 3, - n if n > 0.95 => 2, - n if n > 0.8 => 1, - _ => 0 - }; - for _ in 0..klingon_count { - quadrant.klingons.push(Klingon { sector: quadrant.find_empty_sector(), energy: rng.gen_range(100..=300) as f32 }); - } - - result.push(quadrant); - } - result - } -} - -impl Quadrant { - pub fn sector_status(&self, sector: Pos) -> SectorStatus { - if self.stars.contains(§or) { - SectorStatus::Star - } else if self.is_starbase(sector) { - SectorStatus::StarBase - } else if self.has_klingon(sector) { - SectorStatus::Klingon - } else { - SectorStatus::Empty - } - } - - fn is_starbase(&self, sector: Pos) -> bool { - match &self.star_base { - None => false, - Some(p) => p.sector == sector - } - } - - fn has_klingon(&self, sector: Pos) -> bool { - let klingons = &self.klingons; - klingons.into_iter().find(|k| k.sector == sector).is_some() - } - - pub fn get_klingon(&mut self, sector: Pos) -> Option<&mut Klingon> { - let klingons = &mut self.klingons; - klingons.into_iter().find(|k| k.sector == sector) - } - - pub fn find_empty_sector(&self) -> Pos { - let mut rng = rand::thread_rng(); - loop { - let pos = Pos(rng.gen_range(0..8), rng.gen_range(0..8)); - if self.sector_status(pos) == SectorStatus::Empty { - return pos - } - } - } - - pub fn docked_at_starbase(&self, enterprise_sector: Pos) -> bool { - self.star_base.is_some() && self.star_base.as_ref().unwrap().sector.abs_diff(enterprise_sector) == 1 - } -} diff --git a/84_Super_Star_Trek/rust/src/view.rs b/84_Super_Star_Trek/rust/src/view.rs deleted file mode 100644 index caf6b74d2..000000000 --- a/84_Super_Star_Trek/rust/src/view.rs +++ /dev/null @@ -1,635 +0,0 @@ -use crate::model::{Galaxy, Pos, SectorStatus, Enterprise, systems}; - -pub mod prompts { - pub const INSTRUCTIONS: &str = "Do you need instructions"; - pub const COURSE: &str = "Course (1-9)?"; - pub const TORPEDO_COURSE: &str = "Photon torpedo course (1-9)?"; - pub const SHIELDS: &str = "Number of units to shields"; - pub const REPAIR: &str = "Will you authorize the repair order"; - pub const COMPUTER: &str = "Computer active and waiting command?"; - pub const PHASERS: &str = "Number of units to fire"; - pub const WHEN_READY: &str = "Press Enter when ready to accept command"; - pub const COMMAND: &str = "Command?"; - pub const INITIAL_COORDS: &str = " Initial coordinates (X/Y)"; - pub const TARGET_COORDS: &str = " Final coordinates (X/Y)"; - - pub fn warp_factor(max_warp: f32) -> String { - format!("Warp Factor (0-{})?", max_warp) - } -} - -pub fn title() { - println!(" - - - - - - - - - - - - ************************************* - * * - * * - * * * SUPER STAR TREK * * * - * * - * * - ************************************* - - - - - - - - - - "); -} - -pub fn full_instructions() { - println!( -" INSTRUCTIONS FOR 'SUPER STAR TREK' - - 1. When you see \"Command ?\" printed, enter one of the legal - commands (NAV, SRS, LRS, PHA, TOR, SHE, DAM, COM, OR XXX). - 2. If you should type in an illegal command, you'll get a short - list of the legal commands printed out. - 3. Some commands require you to enter data (for example, the - 'NAV' command comes back with 'Course (1-9) ?'.) If you - type in illegal data (like negative numbers), then command - will be aborted. - - The galaxy is divided into an 8 X 8 quadrant grid, - and each quadrant is further divided into an 8 X 8 sector grid. - - You will be assigned a starting point somewhere in the - galaxy to begin a tour of duty as commander of the starship - Enterprise; your mission: to seek and destroy the fleet of - Klingon warships which are menacing the United Federation of - Planets. - - You have the following commands available to you as captain - of the starship Enterprise: - - NAV command = Warp Engine Control - Course is in a circular numerical 4 3 2 - vector arrangement as shown . . . - integer and real values may be ... - used. (Thus course 1.5 is half- 5 ---*--- 1 - way between 1 and 2. ... - . . . - Values may approach 9.0, which 6 7 8 - itself is equivalent to 1.0 - COURSE - One warp factor is the size of - one quadrant. Therefore, to get - from quadrant 6,5 to 5,5, you WOULD - use course 3, warp factor 1. - - SRS command = Short Range Sensor Scan - Shows you a scan of your present quadrant. - - Symbology on your sensor screen is as follows: - <*> = Your starship's position - +K+ = Klingon battle cruiser - >!< = Federation starbase (refuel/repair/re-arm here!) - * = Star - - A condensed 'status report' will also be presented. - - LRS command = Long Range Sensor Scan - Shows conditions in space for one quadrant on each side - of the Enterprise (which is in the middle of the scan). - The scan is coded in the form ###, where the units digit - is the number of stars, the tens digit is the number of - starbases, and the hundreds digit is the number of - Klingons. - - Example - 207 = 2 Klingons, No starbases, & 7 stars. - - PHA command = Phaser Control - Allows you to destroy the Klingon battle cruisers by - zapping them with suitably large units of energy to - deplete their shield power. (Remember, Klingons have - phasers, too!) - - TOR command = Photon Torpedo Control - Torpedo course is the same as used in warp engine control. - If you hit the Klingon vessel, he is destroyed and - cannot fire back at you. If you miss, you are subject to - his phaser fire. In either case, you are also subject to - the phaser fire of all other Klingons in the quadrant. - - The library-computer (COM command) has an option to - compute torpedo trajectory for you (Option 2). - - SHE command = Shield Control - Defines the number of energy units to be assigned to the - shields. Energy is taken from total ship's energy. Note - that the status display total energy includes shield energy. - - DAM command = Damage Control Report - Gives the state of repair of all devices. Where a negative - 'state of repair' shows that the device is temporarily - damaged. - - COM command = Library-Computer - The library-computer contains six options: - Option 0 = Cumulative Galactic Record - This option shows computer memory of the results of all - previous short and long range sensor scans. - Option 1 = Status Report - This option shows the number of Klingons, Stardates, - and starbases remaining in the game. - Option 2 = Photon Torpedo Data - Which gives directions and distance from the Enterprise - to all Klingons in your quadrant. - Option 3 = Starbase Nav Data - This option gives direction and distance to any - starbase within your quadrant. - Option 4 = Direction/Distance Calculator - This option allows you to enter coordinates for - direction/distance calculations. - Option 5 = Galactic Region Name Map - This option prints the names of the sixteen major - galactic regions referred to in the game. - -") -} - -pub fn enterprise() { - println!(" - - - - - - - - - - - ,------*------, - ,------------- '--- ------' - '-------- --' / / - ,---' '-------/ /--, - '----------------' - - THE USS ENTERPRISE --- NCC-1701 - - - - - - -") -} - -pub fn intro(model: &Galaxy) { - let star_bases = model.remaining_starbases(); - let mut star_base_message: String = "There is 1 starbase".into(); - if star_bases > 1 { - star_base_message = format!("There are {} starbases", star_bases); - } - println!( -"Your orders are as follows: - Destroy the {} Klingon warships which have invaded - the galaxy before they can attack federation headquarters - on stardate {:.1}. This gives you {} days. {} in the galaxy for resupplying your ship.\n", - model.remaining_klingons(), model.final_stardate, model.final_stardate - model.stardate, star_base_message) -} - -const REGION_NAMES: [&str; 16] = [ - "Antares", - "Sirius", - "Rigel", - "Deneb", - "Procyon", - "Capella", - "Vega", - "Betelgeuse", - "Canopus", - "Aldebaran", - "Altair", - "Regulus", - "Sagittarius", - "Arcturus", - "Pollux", - "Spica" -]; - -const SUB_REGION_NAMES: [&str; 4] = ["I", "II", "III", "IV"]; - -fn quadrant_name(quadrant: Pos) -> String { - format!("{} {}", - REGION_NAMES[((quadrant.0 << 1) + (quadrant.1 >> 2)) as usize], - SUB_REGION_NAMES[(quadrant.1 % 4) as usize]) -} - -pub fn starting_quadrant(quadrant: Pos) { - println!( -"\nYour mission begins with your starship located -in the galactic quadrant, '{}'.\n", quadrant_name(quadrant)) -} - -pub fn enter_quadrant(quadrant: Pos) { - println!("\nNow entering {} quadrant . . .\n", quadrant_name(quadrant)) -} - -pub fn short_range_scan(model: &Galaxy) { - let quadrant = &model.quadrants[model.enterprise.quadrant.as_index()]; - let mut condition = "GREEN"; - if quadrant.docked_at_starbase(model.enterprise.sector) { - println!("Shields dropped for docking purposes"); - condition = "DOCKED"; - } else if quadrant.klingons.len() > 0 { - condition = "*RED*"; - } else if model.enterprise.damaged.len() > 0 { - condition = "YELLOW"; - } - - let data : [String; 8] = [ - format!("Stardate {:.1}", model.stardate), - format!("Condition {}", condition), - format!("Quadrant {}", model.enterprise.quadrant), - format!("Sector {}", model.enterprise.sector), - format!("Photon torpedoes {}", model.enterprise.photon_torpedoes), - format!("Total energy {}", model.enterprise.total_energy), - format!("Shields {}", model.enterprise.shields), - format!("Klingons remaining {}", model.remaining_klingons()), - ]; - - println!("{:-^33}", ""); - for x in 0..=7 { - for y in 0..=7 { - let pos = Pos(x, y); - if &pos == &model.enterprise.sector { - print!("<*> ") - } else { - match quadrant.sector_status(pos) { - SectorStatus::Star => print!(" * "), - SectorStatus::StarBase => print!(">!< "), - SectorStatus::Klingon => print!("+K+ "), - _ => print!(" "), - } - } - } - println!("{:>9}{}", "", data[x as usize]) - } - println!("{:-^33}", ""); -} - -pub fn print_command_help() { - println!( -"Enter one of the following: - NAV (To set course) - SRS (For short range sensor scan) - LRS (For long range sensor scan) - PHA (To fire phasers) - TOR (To fire photon torpedoes) - SHE (To raise or lower shields) - DAM (For damage control reports) - COM (To call on library-computer) - XXX (To resign your command) - ") -} - -pub fn end_game_failure(galaxy: &Galaxy) { - println!( -"Is is stardate {:.1}. -There were {} Klingon battle cruisers left at -the end of your mission. -", galaxy.stardate, galaxy.remaining_klingons()); -} - -pub fn enterprise_destroyed() { - println!("The Enterprise has been destroyed. The Federation will be conquered."); -} - -pub fn bad_course_data() { - println!(" Lt. Sulu reports, 'Incorrect course data, sir!'") -} - -pub fn bad_nav(current_sector: Pos) { - println!("Warp engines shut down at sector {current_sector} dues to bad navigation") -} - -pub fn bad_torpedo_course() { - println!(" Ensign Chekov reports, 'Incorrect course data, sir!'") -} - -pub fn enterprise_hit(hit_strength: &u16, from_sector: Pos) { - println!("{hit_strength} unit hit on Enterprise from sector {from_sector}"); -} - -pub fn hit_edge(quadrant: Pos, sector: Pos) { - println!( -"Lt. Uhura report message from Starfleet Command: - 'Permission to attempt crossing of galactic perimeter - is hereby *Denied*. Shut down your engines.' - Chief Engineer Scott reports, 'Warp engines shut down - at sector {} of quadrant {}.'", sector, quadrant); -} - -pub fn condition_red() { - println!("COMBAT AREA CONDITION RED") -} - -pub fn danger_shields() { - println!(" SHIELDS DANGEROUSLY LOW ") -} - -pub fn insuffient_warp_energy(warp_speed: f32) { - println!( -"Engineering reports, 'Insufficient energy available - for maneuvering at warp {warp_speed} !'") -} - -pub fn divert_energy_from_shields() { - println!("Shield Control supplies energy to complete the maneuver.") -} - -pub fn energy_available(total_energy: u16) { - println!("Energy available = {{{total_energy}}}") -} - -pub fn shields_unchanged() { - println!("") -} - -pub fn ridiculous() { - println!("Shield Control reports, 'This is not the Federation Treasury.'") -} - -pub fn shields_set(value: u16) { - println!( -"Deflector control room report: - 'Shields now at {value} units per your command.'") -} - -pub fn shields_hit(shields: u16) { - println!(" ") -} - -pub fn inoperable(arg: &str) { - println!("{} inoperable", arg) -} - -pub fn scanners_out() { - println!("*** Short Range Sensors are out ***") -} - -pub fn damaged_engines(max_warp: f32, warp_factor: f32) { - println!( -"Warp engines are damaged. Maximum speed = warp {max_warp} - Chief Engineer Scott reports, 'The engines won't take warp {warp_factor} !'") -} - -pub fn damage_control_report() { - println!("Damage Control report:") -} - -pub fn random_repair_report_for(name: &str, damaged: bool) { - let mut message = "state of repair improved"; - if damaged { - message = "damaged"; - } - println!("Damage Control report: {name} {message}") -} - -pub fn system_repair_completed(name: String) { - println!(" {name} repair completed.") -} - -pub fn damage_control(enterprise: &Enterprise) { - println!("Device State of Repair"); - for key in systems::KEYS { - let damage = enterprise.damaged.get(key).unwrap_or(&0.0); - println!("{:<25}{}", systems::name_for(key), damage) - } - println!(); -} - -pub fn long_range_scan(galaxy: &Galaxy) -> Vec { - - let cx = galaxy.enterprise.quadrant.0 as i8; - let cy = galaxy.enterprise.quadrant.1 as i8; - - let mut seen = Vec::new(); - - println!("Long range scan for quadrant {}", galaxy.enterprise.quadrant); - println!("{:-^19}", ""); - for x in cx - 1..=cx + 1 { - for y in cy - 1..=cy + 1 { - let mut klingons = "*".into(); - let mut star_bases = "*".into(); - let mut stars = "*".into(); - - if y >= 0 && y < 8 && x >= 0 && x < 8 { - let pos = Pos(x as u8, y as u8); - seen.push(pos); - - let quadrant = &galaxy.quadrants[pos.as_index()]; - klingons = format!("{}", quadrant.klingons.len()); - star_bases = quadrant.star_base.as_ref().map_or("0", |_| "1"); - stars = format!("{}", quadrant.stars.len()); - } - - print!(": {}{}{} ", klingons, star_bases, stars) - } - println!(":"); - println!("{:-^19}", ""); - } - - seen -} - -pub fn stranded() { - println!( -"** FATAL ERROR ** You've just stranded your ship in space -You have insufficient maneuvering energy, and shield control -is presently incapable of cross-circuiting to engine room!!") -} - -pub fn computer_options() { - println!( -" 0 = Cumulative galactic record - 1 = Status report - 2 = Photon torpedo data - 3 = Starbase nav data - 4 = Direction/distance calculator - 5 = Galaxy 'region name' map") -} - -pub fn galaxy_region_map() { - println!( -" The Galaxy - 1 2 3 4 5 6 7 8 - ----- ----- ----- ----- ----- ----- ----- -----"); - for i in (0..REGION_NAMES.len()-1).step_by(2) { - println!( -"{} {:^23} {:^23} - ----- ----- ----- ----- ----- ----- ----- -----", (i/2)+1, REGION_NAMES[i], REGION_NAMES[i+1]); - } -} - -pub fn galaxy_scanned_map(galaxy: &Galaxy) { - println!( -"Computer record of galaxy for quadrant {} - 1 2 3 4 5 6 7 8 - ----- ----- ----- ----- ----- ----- ----- -----", galaxy.enterprise.quadrant); - for x in 0..8 { - print!("{} ", x+1); - for y in 0..8 { - let pos = Pos(x, y); - if galaxy.scanned.contains(&pos) { - let quadrant = &galaxy.quadrants[pos.as_index()]; - print!(" {}{}{} ", quadrant.klingons.len(), quadrant.star_base.as_ref().map_or("0", |_| "1"), quadrant.stars.len()) - } else { - print!(" *** "); - } - } - println!( -"\n ----- ----- ----- ----- ----- ----- ----- -----") - } -} - -pub fn no_local_enemies() { - println!( -"Science Officer Spock reports, 'Sensors show no enemy ships - in this quadrant'") -} - -pub fn computer_accuracy_issue() { - println!("Computer failure hampers accuracy") -} - -pub fn phasers_locked(available_energy: u16) { - println!("Phasers locked on target; Energy available = {available_energy} units") -} - -pub fn starbase_shields() { - println!("Starbase shields protect the Enterprise") -} - -pub fn repair_estimate(repair_time: f32) { - println!( -"Technicians standing by to effect repairs to your ship; -Estimated time to repair: {repair_time:.1} stardates.") -} - -pub fn no_damage(sector: Pos) { - println!("Sensors show no damage to enemy at {sector}") -} - -pub fn hit_on_klingon(hit_strength: f32, sector: Pos) { - println!("{hit_strength} unit hit on Klingon at sector {sector}") -} - -pub fn klingon_remaining_energy(energy: f32) { - println!(" (sensors show {energy} units remaining)") -} - -pub fn klingon_destroyed() { - println!("*** Klingon destroyed ***") -} - -pub fn congratulations(efficiency: f32) { - println!(" -Congratulations, Captain! The last Klingon battle cruiser -menacing the Federation has been destroyed. - -Your efficiency rating is {efficiency}. - ") -} - -pub fn replay() { - println!(" -The Federation is in need of a new starship commander -for a similar mission -- if there is a volunteer -let him step forward and enter 'Aye'") -} - -pub fn no_torpedoes_remaining() { - println!("All photon torpedoes expended") -} - -pub fn torpedo_track() { - println!("Torpedo track:") -} - -pub fn torpedo_path(sector: Pos) { - println!("{:<16}{}", "", sector) -} - -pub fn torpedo_missed() { - println!("Torpedo missed!") -} - -pub fn star_absorbed_torpedo(sector: Pos) { - println!("Star at {sector} absorbed torpedo energy.") -} - -pub fn destroyed_starbase(not_the_last_starbase: bool) { - println!("*** Starbase destroyed ***"); - if not_the_last_starbase { - println!(" -Starfleet Command reviewing your record to consider -court martial!") - } else { - println!(" -That does it, Captain!! You are hereby relieved of command -and sentenced to 99 stardates at hard labor on Cygnus 12!!") - } -} - -pub fn no_local_starbase() { - println!("Mr. Spock reports, 'Sensors show no starbases in this quadrant.'") -} - -pub fn starbase_report() { - println!("From Enterprise to Starbase:'") -} - -pub fn direction_distance(dir: f32, dist: u8) { - println!( -"Direction = {dir} -Distance = {dist}" - ) -} - -pub fn status_report(galaxy: &Galaxy) { - let klingon_count = galaxy.remaining_klingons(); - let star_bases = galaxy.remaining_starbases(); - let time_remaining = galaxy.final_stardate - galaxy.stardate; - let mut plural_starbase = ""; - if star_bases > 1 { - plural_starbase = "s"; - } - - println!(" Status report: -Klingons left: {klingon_count} -Mission must be completed in {time_remaining:.1} stardates. -The Federation is maintaining {star_bases} starbase{plural_starbase} in the galaxy. -") -} - -pub fn direction_dist_intro(enterprise: &Enterprise) { - let quadrant = enterprise.quadrant; - let sector = enterprise.sector; - println!("Direction/distance calculator: -You are at quadrant {quadrant} sector {sector} -Please enter") -} - -pub fn klingon_report(more_than_one: bool) { - let mut plural = ""; - if more_than_one { - plural = "s"; - } - println!("From Enterprise to Klingon battle cruiser{}", plural) -} \ No newline at end of file diff --git a/84_Super_Star_Trek/superstartrek.bas b/84_Super_Star_Trek/superstartrek.bas index efd74cb0d..74300763a 100644 --- a/84_Super_Star_Trek/superstartrek.bas +++ b/84_Super_Star_Trek/superstartrek.bas @@ -21,12 +21,12 @@ 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$=" " @@ -37,353 +37,353 @@ 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 FOR I=1 TO 9:C(I,1)=0:C(I,2)=0:NEXT I +530 FORI=1TO9:C(I,1)=0:C(I,2)=0:NEXTI 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 FOR I=1 TO 8:D(I)=0:NEXT I +670 FORI=1TO8:D(I)=0:NEXTI 710 A1$="NAVSRSLRSPHATORSHEDAMCOMXXX" 810 REM SETUP WHAT EXHISTS IN GALAXY . . . 815 REM K3= # KLINGONS B3= # STARBASES S3 = # STARS -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 +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 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" +1200 K7=K9:IFB9<>1THENX$="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" 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 +1390 IFQ1<1ORQ1>8ORQ2<1ORQ2>8THEN1600 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" -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) +1540 S3=G(Q1,Q2)-100*K3-10*B3:IFK3=0THEN1590 +1560 PRINT"COMBAT AREA CONDITION RED":IFS>200THEN1590 +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) 1660 REM POSITION ENTERPRISE IN QUADRANT, THEN PLACE "K3" KLINGONS, & 1670 REM "B3" STARBASES, & "S3" STARS ELSEWHERE. -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!!":GOTO 6220 +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 +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 2060 INPUT"COMMAND";A$ -2080 FOR I=1 TO 9:IF LEFT$(A$,3)<>MID$(A1$,3*I-2,3) THEN 2160 -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)" -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 +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:" +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 -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;"!'":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 IF S=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 +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 +2500 PRINT"ENGINEERING REPORTS 'INSUFFICIENT ENERGY AVAILABLE" +2510 PRINT" FOR MANEUVERING AT WARP";W1;"!'" +2530 IFS=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 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: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 +2590 FORI=1TOK3:IFK(I,3)=0THEN2700 +2610 A$=" ":Z1=K(I,1):Z2=K(I,2):GOSUB8670:GOSUB8590 +2660 K(I,1)=Z1:K(I,2)=Z2:A$="+K+":GOSUB8670 +2700 NEXTI:GOSUB6000:D1=0:D6=W1:IFW1>=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 +2930 D(R1)=D(R1)-(RND(1)*5+1):PRINT"DAMAGE CONTROL REPORT: "; +2960 GOSUB8790:PRINTG2$;" DAMAGED":PRINT:GOTO3070 +3000 D(R1)=D(R1)+RND(1)*3+1:PRINT"DAMAGE CONTROL REPORT: "; +3030 GOSUB8790:PRINTG2$;" STATE OF REPAIR IMPROVED":PRINT 3060 REM BEGIN MOVING STARSHIP -3070 A$=" ":Z1=INT(S1):Z2=INT(S2):GOSUB 8670 +3070 A$=" ":Z1=INT(S1):Z2=INT(S2):GOSUB8670 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<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 -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 +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 +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 3470 REM SEE IF DOCKED, THEN GET COMMAND -3480 GOTO 1980 +3480 GOTO1980 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):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 IF T>T0+T9 THEN 6220 -3860 IF 8*Q1+Q2=8*Q4+Q5 THEN 3370 -3870 T=T+1:GOSUB 3910:GOTO 1320 +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 +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 3900 REM MANEUVER ENERGY S/R ** -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 +3910 E=E-N-10:IFE>=0THENRETURN +3930 PRINT"SHIELD CONTROL SUPPLIES ENERGY TO COMPLETE THE MANEUVER." +3940 S=S+E:E=0:IFS<=0THENS=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 -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>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 +4000 IFD(3)<0THENPRINT"LONG RANGE SENSORS ARE INOPERABLE":GOTO1990 +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 +4210 PRINTRIGHT$(STR$(N(L)+1000),3);" "; +4230 NEXTL:PRINT":":PRINTO1$:NEXTI:GOTO1990 4250 REM PHASER CONTROL CODE BEGINS HERE -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" -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: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 +4260 IFD(4)<0THENPRINT"PHASERS INOPERATIVE":GOTO1990 +4265 IFK3>0THEN4330 +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" +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 +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 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 -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 GOTO 1990 +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 +4790 PRINT"ENSIGN CHEKOV REPORTS, 'INCORRECT COURSE DATA, SIR!'" +4800 GOTO1990 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<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 -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 -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>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!!" +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 +5330 PRINT"*** STARBASE DESTROYED ***":B3=B3-1:B9=B9-1 +5360 IFB9>0ORK9>T-T0-T9THEN5400 +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$=" ":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 +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 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<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 -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 +5530 IFD(7)<0THENPRINT"SHIELD CONTROL INOPERABLE":GOTO1990 +5560 PRINT"ENERGY AVAILABLE =";E+S;:INPUT"NUMBER OF UNITS TO SHIELDS";X +5580 IFX<0ORS=XTHENPRINT"":GOTO1990 +5590 IFX<=E+STHEN5630 +5600 PRINT"SHIELD CONTROL REPORTS 'THIS IS NOT THE FEDERATION TREASURY.'" +5610 PRINT"":GOTO1990 +5630 E=E+S-X:S=X:PRINT"DEFLECTOR CONTROL ROOM REPORT:" +5660 PRINT" 'SHIELDS NOW AT";INT(S);"UNITS PER YOUR COMMAND.'":GOTO1990 5680 REM DAMAGE CONTROL -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" +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 +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 -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:PRINT G2$;LEFT$(Z$,25-LEN(G2$));INT(D(R1)*100)*.01 -5950 NEXT R1:PRINT:IF D0<>0 THEN 5720 +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 5980 GOTO 1990 5990 REM KLINGONS SHOOTING -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 +6000 IFK3<=0THENRETURN +6010 IFD0<>0THENPRINT"STARBASE SHIELDS PROTECT THE ENTERPRISE":RETURN +6040 FORI=1TO3:IFK(I,3)<=0THEN6200 6060 H=INT((K(I,3)/FND(1))*(2+RND(1))):S=S-H:K(I,3)=K(I,3)/(3+RND(0)) -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)>.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 +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 +6170 PRINT"DAMAGE CONTROL REPORTS ";G2$;" DAMAGED BY THE HIT'" +6200 NEXTI: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: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$:IF A$="AYE" THEN 10 +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 +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 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:GOTO6290 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)<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 +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 6580 D0=1:C$="DOCKED":E=E0:P=P0 -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$="---------------------------------":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 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 -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 +6620 PRINT"SHIELDS DROPPED FOR DOCKING PURPOSES":S=0:GOTO6720 +6650 IFK3>0THENC$="*RED*":GOTO6720 +6660 C$="GREEN":IFE=0THEN6770 +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 +7240 PRINT" KLINGONS REMAINING";INT(K9) +7260 NEXTI:PRINTO1$:RETURN 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: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" -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 +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 +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 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":GOTO7550 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 +7542 REM IFA$="Y"THENPOKE1229,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" +7550 PRINT" 1 2 3 4 5 6 7 8" 7560 O1$=" ----- ----- ----- ----- ----- ----- ----- -----" -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$)):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 +7570 PRINTO1$:FORI=1TO8:PRINTI;:IFH8=0THEN7740 +7630 FORJ=1TO8:PRINT" ";:IFZ(I,J)=0THENPRINT"***";:GOTO7720 +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$; +7800 Z5=5:GOSUB 9030:J0=INT(39-.5*LEN(G2$)):PRINTTAB(J0);G2$; +7850 PRINT:PRINTO1$:NEXTI:PRINT:GOTO1990 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" -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 GOTO 5690 -8010 PRINT "YOUR STUPIDITY HAS LEFT YOU ON YOUR ON IN" -8020 PRINT " THE GALAXY -- YOU HAVE NO STARBASES LEFT!":GOTO 5690 +7900 PRINT " STATUS REPORT:":X$="":IFK9>1THENX$="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 +7980 PRINT"THE FEDERATION IS MAINTAINING";B9;"STARBASE";X$;" IN THE GALAXY" +7990 GOTO5690 +8010 PRINT"YOUR STUPIDITY HAS LEFT YOU ON YOUR ON IN" +8020 PRINT" THE GALAXY -- YOU HAVE NO STARBASES LEFT!":GOTO5690 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$ -8100 H8=0:FOR I=1 TO 3:IF K(I,3)<=0 THEN 8480 +8070 IFK3<=0THEN4270 +8080 X$="":IFK3>1THENX$="S" +8090 PRINT"FROM ENTERPRISE TO KLINGON BATTLE CRUSER";X$ +8100 H8=0:FORI=1TO3:IFK(I,3)<=0THEN8480 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 +8120 C1=S1:A=S2:GOTO8220 +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 -8260 IF X>0 THEN 8280 -8270 IF A=0 THEN C1=5:GOTO 8290 +8220 X=X-A:A=C1-W1:IFX<0THEN8350 +8250 IFA<0THEN8410 +8260 IFX>0THEN8280 +8270 IFA=0THENC1=5:GOTO8290 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 -8350 IF A>0 THEN C1=3:GOTO 8420 -8360 IF X<>0 THEN C1=5:GOTO 8290 +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 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 -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 +8420 IFABS(A)>=ABS(X)THEN8450 +8430 PRINT"DIRECTION =";C1+(((ABS(X)-ABS(A))+ABS(X))/ABS(X)):GOTO8460 +8450 PRINT"DIRECTION =";C1+(ABS(X)/ABS(A)) +8460 PRINT"DISTANCE =";SQR(X^2+A^2):IFH8=1THEN1990 +8480 NEXTI:GOTO1990 +8500 IFB3<>0THENPRINT"FROM ENTERPRISE TO STARBASE:":W1=B4:X=B5:GOTO8120 +8510 PRINT"MR. SPOCK REPORTS, 'SENSORS SHOW NO STARBASES IN THIS"; +8520 PRINT" QUADRANT.'":GOTO1990 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 +8590 R1=FNR(1):R2=FNR(1):A$=" ":Z1=R1:Z2=R2:GOSUB8830:IFZ3=0THEN8590 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$)<>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 +8675 IF LEN(A$)<>3THEN PRINT"ERROR":STOP +8680 IFS8=1THENQ$=A$+RIGHT$(Q$,189):RETURN +8690 IFS8=190THENQ$=LEFT$(Q$,189)+A$:RETURN 8700 Q$=LEFT$(Q$,S8-1)+A$+RIGHT$(Q$,190-S8):RETURN 8780 REM PRINTS DEVICE NAME -8790 ON R1 GOTO 8792,8794,8796,8798,8800,8802,8804,8806 +8790 ONR1GOTO8792,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 IF MID$(Q$,S8,3)<>A$ THEN RETURN +8890 IFMID$(Q$,S8,3)<>A$THENRETURN 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 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 +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 9200 G2$="SPICA" -9210 IF G5<>1 THEN ON Z5 GOTO 9230,9240,9250,9260,9230,9240,9250,9260 +9210 IFG5<>1THENONZ5GOTO9230,9240,9250,9260,9230,9240,9250,9260 9220 RETURN 9230 G2$=G2$+" I":RETURN 9240 G2$=G2$+" II":RETURN diff --git a/84_Super_Star_Trek/superstartrekins.bas b/84_Super_Star_Trek/superstartrekins.bas index b3aa1daa6..9f5f3a33b 100644 --- a/84_Super_Star_Trek/superstartrekins.bas +++ b/84_Super_Star_Trek/superstartrekins.bas @@ -44,7 +44,7 @@ 440 PRINT" WAY BETWEEN 1 AND 2 ..." 450 PRINT" . . ." 460 PRINT" VALUES MAY APPROACH 9.0, WHICH 6 7 8" -470 PRINT" ITSELF IS EQUIVALENT TO 1.0" +470 PRINT" ITSELF IS EQUIVALENT TO 1.0" 480 PRINT" COURSE" 490 PRINT" ONE WARP FACTOR IS THE SIZE OF " 500 PRINT" ONE QUADTANT. THEREFORE, TO GET" diff --git a/84_Super_Star_Trek/vbnet/SuperStarTrek.sln b/84_Super_Star_Trek/vbnet/SuperStarTrek.sln deleted file mode 100644 index 82633753d..000000000 --- a/84_Super_Star_Trek/vbnet/SuperStarTrek.sln +++ /dev/null @@ -1,22 +0,0 @@ - -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 deleted file mode 100644 index 1a4afed57..000000000 --- a/84_Super_Star_Trek/vbnet/SuperStarTrek.vbproj +++ /dev/null @@ -1,8 +0,0 @@ - - - Exe - SuperStarTrek - net6.0 - 16.9 - - diff --git a/85_Synonym/README.md b/85_Synonym/README.md index beb833299..66c3c4c3a 100644 --- a/85_Synonym/README.md +++ b/85_Synonym/README.md @@ -19,7 +19,8 @@ As published in Basic Computer Games (1978): Downloaded from Vintage Basic at http://www.vintage-basic.net/games.html -#### Porting Notes + +## Known Issues - Each time the player asks for HELP, one of the synonyms is shown and discarded. There is no protection against the player using up diff --git a/85_Synonym/csharp/Synonym.cs b/85_Synonym/csharp/Synonym.cs deleted file mode 100644 index 1a90fd724..000000000 --- a/85_Synonym/csharp/Synonym.cs +++ /dev/null @@ -1,149 +0,0 @@ -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(); - - } - } -} diff --git a/85_Synonym/csharp/Synonym.csproj b/85_Synonym/csharp/Synonym.csproj deleted file mode 100644 index 1fd332a69..000000000 --- a/85_Synonym/csharp/Synonym.csproj +++ /dev/null @@ -1,10 +0,0 @@ - - - Exe - net6.0 - 10 - enable - enable - Synonym.Program - - diff --git a/85_Synonym/csharp/Synonym.sln b/85_Synonym/csharp/Synonym.sln deleted file mode 100644 index 69614affa..000000000 --- a/85_Synonym/csharp/Synonym.sln +++ /dev/null @@ -1,22 +0,0 @@ - -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/javascript/synonym.html b/85_Synonym/javascript/synonym.html index ce54a1c09..ec24a89a9 100644 --- a/85_Synonym/javascript/synonym.html +++ b/85_Synonym/javascript/synonym.html @@ -1,10 +1,9 @@ SYNONYM - -
    
    +
    
     
     
     
    diff --git a/85_Synonym/javascript/synonym.js b/85_Synonym/javascript/synonym.js
    index e48bf77f1..ad3175b7c 100644
    --- a/85_Synonym/javascript/synonym.js
    +++ b/85_Synonym/javascript/synonym.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/85_Synonym/kotlin/Synonym.kt b/85_Synonym/kotlin/Synonym.kt
    index e85b142a5..386a2525e 100644
    --- a/85_Synonym/kotlin/Synonym.kt
    +++ b/85_Synonym/kotlin/Synonym.kt
    @@ -70,4 +70,4 @@ private val synonyms = listOf(
         SynonymList("PAIN", listOf("SUFFERING", "HURT", "MISERY", "DISTRESS", "ACHE", "DISCOMFORT"))
     )
     
    -class SynonymList(val word: String, val synonyms: List)
    +class SynonymList(val word: String, val synonyms: List)
    \ No newline at end of file
    diff --git a/85_Synonym/lua/README.md b/85_Synonym/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/85_Synonym/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/85_Synonym/pascal/README.md b/85_Synonym/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/85_Synonym/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/85_Synonym/perl/README.md b/85_Synonym/perl/README.md
    index 977a834a7..f947aea0e 100644
    --- a/85_Synonym/perl/README.md
    +++ b/85_Synonym/perl/README.md
    @@ -3,5 +3,5 @@ Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/gam
     Conversion to [Perl](https://www.perl.org/)
     
     I used List::Util to do all the heavy work to show that perl can handle all the various
    -array functions.  It would be interesting to see a version that handled all of this
    +array functions.  It would be interesting to see a version that handled all of this 
     manually as there ended up being very little code left in this program.
    diff --git a/85_Synonym/perl/synonym.pl b/85_Synonym/perl/synonym.pl
    index 7b9ef90cd..37f323660 100755
    --- a/85_Synonym/perl/synonym.pl
    +++ b/85_Synonym/perl/synonym.pl
    @@ -55,3 +55,4 @@
     }
     
     say "\nSynonym drill completed.";
    +
    diff --git a/85_Synonym/python/synonym.py b/85_Synonym/python/synonym.py
    index 0680bb78a..02ac24e6d 100644
    --- a/85_Synonym/python/synonym.py
    +++ b/85_Synonym/python/synonym.py
    @@ -8,15 +8,16 @@
     
     import random
     
    +
     PAGE_WIDTH = 64
     
     
    -def print_centered(msg: str) -> None:
    +def print_centered(msg):
         spaces = " " * ((PAGE_WIDTH - len(msg)) // 2)
         print(spaces + msg)
     
     
    -def print_header(title: str) -> None:
    +def print_header(title):
         print_centered(title)
         print_centered("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
         print()
    @@ -24,7 +25,7 @@ def print_header(title: str) -> None:
         print()
     
     
    -def print_instructions() -> None:
    +def print_instructions():
         print("A SYNONYM OF A WORD MEANS ANOTHER WORD IN THE ENGLISH")
         print("LANGUAGE WHICH HAS THE SAME OR VERY NEARLY THE SAME MEANING.")
         print("I CHOOSE A WORD -- YOU TYPE A SYNONYM.")
    @@ -49,11 +50,11 @@ def print_instructions() -> None:
     ]
     
     
    -def print_right() -> None:
    +def print_right():
         print(random.choice(right_words))
     
     
    -def ask_question(question_number: int) -> None:
    +def ask_question(question_number):
         words = synonym_words[question_number]
         clues = words[:]
         base_word = clues.pop(0)
    @@ -76,12 +77,12 @@ def ask_question(question_number: int) -> None:
                 return
     
     
    -def finish() -> None:
    +def finish():
         print()
         print("SYNONYM DRILL COMPLETED.")
     
     
    -def main() -> None:
    +def main():
         print_header("SYNONYM")
         print_instructions()
     
    diff --git a/85_Synonym/ruby/synonim.rb b/85_Synonym/ruby/synonim.rb
    index d155af5b1..92d2e8c7d 100644
    --- a/85_Synonym/ruby/synonim.rb
    +++ b/85_Synonym/ruby/synonim.rb
    @@ -49,13 +49,13 @@
         ["PAIN", "SUFFERING", "HURT", "MISERY", "DISTRESS", "ACHE", "DISCOMFORT"],
     ]
     
    -synonym_words.shuffle.each {|words_ar|
    +synonym_words.shuffle.each {|words_ar| 
     
     }
     
     
    -synonym_words.each {|words_ar|
    -    answer = false
    +synonym_words.each {|words_ar| 
    +    answer = false 
         keyword = words_ar.shift
     
         while not answer and words_ar.length != 0
    diff --git a/85_Synonym/rust/Cargo.lock b/85_Synonym/rust/Cargo.lock
    deleted file mode 100644
    index 4fe2abbea..000000000
    --- a/85_Synonym/rust/Cargo.lock
    +++ /dev/null
    @@ -1,75 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.10"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.147"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/85_Synonym/rust/Cargo.toml b/85_Synonym/rust/Cargo.toml
    deleted file mode 100644
    index 3b1d02f52..000000000
    --- a/85_Synonym/rust/Cargo.toml
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -[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/85_Synonym/rust/README.md b/85_Synonym/rust/README.md
    deleted file mode 100644
    index 4c54b94cb..000000000
    --- a/85_Synonym/rust/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Rust](https://www.rust-lang.org/) by [Jadi](https://github.com/jadijadi)
    diff --git a/85_Synonym/rust/src/main.rs b/85_Synonym/rust/src/main.rs
    deleted file mode 100644
    index 184f51bd9..000000000
    --- a/85_Synonym/rust/src/main.rs
    +++ /dev/null
    @@ -1,102 +0,0 @@
    -use rand::seq::SliceRandom;
    -use rand::thread_rng;
    -use rand::Rng;
    -use std::io::{self, Write};
    -
    -fn print_centered(text: &str, width: usize) {
    -    let pad_size: usize = if width > text.len() {
    -        (width - text.len()) / 2
    -    } else {
    -        0
    -    };
    -    println!("{}{}", " ".repeat(pad_size), text);
    -}
    -
    -fn print_instructions() {
    -    println!("A SYNONYM OF A WORD MEANS ANOTHER WORD IN THE ENGLISH");
    -    println!("LANGUAGE WHICH HAS THE SAME OR VERY NEARLY THE SAME MEANING.");
    -    println!("I CHOOSE A WORD -- YOU TYPE A SYNONYM.");
    -    println!("IF YOU CAN'T THINK OF A SYNONYM, TYPE THE WORD 'HELP'");
    -    println!("AND I WILL TELL YOU A SYNONYM.\n");
    -}
    -
    -fn ask_question(mut this_question: Vec<&str>) {
    -    let right_words = ["RIGHT", "CORRECT", "FINE", "GOOD!", "CHECK"];
    -
    -    // use the first one in the main question
    -    let base_word = this_question.remove(0);
    -
    -    loop {
    -        print!("     WHAT IS A SYNONYM OF {base_word}? ");
    -        io::stdout().flush().unwrap();
    -        let mut answer: String = String::new();
    -        io::stdin()
    -            .read_line(&mut answer)
    -            .expect("Failed to read the line");
    -        let answer = answer.trim();
    -        if answer == "HELP" {
    -            // remove one random from the answers and show it
    -            let random_index = thread_rng().gen_range(0..this_question.len());
    -            println!(
    -                "**** A SYNONYM OF {base_word} IS {}.",
    -                this_question.remove(random_index)
    -            );
    -        } else if this_question.contains(&answer) {
    -            println!("{}", right_words.choose(&mut rand::thread_rng()).unwrap());
    -            break;
    -        }
    -    }
    -}
    -
    -fn main() {
    -    const PAGE_WIDTH: usize = 64;
    -
    -    let mut synonyms = vec![
    -        vec!["FIRST", "START", "BEGINNING", "ONSET", "INITIAL"],
    -        vec!["SIMILAR", "ALIKE", "SAME", "LIKE", "RESEMBLING"],
    -        vec!["MODEL", "PATTERN", "PROTOTYPE", "STANDARD", "CRITERION"],
    -        vec!["SMALL", "INSIGNIFICANT", "LITTLE", "TINY", "MINUTE"],
    -        vec!["STOP", "HALT", "STAY", "ARREST", "CHECK", "STANDSTILL"],
    -        vec![
    -            "HOUSE",
    -            "DWELLING",
    -            "RESIDENCE",
    -            "DOMICILE",
    -            "LODGING",
    -            "HABITATION",
    -        ],
    -        vec!["PIT", "HOLE", "HOLLOW", "WELL", "GULF", "CHASM", "ABYSS"],
    -        vec!["PUSH", "SHOVE", "THRUST", "PROD", "POKE", "BUTT", "PRESS"],
    -        vec!["RED", "ROUGE", "SCARLET", "CRIMSON", "FLAME", "RUBY"],
    -        vec![
    -            "PAIN",
    -            "SUFFERING",
    -            "HURT",
    -            "MISERY",
    -            "DISTRESS",
    -            "ACHE",
    -            "DISCOMFORT",
    -        ],
    -    ];
    -
    -    synonyms.shuffle(&mut thread_rng());
    -
    -    print_centered("SYNONYM", PAGE_WIDTH);
    -    print_centered("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY", PAGE_WIDTH);
    -    println!("\n\n\n");
    -
    -    print_instructions();
    -
    -    for this_question in synonyms {
    -        ask_question(this_question)
    -    }
    -    println!("SYNONYM DRILL COMPLETED.");
    -}
    -
    -////////////////////////////////////////////////////////////
    -// Poring Notes
    -// Poring Note: The "HELP" function .removes a variable
    -// from lists and shows it. This can lead to errors when
    -// the list becomes empty. But since the same issue happens
    -// on the original BASIC program, kept it intact
    -////////////////////////////////////////////////////////////
    diff --git a/85_Synonym/vbnet/Synonym.sln b/85_Synonym/vbnet/Synonym.sln
    deleted file mode 100644
    index 8b55f812e..000000000
    --- a/85_Synonym/vbnet/Synonym.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 8c920a56d..000000000
    --- a/85_Synonym/vbnet/Synonym.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Synonym
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/86_Target/README.md b/86_Target/README.md
    index 04f8714f7..29e14e64a 100644
    --- a/86_Target/README.md
    +++ b/86_Target/README.md
    @@ -14,8 +14,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/86_Target/csharp/FiringRange.cs b/86_Target/csharp/FiringRange.cs
    deleted file mode 100644
    index b8a6399cc..000000000
    --- a/86_Target/csharp/FiringRange.cs
    +++ /dev/null
    @@ -1,24 +0,0 @@
    -using Games.Common.Randomness;
    -
    -namespace Target
    -{
    -    internal class FiringRange
    -    {
    -        private readonly IRandom _random;
    -        private Point _targetPosition;
    -
    -        public FiringRange(IRandom random)
    -        {
    -            _random = random;
    -        }
    -
    -        public Point NextTarget() =>  _targetPosition = _random.NextPosition();
    -
    -        public Explosion Fire(Angle angleFromX, Angle angleFromZ, float distance)
    -        {
    -            var explosionPosition = new Point(angleFromX, angleFromZ, distance);
    -            var targetOffset = explosionPosition - _targetPosition;
    -            return new (explosionPosition, targetOffset);
    -        }
    -    }
    -}
    diff --git a/86_Target/csharp/Game.cs b/86_Target/csharp/Game.cs
    deleted file mode 100644
    index 4bb4f9b24..000000000
    --- a/86_Target/csharp/Game.cs
    +++ /dev/null
    @@ -1,92 +0,0 @@
    -using System;
    -using Games.Common.IO;
    -
    -namespace Target
    -{
    -    internal class Game
    -    {
    -        private readonly IReadWrite _io;
    -        private readonly FiringRange _firingRange;
    -        private int _shotCount;
    -
    -        public Game(IReadWrite io, FiringRange firingRange)
    -        {
    -            _io = io;
    -            _firingRange = firingRange;
    -        }
    -
    -        public void Play()
    -        {
    -            _shotCount = 0;
    -            var target = _firingRange.NextTarget();
    -            _io.WriteLine(target.GetBearing());
    -            _io.WriteLine($"Target sighted: approximate coordinates:  {target}");
    -
    -            while (true)
    -            {
    -                _io.WriteLine($"     Estimated distance: {target.EstimateDistance()}");
    -                _io.WriteLine();
    -
    -                var explosion = Shoot();
    -
    -                if (explosion.IsTooClose)
    -                {
    -                    _io.WriteLine("You blew yourself up!!");
    -                    return;
    -                }
    -
    -                _io.WriteLine(explosion.GetBearing());
    -
    -                if (explosion.IsHit)
    -                {
    -                    ReportHit(explosion.DistanceToTarget);
    -                    return;
    -                }
    -
    -                ReportMiss(explosion);
    -            }
    -        }
    -
    -        private Explosion Shoot()
    -        {
    -            var (xDeviation, zDeviation, distance) = _io.Read3Numbers(
    -                "Input angle deviation from X, angle deviation from Z, distance");
    -            _shotCount++;
    -            _io.WriteLine();
    -
    -            return _firingRange.Fire(Angle.InDegrees(xDeviation), Angle.InDegrees(zDeviation), distance);
    -        }
    -
    -        private void ReportHit(float distance)
    -        {
    -            _io.WriteLine();
    -            _io.WriteLine($" * * * HIT * * *   Target is non-functional");
    -            _io.WriteLine();
    -            _io.WriteLine($"Distance of explosion from target was {distance} kilometers.");
    -            _io.WriteLine();
    -            _io.WriteLine($"Mission accomplished in {_shotCount} shots.");
    -        }
    -
    -        private void ReportMiss(Explosion explosion)
    -        {
    -            ReportMiss(explosion.FromTarget);
    -            _io.WriteLine($"Approx position of explosion:  {explosion.Position}");
    -            _io.WriteLine($"     Distance from target = {explosion.DistanceToTarget}");
    -            _io.WriteLine();
    -            _io.WriteLine();
    -            _io.WriteLine();
    -        }
    -
    -        private void ReportMiss(Offset targetOffset)
    -        {
    -            ReportMiss(targetOffset.DeltaX, "in front of", "behind");
    -            ReportMiss(targetOffset.DeltaY, "to left of", "to right of");
    -            ReportMiss(targetOffset.DeltaZ, "above", "below");
    -        }
    -
    -        private void ReportMiss(float delta, string positiveText, string negativeText) =>
    -            _io.WriteLine(delta >= 0 ? GetOffsetText(positiveText, delta) : GetOffsetText(negativeText, -delta));
    -
    -        private static string GetOffsetText(string text, float distance) => $"Shot {text} target {distance} kilometers.";
    -    }
    -}
    diff --git a/86_Target/csharp/Program.cs b/86_Target/csharp/Program.cs
    deleted file mode 100644
    index cafa559a1..000000000
    --- a/86_Target/csharp/Program.cs
    +++ /dev/null
    @@ -1,43 +0,0 @@
    -using System;
    -using System.Reflection;
    -using Games.Common.IO;
    -using Games.Common.Randomness;
    -
    -namespace Target
    -{
    -    class Program
    -    {
    -        static void Main()
    -        {
    -            var io = new ConsoleIO();
    -            var game = new Game(io, new FiringRange(new RandomNumberGenerator()));
    -
    -            Play(game, io, () => true);
    -        }
    -
    -        public static void Play(Game game, TextIO io, Func playAgain)
    -        {
    -            DisplayTitleAndInstructions(io);
    -
    -            while (playAgain())
    -            {
    -                game.Play();
    -
    -                io.WriteLine();
    -                io.WriteLine();
    -                io.WriteLine();
    -                io.WriteLine();
    -                io.WriteLine();
    -                io.WriteLine("Next target...");
    -                io.WriteLine();
    -            }
    -        }
    -
    -        private static void DisplayTitleAndInstructions(TextIO io)
    -        {
    -            using var stream = Assembly.GetExecutingAssembly()
    -                .GetManifestResourceStream("Target.Strings.TitleAndInstructions.txt");
    -            io.Write(stream);
    -        }
    -    }
    -}
    diff --git a/86_Target/csharp/RandomExtensions.cs b/86_Target/csharp/RandomExtensions.cs
    deleted file mode 100644
    index a76b02790..000000000
    --- a/86_Target/csharp/RandomExtensions.cs
    +++ /dev/null
    @@ -1,12 +0,0 @@
    -using Games.Common.Randomness;
    -
    -namespace Target
    -{
    -    internal static class RandomExtensions
    -    {
    -        public static Point NextPosition(this IRandom rnd) => new (
    -            Angle.InRotations(rnd.NextFloat()),
    -            Angle.InRotations(rnd.NextFloat()),
    -            100000 * rnd.NextFloat() + rnd.NextFloat());
    -    }
    -}
    diff --git a/86_Target/csharp/Target.csproj b/86_Target/csharp/Target.csproj
    deleted file mode 100644
    index 9f0cf96b8..000000000
    --- a/86_Target/csharp/Target.csproj
    +++ /dev/null
    @@ -1,16 +0,0 @@
    -
    -
    -  
    -    Exe
    -    net6.0
    -  
    -
    -  
    -    
    -  
    -
    -  
    -    
    -  
    -
    -
    diff --git a/86_Target/csharp/Target.sln b/86_Target/csharp/Target.sln
    index 9aa2c86d0..3e1117021 100644
    --- a/86_Target/csharp/Target.sln
    +++ b/86_Target/csharp/Target.sln
    @@ -1,25 +1,34 @@
     
     Microsoft Visual Studio Solution File, Format Version 12.00
    -# Visual Studio Version 17
    -VisualStudioVersion = 17.0.32014.148
    +# Visual Studio 15
    +VisualStudioVersion = 15.0.26124.0
     MinimumVisualStudioVersion = 15.0.26124.0
    -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Target", "Target.csproj", "{DF03CFDB-2857-4416-A07A-80D84874F46E}"
    +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Target", "Target\Target.csproj", "{8B0B5114-1D05-4F8D-B328-EA2FB89992E7}"
     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
    -	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
    +		Release|x64 = Release|x64
    +		Release|x86 = Release|x86
     	EndGlobalSection
     	GlobalSection(SolutionProperties) = preSolution
     		HideSolutionNode = FALSE
     	EndGlobalSection
    -	GlobalSection(ExtensibilityGlobals) = postSolution
    -		SolutionGuid = {B49DF932-4DF9-44C3-B63F-FD9443B4DDD2}
    +	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
     	EndGlobalSection
     EndGlobal
    diff --git a/86_Target/csharp/Angle.cs b/86_Target/csharp/Target/Angle.cs
    similarity index 100%
    rename from 86_Target/csharp/Angle.cs
    rename to 86_Target/csharp/Target/Angle.cs
    diff --git a/86_Target/csharp/Explosion.cs b/86_Target/csharp/Target/Explosion.cs
    similarity index 100%
    rename from 86_Target/csharp/Explosion.cs
    rename to 86_Target/csharp/Target/Explosion.cs
    diff --git a/86_Target/csharp/Target/FiringRange.cs b/86_Target/csharp/Target/FiringRange.cs
    new file mode 100644
    index 000000000..368dc453f
    --- /dev/null
    +++ b/86_Target/csharp/Target/FiringRange.cs
    @@ -0,0 +1,26 @@
    +using System;
    +
    +namespace Target
    +{
    +    internal class FiringRange
    +    {
    +        private readonly Random random;
    +
    +        public FiringRange()
    +        {
    +            random = new Random();
    +            NextTarget();
    +        }
    +
    +        public Point TargetPosition { get; private set; }
    +
    +        public void NextTarget() =>  TargetPosition = random.NextPosition();
    +
    +        public Explosion Fire(Angle angleFromX, Angle angleFromZ, float distance)
    +        {
    +            var explosionPosition = new Point(angleFromX, angleFromZ, distance);
    +            var targetOffset = explosionPosition - TargetPosition;
    +            return new (explosionPosition, targetOffset);
    +        }
    +    }
    +}
    diff --git a/86_Target/csharp/Target/Game.cs b/86_Target/csharp/Target/Game.cs
    new file mode 100644
    index 000000000..2cef015ae
    --- /dev/null
    +++ b/86_Target/csharp/Target/Game.cs
    @@ -0,0 +1,89 @@
    +using System;
    +
    +namespace Target
    +{
    +    internal class Game
    +    {
    +        private readonly FiringRange _firingRange;
    +        private int _shotCount;
    +
    +        private Game(FiringRange firingRange)
    +        {
    +            _firingRange = firingRange;
    +        }
    +
    +        public static void Play(FiringRange firingRange) => new Game(firingRange).Play();
    +
    +        private void Play()
    +        {
    +            var target = _firingRange.TargetPosition;
    +            Console.WriteLine(target.GetBearing());
    +            Console.WriteLine($"Target sighted: approximate coordinates:  {target}");
    +
    +            while (true)
    +            {
    +                Console.WriteLine($"     Estimated distance: {target.EstimateDistance()}");
    +                Console.WriteLine();
    +
    +                var explosion = Shoot();
    +
    +                if (explosion.IsTooClose)
    +                {
    +                    Console.WriteLine("You blew yourself up!!");
    +                    return;
    +                }
    +
    +                Console.WriteLine(explosion.GetBearing());
    +
    +                if (explosion.IsHit)
    +                {
    +                    ReportHit(explosion.DistanceToTarget);
    +                    return;
    +                }
    +
    +                ReportMiss(explosion);
    +            }
    +        }
    +
    +        private Explosion Shoot()
    +        {
    +            var input = Input.ReadNumbers("Input angle deviation from X, angle deviation from Z, distance", 3);
    +            _shotCount++;
    +            Console.WriteLine();
    +
    +            return _firingRange.Fire(Angle.InDegrees(input[0]), Angle.InDegrees(input[1]), input[2]);
    +        }
    +
    +        private void ReportHit(float distance)
    +        {
    +            Console.WriteLine();
    +            Console.WriteLine($" * * * HIT * * *   Target is non-functional");
    +            Console.WriteLine();
    +            Console.WriteLine($"Distance of explosion from target was {distance} kilometers.");
    +            Console.WriteLine();
    +            Console.WriteLine($"Mission accomplished in {_shotCount} shots.");
    +        }
    +
    +        private void ReportMiss(Explosion explosion)
    +        {
    +            ReportMiss(explosion.FromTarget);
    +            Console.WriteLine($"Approx position of explosion:  {explosion.Position}");
    +            Console.WriteLine($"     Distance from target = {explosion.DistanceToTarget}");
    +            Console.WriteLine();
    +            Console.WriteLine();
    +            Console.WriteLine();
    +        }
    +
    +        private void ReportMiss(Offset targetOffset)
    +        {
    +            ReportMiss(targetOffset.DeltaX, "in front of", "behind");
    +            ReportMiss(targetOffset.DeltaY, "to left of", "to right of");
    +            ReportMiss(targetOffset.DeltaZ, "above", "below");
    +        }
    +
    +        private void ReportMiss(float delta, string positiveText, string negativeText) =>
    +            Console.WriteLine(delta >= 0 ? GetOffsetText(positiveText, delta) : GetOffsetText(negativeText, -delta));
    +
    +        private static string GetOffsetText(string text, float distance) => $"Shot {text} target {distance} kilometers.";
    +    }
    +}
    diff --git a/86_Target/csharp/Target/Input.cs b/86_Target/csharp/Target/Input.cs
    new file mode 100644
    index 000000000..3cfce2c04
    --- /dev/null
    +++ b/86_Target/csharp/Target/Input.cs
    @@ -0,0 +1,59 @@
    +using System;
    +using System.Collections.Generic;
    +
    +namespace Target
    +{
    +    // Provides input methods which emulate the BASIC interpreter's keyboard input routines
    +    internal static class Input
    +    {
    +        internal static void Prompt(string text = "") => Console.Write($"{text}? ");
    +
    +        internal static List ReadNumbers(string prompt, int requiredCount)
    +        {
    +            var numbers = new List();
    +
    +            while (!TryReadNumbers(prompt, requiredCount, numbers))
    +            {
    +                numbers.Clear();
    +                prompt = "";
    +            }
    +
    +            return numbers;
    +        }
    +
    +        private static bool TryReadNumbers(string prompt, int requiredCount, List numbers)
    +        {
    +            Prompt(prompt);
    +            var inputValues = ReadStrings();
    +
    +            foreach (var value in inputValues)
    +            {
    +                if (numbers.Count == requiredCount)
    +                {
    +                    Console.WriteLine("!Extra input ingored");
    +                    break;
    +                }
    +
    +                if (!TryParseNumber(value, out var number))
    +                {
    +                    return false;
    +                }
    +
    +                numbers.Add(number);
    +            }
    +
    +            return numbers.Count == requiredCount || TryReadNumbers("?", requiredCount, numbers);
    +        }
    +
    +        private static string[] ReadStrings() => Console.ReadLine().Split(',', StringSplitOptions.TrimEntries);
    +
    +        private static bool TryParseNumber(string text, out float number)
    +        {
    +            if (float.TryParse(text, out number)) { return true; }
    +
    +            Console.WriteLine("!Number expected - retry input line");
    +            number = default;
    +            return false;
    +        }
    +    }
    +}
    diff --git a/86_Target/csharp/Offset.cs b/86_Target/csharp/Target/Offset.cs
    similarity index 100%
    rename from 86_Target/csharp/Offset.cs
    rename to 86_Target/csharp/Target/Offset.cs
    diff --git a/86_Target/csharp/Point.cs b/86_Target/csharp/Target/Point.cs
    similarity index 100%
    rename from 86_Target/csharp/Point.cs
    rename to 86_Target/csharp/Target/Point.cs
    diff --git a/86_Target/csharp/Target/Program.cs b/86_Target/csharp/Target/Program.cs
    new file mode 100644
    index 000000000..b861f0e6f
    --- /dev/null
    +++ b/86_Target/csharp/Target/Program.cs
    @@ -0,0 +1,39 @@
    +using System;
    +using System.Reflection;
    +
    +namespace Target
    +{
    +    class Program
    +    {
    +        static void Main(string[] args)
    +        {
    +            DisplayTitleAndInstructions();
    +
    +            var firingRange = new FiringRange();
    +
    +            while (true)
    +            {
    +                Game.Play(firingRange);
    +
    +                Console.WriteLine();
    +                Console.WriteLine();
    +                Console.WriteLine();
    +                Console.WriteLine();
    +                Console.WriteLine();
    +                Console.WriteLine("Next target...");
    +                Console.WriteLine();
    +
    +                firingRange.NextTarget();
    +            }
    +        }
    +
    +        private static void DisplayTitleAndInstructions()
    +        {
    +            using var stream = Assembly.GetExecutingAssembly()
    +                .GetManifestResourceStream("Target.Strings.TitleAndInstructions.txt");
    +            using var stdout = Console.OpenStandardOutput();
    +
    +            stream.CopyTo(stdout);
    +        }
    +    }
    +}
    diff --git a/86_Target/csharp/Target/RandomExtensions.cs b/86_Target/csharp/Target/RandomExtensions.cs
    new file mode 100644
    index 000000000..45443c262
    --- /dev/null
    +++ b/86_Target/csharp/Target/RandomExtensions.cs
    @@ -0,0 +1,14 @@
    +using System;
    +
    +namespace Target
    +{
    +    internal static class RandomExtensions
    +    {
    +        public static float NextFloat(this Random rnd) => (float)rnd.NextDouble();
    +
    +        public static Point NextPosition(this Random rnd) => new (
    +            Angle.InRotations(rnd.NextFloat()),
    +            Angle.InRotations(rnd.NextFloat()),
    +            100000 * rnd.NextFloat() + rnd.NextFloat());
    +    }
    +}
    diff --git a/86_Target/csharp/Strings/TitleAndInstructions.txt b/86_Target/csharp/Target/Strings/TitleAndInstructions.txt
    similarity index 99%
    rename from 86_Target/csharp/Strings/TitleAndInstructions.txt
    rename to 86_Target/csharp/Target/Strings/TitleAndInstructions.txt
    index f883ac7a4..0142e4204 100644
    --- a/86_Target/csharp/Strings/TitleAndInstructions.txt
    +++ b/86_Target/csharp/Target/Strings/TitleAndInstructions.txt
    @@ -14,3 +14,5 @@ You will then proceed to shoot at the target until it is
     destroyed!
     
     Good luck!!
    +
    +
    diff --git a/86_Target/csharp/Target/Target.csproj b/86_Target/csharp/Target/Target.csproj
    new file mode 100644
    index 000000000..2df33b677
    --- /dev/null
    +++ b/86_Target/csharp/Target/Target.csproj
    @@ -0,0 +1,12 @@
    +
    +
    +  
    +    Exe
    +    net5.0
    +  
    +
    +  
    +    
    +  
    +
    +
    diff --git a/86_Target/java/Target.java b/86_Target/java/Target.java
    index 4a60005d1..869c443ad 100644
    --- a/86_Target/java/Target.java
    +++ b/86_Target/java/Target.java
    @@ -142,3 +142,5 @@ private static class TargetAttempt {
     		double distance;
     	}
     }
    +
    +
    diff --git a/86_Target/javascript/target.html b/86_Target/javascript/target.html
    index 321de6a96..97bba5ea6 100644
    --- a/86_Target/javascript/target.html
    +++ b/86_Target/javascript/target.html
    @@ -1,10 +1,9 @@
     
     
     TARGET
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/86_Target/javascript/target.js b/86_Target/javascript/target.js
    index f32fc6b99..e61fba8b4 100644
    --- a/86_Target/javascript/target.js
    +++ b/86_Target/javascript/target.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/86_Target/kotlin/README.md b/86_Target/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/86_Target/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/86_Target/lua/README.md b/86_Target/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/86_Target/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/86_Target/pascal/README.md b/86_Target/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/86_Target/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/86_Target/perl/README.md b/86_Target/perl/README.md
    index eca6b9fa7..e69c8b819 100644
    --- a/86_Target/perl/README.md
    +++ b/86_Target/perl/README.md
    @@ -1,9 +1,3 @@
     Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
     
     Conversion to [Perl](https://www.perl.org/)
    -
    -Modified so that if the user enters "quit" or "stop" for the input, the program will exit.
    -This way the user doesn't have to enter Contorl-C to quit.
    -
    -Target values can be space and/or comma separated, so "1 2 3" is valid, as is "1,2,3" or even "1, 2, 3".
    -I believe the original Basic program wanted "1,2,3" or else each on a separate line.
    diff --git a/86_Target/perl/target.pl b/86_Target/perl/target.pl
    deleted file mode 100644
    index cb552a39d..000000000
    --- a/86_Target/perl/target.pl
    +++ /dev/null
    @@ -1,107 +0,0 @@
    -#!/usr/bin/perl
    -
    -# Target program in Perl
    -#   Modified so that if the user enters "quit" or "stop" for the input, the program will exit.
    -#   Values can be space and/or comma separated.
    -# Translated by Kevin Brannen (kbrannen)
    -
    -use strict;
    -use warnings;
    -
    -# globals
    -my $R = 1;
    -my $R1 = 57.296;
    -my $Pi = 3.14159;
    -
    -print "\n";
    -print " " x 33, "TARGET\n";
    -print " " x 15, "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n";
    -
    -print "YOU ARE THE WEAPONS OFFICER ON THE STARSHIP ENTERPRISE\n";
    -print "AND THIS IS A TEST TO SEE HOW ACCURATE A SHOT YOU\n";
    -print "ARE IN A THREE-DIMENSIONAL RANGE.  YOU WILL BE TOLD\n";
    -print "THE RADIAN OFFSET FOR THE X AND Z AXES, THE LOCATION\n";
    -print "OF THE TARGET IN THREE DIMENSIONAL RECTANGULAR COORDINATES,\n";
    -print "THE APPROXIMATE NUMBER OF DEGREES FROM THE X AND Z\n";
    -print "AXES, AND THE APPROXIMATE DISTANCE TO THE TARGET.\n";
    -print "YOU WILL THEN PROCEEED TO SHOOT AT THE TARGET UNTIL IT IS\n";
    -print "DESTROYED!\n\n";
    -print "GOOD LUCK!!\n\n";
    -
    -while (1)
    -{
    -    my $A = rand(1) * 2 * $Pi;
    -    my $B = rand(1) * 2 * $Pi;
    -    my $P1 = 100000 * rand(1) + rand(1);
    -    my $X = sin($B) * cos($A) * $P1;
    -    my $Y = sin($B) * sin($A) * $P1;
    -    my $Z = cos($B) * $P1;
    -    print "RADIANS FROM X AXIS = $A   FROM Z AXIS = $B\n";
    -    print "TARGET SIGHTED: APPROXIMATE COORDINATES:  X=$X  Y=$Y  Z=$Z\n";
    -
    -    while (1)
    -    {
    -        my $P3;
    -        $R++;
    -
    -        if    ($R == 1) { $P3 = int($P1 * .05) * 20; }
    -        elsif ($R == 2) { $P3 = int($P1 * .1) * 10; }
    -        elsif ($R == 3) { $P3 = int($P1 * .5) * 2; }
    -        elsif ($R == 4) { $P3 = int($P1); }
    -        else            { $P3 = $P1; }
    -
    -        print "     ESTIMATED DISTANCE: $P3\n\n";
    -        print "INPUT ANGLE DEVIATION FROM X, DEVIATION FROM Z, DISTANCE: ";
    -        chomp(my $ans = lc(<>));
    -        exit(0) if ($ans eq "quit" || $ans eq "stop");
    -
    -        my ($A1, $B1, $P2) = split(/[,\s]+/, $ans);
    -        print "\n";
    -
    -        if ($P2 >= 20)
    -        {
    -            $A1 /= $R1;
    -            $B1 /= $R1;
    -            print "RADIANS FROM X AXIS = $A1  FROM Z AXIS = $B1\n";
    -            my $X1 = $P2 * sin($B1) * cos($A1);
    -            my $Y1 = $P2 * sin($B1) * sin($A1);
    -            my $Z1 = $P2 * cos($B1);
    -            my $D = (($X1 - $X) ** 2 + ($Y1 - $Y) ** 2 + ($Z1 - $Z) ** 2) ** (0.5);
    -
    -            if ($D <= 20)
    -            {
    -                print "\n * * * HIT * * *   TARGET IS NON-FUNCTIONAL\n";
    -                print "\nDISTANCE OF EXPLOSION FROM TARGET WAS $D KILOMETERS.\n";
    -                print "\nMISSION ACCOMPLISHED IN $R SHOTS.\n";
    -                last;
    -            }
    -            else
    -            {
    -                my $X2 = $X1 - $X;
    -                my $Y2 = $Y1 - $Y;
    -                my $Z2 = $Z1 - $Z;
    -
    -                if ($X2 < 0) { print "SHOT BEHIND TARGET ", -$X2, " KILOMETERS.\n"; }
    -                else         { print "SHOT IN FRONT OF TARGET $X2 KILOMETERS.\n"; }
    -
    -                if ($Y2 < 0) { print "SHOT TO RIGHT OF TARGET ", -$Y2, " KILOMETERS.\n"; }
    -                else         { print "SHOT TO LEFT OF TARGET $Y2 KILOMETERS.\n"; }
    -
    -                if ($Z2 < 0) { print "SHOT BELOW TARGET ", -$Z2, " KILOMETERS.\n"; }
    -                else         { print "SHOT ABOVE TARGET $Z2 KILOMETERS.\n"; }
    -
    -                print "APPROX POSITION OF EXPLOSION:  X=$X1   Y=$Y1   Z=$Z1\n";
    -                print "     DISTANCE FROM TARGET = $D\n\n\n";
    -                next;
    -            }
    -        }
    -        else
    -        {
    -            print "YOU BLEW YOURSELF UP!!\n";
    -            last;
    -        }
    -    }
    -
    -    $R = 0;
    -    print "\n\n\n\n\nNEXT TARGET...\n\n";
    -}
    diff --git a/86_Target/python/target.py b/86_Target/python/target.py
    index 122c82d11..68fd95211 100644
    --- a/86_Target/python/target.py
    +++ b/86_Target/python/target.py
    @@ -6,19 +6,19 @@
     Ported by Dave LeCompte
     """
     
    +import collections
     import math
     import random
    -from typing import List
     
     PAGE_WIDTH = 64
     
     
    -def print_centered(msg: str) -> None:
    +def print_centered(msg):
         spaces = " " * ((PAGE_WIDTH - len(msg)) // 2)
         print(spaces + msg)
     
     
    -def print_header(title: str) -> None:
    +def print_header(title):
         print_centered(title)
         print_centered("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
         print()
    @@ -26,7 +26,7 @@ def print_header(title: str) -> None:
         print()
     
     
    -def print_instructions() -> None:
    +def print_instructions():
         print("YOU ARE THE WEAPONS OFFICER ON THE STARSHIP ENTERPRISE")
         print("AND THIS IS A TEST TO SEE HOW ACCURATE A SHOT YOU")
         print("ARE IN A THREE-DIMENSIONAL RANGE.  YOU WILL BE TOLD")
    @@ -42,10 +42,10 @@ def print_instructions() -> None:
         print()
     
     
    -def prompt() -> List[float]:
    +def prompt():
         while True:
             response = input("INPUT ANGLE DEVIATION FROM X, DEVIATION FROM Z, DISTANCE? ")
    -        if "," not in response:
    +        if not ("," in response):
                 continue
     
             terms = response.split(",")
    @@ -55,14 +55,14 @@ def prompt() -> List[float]:
             return [float(t) for t in terms]
     
     
    -def next_target() -> None:
    -    for _ in range(5):
    +def next_target():
    +    for i in range(5):
             print()
         print("NEXT TARGET...")
         print()
     
     
    -def describe_miss(x, y, z, x1, y1, z1, d) -> None:
    +def describe_miss(x, y, z, x1, y1, z1, d):
         x2 = x1 - x
         y2 = y1 - y
         z2 = z1 - z
    @@ -89,7 +89,7 @@ def describe_miss(x, y, z, x1, y1, z1, d) -> None:
         print()
     
     
    -def do_shot_loop(p1, x, y, z) -> None:
    +def do_shot_loop(p1, x, y, z):
         shot_count = 0
         while True:
             shot_count += 1
    @@ -129,20 +129,20 @@ def do_shot_loop(p1, x, y, z) -> None:
                 print()
                 print(" * * * HIT * * *   TARGET IS NON FUNCTIONAL")
                 print()
    -            print(f"DISTANCE OF EXPLOSION FROM TARGET WAS {distance:.4f} KILOMETERS")
    +            print(f"DISTANCE OF EXPLOSION FROM TARGET WAS {d:.4f} KILOMETERS")
                 print()
    -            print(f"MISSION ACCOMPLISHED IN {shot_count} SHOTS.")
    +            print(f"MISSION ACCOMPLISHED IN {r} SHOTS.")
     
                 return
             else:
                 describe_miss(x, y, z, x1, y1, z1, distance)
     
     
    -def show_radians(a, b) -> None:
    +def show_radians(a, b):
         print(f"RADIANS FROM X AXIS = {a:.4f}   FROM Z AXIS = {b:.4f}")
     
     
    -def play_game() -> None:
    +def play_game():
         while True:
             a = random.uniform(0, 2 * math.pi)  # random angle
             b = random.uniform(0, 2 * math.pi)  # random angle
    @@ -161,7 +161,7 @@ def play_game() -> None:
             next_target()
     
     
    -def main() -> None:
    +def main():
         print_header("TARGET")
         print_instructions()
     
    diff --git a/86_Target/vbnet/Target.sln b/86_Target/vbnet/Target.sln
    deleted file mode 100644
    index 3b1edd8c5..000000000
    --- a/86_Target/vbnet/Target.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 21a19379f..000000000
    --- a/86_Target/vbnet/Target.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Target
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/87_3-D_Plot/README.md b/87_3-D_Plot/README.md
    index 60505c221..3361976a3 100644
    --- a/87_3-D_Plot/README.md
    +++ b/87_3-D_Plot/README.md
    @@ -14,7 +14,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/87_3-D_Plot/csharp/Plot.sln b/87_3-D_Plot/csharp/Plot.sln
    index b296ace9e..1402bc2ac 100644
    --- a/87_3-D_Plot/csharp/Plot.sln
    +++ b/87_3-D_Plot/csharp/Plot.sln
    @@ -1,25 +1,34 @@
     
     Microsoft Visual Studio Solution File, Format Version 12.00
    -# Visual Studio Version 17
    -VisualStudioVersion = 17.0.32014.148
    +# Visual Studio 15
    +VisualStudioVersion = 15.0.26124.0
     MinimumVisualStudioVersion = 15.0.26124.0
    -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Plot", "Plot.csproj", "{8000A3CF-612D-4FB7-B53D-885BB6E5492B}"
    +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plot", "Plot\Plot.csproj", "{8857AE83-F481-43B0-AA51-D78E1340BD93}"
     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
    -	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
    +		Release|x64 = Release|x64
    +		Release|x86 = Release|x86
     	EndGlobalSection
     	GlobalSection(SolutionProperties) = preSolution
     		HideSolutionNode = FALSE
     	EndGlobalSection
    -	GlobalSection(ExtensibilityGlobals) = postSolution
    -		SolutionGuid = {5DE8E572-67C9-4DE3-B851-447B78FE983A}
    +	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
     	EndGlobalSection
     EndGlobal
    diff --git a/87_3-D_Plot/csharp/Function.cs b/87_3-D_Plot/csharp/Plot/Function.cs
    similarity index 100%
    rename from 87_3-D_Plot/csharp/Function.cs
    rename to 87_3-D_Plot/csharp/Plot/Function.cs
    diff --git a/87_3-D_Plot/csharp/Plot.csproj b/87_3-D_Plot/csharp/Plot/Plot.csproj
    similarity index 100%
    rename from 87_3-D_Plot/csharp/Plot.csproj
    rename to 87_3-D_Plot/csharp/Plot/Plot.csproj
    diff --git a/87_3-D_Plot/csharp/Program.cs b/87_3-D_Plot/csharp/Plot/Program.cs
    similarity index 100%
    rename from 87_3-D_Plot/csharp/Program.cs
    rename to 87_3-D_Plot/csharp/Plot/Program.cs
    diff --git a/87_3-D_Plot/java/Plot3D.java b/87_3-D_Plot/java/Plot3D.java
    index ee9b02341..a12848d8d 100644
    --- a/87_3-D_Plot/java/Plot3D.java
    +++ b/87_3-D_Plot/java/Plot3D.java
    @@ -8,90 +8,90 @@
      * 

    * Note: The idea was to create a version of the 1970's BASIC game in Java, without introducing * new features - no additional text, error checking, etc has been added. - * + * * Converted from BASIC to Java by Darren Cardenas. */ - + // Java class names cannot begin with a letter, so class name 3dplot cannot be used -public class Plot3D { - +public class Plot3D { + public void play() { showIntro(); startGame(); - } // End of method play - - - private void showIntro() { - + } // End of method play + + + private void showIntro() { + System.out.println(" ".repeat(31) + "3D PLOT"); System.out.println(" ".repeat(14) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); System.out.println("\n\n\n"); - - } // End of method showIntro + + } // End of method showIntro - private void startGame() { + private void startGame() { float row = 0; int column = 0; int limit = 0; int plotVal = 0; int root = 0; - + String lineContent = ""; - + // Begin loop through all rows for (row = -30; row <= 30; row += 1.5) { - - limit = 0; - + + limit = 0; + root = 5 * (int) Math.floor((Math.sqrt(900 - row * row) / 5)); - + // Begin loop through all columns for (column = root; column >= -root; column += -5) { - + plotVal = 25 + (int) Math.floor(func(Math.sqrt(row * row + column * column)) - 0.7 * column); - + if (plotVal > limit) { - + limit = plotVal; - + // Add whitespace while (lineContent.length() < (plotVal-1)) { lineContent += " "; - } - - lineContent += "*"; + } + lineContent += "*"; + } } // End loop through all columns - - System.out.println(lineContent); - + + System.out.println(lineContent); + lineContent = ""; } // End loop through all rows - + } // End of method startGame - + // Function to be plotted public double func(double inputVal) { - - return (30 * Math.exp(-inputVal * inputVal / 100)); - + + return (30 * Math.exp(-inputVal * inputVal / 100)); + } - + public static void main(String[] args) { - + Plot3D plot = new Plot3D(); plot.play(); - + } // End of method main } // End of class Plot3D diff --git a/87_3-D_Plot/javascript/3dplot.html b/87_3-D_Plot/javascript/3dplot.html index 8d441ee4a..003096bf7 100644 --- a/87_3-D_Plot/javascript/3dplot.html +++ b/87_3-D_Plot/javascript/3dplot.html @@ -1,7 +1,6 @@ 3D PLOT -

    
    diff --git a/87_3-D_Plot/kotlin/README.md b/87_3-D_Plot/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/87_3-D_Plot/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/87_3-D_Plot/lua/README.md b/87_3-D_Plot/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/87_3-D_Plot/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/87_3-D_Plot/pascal/README.md b/87_3-D_Plot/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/87_3-D_Plot/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/87_3-D_Plot/python/3dplot.py b/87_3-D_Plot/python/3dplot.py
    index ea3f3ee96..2dda44ff7 100644
    --- a/87_3-D_Plot/python/3dplot.py
    +++ b/87_3-D_Plot/python/3dplot.py
    @@ -4,30 +4,23 @@
     #
     # Converted from BASIC to Python by Trevor Hobson
     
    -from math import exp, floor, sqrt
    -
    -
    -def equation(x: float) -> float:
    -    return 30 * exp(-x * x / 100)
    -
    -
    -def main() -> None:
    -    print(" " * 32 + "3D PLOT")
    -    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n\n")
    -
    -    for x in range(-300, 315, 15):
    -        x1 = x / 10
    -        max_column = 0
    -        y1 = 5 * floor(sqrt(900 - x1 * x1) / 5)
    -        y_plot = [" "] * 80
    -
    -        for y in range(y1, -(y1 + 5), -5):
    -            column = floor(25 + equation(sqrt(x1 * x1 + y * y)) - 0.7 * y)
    -            if column > max_column:
    -                max_column = column
    -                y_plot[column] = "*"
    -        print("".join(y_plot))
    -
    -
    -if __name__ == "__main__":
    -    main()
    +import math
    +
    +def equation(input):
    +	return 30 * math.exp(-input * input / 100)
    +
    +print(" " * 32 + "3D PLOT")
    +print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n\n")
    +
    +for x in range (-300, 315, 15):
    +	x1 = x / 10
    +	l = 0
    +	y1 = 5 * math.floor(math.sqrt(900 - x1 * x1) / 5)
    +	yPlot = [" "] * 80
    +
    +	for y in range (y1, -(y1 + 5), -5):
    +		z = math.floor(25 + equation(math.sqrt(x1 * x1 + y * y)) - .7 * y)
    +		if z > l:
    +			l = z
    +			yPlot[z] = "*"
    +	print("".join(yPlot))
    \ No newline at end of file
    diff --git a/87_3-D_Plot/ruby/3dplot.rb b/87_3-D_Plot/ruby/3dplot.rb
    index ca673e9c6..9c4e8394b 100644
    --- a/87_3-D_Plot/ruby/3dplot.rb
    +++ b/87_3-D_Plot/ruby/3dplot.rb
    @@ -25,4 +25,4 @@ def main
       render
     end
     
    -main
    +main
    \ No newline at end of file
    diff --git a/87_3-D_Plot/rust/Cargo.lock b/87_3-D_Plot/rust/Cargo.lock
    deleted file mode 100644
    index b21cc6a2d..000000000
    --- a/87_3-D_Plot/rust/Cargo.lock
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    diff --git a/87_3-D_Plot/rust/Cargo.toml b/87_3-D_Plot/rust/Cargo.toml
    deleted file mode 100644
    index 7d75412a6..000000000
    --- a/87_3-D_Plot/rust/Cargo.toml
    +++ /dev/null
    @@ -1,6 +0,0 @@
    -[package]
    -name = "rust"
    -version = "0.1.0"
    -edition = "2021"
    -
    -[dependencies]
    diff --git a/87_3-D_Plot/rust/src/main.rs b/87_3-D_Plot/rust/src/main.rs
    deleted file mode 100644
    index ebd66dfa2..000000000
    --- a/87_3-D_Plot/rust/src/main.rs
    +++ /dev/null
    @@ -1,68 +0,0 @@
    -/** 3D Plot GAME 
    - * https://github.com/coding-horror/basic-computer-games/blob/main/87_3-D_Plot/3dplot.bas
    - * Direct conversion from BASIC to Rust by Pablo Marques (marquesrs).
    - * No additional features or improvements were added. As a faithful translation, 
    - * many of the code here are done in an unrecommended way by today's standards.
    - * 03/03/25
    -*/
    -
    -fn main() {
    -    //1 PRINT TAB(32);"3D PLOT"
    -    //2 PRINT TAB(15);"CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY"
    -    //3 PRINT:PRINT:PRINT
    -    print!("{}",
    -        format!("{}{}\n{}{}\n\n\n\n",
    -            " ".repeat(31),
    -            "3D PLOT",
    -            " ".repeat(14),
    -            "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY"
    -        )
    -    );
    -
    -    //5 DEF FNA(Z)=30*EXP(-Z*Z/100)
    -    let fna = |z: f32| {30.0 * f32::exp(-z*z/100.0)};
    -
    -    //100 PRINT
    -    println!();
    -    
    -    let mut line_content = String::new();
    -    //110 FOR X=-30 TO 30 STEP 1.5
    -    let mut x = -30.0;
    -    while x <= 30.0 {
    -        //120 L=0
    -        let mut l = 0;
    -        
    -        //130 Y1=5*INT(SQR(900-X*X)/5)
    -        let y1 = 5.0 * (f32::sqrt(900.0-x*x)/5.0).floor();
    -
    -        //140 FOR Y=Y1 TO -Y1 STEP -5
    -        let mut y = y1;
    -        while y >= -y1 {
    -            //150 Z=INT(25+FNA(SQR(X*X+Y*Y))-.7*Y)
    -            let z = (25.0 + fna(f32::sqrt(x*x+y*y))-0.7*y) as i32;
    -
    -            //160 IF Z<=L THEN 190
    -            if z <= l {
    -                y = y - 5.0;
    -                continue;
    -            }
    -            //170 L=Z
    -            l = z;
    -            //180 PRINT TAB(Z);"*";
    -            while (line_content.len() as i32) < (z-1) {
    -                line_content += " ";
    -            }
    -            line_content += "*";
    -            //190 NEXT Y
    -            y = y - 5.0;
    -        }
    -        print!("{}", line_content);
    -        line_content.clear();
    -
    -        //200 PRINT
    -        println!();
    -        //210 NEXT X
    -        x = x + 1.5;
    -    }
    -    //300 END
    -}
    \ No newline at end of file
    diff --git a/87_3-D_Plot/vbnet/Plot.sln b/87_3-D_Plot/vbnet/Plot.sln
    deleted file mode 100644
    index a0dcbfcb4..000000000
    --- a/87_3-D_Plot/vbnet/Plot.sln
    +++ /dev/null
    @@ -1,25 +0,0 @@
    -
    -Microsoft Visual Studio Solution File, Format Version 12.00
    -# Visual Studio Version 16
    -VisualStudioVersion = 16.0.30114.105
    -MinimumVisualStudioVersion = 10.0.40219.1
    -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(ExtensibilityGlobals) = postSolution
    -		SolutionGuid = {CAD09CCC-4522-438E-A8C6-514A866D90DE}
    -	EndGlobalSection
    -EndGlobal
    diff --git a/87_3-D_Plot/vbnet/Plot.vbproj b/87_3-D_Plot/vbnet/Plot.vbproj
    deleted file mode 100644
    index be687f578..000000000
    --- a/87_3-D_Plot/vbnet/Plot.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Plot
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/88_3-D_Tic-Tac-Toe/README.md b/88_3-D_Tic-Tac-Toe/README.md
    index 2ab13480d..df9cabf41 100644
    --- a/88_3-D_Tic-Tac-Toe/README.md
    +++ b/88_3-D_Tic-Tac-Toe/README.md
    @@ -6,17 +6,6 @@ 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.
    -
    -Also note that while the file is called qubit.bas (with a "T"), the title shown in the program listing is "QUBIC" (with "C")... and the sample output shows "TIC TAC TOE" instead of either of these.
    -
     ---
     
     As published in Basic Computer Games (1978):
    @@ -26,7 +15,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/88_3-D_Tic-Tac-Toe/csharp/Program.cs b/88_3-D_Tic-Tac-Toe/csharp/Program.cs
    deleted file mode 100644
    index 12c6ca83f..000000000
    --- a/88_3-D_Tic-Tac-Toe/csharp/Program.cs
    +++ /dev/null
    @@ -1,10 +0,0 @@
    -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
    deleted file mode 100644
    index a01944e19..000000000
    --- a/88_3-D_Tic-Tac-Toe/csharp/Qubic.cs
    +++ /dev/null
    @@ -1,1192 +0,0 @@
    -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 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,
    -        /// 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. Such rows may help set up trapping opportunities.
    -                if (RowSums[row] == (POTENTIAL * 4) || RowSums[row] == MACHINE + (POTENTIAL * 3))
    -                {
    -                    // Try moving to a plane edge in an advantageous row.
    -                    return MovePlaneEdge(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 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,
    -        /// 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. 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 plane edge in an advantageous row.
    -                    return MovePlaneEdge(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 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.
    -        ///  Such a plane is one that the player could likely use to form traps.
    -        ///
    -        /// Original BASIC: 1830-2020
    -        ///
    -        /// 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,
    -        /// 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 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 = MovePlaneEdge(row, POTENTIAL);
    -                        if (moveResult != MachineAction.None)
    -                        {
    -                            return moveResult;
    -                        }
    -                    }
    -
    -                    // If no POTENTIAL plane edge found, look for an EMPTY one.
    -                    for (int row = (4 * plane) - 4; row < (4 * plane); row++)
    -                    {
    -                        var moveResult = MovePlaneEdge(row, EMPTY);
    -                        if (moveResult != MachineAction.None)
    -                        {
    -                            return moveResult;
    -                        }
    -                    }
    -                }
    -            }
    -
    -            // No satisfactory planes with open plane edges found.
    -            ClearPotentialMoves();
    -            return MachineAction.None;
    -        }
    -
    -        /// 
    -        /// 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
    -        ///
    -        /// 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 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.
    -        /// 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 plane edge piece in the row with the given spaceValue was
    -        /// found,
    -        /// None otherwise
    -        /// 
    -        private MachineAction MovePlaneEdge(int row, double spaceValue)
    -        {
    -            // 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
    -            // plane 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 plane edge pieces have their row indices marked. The pattern
    -            // above shows that:
    -            //
    -            //  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):
    -            //
    -            //  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 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]
    -            for (int space = a - 1; space <= 4 - a; space += 5 - (2 * a))
    -            {
    -                if (Board[RowsByPlane[row, space]] == spaceValue)
    -                {
    -                    // Found a plane 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
    deleted file mode 100644
    index 1735904d7..000000000
    --- a/88_3-D_Tic-Tac-Toe/csharp/QubicData.cs
    +++ /dev/null
    @@ -1,559 +0,0 @@
    -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, },
    -        };
    -    }
    -}
    diff --git a/88_3-D_Tic-Tac-Toe/csharp/ThreeDTicTacToe.csproj b/88_3-D_Tic-Tac-Toe/csharp/ThreeDTicTacToe.csproj
    deleted file mode 100644
    index d3fe4757c..000000000
    --- a/88_3-D_Tic-Tac-Toe/csharp/ThreeDTicTacToe.csproj
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -
    -  
    -    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
    deleted file mode 100644
    index 0dcb9034a..000000000
    --- a/88_3-D_Tic-Tac-Toe/csharp/ThreeDTicTacToe.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/javascript/qubit.html b/88_3-D_Tic-Tac-Toe/javascript/qubit.html
    index a971269c4..813015bbe 100644
    --- a/88_3-D_Tic-Tac-Toe/javascript/qubit.html
    +++ b/88_3-D_Tic-Tac-Toe/javascript/qubit.html
    @@ -1,10 +1,9 @@
     
     
     QUBIT
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/88_3-D_Tic-Tac-Toe/javascript/qubit.js b/88_3-D_Tic-Tac-Toe/javascript/qubit.js
    index 6f1cbe64e..9d73734d6 100644
    --- a/88_3-D_Tic-Tac-Toe/javascript/qubit.js
    +++ b/88_3-D_Tic-Tac-Toe/javascript/qubit.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    @@ -193,7 +193,7 @@ function select_move() {
         }
         if (j > 5 - a)
             return false;
    -    xa[ma[i][j]] = 5;
    +    xa[ma[i][j]] = s;
         m = ma[i][j];
         print("MACHINE TAKES");
         show_square(m);
    @@ -357,9 +357,9 @@ async function main()
                 } while (++i <= 76) ;
                 if (i <= 76)
                     continue;
    -
    +            
                 process_board();
    -
    +            
                 i = 1;
                 do {
                     la[i] = xa[ma[i][1]] + xa[ma[i][2]] + xa[ma[i][3]] + xa[ma[i][4]];
    @@ -387,7 +387,7 @@ async function main()
                 } while (++i <= 76) ;
                 if (i <= 76)
                     continue;
    -
    +            
                 for (k = 1; k <= 18; k++) {
                     p = 0;
                     for (i = 4 * k - 3; i <= 4 * k; i++) {
    diff --git a/88_3-D_Tic-Tac-Toe/kotlin/README.md b/88_3-D_Tic-Tac-Toe/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/88_3-D_Tic-Tac-Toe/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/88_3-D_Tic-Tac-Toe/lua/README.md b/88_3-D_Tic-Tac-Toe/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/88_3-D_Tic-Tac-Toe/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/88_3-D_Tic-Tac-Toe/pascal/README.md b/88_3-D_Tic-Tac-Toe/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/88_3-D_Tic-Tac-Toe/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/88_3-D_Tic-Tac-Toe/python/qubit.py b/88_3-D_Tic-Tac-Toe/python/qubit.py
    index e0dd531e8..e8840a872 100644
    --- a/88_3-D_Tic-Tac-Toe/python/qubit.py
    +++ b/88_3-D_Tic-Tac-Toe/python/qubit.py
    @@ -1,16 +1,14 @@
    -#!/usr/bin/env python3
    +#!/usr/bin/python3
     
     # Ported from the BASIC source for 3D Tic Tac Toe
     # in BASIC Computer Games, by David H. Ahl
     # The code originated from Dartmouth College
     
     from enum import Enum
    -from typing import Optional, Tuple, Union
     
     
     class Move(Enum):
    -    """Game status and types of machine move"""
    -
    +    """ Game status and types of machine move """
         HUMAN_WIN = 0
         MACHINE_WIN = 1
         DRAW = 2
    @@ -22,106 +20,104 @@ class Move(Enum):
         NICE_TRY = 8
         CONCEDES = 9
     
    -
     class Player(Enum):
         EMPTY = 0
         HUMAN = 1
         MACHINE = 2
     
    -
     class TicTacToe3D:
    -    """The game logic for 3D Tic Tac Toe and the machine opponent"""
    +    """ The game logic for 3D Tic Tac Toe and the machine opponent """
     
    -    def __init__(self) -> None:
    +    def __init__(self):
    +        
             # 4x4x4 board keeps track of which player occupies each place
             # and used by machine to work out its strategy
             self.board = [0] * 64
     
             # starting move
    -        self.corners = [0, 48, 51, 3, 12, 60, 63, 15, 21, 38, 22, 37, 25, 41, 26, 42]
    +        self.corners = [0, 48, 51, 3, 12, 60, 63, 15,
    +                        21, 38, 22, 37, 25, 41, 26, 42]
     
             # lines to check for end game
    -        self.lines = [
    -            [0, 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, 37, 38, 39],
    -            [40, 41, 42, 43],
    -            [44, 45, 46, 47],
    -            [48, 49, 50, 51],
    -            [52, 53, 54, 55],
    -            [56, 57, 58, 59],
    -            [60, 61, 62, 63],
    -            [0, 16, 32, 48],
    -            [4, 20, 36, 52],
    -            [8, 24, 40, 56],
    -            [12, 28, 44, 60],
    -            [1, 17, 33, 49],
    -            [5, 21, 37, 53],
    -            [9, 25, 41, 57],
    -            [13, 29, 45, 61],
    -            [2, 18, 34, 50],
    -            [6, 22, 38, 54],
    -            [10, 26, 42, 58],
    -            [14, 30, 46, 62],
    -            [3, 19, 35, 51],
    -            [7, 23, 39, 55],
    -            [11, 27, 43, 59],
    -            [15, 31, 47, 63],
    -            [0, 4, 8, 12],
    -            [16, 20, 24, 28],
    -            [32, 36, 40, 44],
    -            [48, 52, 56, 60],
    -            [1, 5, 9, 13],
    -            [17, 21, 25, 29],
    -            [33, 37, 41, 45],
    -            [49, 53, 57, 61],
    -            [2, 6, 10, 14],
    -            [18, 22, 26, 30],
    -            [34, 38, 42, 46],
    -            [50, 54, 58, 62],
    -            [3, 7, 11, 15],
    -            [19, 23, 27, 31],
    -            [35, 39, 43, 47],
    -            [51, 55, 59, 63],
    -            [0, 5, 10, 15],
    -            [16, 21, 26, 31],
    -            [32, 37, 42, 47],
    -            [48, 53, 58, 63],
    -            [12, 9, 6, 3],
    -            [28, 25, 22, 19],
    -            [44, 41, 38, 35],
    -            [60, 57, 54, 51],
    -            [0, 20, 40, 60],
    -            [1, 21, 41, 61],
    -            [2, 22, 42, 62],
    -            [3, 23, 43, 63],
    -            [48, 36, 24, 12],
    -            [49, 37, 25, 13],
    -            [50, 38, 26, 14],
    -            [51, 39, 27, 15],
    -            [0, 17, 34, 51],
    -            [4, 21, 38, 55],
    -            [8, 25, 42, 59],
    -            [12, 29, 46, 63],
    -            [48, 33, 18, 3],
    -            [52, 37, 22, 7],
    -            [56, 41, 26, 11],
    -            [60, 45, 30, 15],
    -            [0, 21, 42, 63],
    -            [15, 26, 37, 48],
    -            [3, 22, 41, 60],
    -            [12, 25, 38, 51],
    -        ]
    -
    -    def get(self, x, y, z) -> Player:
    -        m = self.board[4 * (4 * z + y) + x]
    +        self.lines = [[0, 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, 37, 38, 39],
    +                      [40, 41, 42, 43],
    +                      [44, 45, 46, 47],
    +                      [48, 49, 50, 51],
    +                      [52, 53, 54, 55],
    +                      [56, 57, 58, 59],
    +                      [60, 61, 62, 63],
    +                      [0, 16, 32, 48],
    +                      [4, 20, 36, 52],
    +                      [8, 24, 40, 56],
    +                      [12, 28, 44, 60],
    +                      [1, 17, 33, 49],
    +                      [5, 21, 37, 53],
    +                      [9, 25, 41, 57],
    +                      [13, 29, 45, 61],
    +                      [2, 18, 34, 50],
    +                      [6, 22, 38, 54],
    +                      [10, 26, 42, 58],
    +                      [14, 30, 46, 62],
    +                      [3, 19, 35, 51],
    +                      [7, 23, 39, 55],
    +                      [11, 27, 43, 59],
    +                      [15, 31, 47, 63],
    +                      [0, 4, 8, 12],
    +                      [16, 20, 24, 28],
    +                      [32, 36, 40, 44],
    +                      [48, 52, 56, 60],
    +                      [1, 5, 9, 13],
    +                      [17, 21, 25, 29],
    +                      [33, 37, 41, 45],
    +                      [49, 53, 57, 61],
    +                      [2, 6, 10, 14],
    +                      [18, 22, 26, 30],
    +                      [34, 38, 42, 46],
    +                      [50, 54, 58, 62],
    +                      [3, 7, 11, 15],
    +                      [19, 23, 27, 31],
    +                      [35, 39, 43, 47],
    +                      [51, 55, 59, 63],
    +                      [0, 5, 10, 15],
    +                      [16, 21, 26, 31],
    +                      [32, 37, 42, 47],
    +                      [48, 53, 58, 63],
    +                      [12, 9, 6, 3],
    +                      [28, 25, 22, 19],
    +                      [44, 41, 38, 35],
    +                      [60, 57, 54, 51],
    +                      [0, 20, 40, 60],
    +                      [1, 21, 41, 61],
    +                      [2, 22, 42, 62],
    +                      [3, 23, 43, 63],
    +                      [48, 36, 24, 12],
    +                      [49, 37, 25, 13],
    +                      [50, 38, 26, 14],
    +                      [51, 39, 27, 15],
    +                      [0, 17, 34, 51],
    +                      [4, 21, 38, 55],
    +                      [8, 25, 42, 59],
    +                      [12, 29, 46, 63],
    +                      [48, 33, 18, 3],
    +                      [52, 37, 22, 7],
    +                      [56, 41, 26, 11],
    +                      [60, 45, 30, 15],
    +                      [0, 21, 42, 63],
    +                      [15, 26, 37, 48],
    +                      [3, 22, 41, 60],
    +                      [12, 25, 38, 51]]
    +
    +    def get(self, x, y, z):
    +        m = self.board[4*(4*z + y) + x]
             if m == 40:
                 return Player.MACHINE
             elif m == 8:
    @@ -129,186 +125,199 @@ def get(self, x, y, z) -> Player:
             else:
                 return Player.EMPTY
     
    -    def move_3d(self, x, y, z, player) -> bool:
    -        m = 4 * (4 * z + y) + x
    +    def move3D(self, x, y, z, player):
    +        m = 4*(4*z + y) + x
             return self.move(m, player)
     
    -    def move(self, m, player) -> bool:
    +    def move(self, m, player):
             if self.board[m] > 1:
                 return False
    -
    -        self.board[m] = 40 if player == Player.MACHINE else 8
    +        
    +        if player == Player.MACHINE:
    +            self.board[m] = 40
    +        else:
    +            self.board[m] = 8
             return True
     
    -    def get_3d_position(self, m) -> Tuple[int, int, int]:
    +    def get3DPosition(self, m):
             x = m % 4
             y = (m // 4) % 4
             z = m // 16
             return x, y, z
     
    -    def evaluate_lines(self) -> None:
    +    def evaluateLines(self):
             self.lineValues = [0] * 76
             for j in range(76):
    -            value = sum(self.board[self.lines[j][k]] for k in range(4))
    +            value = 0
    +            for k in range(4):
    +                value += self.board[self.lines[j][k]]
                 self.lineValues[j] = value
     
    -    def strategy_mark_line(self, i) -> None:
    +    def strategyMarkLine(self, i):
             for j in range(4):
                 m = self.lines[i][j]
                 if self.board[m] == 0:
                     self.board[m] = 1
     
    -    def clear_strategy_marks(self) -> None:
    +    def clearStrategyMarks(self):
             for i in range(64):
                 if self.board[i] == 1:
                     self.board[i] = 0
     
    -    def mark_and_move(self, vlow, vhigh, vmove) -> Optional[Tuple[Move, int]]:
    -        """
    +    def markAndMove(self, vlow, vhigh, vmove):
    +        """ 
             mark lines that can potentially win the game for the human
             or the machine and choose best place to play
             """
             for i in range(76):
    -            value = sum(self.board[self.lines[i][j]] for j in range(4))
    +            value = 0
    +            for j in range(4):
    +                value += self.board[self.lines[i][j]]
                 self.lineValues[i] = value
                 if vlow <= value < vhigh:
                     if value > vlow:
    -                    return self.move_triple(i)
    -                self.strategy_mark_line(i)
    -        self.evaluate_lines()
    +                    return self.moveTriple(i)
    +                self.strategyMarkLine(i)
    +        self.evaluateLines()
     
             for i in range(76):
                 value = self.lineValues[i]
    -            if value in [4, vmove]:
    -                return self.move_diagonals(i, 1)
    +            if value == 4 or value == vmove:
    +                return self.moveDiagonals(i, 1)
             return None
     
    -    def machine_move(self) -> Union[None, Tuple[Move, int], Tuple[Move, int, int]]:
    -        """machine works out what move to play"""
    -        self.clear_strategy_marks()
    +    def machineMove(self):
    +        """ machine works out what move to play """
    +        self.clearStrategyMarks()
     
    -        self.evaluate_lines()
    -        for value, event in [
    -            (32, self.human_win),
    -            (120, self.machine_win),
    -            (24, self.block_human_win),
    -        ]:
    +        self.evaluateLines()
    +        for value, event in [(32, self.humanWin),
    +                             (120, self.machineWin),
    +                             (24, self.blockHumanWin)]:
                 for i in range(76):
                     if self.lineValues[i] == value:
                         return event(i)
     
    -        m = self.mark_and_move(80, 88, 43)
    -        if m is not None:
    +        m = self.markAndMove(80, 88, 43)
    +        if m != None:
                 return m
     
    -        self.clear_strategy_marks()
    +        self.clearStrategyMarks()
     
    -        m = self.mark_and_move(16, 24, 11)
    -        if m is not None:
    +        m = self.markAndMove(16, 24, 11)
    +        if m != None:
                 return m
     
             for k in range(18):
                 value = 0
    -            for i in range(4 * k, 4 * k + 4):
    +            for i in range(4*k, 4*k+4):
                     for j in range(4):
                         value += self.board[self.lines[i][j]]
                 if (32 <= value < 40) or (72 <= value < 80):
                     for s in [1, 0]:
    -                    for i in range(4 * k, 4 * k + 4):
    -                        m = self.move_diagonals(i, s)
    -                        if m is not None:
    +                    for i in range(4*k, 4*k+4):
    +                        m = self.moveDiagonals(i, s)
    +                        if m != None:
                                 return m
     
    -        self.clear_strategy_marks()
    +        self.clearStrategyMarks()
     
             for y in self.corners:
                 if self.board[y] == 0:
                     return (Move.MOVES, y)
     
    -        return next(
    -            ((Move.LIKES, i) for i in range(64) if self.board[i] == 0),
    -            (Move.DRAW, -1),
    -        )
    +        for i in range(64):
    +            if self.board[i] == 0:
    +                return (Move.LIKES, i)
     
    -    def human_win(self, i) -> Tuple[Move, int, int]:
    +        return (Move.DRAW, -1)
    +            
    +    def humanWin(self, i):
             return (Move.HUMAN_WIN, -1, i)
     
    -    def machine_win(self, i) -> Optional[Tuple[Move, int, int]]:
    +    def machineWin(self, i):
             for j in range(4):
                 m = self.lines[i][j]
                 if self.board[m] == 0:
                     return (Move.MACHINE_WIN, m, i)
             return None
     
    -    def block_human_win(self, i) -> Optional[Tuple[Move, int]]:
    +    def blockHumanWin(self, i):
             for j in range(4):
                 m = self.lines[i][j]
                 if self.board[m] == 0:
                     return (Move.NICE_TRY, m)
             return None
     
    -    def move_triple(self, i) -> Tuple[Move, int]:
    -        """make two lines-of-3 or prevent human from doing this"""
    +
    +    def moveTriple(self, i):
    +        """ make two lines-of-3 or prevent human from doing this """
             for j in range(4):
                 m = self.lines[i][j]
                 if self.board[m] == 1:
    -                return (Move.YOU_FOX, m) if self.lineValues[i] < 40 else (Move.GET_OUT, m)
    +                if self.lineValues[i] < 40:
    +                    return (Move.YOU_FOX, m)
    +                else:
    +                    return (Move.GET_OUT, m)
             return (Move.CONCEDES, -1)
     
         # choose move in corners or center boxes of square 4x4
    -    def move_diagonals(self, i, s) -> Optional[Tuple[Move, int]]:
    -        jrange = [1, 2] if 0 < (i % 4) < 3 else [0, 3]
    +    def moveDiagonals(self, i, s):
    +        if 0 < (i % 4) < 3:
    +            jrange = [1, 2]
    +        else:
    +            jrange = [0, 3]
             for j in jrange:
                 m = self.lines[i][j]
                 if self.board[m] == s:
                     return (Move.TAKES, m)
             return None
     
    -
     class Qubit:
    -    def move_code(self, board, m) -> str:
    -        x, y, z = board.get_3d_position(m)
    -        return f"{z + 1:d}{y + 1:d}{x + 1:d}"
    -
    -    def show_win(self, board, i) -> None:
    +    
    +    def moveCode(self, board, m):
    +        x, y, z = board.get3DPosition(m)
    +        return "{:d}{:d}{:d}".format(z+1, y+1, x+1)
    +        
    +    def showWin(self, board, i):
             for m in board.lines[i]:
    -            print(self.move_code(board, m))
    +            print(self.moveCode(board, m))
     
    -    def show_board(self, board) -> None:
    +    def showBoard(self, board):
             c = " YM"
             for z in range(4):
                 for y in range(4):
                     print("   " * y, end="")
                     for x in range(4):
                         p = board.get(x, y, z)
    -                    print(f"({c[p.value]})      ", end="")
    +                    print("({})      ".format(c[p.value]), end="")
                     print("\n")
                 print("\n")
    -
    -    def human_move(self, board) -> bool:
    -        print()
    +        
    +    def humanMove(self, board):
    +        print("")
             c = "1234"
             while True:
                 h = input("Your move?\n")
                 if h == "1":
                     return False
                 if h == "0":
    -                self.show_board(board)
    +                self.showBoard(board)
                     continue
                 if (len(h) == 3) and (h[0] in c) and (h[1] in c) and (h[2] in c):
                     x = c.find(h[2])
                     y = c.find(h[1])
                     z = c.find(h[0])
    -                if board.move_3d(x, y, z, Player.HUMAN):
    +                if board.move3D(x, y, z, Player.HUMAN):
                         break
    -
    +                
                     print("That square is used. Try again.")
                 else:
                     print("Incorrect move. Retype it--")
     
             return True
    -
    -    def play(self) -> None:
    +        
    +    def play(self):
             print("Qubic\n")
             print("Create Computing Morristown, New Jersey\n\n\n")
             while True:
    @@ -316,9 +325,9 @@ def play(self) -> None:
                 if len(c) >= 1 and (c[0] in "ynYN"):
                     break
                 print("Incorrect answer. Please type 'yes' or 'no.")
    -
    +            
             c = c.lower()
    -        if c[0] == "y":
    +        if c[0] == 'y':
                 print("The game is Tic-Tac-Toe in a 4 x 4 x 4 cube.")
                 print("Each move is indicated by a 3 digit number, with each")
                 print("digit between 1 and 4 inclusive.  The digits indicate the")
    @@ -332,6 +341,8 @@ def play(self) -> None:
     
                 print("To stop the program run, type 1 as your move.\n\n")
     
    +        
    +            
             play_again = True
             while play_again:
                 board = TicTacToe3D()
    @@ -342,31 +353,29 @@ def play(self) -> None:
                         break
                     print("Incorrect answer. Please type 'yes' or 'no'.")
     
    -            skip_human = s[0] in "nN"
    +            skipHuman = s[0] in "nN"
     
    -            move_text = [
    -                "Machine moves to",
    -                "Machine likes",
    -                "Machine takes",
    -                "Let's see you get out of this:  Machine moves to",
    -                "You fox.  Just in the nick of time, machine moves to",
    -                "Nice try. Machine moves to",
    -            ]
    +            move_text = ["Machine moves to",
    +                         "Machine likes",
    +                         "Machine takes",
    +                         "Let's see you get out of this:  Machine moves to",
    +                         "You fox.  Just in the nick of time, machine moves to",
    +                         "Nice try. Machine moves to"]
     
                 while True:
    -                if not skip_human and not self.human_move(board):
    -                    break
    -                skip_human = False
    +                if not skipHuman:
    +                    if not self.humanMove(board):
    +                        break
    +                skipHuman = False
     
    -                m = board.machine_move()
    -                assert m is not None
    +                m = board.machineMove()
                     if m[0] == Move.HUMAN_WIN:
                         print("You win as follows,")
    -                    self.show_win(board, m[2])  # type: ignore
    +                    self.showWin(board, m[2])
                         break
                     elif m[0] == Move.MACHINE_WIN:
    -                    print(f"Machine moves to {self.move_code(board, m[1])}, and wins as follows")
    -                    self.show_win(board, m[2])  # type: ignore
    +                    print("Machine moves to {}, and wins as follows".format(self.moveCode(board, m[1])))
    +                    self.showWin(board, m[2])
                         break
                     elif m[0] == Move.DRAW:
                         print("The game is a draw.")
    @@ -376,10 +385,10 @@ def play(self) -> None:
                         break
                     else:
                         print(move_text[m[0].value - Move.MOVES.value])
    -                    print(self.move_code(board, m[1]))
    +                    print(self.moveCode(board, m[1]))
                         board.move(m[1], Player.MACHINE)
     
    -                self.show_board(board)
    +                self.showBoard(board)
     
                 print(" ")
                 while True:
    @@ -389,7 +398,8 @@ def play(self) -> None:
                     print("Incorrect answer. Please Type 'yes' or 'no'.")
     
                 play_again = x[0] in "yY"
    -
    +        
    +        
     
     if __name__ == "__main__":
         game = Qubit()
    diff --git a/88_3-D_Tic-Tac-Toe/qubit.bas b/88_3-D_Tic-Tac-Toe/qubit.bas
    index 473e955aa..8dadf79e9 100644
    --- a/88_3-D_Tic-Tac-Toe/qubit.bas
    +++ b/88_3-D_Tic-Tac-Toe/qubit.bas
    @@ -92,7 +92,7 @@
     920 GOTO 1490
     930 IF L(I)<>3 THEN 690
     940 PRINT "NICE TRY. MACHINE MOVES TO";
    -950 FOR J=1 TO 4
    +950 FOR J=1 TO 4 
     960 LET M=M(I,J)
     970 IF X(M)<>0 THEN 1010
     980 LET X(M)=5
    diff --git a/88_3-D_Tic-Tac-Toe/vbnet/ThreeDTicTacToe.sln b/88_3-D_Tic-Tac-Toe/vbnet/ThreeDTicTacToe.sln
    deleted file mode 100644
    index 6479b0138..000000000
    --- a/88_3-D_Tic-Tac-Toe/vbnet/ThreeDTicTacToe.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index d1cd4c2b2..000000000
    --- a/88_3-D_Tic-Tac-Toe/vbnet/ThreeDTicTacToe.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    ThreeDTicTacToe
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/89_Tic-Tac-Toe/README.md b/89_Tic-Tac-Toe/README.md
    index 0205ab74a..311322fac 100644
    --- a/89_Tic-Tac-Toe/README.md
    +++ b/89_Tic-Tac-Toe/README.md
    @@ -23,7 +23,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/89_Tic-Tac-Toe/csharp/TicTacToe.sln b/89_Tic-Tac-Toe/csharp/TicTacToe.sln
    deleted file mode 100644
    index a77baf985..000000000
    --- a/89_Tic-Tac-Toe/csharp/TicTacToe.sln
    +++ /dev/null
    @@ -1,28 +0,0 @@
    -
    -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", "{E0AF55BF-4C2B-41C6-B556-E8EC8C1BE647}"
    -EndProject
    -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "tictactoe2", "tictactoe2\tictactoe2.csproj", "{B98682C9-132E-44F1-B288-8BE04CF53BCF}"
    -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
    -		{E0AF55BF-4C2B-41C6-B556-E8EC8C1BE647}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
    -		{E0AF55BF-4C2B-41C6-B556-E8EC8C1BE647}.Debug|Any CPU.Build.0 = Debug|Any CPU
    -		{E0AF55BF-4C2B-41C6-B556-E8EC8C1BE647}.Release|Any CPU.ActiveCfg = Release|Any CPU
    -		{E0AF55BF-4C2B-41C6-B556-E8EC8C1BE647}.Release|Any CPU.Build.0 = Release|Any CPU
    -		{B98682C9-132E-44F1-B288-8BE04CF53BCF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
    -		{B98682C9-132E-44F1-B288-8BE04CF53BCF}.Debug|Any CPU.Build.0 = Debug|Any CPU
    -		{B98682C9-132E-44F1-B288-8BE04CF53BCF}.Release|Any CPU.ActiveCfg = Release|Any CPU
    -		{B98682C9-132E-44F1-B288-8BE04CF53BCF}.Release|Any CPU.Build.0 = Release|Any CPU
    -	EndGlobalSection
    -EndGlobal
    diff --git a/89_Tic-Tac-Toe/csharp/tictactoe1/Program.cs b/89_Tic-Tac-Toe/csharp/tictactoe1/Program.cs
    index 72b985704..58f7d36fa 100644
    --- a/89_Tic-Tac-Toe/csharp/tictactoe1/Program.cs
    +++ b/89_Tic-Tac-Toe/csharp/tictactoe1/Program.cs
    @@ -1,4 +1,5 @@
     // See https://aka.ms/new-console-template for more information
    +Console.WriteLine("Hello, World!");
     // Print text on the screen with 30 spaces before text
     Console.WriteLine("TIC TAC TOE".PadLeft(30));
     // Print text on screen with 15 spaces before text
    @@ -32,15 +33,13 @@
     				d = move(c + 3);
     				computerMoves(d);
     				s = readYourMove();
    -				if (s == move(d + 4)) {
    -					e = move(d + 6);
    -					computerMoves(e);
    -					Console.WriteLine("THE GAME IS A DRAW.");
    -				} else {
    +				if (s != move(d + 4)) {
     					e = move(d + 4);
     					computerMoves(e);
    -					Console.WriteLine("AND WINS ********");
     				}
    +				e = move(d + 6);
    +				computerMoves(e);
    +				Console.WriteLine("THE GAME IS A DRAW.");
     			} else {
     				d = move(c + 7);
     				computerMoves(d);
    diff --git a/89_Tic-Tac-Toe/csharp/tictactoe2/Program.cs b/89_Tic-Tac-Toe/csharp/tictactoe2/Program.cs
    deleted file mode 100644
    index 59de85862..000000000
    --- a/89_Tic-Tac-Toe/csharp/tictactoe2/Program.cs
    +++ /dev/null
    @@ -1,232 +0,0 @@
    -// See https://aka.ms/new-console-template for more information
    -char[] board = new char[10];
    -char human;
    -char computer;
    -int move = 0;
    -char result;
    -for(;;){
    -    // Print text on the screen with 30 spaces before text
    -    Console.WriteLine("TIC TAC TOE".PadLeft(30));
    -    // Print text on screen with 15 spaces before text
    -    Console.WriteLine("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY".PadLeft(15));
    -    // THIS PROGRAM PLAYS TIC TAC TOE
    -    Console.WriteLine("THE BOARD IS NUMBERED:");
    -    Console.WriteLine("1  2  3");
    -    Console.WriteLine("4  5  6");
    -    Console.WriteLine("7  8  9");
    -    Console.Write("\n\nDO YOU WANT 'X' OR 'O'");
    -    var key = Console.ReadKey();
    -	Console.WriteLine();
    -	// cleanup the board
    -	for(int i=0; i < 10; i++) {
    -		board[i]=' ';
    -	}
    -	// X GOES FIRST
    -    if (key.Key == ConsoleKey.X) {
    -		human = 'X';
    -		computer = 'O';
    -		move = readYourMove();
    -		board[move] = human;
    -		printBoard();
    -    } else {
    -		human = 'O';
    -		computer = 'X';
    -    }
    -	for(;;){
    -		Console.WriteLine("THE COMPUTER MOVES TO...");
    -		move = computerMove(move);
    -		board[move] = computer;
    -		result = printBoard();
    -		printResult(result);
    -		move = readYourMove();
    -		board[move] = human;
    -		result = printBoard();
    -		printResult(result);
    -	}
    -}
    -
    -void printResult(int result) {
    -	if (result == '\0') {
    -		Console.WriteLine("IT'S A DRAW. THANK YOU.");
    -		Environment.Exit(0);
    -	} else if (result == computer) {
    -		Console.WriteLine("I WIN, TURKEY!!!");
    -		Environment.Exit(0);
    -	} else if (result == human) {
    -		Console.WriteLine("YOU BEAT ME!! GOOD GAME.");
    -		Environment.Exit(0);
    -	}
    -}
    -char printBoard() {
    -	for (int i=1; i < 10; i++){
    -		Console.Write($" {board[i]} ");
    -		if (i % 3 == 0) {
    -			if (i < 9) {
    -				Console.Write("\n---+---+---\n");
    -			} else {
    -				Console.Write("\n");
    -			}
    -		} else {
    -			Console.Write("!");
    -		}
    -	}
    -	// horizontal check
    -	for (int i = 1; i <= 9; i += 3) {
    -		if (board[i] != ' ' && (board[i] == board[i+1]) && (board[i+1] == board[i+2])) {
    -			return board[i];
    -		}
    -	}
    -	// vertical check
    -	for (int i = 1; i <= 3; i++) {
    -		if (board[i] != ' ' && (board[i] == board[i+3]) && (board[i] == board[i+6])) {
    -			return board[i];
    -		}
    -	}
    -	// cross
    -	if (board[5] != ' ') {
    -		if ((board[1] == board[5] && board[9] == board[5]) || (board[3] == board[5] && board[7] == board[5])) {
    -			return board[5];
    -		}
    -	}
    -	// draw check
    -	for (int i = 1; i <= 9; i++) {
    -		if (board[i] == ' ') {
    -			return ' ';
    -		}
    -	}
    -	return '\0';
    -}
    -
    -int readYourMove()  {
    -	int number = 0;
    -    for(;;) {
    -		Console.Write("\n\nWHERE DO YOU MOVE? ");
    -		var key = Console.ReadKey();
    -        Console.WriteLine();
    -		if (key.Key == ConsoleKey.D0) {
    -			Console.WriteLine("THANKS FOR THE GAME.");
    -            Environment.Exit(0);
    -        }
    -        if (key.Key >= ConsoleKey.D1 && key.Key <= ConsoleKey.D9) {
    -            number = key.Key - ConsoleKey.D0;
    -            if (number > 9 || board[number] != ' ') {
    -                Console.WriteLine("THAT SQUARE IS OCCUPIED.\n");
    -                continue;
    -            }
    -        }
    -		return number;
    -	}
    -}
    -
    -int getIndex(int number) {
    -	return ((number - 1) % 8) + 1; //number - 8 * (int)((number - 1) / 8);
    -}
    -int computerMove(int lastMove) {
    -	int[] boardMap = new int[] {0, 1, 2, 3, 6, 9, 8, 7, 4, 5};
    -	int index = Array.IndexOf(boardMap, lastMove);
    -	if (lastMove == 0 || board[5] == ' '){
    -		return 5;
    -	}
    -	if (lastMove == 5) {
    -		return 1;
    -	}
    -	if (board[5] == human) {
    -		// check possible win
    -		if (board[1] == computer && board[2] == ' ' && board[3] == computer) {
    -			return 2;
    -		}
    -		if (board[7] == computer && board[8] == ' ' && board[9] == computer) {
    -			return 8;
    -		}
    -		if (board[1] == computer && board[4] == ' ' && board[7] == computer) {
    -			return 4;
    -		}
    -		if (board[3] == computer && board[6] == ' ' && board[7] == computer) {
    -			return 6;
    -		}
    -		// check cross
    -		int crossIndex = boardMap[getIndex(index + 4)];
    -		if (board[crossIndex] == ' ') {
    -			return crossIndex;
    -		}
    -		int stepForward2 = boardMap[getIndex(index + 2)];
    -		if (board[stepForward2] == ' ') {
    -			return stepForward2;
    -		}
    -		int stepBackward2 = boardMap[getIndex(index + 6)];
    -		if (board[stepBackward2] == ' ') {
    -			return stepBackward2;
    -		}
    -		int stepForward1 = boardMap[getIndex(index + 1)];
    -		if (board[stepForward1] == ' ') {
    -			return stepForward1;
    -		}
    -		int stepBackward1 = boardMap[getIndex(index + 7)];
    -		if (board[stepBackward1] == ' ') {
    -			return stepBackward1;
    -		}
    -		int stepForward3 = boardMap[getIndex(index + 3)];
    -		if (board[stepForward3] == ' ') {
    -			return stepForward3;
    -		}
    -		int stepBackward3 = boardMap[getIndex(index + 5)];
    -		if (board[stepBackward3] == ' ') {
    -			return stepBackward3;
    -		}
    -	} else {
    -		// check possible win
    -		if (board[1] == computer && board[9] == ' ') {
    -			return 9;
    -		}
    -		if (board[9] == computer && board[1] == ' ') {
    -			return 1;
    -		}
    -		if (board[3] == computer && board[7] == ' ') {
    -			return 7;
    -		}
    -		if (board[7] == computer && board[3] == ' ') {
    -			return 3;
    -		}
    -		// if corner
    -		if (index % 2 == 1) {
    -			int stepForward2 = boardMap[getIndex(index + 2)];
    -			if (board[stepForward2] == ' ') {
    -				return stepForward2;
    -			}
    -			int stepBackward2 = boardMap[getIndex(index + 6)];
    -			if (board[stepBackward2] == ' ') {
    -				return stepBackward2;
    -			}
    -		} else {
    -			int stepForward1 = boardMap[getIndex(index + 1)];
    -			if (board[stepForward1] == ' ') {
    -				return stepForward1;
    -			}
    -			int stepBackward1 = boardMap[getIndex(index + 7)];
    -			if (board[stepBackward1] == ' ') {
    -				return stepBackward1;
    -			}
    -			int stepForward3 = boardMap[getIndex(index + 3)];
    -			if (board[stepForward3] == ' ') {
    -				return stepForward3;
    -			}
    -			int stepBackward3 = boardMap[getIndex(index + 5)];
    -			if (board[stepBackward3] == ' ') {
    -				return stepBackward3;
    -			}
    -					int crossIndex = boardMap[getIndex(index + 4)];
    -			if (board[crossIndex] == ' ') {
    -				return crossIndex;
    -			}
    -			int stepForward2 = boardMap[getIndex(index + 2)];
    -			if (board[stepForward2] == ' ') {
    -				return stepForward2;
    -			}
    -			int stepBackward2 = boardMap[getIndex(index + 6)];
    -			if (board[stepBackward2] == ' ') {
    -				return stepBackward2;
    -			}
    -		}
    -	}
    -	return 0;
    -}
    diff --git a/89_Tic-Tac-Toe/csharp/tictactoe2/tictactoe2.csproj b/89_Tic-Tac-Toe/csharp/tictactoe2/tictactoe2.csproj
    deleted file mode 100644
    index 74abf5c97..000000000
    --- a/89_Tic-Tac-Toe/csharp/tictactoe2/tictactoe2.csproj
    +++ /dev/null
    @@ -1,10 +0,0 @@
    -
    -
    -  
    -    Exe
    -    net6.0
    -    enable
    -    enable
    -  
    -
    -
    diff --git a/89_Tic-Tac-Toe/java/src/Board.java b/89_Tic-Tac-Toe/java/src/Board.java
    index 361643877..834c91cab 100644
    --- a/89_Tic-Tac-Toe/java/src/Board.java
    +++ b/89_Tic-Tac-Toe/java/src/Board.java
    @@ -11,8 +11,8 @@ public Board() {
             }
         }
     
    -
    -    /**
    +    
    +    /** 
          * Place 'X' or 'O' on the board position passed
          * @param position
          * @param player
    @@ -26,13 +26,13 @@ public void setArr(int position, char player) {
         }
     
         public void printBoard() {
    -        System.out.format("%-3c ! %-3c ! %-3c\n----+----+----\n%-3c ! %-3c ! %-3c\n----+----+----\n%-3c ! %-3c ! %-3c\n",
    +        System.out.format("%-3c ! %-3c ! %-3c\n----+----+----\n%-3c ! %-3c ! %-3c\n----+----+----\n%-3c ! %-3c ! %-3c\n", 
             this.arr[0], this.arr[1], this.arr[2], this.arr[3], this.arr[4], this.arr[5], this.arr[6], this.arr[7], this.arr[8]
             );
    -    }
    -
    +    }   
     
    -    /**
    +    
    +    /** 
          * @param x
          * @return the value of the char at a given position
          */
    @@ -40,37 +40,37 @@ public char getBoardValue(int x) {
             return arr[x-1];
         }
     
    -
    -    /**
    +    
    +    /** 
          * Go through the board and check for win (horizontal, diagonal, vertical)
          * @param player
          * @return whether a win has occured
          */
         public boolean checkWin(char player) {
    -        if(this.arr[0] == player && this.arr[1] == player && this.arr[2] == player)
    +        if(this.arr[0] == player && this.arr[1] == player && this.arr[2] == player) 
                 return true;
    +        
     
    -
    -        if(this.arr[3] == player && this.arr[4] == player && this.arr[5] == player)
    +        if(this.arr[3] == player && this.arr[4] == player && this.arr[5] == player) 
                 return true;
    +        
     
    -
    -        if(this.arr[6] == player && this.arr[7] == player && this.arr[8] == player)
    +        if(this.arr[6] == player && this.arr[7] == player && this.arr[8] == player) 
                 return true;
    -
    +        
             if(this.arr[0] == player && this.arr[4] == player && this.arr[8] == player)
                 return true;
    -
    +        
             if(this.arr[2] == player && this.arr[4] == player && this.arr[6] == player)
                 return true;
     
    -        if(this.arr[0] == player && this.arr[3] == player && this.arr[6] == player)
    +        if(this.arr[0] == player && this.arr[3] == player && this.arr[6] == player) 
                 return true;
     
    -        if(this.arr[1] == player && this.arr[4] == player && this.arr[7] == player)
    +        if(this.arr[1] == player && this.arr[4] == player && this.arr[7] == player) 
                 return true;
     
    -        if(this.arr[2] == player && this.arr[5] == player && this.arr[8] == player)
    +        if(this.arr[2] == player && this.arr[5] == player && this.arr[8] == player) 
                 return true;
     
             return false;
    @@ -80,9 +80,9 @@ public boolean checkDraw() {
                 if(this.getBoardValue(1) != ' ' && this.getBoardValue(2) != ' ' && this.getBoardValue(3) != ' ' && this.getBoardValue(4) != ' ' && this.getBoardValue(5) != ' ' && this.getBoardValue(6) != ' ' && this.getBoardValue(7) != ' ' && this.getBoardValue(8) != ' ' && this.getBoardValue(9) != ' ' ) {
                     return true;
                 }
    -        }
    -
    -        return false;
    +        } 
    +        
    +        return false; 
         }
         /**
          * Reset the board
    diff --git a/89_Tic-Tac-Toe/java/src/TicTacToe2.java b/89_Tic-Tac-Toe/java/src/TicTacToe2.java
    index a2467b9df..bda3793c6 100644
    --- a/89_Tic-Tac-Toe/java/src/TicTacToe2.java
    +++ b/89_Tic-Tac-Toe/java/src/TicTacToe2.java
    @@ -33,7 +33,6 @@ public static void main(String[] args) {
                         } else if (input == 'O' || input == 'o') {
                             yourChar = 'O';
                             compChar = 'X';
    -                        break;
                         } else {
                             System.out.println("THATS NOT 'X' OR 'O', TRY AGAIN");
                             in.nextLine();
    @@ -148,9 +147,9 @@ public static void main(String[] args) {
                                 System.out.println("THATS NOT 'Y' OR 'N', TRY AGAIN");
                                 in.nextLine();
                             }
    -                    }
    +                    } 
                         break;
    -                }
    +                } 
     
                 }
             }
    diff --git a/89_Tic-Tac-Toe/javascript/tictactoe1.html b/89_Tic-Tac-Toe/javascript/tictactoe1.html
    index 1c2cf7add..7aafc617b 100644
    --- a/89_Tic-Tac-Toe/javascript/tictactoe1.html
    +++ b/89_Tic-Tac-Toe/javascript/tictactoe1.html
    @@ -1,10 +1,9 @@
     
     
     TIC TAC TOE 1
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/89_Tic-Tac-Toe/javascript/tictactoe1.js b/89_Tic-Tac-Toe/javascript/tictactoe1.js
    index 8596febfc..fce4b7da4 100644
    --- a/89_Tic-Tac-Toe/javascript/tictactoe1.js
    +++ b/89_Tic-Tac-Toe/javascript/tictactoe1.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    @@ -78,19 +78,19 @@ async function main()
             print("\n");
             a = 9;
             m = a;
    -
    +        
             computer_moves();
             print("YOUR MOVE");
             m = parseInt(await input());
    -
    +        
             p = m;
             b = mf(p + 1);
             m = b;
    -
    +        
             computer_moves();
             print("YOUR MOVE");
             m = parseInt(await input());
    -
    +        
             q = m;
             if (q != mf(b + 4)) {
                 c = mf(b + 4);
    @@ -99,7 +99,7 @@ async function main()
                 print("AND WINS ********\n");
                 continue;
             }
    -
    +        
             c = mf(b + 2);
             m = c;
     
    @@ -115,7 +115,7 @@ async function main()
                 print("AND WINS ********\n");
                 continue;
             }
    -
    +        
             if (p % 2 == 0) {
                 d = mf(c + 7);
                 m = d;
    @@ -123,14 +123,14 @@ async function main()
                 print("AND WINS ********\n");
                 continue;
             }
    -
    +        
             d = mf(c + 3);
             m = d;
    -
    +        
             computer_moves();
             print("YOUR MOVE");
             m = parseInt(await input());
    -
    +        
             s = m;
             if (s != mf(d + 4)) {
                 e = mf(d + 4);
    diff --git a/89_Tic-Tac-Toe/javascript/tictactoe2.html b/89_Tic-Tac-Toe/javascript/tictactoe2.html
    index 02f200ea3..418bf65c3 100644
    --- a/89_Tic-Tac-Toe/javascript/tictactoe2.html
    +++ b/89_Tic-Tac-Toe/javascript/tictactoe2.html
    @@ -1,10 +1,9 @@
     
     
     TIC TAC TOE 2
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/89_Tic-Tac-Toe/javascript/tictactoe2.js b/89_Tic-Tac-Toe/javascript/tictactoe2.js
    index 9db5f99b7..beab1df6d 100644
    --- a/89_Tic-Tac-Toe/javascript/tictactoe2.js
    +++ b/89_Tic-Tac-Toe/javascript/tictactoe2.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/89_Tic-Tac-Toe/kotlin/Board.kt b/89_Tic-Tac-Toe/kotlin/Board.kt
    index e70d1be3b..287a8d370 100644
    --- a/89_Tic-Tac-Toe/kotlin/Board.kt
    +++ b/89_Tic-Tac-Toe/kotlin/Board.kt
    @@ -77,4 +77,4 @@ class Board {
         fun clear() {
             boxes = arrayOfNulls(9)
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/89_Tic-Tac-Toe/lua/README.md b/89_Tic-Tac-Toe/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/89_Tic-Tac-Toe/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/89_Tic-Tac-Toe/pascal/README.md b/89_Tic-Tac-Toe/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/89_Tic-Tac-Toe/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/89_Tic-Tac-Toe/perl/tictactoe2.pl b/89_Tic-Tac-Toe/perl/tictactoe2.pl
    index 4bc7cc0bd..0cbf4c10e 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,2,4,6,8,1,9,7,3);
    +		@precedence=(5,1,9,7,3,2,4,6,8);
     	}
     	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 "!" }
    diff --git a/89_Tic-Tac-Toe/python/TicTacToe_Hard.py b/89_Tic-Tac-Toe/python/TicTacToe_Hard.py
    deleted file mode 100644
    index 3a37cc6fe..000000000
    --- a/89_Tic-Tac-Toe/python/TicTacToe_Hard.py
    +++ /dev/null
    @@ -1,212 +0,0 @@
    -from typing import List, Tuple, Union
    -
    -
    -class TicTacToe:
    -    def __init__(self, pick, sz=3) -> None:
    -        self.pick = pick
    -        self.dim_sz = sz
    -        self.board = self.clear_board()
    -
    -    def clear_board(self) -> List[List[str]]:
    -        return [["blur" for _ in range(self.dim_sz)] for _ in range(self.dim_sz)]
    -
    -    def move_record(self, r, c) -> Union[str, bool]:
    -        if r > self.dim_sz or c > self.dim_sz:
    -            return "Out of Bounds"
    -        if self.board[r][c] != "blur":
    -            return "Spot Pre-Occupied"
    -        self.board[r][c] = self.pick
    -        return True
    -
    -    def check_win(self) -> int:  # 1 you won, 0 computer won, -1 tie
    -        # Flag syntax -> first player no. ,
    -        # User is Player#1 ;
    -        # Check set 1 -> row and '\' diagonal & Check set 2 -> col and '/' diagonal
    -
    -        for i in range(0, self.dim_sz):  # Rows
    -            flag11 = True
    -            flag21 = True
    -
    -            flag12 = True
    -            flag22 = True
    -            for j in range(0, self.dim_sz):
    -
    -                ch2 = self.board[i][j]
    -                ch1 = self.board[j][i]
    -                # Row
    -                if ch1 == self.pick:  # if it's mine, computer didn't make it
    -                    flag21 = False
    -                elif ch1 == "blur":  # if it's blank no one made it
    -                    flag11 = False
    -                    flag21 = False
    -                else:
    -                    flag11 = False  # else i didn't make it
    -
    -                if ch2 == self.pick:  # Same but for Col
    -                    flag22 = False
    -                elif ch2 == "blur":
    -                    flag12 = False
    -                    flag22 = False
    -                else:
    -                    flag12 = False
    -
    -            if flag11 is True or flag12 is True:  # I won
    -                return 1
    -            if flag21 is True or flag22 is True:  # Computer Won
    -                return 0
    -
    -        # Diagonals#
    -        flag11 = True
    -        flag21 = True
    -
    -        flag12 = True
    -        flag22 = True
    -        for i in range(0, self.dim_sz):
    -
    -            ch2 = self.board[i][i]
    -            ch1 = self.board[i][self.dim_sz - 1 - i]
    -
    -            if ch1 == self.pick:
    -                flag21 = False
    -            elif ch1 == "blur":
    -                flag11 = False
    -                flag21 = False
    -            else:
    -                flag11 = False
    -
    -            if ch2 == self.pick:
    -                flag22 = False
    -            elif ch2 == "blur":
    -                flag12 = False
    -                flag22 = False
    -            else:
    -                flag12 = False
    -
    -        if flag11 or flag12:
    -            return 1
    -        return 0 if flag21 or flag22 else -1
    -
    -    def next_move(self) -> Union[Tuple[int, int], Tuple[List[int], List[int]]]:
    -        available_moves = []  # will carry all available moves
    -        player_win_spot = []  # if player (user Wins)
    -        comp_pick = "X" if self.pick == "O" else "O"
    -        for i in range(0, self.dim_sz):
    -            for j in range(0, self.dim_sz):
    -
    -                if self.board[i][j] == "blur":  # BLANK
    -                    t = (i, j)
    -                    available_moves.append(t)  # add it to available moves
    -                    self.board[i][j] = comp_pick  # Check if I (Computer can win)
    -                    if self.check_win() == 0:  # Best Case I(Computer) win!
    -                        return i, j
    -                    self.board[i][j] = self.pick
    -                    if (
    -                        self.check_win() == 1
    -                    ):  # Second Best Case, he (player) didn't won
    -                        player_win_spot.append(t)
    -                    self.board[i][j] = "blur"
    -
    -        if player_win_spot:
    -            self.board[player_win_spot[0][0]][player_win_spot[0][1]] = comp_pick
    -            return player_win_spot[0][0], player_win_spot[0][1]
    -        if len(available_moves) == 1:
    -            self.board[available_moves[0][0]][available_moves[0][1]] = comp_pick
    -            return [available_moves[0][0]], [available_moves[0][1]]
    -        if not available_moves:
    -            return -1, -1
    -
    -        c1, c2 = self.dim_sz // 2, self.dim_sz // 2
    -        if (c1, c2) in available_moves:  # CENTER
    -            self.board[c1][c2] = comp_pick
    -            return c1, c2
    -        for i in range(c1 - 1, -1, -1):  # IN TO OUT
    -            gap = c1 - i
    -            # checking  - 4 possibilities at max
    -            # EDGES
    -            if (c1 - gap, c2 - gap) in available_moves:
    -                self.board[c1 - gap][c2 - gap] = comp_pick
    -                return c1 - gap, c2 - gap
    -            if (c1 - gap, c2 + gap) in available_moves:
    -                self.board[c1 - gap][c2 + gap] = comp_pick
    -                return c1 - gap, c2 + gap
    -            if (c1 + gap, c2 - gap) in available_moves:
    -                self.board[c1 + gap][c2 - gap] = comp_pick
    -                return c1 + gap, c2 - gap
    -            if (c1 + gap, c2 + gap) in available_moves:
    -                self.board[c1 + gap][c2 + gap] = comp_pick
    -                return c1 + gap, c2 + gap
    -
    -            # Four Lines
    -
    -            for i in range(0, gap):
    -                if (c1 - gap, c2 - gap + i) in available_moves:  # TOP LEFT TO TOP RIGHT
    -                    self.board[c1 - gap][c2 - gap + i] = comp_pick
    -                    return c1 - gap, c2 - gap + i
    -                if (
    -                    c1 + gap,
    -                    c2 - gap + i,
    -                ) in available_moves:  # BOTTOM LEFT TO BOTTOM RIGHT
    -                    self.board[c1 + gap][c2 - gap + i] = comp_pick
    -                    return c1 + gap, c2 - gap + i
    -                if (c1 - gap, c2 - gap) in available_moves:  # LEFT TOP TO LEFT BOTTOM
    -                    self.board[c1 - gap + i][c2 - gap] = comp_pick
    -                    return c1 - gap + i, c2 - gap
    -                if (
    -                    c1 - gap + i,
    -                    c2 + gap,
    -                ) in available_moves:  # RIGHT TOP TO RIGHT BOTTOM
    -                    self.board[c1 - gap + i][c2 + gap] = comp_pick
    -                    return c1 - gap + i, c2 + gap
    -        raise RuntimeError("No moves available")
    -
    -
    -def display(game: TicTacToe) -> None:
    -    line1 = ""
    -    for i in range(0, game.dim_sz):
    -        for j in range(0, game.dim_sz - 1):
    -            if game.board[i][j] == "blur":
    -                line1 = f"{line1}    |"
    -            else:
    -                line1 = f"{line1}  {game.board[i][j]} |"
    -        if game.board[i][game.dim_sz - 1] == "blur":
    -            line1 = line1 + "    \n"
    -        else:
    -            line1 = f"{line1}  {game.board[i][game.dim_sz - 1]} \n"
    -    print(line1, "\n\n")
    -
    -
    -def main() -> None:
    -    pick = input("Pick 'X' or 'O' ").strip().upper()
    -    game = TicTacToe("O") if pick == "O" else TicTacToe("X")
    -    display(game=game)
    -    while True:
    -        temp: Union[bool, str] = False
    -        while not temp:
    -            move = list(
    -                map(
    -                    int,
    -                    input("Make A Move in Grid System from (0,0) to (2,2) ").split(),
    -                )
    -            )
    -            temp = game.move_record(move[0], move[1])
    -            if not temp:
    -                print(temp)
    -
    -        if game.check_win() == 1:
    -            print("You Won!")
    -            break
    -        print("Your Move:- ")
    -        display(game)
    -        C1, C2 = game.next_move()
    -        if C1 == -1 and C2 == -1:
    -            print("Game Tie!")
    -            break
    -        if game.check_win() == 0:
    -            print("You lost!")
    -            break
    -        print("Computer's Move :-")
    -        display(game)
    -
    -
    -if __name__ == "__main__":
    -    main()
    diff --git a/89_Tic-Tac-Toe/python/tictactoe2.py b/89_Tic-Tac-Toe/python/tictactoe2.py
    index e6fce18a2..181e86ebf 100755
    --- a/89_Tic-Tac-Toe/python/tictactoe2.py
    +++ b/89_Tic-Tac-Toe/python/tictactoe2.py
    @@ -3,16 +3,16 @@
     
     
     class OccupiedBy(Enum):
    -    COMPUTER = -1
    -    EMPTY = 0
    -    PLAYER = 1
    +    COMPUTER=-1
    +    EMPTY=0
    +    PLAYER=1
     
     
     class Winner(Enum):
    -    NONE = 0
    -    COMPUTER = 1
    -    PLAYER = 2
    -    DRAW = 3
    +    NONE=0
    +    COMPUTER=1
    +    PLAYER=2
    +    DRAW=3
     
     
     class Space(Enum):
    @@ -28,55 +28,55 @@ class Space(Enum):
     
     
     def line_170(board, g, h, j, k):
    -    if g == OccupiedBy.Player and board[Space.MID_CENTER] == g:
    -        if (
    -            board[Space.TOP_RIGHT] == g and board[Space.BOTTOM_LEFT] is OccupiedBy.EMPTY
    -        ):  # Line 171
    -            return Space.BOTTOM_LEFT  # Line 187
    -        elif (
    -            board[Space.BOTTOM_RIGHT] == g and board[Space.TOP_LEFT] is OccupiedBy.EMPTY
    -        ):  # Line 172
    -            return Space.TOP_LEFT  # Line 181
    -        elif (
    -            board[Space.BOTTOM_LEFT] == g and board[Space.TOP_RIGHT] is OccupiedBy.EMPTY
    -        ) or (
    -            board[Space.BOTTOM_RIGHT] is OccupiedBy.PLAYER
    -            and board[Space.TOP_RIGHT] is OccupiedBy.EMPTY
    -        ):  # Line 173 and 174
    -            return Space.TOP_RIGHT  # Line 183 and Line 189
    -        elif g is OccupiedBy.COMPUTER:
    -            g = OccupiedBy.PLAYER
    -            h = OccupiedBy.COMPUTER
    -            return line_118(board, g, h, j, k)
    +    if g == OccupiedBy.Player:
    +        if board[Space.MID_CENTER] == g:
    +            if board[Space.TOP_RIGHT] == g and board[Space.BOTTOM_LEFT] is OccupiedBy.EMPTY: # Line 171
    +                return Space.BOTTOM_LEFT # Line 187
    +            elif board[Space.BOTTOM_RIGHT] == g and board[Space.TOP_LEFT] is OccupiedBy.EMPTY: # Line 172
    +                return Space.TOP_LEFT # Line 181
    +            elif board[Space.BOTTOM_LEFT] == g and board[Space.TOP_RIGHT] is OccupiedBy.EMPTY: # Line 173
    +                return Space.TOP_RIGHT # Line 183
    +            elif board[Space.BOTTOM_RIGHT] is OccupiedBy.PLAYER and board[Space.TOP_RIGHT] is OccupiedBy.EMPTY: # Line 174
    +                return Space.TOP_RIGHT # Line 189
    +            elif g is OccupiedBy.COMPUTER:
    +                g = OccupiedBy.PLAYER
    +                h = OccupiedBy.COMPUTER
    +                return line_118(board, g, h, j, k)
     
     
     def line_150(board, g, h, j, k):
    -    if board[k] != g:  # line 150
    -        return (
    -            -1
    -            if (
    -                board[k] == h  # line 160
    -                or board[k + 6] != g  # line 161
    -                or board[k + 3] != g
    -            )
    -            else k + 3
    -        )
    -    elif board[k + 6] != g:  # line 152
    -        if board[k + 6] != 0 or board[k + 3] != g:  # line 165
    -            return -1  # Goto 170
    -    elif board[k + 3]:  # line 156
    -        return -1
    +    if board[k] != g: # line 150
    +        if (board[k] == h       # line 160
    +            or board[k + 6] != g   # line 161
    +            or board[k + 3] != g): # line 162
    +            return -1 # Goto 170
    +        else:
    +            return k + 3  # Line 163
    +    elif board[k + 6] != g: # line 152
    +        if board[k + 6] != 0 or board[k + 3] != g: # line 165
    +            return -1 # Goto 170
    +    elif board[k + 3]: # line 156
    +        return - 1
     
         return k + 6
     
     
     def line_120(board, g, h, j, k):
    -    pass
    +    if board[j] != g:
    +        if board[j] == h or board[j+2] != g or board[j+1] != g:
    +            if board[k] != g:
    +                if board[k + 6] != g and (board[k + 6] != 0 or board[k+3] != g):
    +                    # 450 IF G=1 THEN 465
    +                    pass
    +            elif board[j + 2] is not g: # Line 122
    +                pass
    +            elif board[j + 1] is not OccupiedBy.EMPTY:
    +                pass
     
     
     def line_118(board, g, h):
         for j in range(7):
    -        for k in range(3):
    +        for k in range (3):
                 return line_120(board, g, h, j, k)
     
     
    @@ -86,75 +86,61 @@ def think(board, g, h, moves):
             return Space.MID_CENTER
     
         if board[Space.MID_CENTER] is OccupiedBy.PLAYER:
    -        if (
    -            board[Space.TOP_CENTER] is OccupiedBy.PLAYER
    -            and board[Space.TOP_LEFT] is OccupiedBy.EMPTY
    -            or board[Space.MID_LEFT] is OccupiedBy.PLAYER
    -            and board[Space.TOP_LEFT] is OccupiedBy.EMPTY
    -        ):
    -            return Space.BOT_LEFT
    -        elif (
    -            board[Space.MID_RIGHT] is OccupiedBy.PLAYER
    -            and board[Space.BOT_RIGHT] is OccupiedBy.EMPTY
    -            or board[Space.BOT_CENTER] is OccupiedBy.PLAYER
    -            and board[Space.BOT_RIGHT] is OccupiedBy.EMPTY
    -        ):
    -            return Space.BOT_RIGHT
    +        if board[Space.TOP_CENTER] is OccupiedBy.PLAYER and board[Space.TOP_LEFT] is OccupiedBy.EMPTY \
    +           or board[Space.MID_LEFT] is OccupiedBy.PLAYER and board[Space.TOP_LEFT] is OccupiedBy.EMPTY:
    +             return Space.BOT_LEFT
    +        elif board[Space.MID_RIGHT] is OccupiedBy.PLAYER and board[Space.BOT_RIGHT] is OccupiedBy.EMPTY \
    +           or board[Space.BOT_CENTER] is OccupiedBy.PLAYER and board[Space.BOT_RIGHT] is OccupiedBy.EMPTY:
    +             return Space.BOT_RIGHT
     
         if g == OccupiedBy.PLAYER:
    -        j = 3 * int((moves - 1) / 3)
    -        if move == j + 1:  # noqa: This definitely is a bug!
    +        j = 3 * int((moves-1) / 3)
    +        if move == j + 1:
                 k = 1
    -        if move == j + 2:  # noqa: This definitely is a bug!
    +        if move == j + 2:
                 k = 2
    -        if move == j + 3:  # noqa: This definitely is a bug!
    +        if move == j + 3:
                 k = 3
    -        return subthink(g, h, j, k)  # noqa: This definitely is a bug!
    +        return subthink(g, h, j, k)
     
     
     def render_board(board, space_mapping):
    -    vertical_divider = "!"
    -    horizontal_divider = "---+---+---"
    -    lines = [
    -        vertical_divider.join(space_mapping[space] for space in board[:3]),
    -        horizontal_divider,
    -        vertical_divider.join((space_mapping[space] for space in board[3:6])),
    -        horizontal_divider,
    -        vertical_divider.join((space_mapping[space] for space in board[6:9])),
    -    ]
    -    return "\n".join(lines)
    +    vertical_divider = '!'
    +    horizontal_divider = '---+---+---'
    +    lines = []
    +    lines.append(vertical_divider.join(space_mapping[space] for space in board[0:3]))
    +    lines.append(horizontal_divider)
    +    lines.append(vertical_divider.join(space_mapping[space] for space in board[3:6]))
    +    lines.append(horizontal_divider)
    +    lines.append(vertical_divider.join(space_mapping[space] for space in board[6:9]))
    +    return '\n'.join(lines)
     
     
     def determine_winner(board, g):
         # Check for matching horizontal lines
    -    for i in range(Space.TOP_LEFT.value, Space.BOT_LEFT.value + 1, 3):  # Line 1095
    -        if board[i] != board[i + 1] or board[i] != board[i + 2]:  # Lines 1100 and 1105
    -            continue  # First third of Line 1115
    -        elif board[i] == OccupiedBy.COMPUTER:  #
    +    for i in range(Space.TOP_LEFT.value, Space.BOT_LEFT.value + 1, 3):      # Line 1095
    +        if board[i] != board[i+1] or board[i] != board[i+2]:  # Lines 1100 and 1105
    +            continue # First third of Line 1115 
    +        elif board[i] == OccupiedBy.COMPUTER: # 
                 return Winner.COMPUTER
             elif board[i] == OccupiedBy.PLAYER:
                 return Winner.PLAYER
     
         # Check for matching vertical lines
    -    for i in range(
    -        Space.TOP_LEFT.value, Space.TOP_RIGHT.value + 1, 1
    -    ):  # Second third of Line 1115
    -        if (
    -            board[i] != board[i + 3] or board[i] != board[i + 6]
    -        ):  # Last third of Line 1115
    -            continue  # First third of 1150
    -        elif board[i] == OccupiedBy.COMPUTER:  # Line 1135
    +    for i in range(Space.TOP_LEFT.value, Space.TOP_RIGHT.value + 1, 1):  # Second third of Line 1115
    +        if board[i] != board[i+3] or board[i] != board[i+6]: # Last third of Line 1115
    +            continue # First third of 1150
    +        elif board[i] == OccupiedBy.COMPUTER: # Line 1135
                 return Winner.COMPUTER
    -        elif board[i] == OccupiedBy.PLAYER:  # Line 1137
    +        elif board[i] == OccupiedBy.PLAYER:   # Line 1137
                 return Winner.PLAYER
     
         # Check diagonals
         if any(space is OccupiedBy.EMPTY for space in board):
             if board[Space.MID_CENTER.value] != g:
                 return Winner.NONE
    -        elif (
    -            board[Space.TOP_LEFT.value] == g and board[Space.BOT_RIGHT.value] == g
    -        ) or (board[Space.BOT_LEFT.value] == g and board[Space.TOP_RIGHT.value] == g):
    +        elif (board[Space.TOP_LEFT.value] == g and board[Space.BOT_RIGHT.value] == g) or \
    +            (board[Space.BOT_LEFT.value] == g and board[Space.TOP_RIGHT.value] == g):
                 return Winner.COMPUTER if g is OccupiedBy.COMPUTER else Winner.PLAYER
             else:
                 return Winner.NONE
    @@ -163,11 +149,10 @@ def determine_winner(board, g):
     
     
     def computer_think(board):
    -    empty_indices = [
    -        index for index, space in enumerate(board) if space is OccupiedBy.EMPTY
    -    ]
    +        empty_indices = [index for index, space in enumerate(board)
    +                         if space is OccupiedBy.EMPTY]
     
    -    return empty_indices[0]
    +        return empty_indices[0]
     
     
     def prompt_player(board):
    @@ -184,24 +169,24 @@ def prompt_player(board):
             return move
     
     
    -def main() -> None:
    -    print(" " * 30 + "TIC-TAC-TOE")
    -    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
    -    print("\n\n")
    +def play():
    +    print(' '*30 + 'TIC-TAC-TOE')
    +    print(' '*15 + 'CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY')
    +    print('\n\n')
     
    -    print("THE BOARD IS NUMBERED:")
    -    print(" 1  2  3")
    -    print(" 4  5  6")
    -    print(" 7  8  9")
    -    print("\n\n")
    +    print('THE BOARD IS NUMBERED:')
    +    print(' 1  2  3')
    +    print(' 4  5  6')
    +    print(' 7  8  9')
    +    print('\n\n')
     
         # Default state
         board = [OccupiedBy.EMPTY] * 9
         current_player = OccupiedBy.PLAYER
         space_mapping = {
    -        OccupiedBy.EMPTY: "   ",
    -        OccupiedBy.PLAYER: " X ",
    -        OccupiedBy.COMPUTER: " O ",
    +        OccupiedBy.EMPTY: '   ',
    +        OccupiedBy.PLAYER: ' X ',
    +        OccupiedBy.COMPUTER: ' O '
         }
     
         symbol = input("DO YOU WANT 'X' OR 'O'? ").upper()
    @@ -209,8 +194,8 @@ def main() -> None:
         # If the player doesn't choose X, then assume you want O
         # and the computer goes first.
         if symbol != "X":
    -        space_mapping[OccupiedBy.PLAYER] = " O "
    -        space_mapping[OccupiedBy.COMPUTER] = " X "
    +        space_mapping[OccupiedBy.PLAYER] = ' O '
    +        space_mapping[OccupiedBy.COMPUTER] = ' X '
             current_player = OccupiedBy.COMPUTER
     
         while True:
    @@ -230,8 +215,8 @@ def main() -> None:
             winner = determine_winner(board, current_player)
     
             if winner is not Winner.NONE:
    -            print(winner)
    -            break
    +           print(winner)
    +           break
     
             if current_player is OccupiedBy.COMPUTER:
                 current_player = OccupiedBy.PLAYER
    @@ -239,5 +224,5 @@ def main() -> None:
                 current_player = OccupiedBy.COMPUTER
     
     
    -if __name__ == "__main__":
    -    main()
    +if __name__ == '__main__':
    +    play()
    diff --git a/89_Tic-Tac-Toe/rust/Cargo.lock b/89_Tic-Tac-Toe/rust/Cargo.lock
    deleted file mode 100644
    index b21cc6a2d..000000000
    --- a/89_Tic-Tac-Toe/rust/Cargo.lock
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    diff --git a/89_Tic-Tac-Toe/rust/Cargo.toml b/89_Tic-Tac-Toe/rust/Cargo.toml
    deleted file mode 100644
    index 39d7d04bb..000000000
    --- a/89_Tic-Tac-Toe/rust/Cargo.toml
    +++ /dev/null
    @@ -1,4 +0,0 @@
    -[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
    deleted file mode 100644
    index 7ff91cd1b..000000000
    --- a/89_Tic-Tac-Toe/rust/README.md
    +++ /dev/null
    @@ -1,5 +0,0 @@
    -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
    deleted file mode 100644
    index 5aab976b5..000000000
    --- a/89_Tic-Tac-Toe/rust/src/main.rs
    +++ /dev/null
    @@ -1,110 +0,0 @@
    -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]
    -    );
    -}
    diff --git a/89_Tic-Tac-Toe/vbnet/TicTacToe.sln b/89_Tic-Tac-Toe/vbnet/TicTacToe.sln
    deleted file mode 100644
    index 479356240..000000000
    --- a/89_Tic-Tac-Toe/vbnet/TicTacToe.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 5bac9e9e4..000000000
    --- a/89_Tic-Tac-Toe/vbnet/TicTacToe.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    TicTacToe
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/90_Tower/README.md b/90_Tower/README.md
    index f98078c18..cbd05830c 100644
    --- a/90_Tower/README.md
    +++ b/90_Tower/README.md
    @@ -18,7 +18,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/90_Tower/csharp/Resources/DiskCountPrompt.txt b/90_Tower/csharp/Resources/DiskCountPrompt.txt
    deleted file mode 100644
    index 454960fc6..000000000
    --- a/90_Tower/csharp/Resources/DiskCountPrompt.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -How many disks do you want to move (7 is max)
    diff --git a/90_Tower/csharp/Resources/DiskCountQuit.txt b/90_Tower/csharp/Resources/DiskCountQuit.txt
    deleted file mode 100644
    index b33b3c51d..000000000
    --- a/90_Tower/csharp/Resources/DiskCountQuit.txt
    +++ /dev/null
    @@ -1,2 +0,0 @@
    -All right, wise guy, if you can't play the game right, I'll
    -just take my puzzle and go home.  So long.
    diff --git a/90_Tower/csharp/Resources/DiskCountRetry.txt b/90_Tower/csharp/Resources/DiskCountRetry.txt
    deleted file mode 100644
    index 4857ffa41..000000000
    --- a/90_Tower/csharp/Resources/DiskCountRetry.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Sorry, but i can't do that job for you.
    diff --git a/90_Tower/csharp/Resources/DiskNotInPlay.txt b/90_Tower/csharp/Resources/DiskNotInPlay.txt
    deleted file mode 100644
    index 817e8455c..000000000
    --- a/90_Tower/csharp/Resources/DiskNotInPlay.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -That disk is not in play.  Make another choice.
    diff --git a/90_Tower/csharp/Resources/DiskPrompt.txt b/90_Tower/csharp/Resources/DiskPrompt.txt
    deleted file mode 100644
    index 91f2583c5..000000000
    --- a/90_Tower/csharp/Resources/DiskPrompt.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Which disk would you like to move
    diff --git a/90_Tower/csharp/Resources/DiskQuit.txt b/90_Tower/csharp/Resources/DiskQuit.txt
    deleted file mode 100644
    index 240fe7d25..000000000
    --- a/90_Tower/csharp/Resources/DiskQuit.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Stop wasting my time.  Go bother someone else.
    diff --git a/90_Tower/csharp/Resources/DiskRetry.txt b/90_Tower/csharp/Resources/DiskRetry.txt
    deleted file mode 100644
    index 5927a86db..000000000
    --- a/90_Tower/csharp/Resources/DiskRetry.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Illegal entry... You may only type 3, 5, 7, 9, 11, 13, or 15.
    diff --git a/90_Tower/csharp/Resources/DiskUnavailable.txt b/90_Tower/csharp/Resources/DiskUnavailable.txt
    deleted file mode 100644
    index 1ce62e02d..000000000
    --- a/90_Tower/csharp/Resources/DiskUnavailable.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -That disk is below another one.  Make another choice.
    diff --git a/90_Tower/csharp/Resources/IllegalMove.txt b/90_Tower/csharp/Resources/IllegalMove.txt
    deleted file mode 100644
    index ccb425e72..000000000
    --- a/90_Tower/csharp/Resources/IllegalMove.txt
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -You can't place a larger disk on top of a smaller one,
    -it might crush it!
    -Now then,
    diff --git a/90_Tower/csharp/Resources/Instructions.txt b/90_Tower/csharp/Resources/Instructions.txt
    deleted file mode 100644
    index 93c71b8d8..000000000
    --- a/90_Tower/csharp/Resources/Instructions.txt
    +++ /dev/null
    @@ -1,10 +0,0 @@
    -In this program, we shall refer to disks by numerical code.
    -3 will represent the smallest disk, 5 the next size,
    -7 the next, and so on, up to 15.  If you do the puzzle with
    -2 disks, their code names would be 13 and 15.  With 3 disks
    -the code names would be 11, 13 and 15, etc.  The needles
    -are numbered from left to right, 1 to 3.  We will
    -startup with the disks on needle 1, and attempt to move them
    -to needle 3.
    -
    -Good luck!
    diff --git a/90_Tower/csharp/Resources/Intro.txt b/90_Tower/csharp/Resources/Intro.txt
    deleted file mode 100644
    index 160d81761..000000000
    --- a/90_Tower/csharp/Resources/Intro.txt
    +++ /dev/null
    @@ -1,6 +0,0 @@
    -
    -Towers of Hanoi puzzle.
    -
    -You must transfer the disks from the left to the right
    -tower, one at a time, never putting a larger dish on a
    -smaller disk.
    diff --git a/90_Tower/csharp/Resources/NeedlePrompt.txt b/90_Tower/csharp/Resources/NeedlePrompt.txt
    deleted file mode 100644
    index 9d70b47b8..000000000
    --- a/90_Tower/csharp/Resources/NeedlePrompt.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Place disk on which needle
    diff --git a/90_Tower/csharp/Resources/NeedleQuit.txt b/90_Tower/csharp/Resources/NeedleQuit.txt
    deleted file mode 100644
    index 942298e44..000000000
    --- a/90_Tower/csharp/Resources/NeedleQuit.txt
    +++ /dev/null
    @@ -1,2 +0,0 @@
    -I tried to warn you, but you wouldn't listen,
    -Bye bye, big shot.
    diff --git a/90_Tower/csharp/Resources/NeedleRetry.txt b/90_Tower/csharp/Resources/NeedleRetry.txt
    deleted file mode 100644
    index 2c4a2286f..000000000
    --- a/90_Tower/csharp/Resources/NeedleRetry.txt
    +++ /dev/null
    @@ -1,2 +0,0 @@
    -I'll assume you hit the wrong key this time.  But watch it,
    -I only allow one mistake
    diff --git a/90_Tower/csharp/Resources/PlayAgainPrompt.txt b/90_Tower/csharp/Resources/PlayAgainPrompt.txt
    deleted file mode 100644
    index 793486ddb..000000000
    --- a/90_Tower/csharp/Resources/PlayAgainPrompt.txt
    +++ /dev/null
    @@ -1,2 +0,0 @@
    -
    -Try again (Yes or No)
    diff --git a/90_Tower/csharp/Resources/TaskFinished.txt b/90_Tower/csharp/Resources/TaskFinished.txt
    deleted file mode 100644
    index 454bc1f41..000000000
    --- a/90_Tower/csharp/Resources/TaskFinished.txt
    +++ /dev/null
    @@ -1,2 +0,0 @@
    -
    -You have performed the task in {0} moves.
    diff --git a/90_Tower/csharp/Resources/Title.txt b/90_Tower/csharp/Resources/Title.txt
    deleted file mode 100644
    index af05e12ed..000000000
    --- a/90_Tower/csharp/Resources/Title.txt
    +++ /dev/null
    @@ -1,2 +0,0 @@
    -                                 Towers
    -               Creative Computing  Morristown, New Jersey
    diff --git a/90_Tower/csharp/Resources/YesNoPrompt.txt b/90_Tower/csharp/Resources/YesNoPrompt.txt
    deleted file mode 100644
    index c4539f5a2..000000000
    --- a/90_Tower/csharp/Resources/YesNoPrompt.txt
    +++ /dev/null
    @@ -1,2 +0,0 @@
    -
    -'Yes' or 'No' please
    diff --git a/90_Tower/csharp/Tower.sln b/90_Tower/csharp/Tower.sln
    index 6f87b0b98..2c6e524d6 100644
    --- a/90_Tower/csharp/Tower.sln
    +++ b/90_Tower/csharp/Tower.sln
    @@ -1,25 +1,34 @@
     
     Microsoft Visual Studio Solution File, Format Version 12.00
    -# Visual Studio Version 17
    -VisualStudioVersion = 17.0.32014.148
    +# Visual Studio 15
    +VisualStudioVersion = 15.0.26124.0
     MinimumVisualStudioVersion = 15.0.26124.0
    -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tower", "Tower.csproj", "{EEED33AD-3DE2-49AA-8AF1-2174C510E128}"
    +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tower", "tower\Tower.csproj", "{2E14FCD5-A52C-4292-A7F4-0C7E5780C962}"
     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
    -	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
    +		Release|x64 = Release|x64
    +		Release|x86 = Release|x86
     	EndGlobalSection
     	GlobalSection(SolutionProperties) = preSolution
     		HideSolutionNode = FALSE
     	EndGlobalSection
    -	GlobalSection(ExtensibilityGlobals) = postSolution
    -		SolutionGuid = {BDCB8278-62ED-46E3-92C2-FF572E0E3ED3}
    +	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
     	EndGlobalSection
     EndGlobal
    diff --git a/90_Tower/csharp/Game.cs b/90_Tower/csharp/Tower/Game.cs
    similarity index 100%
    rename from 90_Tower/csharp/Game.cs
    rename to 90_Tower/csharp/Tower/Game.cs
    diff --git a/90_Tower/csharp/Models/Needle.cs b/90_Tower/csharp/Tower/Models/Needle.cs
    similarity index 99%
    rename from 90_Tower/csharp/Models/Needle.cs
    rename to 90_Tower/csharp/Tower/Models/Needle.cs
    index 8ea67aa4f..1cd929faa 100644
    --- a/90_Tower/csharp/Models/Needle.cs
    +++ b/90_Tower/csharp/Tower/Models/Needle.cs
    @@ -30,4 +30,4 @@ public IEnumerator GetEnumerator() =>
     
             IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/90_Tower/csharp/Models/Towers.cs b/90_Tower/csharp/Tower/Models/Towers.cs
    similarity index 99%
    rename from 90_Tower/csharp/Models/Towers.cs
    rename to 90_Tower/csharp/Tower/Models/Towers.cs
    index 0625a5b75..4b03b933b 100644
    --- a/90_Tower/csharp/Models/Towers.cs
    +++ b/90_Tower/csharp/Tower/Models/Towers.cs
    @@ -84,4 +84,4 @@ public TowersEnumerator(Needle[] needles)
                 public void Reset() => _enumerators.ForEach(e => e.Reset());
             }
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/90_Tower/csharp/Program.cs b/90_Tower/csharp/Tower/Program.cs
    similarity index 100%
    rename from 90_Tower/csharp/Program.cs
    rename to 90_Tower/csharp/Tower/Program.cs
    diff --git a/90_Tower/csharp/Resources/Congratulations.txt b/90_Tower/csharp/Tower/Resources/Congratulations.txt
    similarity index 100%
    rename from 90_Tower/csharp/Resources/Congratulations.txt
    rename to 90_Tower/csharp/Tower/Resources/Congratulations.txt
    diff --git a/90_Tower/csharp/Tower/Resources/DiskCountPrompt.txt b/90_Tower/csharp/Tower/Resources/DiskCountPrompt.txt
    new file mode 100644
    index 000000000..a45c3461d
    --- /dev/null
    +++ b/90_Tower/csharp/Tower/Resources/DiskCountPrompt.txt
    @@ -0,0 +1 @@
    +How many disks do you want to move (7 is max)
    \ No newline at end of file
    diff --git a/90_Tower/csharp/Tower/Resources/DiskCountQuit.txt b/90_Tower/csharp/Tower/Resources/DiskCountQuit.txt
    new file mode 100644
    index 000000000..b573854da
    --- /dev/null
    +++ b/90_Tower/csharp/Tower/Resources/DiskCountQuit.txt
    @@ -0,0 +1,2 @@
    +All right, wise guy, if you can't play the game right, I'll
    +just take my puzzle and go home.  So long.
    \ No newline at end of file
    diff --git a/90_Tower/csharp/Tower/Resources/DiskCountRetry.txt b/90_Tower/csharp/Tower/Resources/DiskCountRetry.txt
    new file mode 100644
    index 000000000..c8ec4b102
    --- /dev/null
    +++ b/90_Tower/csharp/Tower/Resources/DiskCountRetry.txt
    @@ -0,0 +1 @@
    +Sorry, but i can't do that job for you.
    \ No newline at end of file
    diff --git a/90_Tower/csharp/Tower/Resources/DiskNotInPlay.txt b/90_Tower/csharp/Tower/Resources/DiskNotInPlay.txt
    new file mode 100644
    index 000000000..270ed0a58
    --- /dev/null
    +++ b/90_Tower/csharp/Tower/Resources/DiskNotInPlay.txt
    @@ -0,0 +1 @@
    +That disk is not in play.  Make another choice.
    \ No newline at end of file
    diff --git a/90_Tower/csharp/Tower/Resources/DiskPrompt.txt b/90_Tower/csharp/Tower/Resources/DiskPrompt.txt
    new file mode 100644
    index 000000000..a7f127dbf
    --- /dev/null
    +++ b/90_Tower/csharp/Tower/Resources/DiskPrompt.txt
    @@ -0,0 +1 @@
    +Which disk would you like to move
    \ No newline at end of file
    diff --git a/90_Tower/csharp/Tower/Resources/DiskQuit.txt b/90_Tower/csharp/Tower/Resources/DiskQuit.txt
    new file mode 100644
    index 000000000..56d19d5fa
    --- /dev/null
    +++ b/90_Tower/csharp/Tower/Resources/DiskQuit.txt
    @@ -0,0 +1 @@
    +Stop wasting my time.  Go bother someone else.
    \ No newline at end of file
    diff --git a/90_Tower/csharp/Tower/Resources/DiskRetry.txt b/90_Tower/csharp/Tower/Resources/DiskRetry.txt
    new file mode 100644
    index 000000000..1efe29b44
    --- /dev/null
    +++ b/90_Tower/csharp/Tower/Resources/DiskRetry.txt
    @@ -0,0 +1 @@
    +Illegal entry... You may only type 3, 5, 7, 9, 11, 13, or 15.
    \ No newline at end of file
    diff --git a/90_Tower/csharp/Tower/Resources/DiskUnavailable.txt b/90_Tower/csharp/Tower/Resources/DiskUnavailable.txt
    new file mode 100644
    index 000000000..721ddccfe
    --- /dev/null
    +++ b/90_Tower/csharp/Tower/Resources/DiskUnavailable.txt
    @@ -0,0 +1 @@
    +That disk is below another one.  Make another choice.
    \ No newline at end of file
    diff --git a/90_Tower/csharp/Tower/Resources/IllegalMove.txt b/90_Tower/csharp/Tower/Resources/IllegalMove.txt
    new file mode 100644
    index 000000000..243c8d8fa
    --- /dev/null
    +++ b/90_Tower/csharp/Tower/Resources/IllegalMove.txt
    @@ -0,0 +1,3 @@
    +You can't place a larger disk on top of a smaller one,
    +it might crush it!
    +Now then,
    \ No newline at end of file
    diff --git a/90_Tower/csharp/Tower/Resources/Instructions.txt b/90_Tower/csharp/Tower/Resources/Instructions.txt
    new file mode 100644
    index 000000000..ca75537b2
    --- /dev/null
    +++ b/90_Tower/csharp/Tower/Resources/Instructions.txt
    @@ -0,0 +1,11 @@
    +In this program, we shall refer to disks by numerical code.
    +3 will represent the smallest disk, 5 the next size,
    +7 the next, and so on, up to 15.  If you do the puzzle with
    +2 disks, their code names would be 13 and 15.  With 3 disks
    +the code names would be 11, 13 and 15, etc.  The needles
    +are numbered from left to right, 1 to 3.  We will
    +startup with the disks on needle 1, and attempt to move them
    +to needle 3.
    +
    +Good luck!
    +
    diff --git a/90_Tower/csharp/Tower/Resources/Intro.txt b/90_Tower/csharp/Tower/Resources/Intro.txt
    new file mode 100644
    index 000000000..e5345da63
    --- /dev/null
    +++ b/90_Tower/csharp/Tower/Resources/Intro.txt
    @@ -0,0 +1,7 @@
    +
    +Towers of Hanoi puzzle.
    +
    +You must transfer the disks from the left to the right
    +tower, one at a time, never putting a larger dish on a
    +smaller disk.
    +
    diff --git a/90_Tower/csharp/Tower/Resources/NeedlePrompt.txt b/90_Tower/csharp/Tower/Resources/NeedlePrompt.txt
    new file mode 100644
    index 000000000..59dcebe7e
    --- /dev/null
    +++ b/90_Tower/csharp/Tower/Resources/NeedlePrompt.txt
    @@ -0,0 +1 @@
    +Place disk on which needle
    \ No newline at end of file
    diff --git a/90_Tower/csharp/Tower/Resources/NeedleQuit.txt b/90_Tower/csharp/Tower/Resources/NeedleQuit.txt
    new file mode 100644
    index 000000000..e75e3d87b
    --- /dev/null
    +++ b/90_Tower/csharp/Tower/Resources/NeedleQuit.txt
    @@ -0,0 +1,2 @@
    +I tried to warn you, but you wouldn't listen,
    +Bye bye, big shot.
    \ No newline at end of file
    diff --git a/90_Tower/csharp/Tower/Resources/NeedleRetry.txt b/90_Tower/csharp/Tower/Resources/NeedleRetry.txt
    new file mode 100644
    index 000000000..19701eec9
    --- /dev/null
    +++ b/90_Tower/csharp/Tower/Resources/NeedleRetry.txt
    @@ -0,0 +1,2 @@
    +I'll assume you hit the wrong key this time.  But watch it,
    +I only allow one mistake
    \ No newline at end of file
    diff --git a/90_Tower/csharp/Tower/Resources/PlayAgainPrompt.txt b/90_Tower/csharp/Tower/Resources/PlayAgainPrompt.txt
    new file mode 100644
    index 000000000..3972e7bde
    --- /dev/null
    +++ b/90_Tower/csharp/Tower/Resources/PlayAgainPrompt.txt
    @@ -0,0 +1,2 @@
    +
    +Try again (Yes or No)
    \ No newline at end of file
    diff --git a/90_Tower/csharp/Resources/Strings.cs b/90_Tower/csharp/Tower/Resources/Strings.cs
    similarity index 100%
    rename from 90_Tower/csharp/Resources/Strings.cs
    rename to 90_Tower/csharp/Tower/Resources/Strings.cs
    diff --git a/90_Tower/csharp/Tower/Resources/TaskFinished.txt b/90_Tower/csharp/Tower/Resources/TaskFinished.txt
    new file mode 100644
    index 000000000..e1ea1309b
    --- /dev/null
    +++ b/90_Tower/csharp/Tower/Resources/TaskFinished.txt
    @@ -0,0 +1,2 @@
    +
    +You have performed the task in {0} moves.
    \ No newline at end of file
    diff --git a/90_Tower/csharp/Resources/Thanks.txt b/90_Tower/csharp/Tower/Resources/Thanks.txt
    similarity index 100%
    rename from 90_Tower/csharp/Resources/Thanks.txt
    rename to 90_Tower/csharp/Tower/Resources/Thanks.txt
    diff --git a/90_Tower/csharp/Tower/Resources/Title.txt b/90_Tower/csharp/Tower/Resources/Title.txt
    new file mode 100644
    index 000000000..ae130577e
    --- /dev/null
    +++ b/90_Tower/csharp/Tower/Resources/Title.txt
    @@ -0,0 +1,5 @@
    +                                 Towers
    +               Creative Computing  Morristown, New Jersey
    +
    +
    +
    diff --git a/90_Tower/csharp/Resources/TooManyMoves.txt b/90_Tower/csharp/Tower/Resources/TooManyMoves.txt
    similarity index 83%
    rename from 90_Tower/csharp/Resources/TooManyMoves.txt
    rename to 90_Tower/csharp/Tower/Resources/TooManyMoves.txt
    index 5c190ec34..680803a51 100644
    --- a/90_Tower/csharp/Resources/TooManyMoves.txt
    +++ b/90_Tower/csharp/Tower/Resources/TooManyMoves.txt
    @@ -1,2 +1,2 @@
     Sorry, but I have orders to stop if you make more than
    -128 moves.
    +128 moves.
    \ No newline at end of file
    diff --git a/90_Tower/csharp/Tower/Resources/YesNoPrompt.txt b/90_Tower/csharp/Tower/Resources/YesNoPrompt.txt
    new file mode 100644
    index 000000000..62612ce2e
    --- /dev/null
    +++ b/90_Tower/csharp/Tower/Resources/YesNoPrompt.txt
    @@ -0,0 +1,2 @@
    +
    +'Yes' or 'No' please
    \ No newline at end of file
    diff --git a/90_Tower/csharp/Tower.csproj b/90_Tower/csharp/Tower/Tower.csproj
    similarity index 100%
    rename from 90_Tower/csharp/Tower.csproj
    rename to 90_Tower/csharp/Tower/Tower.csproj
    diff --git a/90_Tower/csharp/UI/Input.cs b/90_Tower/csharp/Tower/UI/Input.cs
    similarity index 100%
    rename from 90_Tower/csharp/UI/Input.cs
    rename to 90_Tower/csharp/Tower/UI/Input.cs
    diff --git a/90_Tower/csharp/UI/Prompt.cs b/90_Tower/csharp/Tower/UI/Prompt.cs
    similarity index 99%
    rename from 90_Tower/csharp/UI/Prompt.cs
    rename to 90_Tower/csharp/Tower/UI/Prompt.cs
    index 34477bb75..bc83f7a67 100644
    --- a/90_Tower/csharp/UI/Prompt.cs
    +++ b/90_Tower/csharp/Tower/UI/Prompt.cs
    @@ -38,4 +38,4 @@ public bool TryValidateResponse(float number, out int integer)
                 return integer == number && _validValues.Contains(integer);
             }
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/90_Tower/csharp/UI/TowerDisplay.cs b/90_Tower/csharp/Tower/UI/TowerDisplay.cs
    similarity index 99%
    rename from 90_Tower/csharp/UI/TowerDisplay.cs
    rename to 90_Tower/csharp/Tower/UI/TowerDisplay.cs
    index d6917fd94..2493201f2 100644
    --- a/90_Tower/csharp/UI/TowerDisplay.cs
    +++ b/90_Tower/csharp/Tower/UI/TowerDisplay.cs
    @@ -34,4 +34,4 @@ void AppendTower(int size)
                 }
             }
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/90_Tower/java/Tower.java b/90_Tower/java/Tower.java
    index a1705c8b6..ed4c454fc 100644
    --- a/90_Tower/java/Tower.java
    +++ b/90_Tower/java/Tower.java
    @@ -9,100 +9,100 @@
      * 

    * Note: The idea was to create a version of the 1970's BASIC game in Java, without introducing * new features - no additional text, error checking, etc has been added. - * + * * Converted from BASIC to Java by Darren Cardenas. */ - + public class Tower { - + private final static int MAX_DISK_SIZE = 15; - + private final static int MAX_NUM_COLUMNS = 3; - + private final static int MAX_NUM_MOVES = 128; - - private final static int MAX_NUM_ROWS = 7; - + + private final static int MAX_NUM_ROWS = 7; + private final Scanner scan; // For user input - + // Represent all possible disk positions private int[][] positions; - + private enum Step { INITIALIZE, SELECT_TOTAL_DISKS, SELECT_DISK_MOVE, SELECT_NEEDLE, CHECK_SOLUTION - } - - + } + + public Tower() { - - scan = new Scanner(System.in); - + + scan = new Scanner(System.in); + // Row 0 and column 0 are not used - positions = new int[MAX_NUM_ROWS + 1][MAX_NUM_COLUMNS + 1]; - - } // End of constructor Tower - - + positions = new int[MAX_NUM_ROWS + 1][MAX_NUM_COLUMNS + 1]; + + } // End of constructor Tower + + public class Position { - + public int row; public int column; - + public Position(int row, int column) { this.row = row; this.column = column; - + } // End of constructor Position - + } // End of inner class Position - - + + public void play() { showIntro(); startGame(); - } // End of method play - - - private void showIntro() { - + } // End of method play + + + private void showIntro() { + System.out.println(" ".repeat(32) + "TOWERS"); System.out.println(" ".repeat(14) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); System.out.println("\n\n"); + + } // End of method showIntro - } // End of method showIntro - - private void startGame() { + private void startGame() { boolean diskMoved = false; - + int column = 0; - int disk = 0; - int needle = 0; + int disk = 0; + int needle = 0; int numDisks = 0; int numErrors = 0; int numMoves = 0; - int row = 0; - - Step nextStep = Step.INITIALIZE; - + int row = 0; + + Step nextStep = Step.INITIALIZE; + String userResponse = ""; - + Position diskPosition = new Position(0, 0); - - // Begin outer while loop + + // Begin outer while loop while (true) { - + switch (nextStep) { - - + + case INITIALIZE: - + // Initialize error count numErrors = 0; - + // Initialize positions for (row = 1; row <= MAX_NUM_ROWS; row++) { for (column = 1; column <= MAX_NUM_COLUMNS; column++) { @@ -116,46 +116,46 @@ private void startGame() { System.out.println("YOU MUST TRANSFER THE DISKS FROM THE LEFT TO THE RIGHT"); System.out.println("TOWER, ONE AT A TIME, NEVER PUTTING A LARGER DISK ON A"); System.out.println("SMALLER DISK.\n"); - + nextStep = Step.SELECT_TOTAL_DISKS; break; - - - case SELECT_TOTAL_DISKS: + + + case SELECT_TOTAL_DISKS: while (numErrors <= 2) { - + // Get user input System.out.print("HOW MANY DISKS DO YOU WANT TO MOVE (" + MAX_NUM_ROWS + " IS MAX)? "); numDisks = scan.nextInt(); System.out.println(""); - + numMoves = 0; - + // Ensure the number of disks is valid if ((numDisks < 1) || (numDisks > MAX_NUM_ROWS)) { - + numErrors++; - + // Handle user input errors if (numErrors < 3) { - System.out.println("SORRY, BUT I CAN'T DO THAT JOB FOR YOU."); - } - + System.out.println("SORRY, BUT I CAN'T DO THAT JOB FOR YOU."); + } + } else { break; // Leave the while loop } - } - + } + // Too many user input errors - if (numErrors > 2) { + if (numErrors > 2) { System.out.println("ALL RIGHT, WISE GUY, IF YOU CAN'T PLAY THE GAME RIGHT, I'LL"); System.out.println("JUST TAKE MY PUZZLE AND GO HOME. SO LONG."); - return; + return; } - // Display detailed instructions + // Display detailed instructions System.out.println("IN THIS PROGRAM, WE SHALL REFER TO DISKS BY NUMERICAL CODE."); System.out.println("3 WILL REPRESENT THE SMALLEST DISK, 5 THE NEXT SIZE,"); System.out.println("7 THE NEXT, AND SO ON, UP TO 15. IF YOU DO THE PUZZLE WITH"); @@ -164,28 +164,28 @@ private void startGame() { System.out.println("ARE NUMBERED FROM LEFT TO RIGHT, 1 TO 3. WE WILL"); System.out.println("START WITH THE DISKS ON NEEDLE 1, AND ATTEMPT TO MOVE THEM"); System.out.println("TO NEEDLE 3.\n"); - System.out.println("GOOD LUCK!\n"); - + System.out.println("GOOD LUCK!\n"); + disk = MAX_DISK_SIZE; - + // Set disk starting positions - for (row = MAX_NUM_ROWS; row > (MAX_NUM_ROWS - numDisks); row--) { - positions[row][1] = disk; - disk = disk - 2; - } - + for (row = MAX_NUM_ROWS; row > (MAX_NUM_ROWS - numDisks); row--) { + positions[row][1] = disk; + disk = disk - 2; + } + printPositions(); - + nextStep = Step.SELECT_DISK_MOVE; break; - + case SELECT_DISK_MOVE: - + System.out.print("WHICH DISK WOULD YOU LIKE TO MOVE? "); - + numErrors = 0; - + while (numErrors < 2) { disk = scan.nextInt(); @@ -194,154 +194,154 @@ private void startGame() { // Check if disk exists diskPosition = getDiskPosition(disk); - + // Disk found if ((diskPosition.row > 0) && (diskPosition.column > 0)) { // Disk can be moved if (isDiskMovable(disk, diskPosition.row, diskPosition.column) == true) { - + break; - + } // Disk cannot be moved else { - - System.out.println("THAT DISK IS BELOW ANOTHER ONE. MAKE ANOTHER CHOICE."); - System.out.print("WHICH DISK WOULD YOU LIKE TO MOVE? "); - - } + + System.out.println("THAT DISK IS BELOW ANOTHER ONE. MAKE ANOTHER CHOICE."); + System.out.print("WHICH DISK WOULD YOU LIKE TO MOVE? "); + + } } // Mimic legacy handling of valid disk number but disk not found else { - + System.out.println("THAT DISK IS BELOW ANOTHER ONE. MAKE ANOTHER CHOICE."); System.out.print("WHICH DISK WOULD YOU LIKE TO MOVE? "); numErrors = 0; continue; - - } - + + } + } // Invalid disk number else { - - System.out.println("ILLEGAL ENTRY... YOU MAY ONLY TYPE 3,5,7,9,11,13, OR 15."); + + System.out.println("ILLEGAL ENTRY... YOU MAY ONLY TYPE 3,5,7,9,11,13, OR 15."); numErrors++; - - if (numErrors > 1) { + + if (numErrors > 1) { break; - } - + } + System.out.print("? "); - + } } - if (numErrors > 1) { - + if (numErrors > 1) { + System.out.println("STOP WASTING MY TIME. GO BOTHER SOMEONE ELSE."); return; } - - nextStep = Step.SELECT_NEEDLE; + + nextStep = Step.SELECT_NEEDLE; break; - + case SELECT_NEEDLE: - + numErrors = 0; while (true) { - + System.out.print("PLACE DISK ON WHICH NEEDLE? "); needle = scan.nextInt(); - + // Handle valid needle numbers - if ((needle - 1) * (needle - 2) * (needle - 3) == 0) { - - // Ensure needle is safe for disk move + if ((needle - 1) * (needle - 2) * (needle - 3) == 0) { + + // Ensure needle is safe for disk move if (isNeedleSafe(needle, disk, row) == false) { - + System.out.println("YOU CAN'T PLACE A LARGER DISK ON TOP OF A SMALLER ONE,"); System.out.println("IT MIGHT CRUSH IT!"); - System.out.print("NOW THEN, "); + System.out.print("NOW THEN, "); nextStep = Step.SELECT_DISK_MOVE; - break; + break; } - + diskPosition = getDiskPosition(disk); - + // Attempt to move the disk on a non-empty needle - diskMoved = false; + diskMoved = false; for (row = 1; row <= MAX_NUM_ROWS; row++) { if (positions[row][needle] != 0) { row--; - + positions[row][needle] = positions[diskPosition.row][diskPosition.column]; positions[diskPosition.row][diskPosition.column] = 0; - + diskMoved = true; - break; - } + break; + } } - + // Needle was empty, so move disk to the bottom if (diskMoved == false) { positions[MAX_NUM_ROWS][needle] = positions[diskPosition.row][diskPosition.column]; - positions[diskPosition.row][diskPosition.column] = 0; - } - + positions[diskPosition.row][diskPosition.column] = 0; + } + nextStep = Step.CHECK_SOLUTION; break; - + } // Handle invalid needle numbers else { - + numErrors++; - - if (numErrors > 1) { + + if (numErrors > 1) { System.out.println("I TRIED TO WARN YOU, BUT YOU WOULDN'T LISTEN."); System.out.println("BYE BYE, BIG SHOT."); return; } - else { + else { System.out.println("I'LL ASSUME YOU HIT THE WRONG KEY THIS TIME. BUT WATCH IT,"); - System.out.println("I ONLY ALLOW ONE MISTAKE."); - } + System.out.println("I ONLY ALLOW ONE MISTAKE."); + } } - - } + + } break; - + case CHECK_SOLUTION: - - printPositions(); - + + printPositions(); + numMoves++; - + // Puzzle is solved if (isPuzzleSolved() == true) { - + // Check for optimal solution if (numMoves == (Math.pow(2, numDisks) - 1)) { System.out.println(""); - System.out.println("CONGRATULATIONS!!\n"); + System.out.println("CONGRATULATIONS!!\n"); } - + System.out.println("YOU HAVE PERFORMED THE TASK IN " + numMoves + " MOVES.\n"); - System.out.print("TRY AGAIN (YES OR NO)? "); + System.out.print("TRY AGAIN (YES OR NO)? "); // Prompt for retries while (true) { userResponse = scan.next(); - - if (userResponse.toUpperCase().equals("YES")) { - nextStep = Step.INITIALIZE; + + if (userResponse.toUpperCase().equals("YES")) { + nextStep = Step.INITIALIZE; break; } else if (userResponse.toUpperCase().equals("NO")) { @@ -352,86 +352,86 @@ else if (userResponse.toUpperCase().equals("NO")) { else { System.out.print("'YES' OR 'NO' PLEASE? "); } - } + } } // Puzzle is not solved else { - + // Exceeded maximum number of moves if (numMoves > MAX_NUM_MOVES) { System.out.println("SORRY, BUT I HAVE ORDERS TO STOP IF YOU MAKE MORE THAN"); - System.out.println("128 MOVES."); - return; - } + System.out.println("128 MOVES."); + return; + } nextStep = Step.SELECT_DISK_MOVE; - break; - } - + break; + } + break; - + default: System.out.println("INVALID STEP"); - break; - - } - - } // End outer while loop + break; + } + + } // End outer while loop + } // End of method startGame - + private boolean isPuzzleSolved() { - + int column = 0; int row = 0; - // Puzzle is solved if first 2 needles are empty - for (row = 1; row <= MAX_NUM_ROWS; row++) { - for (column = 1; column <= 2; column++) { + // Puzzle is solved if first 2 needles are empty + for (row = 1; row <= MAX_NUM_ROWS; row++) { + for (column = 1; column <= 2; column++) { if (positions[row][column] != 0) { - return false; - } - } - } + return false; + } + } + } return true; - + } // End of method isPuzzleSolved - + private Position getDiskPosition(int disk) { - + int column = 0; int row = 0; - + Position pos = new Position(0, 0); - // Begin loop through all rows + // Begin loop through all rows for (row = 1; row <= MAX_NUM_ROWS; row++) { - + // Begin loop through all columns for (column = 1; column <= MAX_NUM_COLUMNS; column++) { - + // Found the disk if (positions[row][column] == disk) { - + pos.row = row; pos.column = column; return pos; } - + } // End loop through all columns - } // End loop through all rows - + } // End loop through all rows + return pos; + + } // End of method getDiskPosition - } // End of method getDiskPosition - - - private boolean isDiskMovable(int disk, int row, int column) { + + private boolean isDiskMovable(int disk, int row, int column) { int ii = 0; // Loop iterator @@ -440,88 +440,88 @@ private boolean isDiskMovable(int disk, int row, int column) { // Disk can be moved if (positions[ii][column] == 0) { - continue; + continue; } - + // Disk cannot be moved if (positions[ii][column] < disk) { - return false; + return false; } } // End loop through all rows above disk - + return true; - } // End of method isDiskMovable + } // End of method isDiskMovable private boolean isNeedleSafe(int needle, int disk, int row) { - + for (row = 1; row <= MAX_NUM_ROWS; row++) { // Needle is not empty if (positions[row][needle] != 0) { - + // Disk crush condition - if (disk >= positions[row][needle]) { + if (disk >= positions[row][needle]) { return false; } } } - + return true; - + } // End of method isNeedleSafe - - + + private void printPositions() { - + int column = 1; int ii = 0; // Loop iterator - int numSpaces = 0; - int row = 1; - + int numSpaces = 0; + int row = 1; + // Begin loop through all rows for (row = 1; row <= MAX_NUM_ROWS; row++) { - - numSpaces = 9; - + + numSpaces = 9; + // Begin loop through all columns for (column = 1; column <= MAX_NUM_COLUMNS; column++) { // No disk at the current position if (positions[row][column] == 0) { - + System.out.print(" ".repeat(numSpaces) + "*"); - numSpaces = 20; - } - + numSpaces = 20; + } + // Draw a disk at the current position else { - + System.out.print(" ".repeat(numSpaces - ((int) (positions[row][column] / 2)))); for (ii = 1; ii <= positions[row][column]; ii++) { - System.out.print("*"); - } - + System.out.print("*"); + } + numSpaces = 20 - ((int) (positions[row][column] / 2)); - } - + } + } // End loop through all columns - - System.out.println(""); - - } // End loop through all rows - - } // End of method printPositions - + + System.out.println(""); + + } // End loop through all rows + + } // End of method printPositions + public static void main(String[] args) { - + Tower tower = new Tower(); tower.play(); - + } // End of method main -} // End of class Tower +} // End of class Tower \ No newline at end of file diff --git a/90_Tower/javascript/tower.html b/90_Tower/javascript/tower.html index c557e9ec2..84318f331 100644 --- a/90_Tower/javascript/tower.html +++ b/90_Tower/javascript/tower.html @@ -1,10 +1,9 @@ TOWER - -

    
    +
    
     
     
     
    diff --git a/90_Tower/javascript/tower.js b/90_Tower/javascript/tower.js
    index 18f1f8fd1..06e8745c0 100644
    --- a/90_Tower/javascript/tower.js
    +++ b/90_Tower/javascript/tower.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    @@ -48,7 +48,7 @@ var ta = [];
     function show_towers()
     {
         var z;
    -
    +    
         for (var k = 1; k <= 7; k++) {
             z = 10;
             str = "";
    diff --git a/90_Tower/kotlin/README.md b/90_Tower/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/90_Tower/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/90_Tower/lua/README.md b/90_Tower/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/90_Tower/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/90_Tower/lua/tower.lua b/90_Tower/lua/tower.lua
    deleted file mode 100644
    index b86539a48..000000000
    --- a/90_Tower/lua/tower.lua
    +++ /dev/null
    @@ -1,268 +0,0 @@
    -print [[
    -            
    -            TOWERS
    -CREATIVE COMPUTING  MORRISTOWN, NEW JERSY
    -
    -
    -]]
    -
    -local MAX_DISKS  = 7
    -local MAX_DISK_SIZE  = 15
    -local MAX_MOVES  = 128
    -local NUM_TOWERS  = 3
    -
    -local towers = {
    -    { size = 0, elem = {} },
    -    { size = 0, elem = {} },
    -    { size = 0, elem = {} },
    -}
    -
    -local total_disks
    -function ask_how_many_disks()
    -
    -    local keep_asking = true
    -    local input
    -    local errors = 0
    -
    -    while keep_asking do
    -
    -        io.write(string.format("HOW MANY DISKS DO YOU WANT TO MOVE (%d IS MAX)? ", MAX_DISKS) )
    -        input = io.read("*number")
    -        io.read() --get rid of the remaining newline character
    -
    -        if input ~= nil and input>0 and input<=MAX_DISKS then
    -            keep_asking = false
    -
    -        else
    -            errors = errors + 1
    -            if errors > 2 then
    -                print "ALL RIGHT, WISE GUY, IF YOU CAN'T PLAY THE GAME RIGHT, I'LL"
    -                print "JUST TAKE MY PUZZLE AND GO HOME. SO LONG."
    -                os.exit()
    -            end
    -
    -            print "SORRY, BUT I CAN'T DO THAT JOB FOR YOU."
    -        end
    -    end
    -    total_disks = input
    -end
    -
    -function init_game()
    -    print("TOWERS OF HANOIR PUZZLE\n") --'\n' indicates a new line
    -
    -    print "YOU MUST TRANSFER THE DISKS FROM THE LEFT TO THE RIGHT TOWER,"
    -    print "ONE AT A TIME, NEVER PUTTING A LARGER DISK ON A SMALLER DISK.\n"
    -
    -    ask_how_many_disks()
    -
    -    print() -- print() already creates a new line at the end, so an empty print leaves an empty line
    -    print "IN THIS PROGRAM, WE SHALL REFER TO DISKS BY NUMERICAL CODE."
    -    print "3 WILL REPRESENT THE SMALLEST DISK, 5 THE NEXT SIZE, 7 THE"
    -    print "NEXT, AND SO ON, UP TO 15. IF YOU DO THE PUZZLE WITH 2 DISKS,"
    -    print "THEIR CODE NAMES WOULD BE 13 AND 15, ETC. THE NEEDLES ARE"
    -    print "NUMBERED FROM LEFT TO RIGHT, 1 TO 3. WE WILL START WITH THE"
    -    print "DISKS ON NEEDLE 1, AND ATTEMPT TO MOVE THEM TO NEEDLE 3.\n"
    -    
    -    print "GOOD LUCK!\n"
    -
    -    local i = 1
    -    local max = MAX_DISK_SIZE
    -    while i<= total_disks do
    -        towers[1].elem[i] = max
    -        max = max-2
    -        i = i+1
    -    end
    -
    -    towers[1].size = total_disks
    -
    -    local idx = 2
    -    while idx <= NUM_TOWERS do
    -        towers[idx].size = 0
    -    end
    -end
    -
    -function print_towers()
    -    local line = MAX_DISKS
    -    
    -    while line > 0 do
    -        local twr = 1
    -        
    -        while twr <=3 do
    -            local rpt = 10
    -            local offset = 0
    -            if line <= towers[twr].size then
    -                offset = (towers[twr].elem[line] - 1) / 2
    -                rpt = rpt - offset
    -            end
    -            io.write( string.rep(' ', rpt) )
    -            io.write( string.rep('*', offset) )
    -            io.write '*'
    -            io.write( string.rep('*', offset) )
    -            io.write( string.rep(' ', rpt) )
    -            twr = twr + 1
    -        end
    -        print ''
    -        line = line - 1
    -    end
    -    
    -end
    -
    -function ask_which_disk()
    -
    -    local keep_asking = true
    -    local input
    -    local errors = 0
    -    while keep_asking do
    -
    -        io.write("WHICH DISK WOULD YOU LIKE TO MOVE? ")
    -        input = io.read("*number")
    -        io.read() --get rid of the remaining newline character
    -
    -        if input==nil or input > MAX_DISK_SIZE or input%2==0 or input <= MAX_DISK_SIZE-(total_disks*2) then
    -            print "ILLEGAL ENTRY... YOU MAY ONLY TYPE 3,5,7,9,11,13 or 15."
    -            errors = errors + 1
    -            if errors > 1 then
    -                print "STOP WASTING MY TIME. GO BOTHER SOMEONE ELSE."
    -                os.exit()
    -            end
    -
    -        --[[
    -        Since there are only 3 towers, it's easier to do an 'if' with three
    -        conditions than to do a loop
    -        ]]
    -        elseif towers[1].elem[ towers[1].size ] ~= input and
    -                towers[2].elem[ towers[2].size ] ~= input and
    -                towers[3].elem[ towers[3].size ] ~= input then
    -
    -            print "THAT DISK IS BELOW ANOTHER ONE. MAKE ANOTHER CHOICE."
    -        else
    -            keep_asking = false 
    -        end
    -    end
    -    
    -    return input
    -end
    -
    -function ask_which_needle(dsk)
    -
    -    local keep_asking = true
    -    local input
    -    local errors = 0
    -
    -    while keep_asking do
    -
    -        io.write("PLACE DISK ON WHICH NEEDLE? ")
    -        input = io.read("*number")
    -        io.read() --get rid of the remaining newline character
    -
    -        if input~=nil and towers[input].size > 0 and towers[input].elem[ towers[input].size ] < dsk then
    -            print "YOU CAN'T PLACE A LARGER DISK ON TOP OF A SMALLER ONE,"
    -            print "IT MIGHT CRUSH IT!"
    -            return 0
    -
    -        elseif input~=nil and input>=1 and input<=3 then
    -                keep_asking = false
    -
    -        else
    -            errors = errors + 1
    -            if errors > 1 then
    -                print "I TRIED TO WARN YOU, BUT YOU WOULDN'T LISTEN."
    -                print "BYE BYE, BIG SHOT."
    -                os.exit() --Stop program
    -            else
    -                print "I'LL ASSUME YOU HIT THE WRONG KEY THIS TIME. BUT WATCH IT,"
    -                print "I ONLY ALLOW ONE MISTAKE."
    -            end
    -        end
    -    end
    -    return input
    -end
    -
    -function is_game_over()
    -    if towers[1].size == 0 and towers[2].size == 0 then
    -        return true
    -    else
    -        return false
    -    end
    -end
    -
    -function game_loop()
    -    local moves = 0
    -    local dsk 
    -    local twr_to
    -    local twr_fr
    -
    -    while not is_game_over() do
    -        moves = moves + 1
    -
    -        if moves > MAX_MOVES then
    -            print(string.format("SORRY, BUT I HAVE ORDERS TO STOP IF YOU MAKE MORE THAN %d MOVES.", MAX_MOVES))
    -            os.exit()
    -        end
    -
    -
    -        repeat
    -            dsk = ask_which_disk()
    -            twr_to = ask_which_needle(dsk)
    -        until twr_to ~= 0
    -
    -
    -        if towers[1].elem[ towers[1].size ] == dsk then
    -            twr_fr = 1
    -        elseif towers[2].elem[ towers[2].size ] == dsk then
    -            twr_fr = 2
    -        else
    -            twr_fr = 3
    -        end
    -
    -        towers[twr_fr].size = towers[twr_fr].size - 1
    -
    -        towers[twr_to].size = towers[twr_to].size + 1
    -        towers[twr_to].elem[ towers[twr_to].size ] = dsk
    -
    -        print_towers()
    -    end
    -
    -    return moves
    -end
    -
    -function keep_playing()
    -    
    -    while true do
    -        io.write("TRY AGAIN (YES OR NO)? ")
    -        local input = io.read("*line")
    -
    -        if input == "YES" or input == "yes" then
    -            return true
    -        elseif input == "NO" or input == "no" then
    -            return false
    -        else
    -            print "'YES' OR 'NO' PLEASE"
    -        end
    -    end
    -end
    -
    -function start_loop()
    -
    -    while true do
    -        init_game()
    -        print_towers()
    -
    -        local moves = game_loop()
    -
    -        --check ideal solution
    -        if moves == (2^total_disks) - 1 then
    -            print "CONGRATULATIONS!!"
    -        end
    -
    -        print ( string.format("YOU HAVE PERFORMED THE TASK IN %d MOVES.\n", moves) )
    -
    -        if not keep_playing() then
    -            break
    -        end
    -    end
    -
    -    print "\nTHANKS FOR THE GAME!"
    -end
    -
    -start_loop()
    diff --git a/90_Tower/pascal/README.md b/90_Tower/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/90_Tower/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/90_Tower/python/tower.py b/90_Tower/python/tower.py
    index d0059e86f..5e4a25b79 100644
    --- a/90_Tower/python/tower.py
    +++ b/90_Tower/python/tower.py
    @@ -1,54 +1,69 @@
     import sys
    -from typing import List, Optional
    -
     
     class Disk:
    -    def __init__(self, size: int) -> None:
    +    def __init__(self, size):
             self.__size = size
     
    -    def size(self) -> int:
    +    def size(self):
             return self.__size
     
    -    def print(self) -> None:
    -        print(f"[ {self.size()} ]")
    -
    +    def print(self):
    +        print("[ %s ]" % self.size())
     
     class Tower:
    -    def __init__(self) -> None:
    -        self.__disks: List[Disk] = []
    +    def __init__(self):
    +        self.__disks = []
     
    -    def empty(self) -> bool:
    +    def empty(self):
             return len(self.__disks) == 0
     
    -    def top(self) -> Optional[Disk]:
    -        return None if self.empty() else self.__disks[-1]
    +    def top(self):
    +        if self.empty():
    +            return None
    +        else:
    +            return self.__disks[-1]
     
    -    def add(self, disk: Disk) -> None:
    +    def add(self, disk):
             if not self.empty():
                 t = self.top()
    -            assert t is not None  # cannot happen as it's not empty
                 if disk.size() > t.size():
    -                raise Exception(
    -                    "YOU CAN'T PLACE A LARGER DISK ON TOP OF A SMALLER ONE, IT MIGHT CRUSH IT!"
    -                )
    +                raise Exception("YOU CAN'T PLACE A LARGER DISK ON TOP OF A SMALLER ONE, IT MIGHT CRUSH IT!")
             self.__disks.append(disk)
     
    -    def pop(self) -> Disk:
    +    def pop(self):
             if self.empty():
                 raise Exception("empty pop")
             return self.__disks.pop()
     
    -    def print(self) -> None:
    -        r = f'Needle: [{", ".join([str(x.size()) for x in self.__disks])}]'
    +    def print(self):
    +        r = "Needle: [%s]" % (", ".join([str(x.size()) for x in self.__disks]))
             print(r)
     
     
    +
    +print("""
    +IN THIS PROGRAM, WE SHALL REFER TO DISKS BY NUMERICAL CODE.
    +3 WILL REPRESENT THE SMALLEST DISK, 5 THE NEXT SIZE,
    +7 THE NEXT, AND SO ON, UP TO 15.  IF YOU DO THE PUZZLE WITH
    +2 DISKS, THEIR CODE NAMES WOULD BE 13 AND 15.  WITH 3 DISKS
    +THE CODE NAMES WOULD BE 11, 13 AND 15, ETC.  THE NEEDLES
    +ARE NUMBERED FROM LEFT TO RIGHT, 1 TO 3.  WE WILL
    +START WITH THE DISKS ON NEEDLE 1, AND ATTEMPT TO MOVE THEM
    +TO NEEDLE 3.
    +
    +GOOD LUCK!
    +
    +""")
    +
    +
    +
    +
     class Game:
    -    def __init__(self) -> None:
    +    def __init__(self):
             # use fewer sizes to make debugging easier
             # self.__sizes = [3, 5, 7]  # ,9,11,13,15]
             self.__sizes = [3, 5, 7, 9, 11, 13, 15]
    -
    +        
             self.__sizes.sort()
     
             self.__towers = []
    @@ -59,32 +74,33 @@ def __init__(self) -> None:
                 disk = Disk(size)
                 self.__towers[0].add(disk)
     
    -    def winner(self) -> bool:
    +    def winner(self):
             return self.__towers[0].empty() and self.__towers[1].empty()
     
    -    def print(self) -> None:
    +    def print(self):
             for t in self.__towers:
                 t.print()
     
    -    def moves(self) -> int:
    +    def moves(self):
             return self.__moves
     
    -    def which_disk(self) -> int:
    +    def which_disk(self):
             w = int(input("WHICH DISK WOULD YOU LIKE TO MOVE\n"))
             if w in self.__sizes:
                 return w
    -        raise Exception()
    +        else:
    +            raise Exception()
     
    -    def pick_disk(self) -> Optional[Tower]:
    +    def pick_disk(self):
             which = None
             while which is None:
                 try:
                     which = self.which_disk()
    -            except Exception:
    +            except:
                     print("ILLEGAL ENTRY... YOU MAY ONLY TYPE 3,5,7,9,11,13, OR 15.\n")
     
             valids = [t for t in self.__towers if t.top() and t.top().size() == which]
    -        assert len(valids) in {0, 1}
    +        assert len(valids) in (0, 1)
             if not valids:
                 print("THAT DISK IS BELOW ANOTHER ONE.  MAKE ANOTHER CHOICE.\n")
                 return None
    @@ -92,19 +108,17 @@ def pick_disk(self) -> Optional[Tower]:
                 assert valids[0].top().size() == which
                 return valids[0]
     
    -    def which_tower(self) -> Optional[Tower]:
    +    def which_tower(self):
             try:
                 needle = int(input("PLACE DISK ON WHICH NEEDLE\n"))
                 tower = self.__towers[needle - 1]
    -        except Exception:
    -            print(
    -                "I'LL ASSUME YOU HIT THE WRONG KEY THIS TIME.  BUT WATCH IT,\nI ONLY ALLOW ONE MISTAKE.\n"
    -            )
    +        except:
    +            print("I'LL ASSUME YOU HIT THE WRONG KEY THIS TIME.  BUT WATCH IT,\nI ONLY ALLOW ONE MISTAKE.\n")
                 return None
             else:
                 return tower
     
    -    def take_turn(self) -> None:
    +    def take_turn(self):
             from_tower = None
             while from_tower is None:
                 from_tower = self.pick_disk()
    @@ -119,55 +133,30 @@ def take_turn(self) -> None:
     
             disk = from_tower.pop()
             try:
    -            to_tower.add(disk)
    +            to_tower.add( disk )
                 self.__moves += 1
             except Exception as err:
                 print(err)
                 from_tower.add(disk)
     
    -
    -def main() -> None:
    -    print(
    -        """
    -    IN THIS PROGRAM, WE SHALL REFER TO DISKS BY NUMERICAL CODE.
    -    3 WILL REPRESENT THE SMALLEST DISK, 5 THE NEXT SIZE,
    -    7 THE NEXT, AND SO ON, UP TO 15.  IF YOU DO THE PUZZLE WITH
    -    2 DISKS, THEIR CODE NAMES WOULD BE 13 AND 15.  WITH 3 DISKS
    -    THE CODE NAMES WOULD BE 11, 13 AND 15, ETC.  THE NEEDLES
    -    ARE NUMBERED FROM LEFT TO RIGHT, 1 TO 3.  WE WILL
    -    START WITH THE DISKS ON NEEDLE 1, AND ATTEMPT TO MOVE THEM
    -    TO NEEDLE 3.
    -
    -    GOOD LUCK!
    -
    -    """
    -    )
    -
    -    game = Game()
    -    while True:
    -        game.print()
    -
    -        game.take_turn()
    -
    -        if game.winner():
    -            print(
    -                "CONGRATULATIONS!!\nYOU HAVE PERFORMED THE TASK IN %s MOVES.\n"
    -                % game.moves()
    -            )
    -            while True:
    -                yesno = input("TRY AGAIN (YES OR NO)\n")
    -                if yesno.upper() == "YES":
    -                    game = Game()
    -                    break
    -                elif yesno.upper() == "NO":
    -                    print("THANKS FOR THE GAME!\n")
    -                    sys.exit(0)
    -                else:
    -                    print("'YES' OR 'NO' PLEASE\n")
    -        elif game.moves() > 128:
    -            print("SORRY, BUT I HAVE ORDERS TO STOP IF YOU MAKE MORE THAN 128 MOVES.")
    -            sys.exit(0)
    -
    -
    -if __name__ == "__main__":
    -    main()
    +game = Game()
    +while True:
    +    game.print()
    +
    +    game.take_turn()
    +
    +    if game.winner():
    +        print("CONGRATULATIONS!!\nYOU HAVE PERFORMED THE TASK IN %s MOVES.\n" % game.moves())
    +        while True:
    +            yesno = input("TRY AGAIN (YES OR NO)\n")
    +            if yesno.upper() == "YES":
    +                game = Game()
    +                break
    +            elif yesno.upper() == "NO":
    +                print("THANKS FOR THE GAME!\n")
    +                sys.exit(0)
    +            else:
    +                print("'YES' OR 'NO' PLEASE\n")
    +    elif game.moves() > 128:
    +        print("SORRY, BUT I HAVE ORDERS TO STOP IF YOU MAKE MORE THAN 128 MOVES.")
    +        sys.exit(0)
    diff --git a/90_Tower/python/tower_test.py b/90_Tower/python/tower_test.py
    new file mode 100644
    index 000000000..a7023a0fa
    --- /dev/null
    +++ b/90_Tower/python/tower_test.py
    @@ -0,0 +1,49 @@
    +import unittest
    +import tower
    +
    +class MyTestCase(unittest.TestCase):
    +    def test_something(self):
    +        t = tower.Tower()
    +        self.assertTrue(t.empty())
    +
    +        d = tower.Disk(3)
    +        t.add(d)
    +        self.assertFalse(t.empty())
    +
    +        d5 = tower.Disk(5)
    +        self.assertRaises(Exception, t.add, d5)
    +        self.assertFalse(t.empty())
    +
    +    def test_oksize(self):
    +        t = tower.Tower()
    +        self.assertTrue(t.empty())
    +
    +        d5 = tower.Disk(5)
    +        t.add(d5)
    +        self.assertFalse(t.empty())
    +
    +        d3 = tower.Disk(3)
    +        t.add(d3)
    +        self.assertFalse(t.empty())
    +
    +        self.assertEqual(t.top(), d3)
    +        self.assertEqual(t.pop(), d3)
    +        self.assertEqual(t.pop(), d5)
    +
    +    def test_game(self):
    +        g = tower.Game()
    +        self.assertEqual(g.moves(), 0)
    +        self.assertFalse(g.winner())
    +
    +    def test_format(self):
    +        t = tower.Tower()
    +        d3 = tower.Disk(3)
    +        d5 = tower.Disk(5)
    +        t.add(d5)
    +        t.add(d3)
    +
    +        f = t.vertical_format(6, 3)
    +        self.assertEqual(f, ['      ', '[ 3 ] ', '[ 5 ] '])
    +
    +if __name__ == '__main__':
    +    unittest.main()
    diff --git a/90_Tower/rust/Cargo.lock b/90_Tower/rust/Cargo.lock
    deleted file mode 100644
    index b21cc6a2d..000000000
    --- a/90_Tower/rust/Cargo.lock
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    diff --git a/90_Tower/rust/Cargo.toml b/90_Tower/rust/Cargo.toml
    deleted file mode 100644
    index 1ec696335..000000000
    --- a/90_Tower/rust/Cargo.toml
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -[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]
    diff --git a/90_Tower/rust/src/disk.rs b/90_Tower/rust/src/disk.rs
    deleted file mode 100644
    index 9d5b4b6d5..000000000
    --- a/90_Tower/rust/src/disk.rs
    +++ /dev/null
    @@ -1,28 +0,0 @@
    -pub struct Disk {
    -    pub size: u8,
    -}
    -
    -impl Disk {
    -    pub fn new(size: u8) -> Self {
    -        Disk { size }
    -    }
    -
    -    pub fn draw(&self) {
    -        let draw_space = || {
    -            let space_amount = (15 - self.size) / 2;
    -
    -            if space_amount > 0 {
    -                for _ in 0..space_amount {
    -                    print!(" ");
    -                }
    -            }
    -        };
    -
    -        draw_space();
    -        for _ in 0..self.size {
    -            print!("*");
    -        }
    -        draw_space();
    -        print!("   ");
    -    }
    -}
    diff --git a/90_Tower/rust/src/game.rs b/90_Tower/rust/src/game.rs
    deleted file mode 100644
    index 50ef0fe1c..000000000
    --- a/90_Tower/rust/src/game.rs
    +++ /dev/null
    @@ -1,138 +0,0 @@
    -use crate::{
    -    disk::Disk,
    -    needle::Needle,
    -    util::{self, prompt, PromptResult},
    -};
    -
    -pub struct Game {
    -    pub needles: Vec,
    -    disk_count: u8,
    -    moves: usize,
    -}
    -
    -impl Game {
    -    pub fn new() -> Self {
    -        let mut needles = Vec::new();
    -        let disk_count = util::get_disk_count();
    -
    -        for i in 1..=3 {
    -            let disks = match i {
    -                1 => {
    -                    let mut disks = Vec::new();
    -
    -                    let mut half_size = 7;
    -                    for _ in (1..=disk_count).rev() {
    -                        disks.push(Disk::new(half_size * 2 + 1));
    -                        half_size -= 1;
    -                    }
    -
    -                    disks
    -                }
    -                2 | 3 => Vec::new(),
    -                _ => panic!("THERE MUST BE EXACTLY THREE NEEDLES!"),
    -            };
    -
    -            needles.push(Needle { disks, number: i });
    -        }
    -
    -        Game {
    -            needles,
    -            disk_count,
    -            moves: 0,
    -        }
    -    }
    -
    -    pub fn update(&mut self) -> bool {
    -        self.draw();
    -
    -        loop {
    -            let (disk_index, from_needle_index) = self.get_disk_to_move();
    -            let to_needle_index = self.ask_which_needle();
    -
    -            if from_needle_index == to_needle_index {
    -                println!("DISK IS ALREADY AT THAT NEEDLE!");
    -                break;
    -            }
    -
    -            let to_needle = &self.needles[to_needle_index];
    -
    -            if to_needle.disks.len() == 0
    -                || to_needle.disks[0].size > self.needles[from_needle_index].disks[disk_index].size
    -            {
    -                self.move_disk(disk_index, from_needle_index, to_needle_index);
    -                break;
    -            } else {
    -                println!("CAN'T PLACE ON A SMALLER DISK!");
    -            }
    -        }
    -
    -        if self.needles[2].disks.len() == self.disk_count as usize {
    -            self.draw();
    -            println!("CONGRATULATIONS!!");
    -            println!("YOU HAVE PERFORMED THE TASK IN {} MOVES.", self.moves);
    -            return true;
    -        }
    -
    -        false
    -    }
    -
    -    pub fn draw(&self) {
    -        println!("");
    -        for r in (1..=7).rev() {
    -            for n in &self.needles {
    -                n.draw(r)
    -            }
    -            println!("");
    -        }
    -        println!("");
    -    }
    -
    -    fn get_disk_to_move(&self) -> (usize, usize) {
    -        loop {
    -            if let PromptResult::Number(n) = prompt(true, "WHICH DISK WOULD YOU LIKE TO MOVE?") {
    -                let smallest_disk = 15 - ((self.disk_count - 1) * 2);
    -
    -                if n < smallest_disk as i32 || n > 15 || (n % 2) == 0 {
    -                    println!("PLEASE ENTER A VALID DISK!")
    -                } else {
    -                    for (n_i, needle) in self.needles.iter().enumerate() {
    -                        if let Some((i, _)) = needle
    -                            .disks
    -                            .iter()
    -                            .enumerate()
    -                            .find(|(_, disk)| disk.size == n as u8)
    -                        {
    -                            if i == (needle.disks.len() - 1) {
    -                                return (i, n_i);
    -                            }
    -
    -                            println!("THAT DISK IS BELOW ANOTHER ONE. MAKE ANOTHER CHOICE.");
    -                        }
    -                    }
    -                }
    -            }
    -        }
    -    }
    -
    -    fn ask_which_needle(&self) -> usize {
    -        loop {
    -            if let PromptResult::Number(n) = prompt(true, "PLACE DISK ON WHICH NEEDLE?") {
    -                if n <= 0 || n > 3 {
    -                    println!("PLEASE ENTER A VALID NEEDLE.");
    -                } else {
    -                    return (n - 1) as usize;
    -                }
    -            }
    -        }
    -    }
    -
    -    fn move_disk(&mut self, disk: usize, from: usize, to: usize) {
    -        let from = &mut self.needles[from];
    -        let size = from.disks[disk].size;
    -
    -        from.disks.remove(disk);
    -        self.needles[to].add(size);
    -
    -        self.moves += 1;
    -    }
    -}
    diff --git a/90_Tower/rust/src/main.rs b/90_Tower/rust/src/main.rs
    deleted file mode 100644
    index 5ec26079d..000000000
    --- a/90_Tower/rust/src/main.rs
    +++ /dev/null
    @@ -1,50 +0,0 @@
    -use game::Game;
    -use util::PromptResult;
    -
    -mod disk;
    -mod game;
    -mod needle;
    -mod util;
    -
    -fn main() {
    -    println!("\n\n\t\tTOWERS");
    -    println!("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
    -
    -    println!("TOWERS OF HANOI PUZZLE\n");
    -
    -    println!("YOU MUST TRANSFER THE DISKS FROM THE LEFT TO THE RIGHT");
    -    println!("TOWER, ON AT A TIME, NEVER PUTTING A LARGER DISK ON A");
    -    println!("SMALLER DISK.\n");
    -
    -    let mut quit = false;
    -
    -    while !quit {
    -        let mut game = Game::new();
    -
    -        println!("");
    -        println!(
    -            r#"IN THIS PROGRAM, WE SHALL REFER TO DISKS BY NUMERICAL CODE.
    -3 WILL REPRESENT THE SMALLEST DISK, 5 THE NEXT SIZE,
    -7 THE NEXT, AND SO ON, UP TO 15.  IF YOU DO THE PUZZLE WITH
    -2 DISKS, THEIR CODE NAMES WOULD BE 13 AND 15.  WITH 3 DISKS
    -THE CODE NAMES WOULD BE 11, 13 AND 15, ETC.  THE NEEDLES
    -ARE NUMBERED FROM LEFT TO RIGHT, 1 TO 3.  WE WILL
    -START WITH THE DISKS ON NEEDLE 1, AND ATTEMPT TO MOVE THEM
    -TO NEEDLE 3.
    -
    -GOOD LUCK!"#
    -        );
    -
    -        loop {
    -            if game.update() {
    -                break;
    -            }
    -        }
    -
    -        if let PromptResult::YesNo(r) = util::prompt(false, "TRY AGAIN (YES OR NO)?") {
    -            quit = !r;
    -        }
    -    }
    -
    -    println!("THANKS FOR THE GAME!");
    -}
    diff --git a/90_Tower/rust/src/needle.rs b/90_Tower/rust/src/needle.rs
    deleted file mode 100644
    index b2286eaf6..000000000
    --- a/90_Tower/rust/src/needle.rs
    +++ /dev/null
    @@ -1,26 +0,0 @@
    -use crate::disk::Disk;
    -
    -pub struct Needle {
    -    pub disks: Vec,
    -    pub number: u8,
    -}
    -
    -impl Needle {
    -    pub fn draw(&self, row: u8) {
    -        let row = row as usize;
    -
    -        if self.disks.len() >= row {
    -            self.disks[row - 1].draw();
    -        } else {
    -            let offset = "       ";
    -
    -            print!("{offset}");
    -            print!("*");
    -            print!("{offset}   ");
    -        }
    -    }
    -
    -    pub fn add(&mut self, size: u8) {
    -        self.disks.push(Disk { size });
    -    }
    -}
    diff --git a/90_Tower/rust/src/util.rs b/90_Tower/rust/src/util.rs
    deleted file mode 100644
    index 9feacf94a..000000000
    --- a/90_Tower/rust/src/util.rs
    +++ /dev/null
    @@ -1,51 +0,0 @@
    -use std::io;
    -
    -pub enum PromptResult {
    -    Number(i32),
    -    YesNo(bool),
    -}
    -
    -pub fn prompt(numeric: bool, msg: &str) -> PromptResult {
    -    use PromptResult::*;
    -    loop {
    -        println!("{}", msg);
    -
    -        let mut input = String::new();
    -
    -        io::stdin()
    -            .read_line(&mut input)
    -            .expect("Failed to read line.");
    -
    -        let input = input.trim().to_string();
    -
    -        if numeric {
    -            if let Ok(n) = input.parse::() {
    -                return Number(n);
    -            }
    -
    -            println!("PLEASE ENTER A NUMBER.")
    -        } else {
    -            match input.to_uppercase().as_str() {
    -                "YES" | "Y" => return YesNo(true),
    -                "NO" | "N" => return YesNo(false),
    -                _ => println!("PLEASE ENTER (Y)ES OR (N)O."),
    -            }
    -        }
    -    }
    -}
    -
    -pub fn get_disk_count() -> u8 {
    -    loop {
    -        if let PromptResult::Number(n) =
    -            prompt(true, "HOW MANY DISKS DO YOU WANT TO MOVE (7 IS MAX)?")
    -        {
    -            if n <= 2 {
    -                println!("THERE MUST BE AT LEAST 3 DISKS!")
    -            } else if n > 7 {
    -                println!("THERE CAN'T BE MORE THAN 7 DISKS!")
    -            } else {
    -                return n as u8;
    -            }
    -        }
    -    }
    -}
    diff --git a/90_Tower/vbnet/Tower.sln b/90_Tower/vbnet/Tower.sln
    deleted file mode 100644
    index 059a8d70f..000000000
    --- a/90_Tower/vbnet/Tower.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index d5d8396bd..000000000
    --- a/90_Tower/vbnet/Tower.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Tower
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/91_Train/README.md b/91_Train/README.md
    index 1717a13ab..50e7cf6ef 100644
    --- a/91_Train/README.md
    +++ b/91_Train/README.md
    @@ -14,7 +14,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/91_Train/csharp/Train.sln b/91_Train/csharp/Train.sln
    deleted file mode 100644
    index 29c49c59e..000000000
    --- a/91_Train/csharp/Train.sln
    +++ /dev/null
    @@ -1,31 +0,0 @@
    -
    -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}") = "TrainGame", "Train\TrainGame.csproj", "{42617537-4E7C-4082-A17B-7F18DFA04C35}"
    -EndProject
    -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TrainTests", "TrainTests\TrainTests.csproj", "{B967AA46-78F2-44F8-A30D-85D35F625991}"
    -EndProject
    -Global
    -	GlobalSection(SolutionConfigurationPlatforms) = preSolution
    -		Debug|Any CPU = Debug|Any CPU
    -		Release|Any CPU = Release|Any CPU
    -	EndGlobalSection
    -	GlobalSection(ProjectConfigurationPlatforms) = postSolution
    -		{42617537-4E7C-4082-A17B-7F18DFA04C35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
    -		{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
    -		{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
    -	EndGlobalSection
    -	GlobalSection(ExtensibilityGlobals) = postSolution
    -		SolutionGuid = {919F73B8-DE34-4992-9B05-E1FEC2D2F7C6}
    -	EndGlobalSection
    -EndGlobal
    diff --git a/91_Train/csharp/Train/Train.sln b/91_Train/csharp/Train/Train.sln
    new file mode 100644
    index 000000000..7735a7371
    --- /dev/null
    +++ b/91_Train/csharp/Train/Train.sln
    @@ -0,0 +1,31 @@
    +
    +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}"
    +EndProject
    +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TrainTests", "..\TrainTests\TrainTests\TrainTests.csproj", "{7C740A47-99C6-44E1-BDEE-140086BCFE8B}"
    +EndProject
    +Global
    +	GlobalSection(SolutionConfigurationPlatforms) = preSolution
    +		Debug|Any CPU = Debug|Any CPU
    +		Release|Any CPU = Release|Any CPU
    +	EndGlobalSection
    +	GlobalSection(ProjectConfigurationPlatforms) = postSolution
    +		{42617537-4E7C-4082-A17B-7F18DFA04C35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
    +		{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
    +	EndGlobalSection
    +	GlobalSection(SolutionProperties) = preSolution
    +		HideSolutionNode = FALSE
    +	EndGlobalSection
    +	GlobalSection(ExtensibilityGlobals) = postSolution
    +		SolutionGuid = {919F73B8-DE34-4992-9B05-E1FEC2D2F7C6}
    +	EndGlobalSection
    +EndGlobal
    diff --git a/91_Train/csharp/Train/TrainGame.cs b/91_Train/csharp/Train/Train/TrainGame.cs
    similarity index 100%
    rename from 91_Train/csharp/Train/TrainGame.cs
    rename to 91_Train/csharp/Train/Train/TrainGame.cs
    diff --git a/91_Train/csharp/Train/TrainGame.csproj b/91_Train/csharp/Train/Train/TrainGame.csproj
    similarity index 100%
    rename from 91_Train/csharp/Train/TrainGame.csproj
    rename to 91_Train/csharp/Train/Train/TrainGame.csproj
    diff --git a/91_Train/csharp/TrainTests/TrainGameTests.cs b/91_Train/csharp/TrainTests/TrainTests/TrainGameTests.cs
    similarity index 100%
    rename from 91_Train/csharp/TrainTests/TrainGameTests.cs
    rename to 91_Train/csharp/TrainTests/TrainTests/TrainGameTests.cs
    diff --git a/91_Train/csharp/TrainTests/TrainTests.csproj b/91_Train/csharp/TrainTests/TrainTests/TrainTests.csproj
    similarity index 92%
    rename from 91_Train/csharp/TrainTests/TrainTests.csproj
    rename to 91_Train/csharp/TrainTests/TrainTests/TrainTests.csproj
    index fb6ab9fba..a8de6dde8 100644
    --- a/91_Train/csharp/TrainTests/TrainTests.csproj
    +++ b/91_Train/csharp/TrainTests/TrainTests/TrainTests.csproj
    @@ -20,7 +20,7 @@
       
    - + diff --git a/91_Train/javascript/train.html b/91_Train/javascript/train.html index 53066b7d5..3aee95e2c 100644 --- a/91_Train/javascript/train.html +++ b/91_Train/javascript/train.html @@ -1,10 +1,9 @@ TRAIN - -
    
    +
    
     
     
     
    diff --git a/91_Train/javascript/train.js b/91_Train/javascript/train.js
    index b05e67912..e49d00bc0 100644
    --- a/91_Train/javascript/train.js
    +++ b/91_Train/javascript/train.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/91_Train/kotlin/README.md b/91_Train/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/91_Train/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/91_Train/lua/README.md b/91_Train/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/91_Train/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/91_Train/lua/train.lua b/91_Train/lua/train.lua
    deleted file mode 100644
    index 50214fa90..000000000
    --- a/91_Train/lua/train.lua
    +++ /dev/null
    @@ -1,59 +0,0 @@
    -print [[
    -            TRAIN
    - CREATIVE COMPUTING  MORRISTOWN, NEW JERSY
    -
    -
    -
    - TIME - SPEED DISTANCE EXERCISE]]
    -
    -math.randomseed(os.time())
    -
    -local ERROR_MARGIN  = 5.0
    -
    -function play()
    -    local car_speed = 25*math.random() + 40--Between 40 and 64
    -    local delta_time = 15*math.random() + 5--Between 5 and 19
    -    local train_speed = 19*math.random() + 20--Between 20 and 38
    -
    -    print( string.format("\nA CAR TRAVELING AT %u MPH CAN MAKE A CERTAIN TRIP IN %u HOURS LESS THAN A TRAIN TRAVELING AT %u MPH.", car_speed, delta_time, train_speed) )
    -
    -    local try = true
    -    local input
    -    while try do
    -        io.write("HOW LONG DOES THE TRIP TAKE BY CAR? ")
    -        input = io.read("n")
    -        if input == nil then
    -            print("PLEASE INSERT A NUMBER")
    -        else
    -            try = false
    -        end
    -        io.read()
    -    end
    -
    -    local car_time = delta_time * train_speed / (car_speed - train_speed)
    -    local percent = ( math.abs(car_time-input) * 100 / car_time + .5)
    -
    -    if percent > ERROR_MARGIN then
    -        print( string.format("SORRY. YOU WERE OFF BY %f PERCENT.", percent) )
    -    else
    -        print( string.format("GOOD! ANSWER WITHIN %f PERCENT.", percent) )
    -    end
    -    
    -    print( string.format("CORRECT ANSWER IS %f HOURS.", car_time) )
    -end
    -
    -function game_loop()
    -    local keep_playing = true
    -    while keep_playing do
    -        play()
    -        io.write("\nANOTHER PROBLEM (YES OR NO)? ")
    -        answer = io.read("l")
    -        
    -        if not (answer == "YES" or answer == "Y" or answer == "yes" or answer == "y") then
    -            keep_playing = false
    -        end
    -    end
    -
    -end
    -
    -game_loop()
    \ No newline at end of file
    diff --git a/91_Train/pascal/README.md b/91_Train/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/91_Train/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/91_Train/perl/train.pl b/91_Train/perl/train.pl
    index f2a4c1d5a..d628b12c4 100755
    --- a/91_Train/perl/train.pl
    +++ b/91_Train/perl/train.pl
    @@ -21,7 +21,7 @@
     
     	my $V= $D*$T/($C-$T);
     	my $E= int(abs(($V-$A)*100/$A)+.5);
    -	if ($E>5) {
    +	if ($E>5) { 
     		print "SORRY.  YOU WERE OFF BY $E PERCENT.\n";
     		} else {
     		print "GOOD! ANSWER WITHIN $E PERCENT.\n";
    diff --git a/91_Train/python/train.py b/91_Train/python/train.py
    index 2affcc0a1..0fd68b3c0 100644
    --- a/91_Train/python/train.py
    +++ b/91_Train/python/train.py
    @@ -6,21 +6,21 @@
     import random
     
     
    -def play_game() -> None:
    +def play_game():
         """Play one round of the game"""
         car_speed = random.randint(40, 65)
         time_difference = random.randint(5, 20)
         train_speed = random.randint(20, 39)
         print("\nA car travelling", car_speed, "MPH can make a certain trip in")
         print(time_difference, "hours less than a train travelling at", train_speed, "MPH")
    -    time_answer: float = 0
    +    time_answer = 0
         while time_answer == 0:
             try:
                 time_answer = float(input("How long does the trip take by car "))
             except ValueError:
                 print("Please enter a number.")
    -    car_time = time_difference * train_speed / (car_speed - train_speed)
    -    error_percent = int(abs((car_time - time_answer) * 100 / time_answer) + 0.5)
    +    car_time = time_difference*train_speed/(car_speed-train_speed)
    +    error_percent = int(abs((car_time-time_answer)*100/time_answer)+.5)
         if error_percent > 5:
             print("Sorry. You were off by", error_percent, "percent.")
             print("Correct answer is", round(car_time, 6), "hours")
    @@ -28,7 +28,7 @@ def play_game() -> None:
             print("Good! Answer within", error_percent, "percent.")
     
     
    -def main() -> None:
    +def main():
         print(" " * 33 + "TRAIN")
         print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n")
         print("Time - speed distance exercise")
    @@ -36,7 +36,8 @@ def main() -> None:
         keep_playing = True
         while keep_playing:
             play_game()
    -        keep_playing = input("\nAnother problem (yes or no) ").lower().startswith("y")
    +        keep_playing = input(
    +            "\nAnother problem (yes or no) ").lower().startswith("y")
     
     
     if __name__ == "__main__":
    diff --git a/91_Train/ruby/train.rb b/91_Train/ruby/train.rb
    index 6499cb24a..c6850035e 100644
    --- a/91_Train/ruby/train.rb
    +++ b/91_Train/ruby/train.rb
    @@ -55,4 +55,4 @@ def main
     
     trap "SIGINT" do puts; exit 130 end
     
    -main
    +main
    \ No newline at end of file
    diff --git a/91_Train/rust/Cargo.lock b/91_Train/rust/Cargo.lock
    deleted file mode 100644
    index 4fe2abbea..000000000
    --- a/91_Train/rust/Cargo.lock
    +++ /dev/null
    @@ -1,75 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.10"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.147"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/91_Train/rust/Cargo.toml b/91_Train/rust/Cargo.toml
    deleted file mode 100644
    index f2fa11b7b..000000000
    --- a/91_Train/rust/Cargo.toml
    +++ /dev/null
    @@ -1,10 +0,0 @@
    -[package]
    -name = "rust"
    -version = "0.1.0"
    -authors = ["AnthonyMichaelTDM <68485672+AnthonyMichaelTDM@users.noreply.github.com>"]
    -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/91_Train/rust/README.md b/91_Train/rust/README.md
    deleted file mode 100644
    index 7e85f9a15..000000000
    --- a/91_Train/rust/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Rust](https://www.rust-lang.org/) by Anthony Rubick [AnthonyMichaelTDM](https://github.com/AnthonyMichaelTDM)
    diff --git a/91_Train/rust/src/lib.rs b/91_Train/rust/src/lib.rs
    deleted file mode 100644
    index d796a20a5..000000000
    --- a/91_Train/rust/src/lib.rs
    +++ /dev/null
    @@ -1,155 +0,0 @@
    -/*
    - lib.rs contains all the logic of the program
    -*/
    -use rand::{Rng, prelude::thread_rng}; //rng
    -use std::error::Error; //better errors
    -use std::io::{self, Write}; //io interactions
    -use std::{str::FromStr, fmt::Display}; //traits
    -
    -//DATA
    -
    -/// handles setup for the game
    -pub struct Config {
    -}
    -impl Config {
    -    /// creates and returns a new Config from user input
    -    pub fn new() -> Result> {
    -        //DATA
    -        let config: Config = Config { 
    -        };
    -        
    -        //return new config
    -        return Ok(config);
    -    }
    -}
    -
    -/// run the program
    -pub fn run(_config: &Config) -> Result<(), Box> {
    -    //DATA
    -    let mut rng = thread_rng();
    -    
    -    let mut speed_train_1;
    -    let mut time_difference;
    -    let mut speed_train_2;
    -
    -    let mut guess;
    -    let mut answer;
    -    
    -    let mut error:f32; 
    -
    -    //Game loop
    -    loop {
    -        //initialize variables
    -        speed_train_1 =  rng.gen_range(40..65);
    -        time_difference = rng.gen_range(5..20); 
    -        speed_train_2 = rng.gen_range(20..39);
    -
    -        //print starting message / conditions
    -        println!("A CAR TRAVELING {} MPH CAN MAKE A CERTAIN TRIP IN\n{} HOURS LESS THAN A TRAIN TRAVELING AT {} MPH",speed_train_1,time_difference,speed_train_2);
    -        println!();
    -
    -        //get guess
    -        guess = loop {
    -            match get_number_from_input("HOW LONG DOES THE TRIP TAKE BY CAR?",0,-1) {
    -                Ok(num) => break num,
    -                Err(err) => {
    -                    eprintln!("{}",err);
    -                    continue;
    -                },
    -            }
    -        };
    -
    -        //calculate answer and error
    -        answer = time_difference * speed_train_2 / (speed_train_1 - speed_train_2);
    -        error = ((answer - guess) as isize).abs() as f32 * 100.0/(guess as f32) + 0.5;
    -
    -        //check guess against answer
    -        if error > 5.0 {
    -            println!("SORRY, YOU WERE OFF BY {} PERCENT.", error);
    -            println!("CORRECT ANSWER IS {} HOURS.",answer);
    -        } else {
    -            println!("GOOD! ANSWER WITHIN {} PERCENT.", error);
    -        }
    -
    -        //ask user if they want to go again
    -        match get_string_from_user_input("ANOTHER PROBLEM (Y/N)") {
    -            Ok(s) => if !s.to_uppercase().eq("Y") {break;} else {continue;},
    -            _ => break,
    -        }
    -    }
    -
    -    //return to main
    -    Ok(())
    -}
    -
    -/// gets a string from user input
    -fn get_string_from_user_input(prompt: &str) -> Result> {
    -    //DATA
    -    let mut raw_input = String::new();
    -
    -    //print prompt
    -    print!("{}", prompt);
    -    //make sure it's printed before getting input
    -    io::stdout().flush().expect("couldn't flush stdout");
    -
    -    //read user input from standard input, and store it to raw_input, then return it or an error as needed
    -    raw_input.clear(); //clear input
    -    match io::stdin().read_line(&mut raw_input) {
    -        Ok(_num_bytes_read) => return Ok(String::from(raw_input.trim())),
    -        Err(err) => return Err(format!("ERROR: CANNOT READ INPUT!: {}", err).into()),
    -    }
    -}
    -/// generic function to get a number from the passed string (user input)
    -/// pass a min lower  than the max to have minimum and maximum bounds
    -/// pass a min higher than the max to only have a minimum bound
    -/// pass a min equal   to  the max to only have a maximum bound
    -/// 
    -/// Errors:
    -/// no number on user input
    -fn get_number_from_input(prompt: &str, min:T, max:T) -> Result> {
    -    //DATA
    -    let raw_input: String;
    -    let processed_input: String;
    -
    -    
    -    //input loop
    -    raw_input = loop {
    -        match get_string_from_user_input(prompt) {
    -            Ok(input) => break input,
    -            Err(e) => {
    -                eprintln!("{}",e);
    -                continue;
    -            },
    -        }
    -    };
    -
    -    //filter out non-numeric characters from user input
    -    processed_input = raw_input.chars().filter(|c| c.is_numeric()).collect();
    -
    -    //from input, try to read a number
    -    match processed_input.trim().parse() {
    -        Ok(i) => {
    -            //what bounds must the input fall into
    -            if min < max {  //have a min and max bound: [min,max]
    -                if i >= min && i <= max {//is input valid, within bounds
    -                    return Ok(i); //exit the loop with the value i, returning it
    -                } else { //print error message specific to this case
    -                    return Err(format!("ONLY BETWEEN {} AND {}, PLEASE!", min, max).into());
    -                } 
    -            } else if min > max { //only a min bound: [min, infinity)
    -                if i >= min {
    -                    return Ok(i);
    -                } else {
    -                    return Err(format!("NO LESS THAN {}, PLEASE!", min).into());
    -                }
    -            } else { //only a max bound: (-infinity, max]
    -                if i <= max {
    -                    return Ok(i);
    -                } else {
    -                    return Err(format!("NO MORE THAN {}, PLEASE!", max).into());
    -                }
    -            }
    -        },
    -        Err(_e) => return Err(format!("Error: couldn't find a valid number in {}",raw_input).into()),
    -    }
    -}
    diff --git a/91_Train/rust/src/main.rs b/91_Train/rust/src/main.rs
    deleted file mode 100644
    index 438f69be1..000000000
    --- a/91_Train/rust/src/main.rs
    +++ /dev/null
    @@ -1,41 +0,0 @@
    -use std::process;//allows for some better error handling
    -
    -mod lib; //allows access to lib.rs
    -use lib::Config;
    -
    -/// main function
    -/// responsibilities:
    -/// - Calling the command line logic with the argument values
    -/// - Setting up any other configuration
    -/// - Calling a run function in lib.rs
    -/// - Handling the error if run returns an error
    -fn main() {
    -    //greet user
    -    welcome();
    -
    -    // set up other configuration
    -    let mut config = Config::new().unwrap_or_else(|err| {
    -        eprintln!("Problem configuring program: {}", err);
    -        process::exit(1);
    -    });
    -
    -    // run the program
    -    if let Err(e) = lib::run(&mut config) {
    -        eprintln!("Application Error: {}", e); //use the eprintln! macro to output to standard error
    -        process::exit(1); //exit the program with an error code
    -    }
    -
    -    //end of program
    -    println!("THANKS FOR PLAYING!");
    -}
    -
    -/// print the welcome message
    -fn welcome() {
    -    println!("
    -                                Train
    -              CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY
    -
    -
    -TIME - SPEED DISTANCE EXERCISE
    -    ");
    -}
    diff --git a/91_Train/vbnet/Train.sln b/91_Train/vbnet/Train.sln
    deleted file mode 100644
    index ea9594815..000000000
    --- a/91_Train/vbnet/Train.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index 84f030136..000000000
    --- a/91_Train/vbnet/Train.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Train
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/92_Trap/README.md b/92_Trap/README.md
    index 4966acff8..18d5db48f 100644
    --- a/92_Trap/README.md
    +++ b/92_Trap/README.md
    @@ -17,7 +17,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/92_Trap/csharp/Program.cs b/92_Trap/csharp/Program.cs
    index 1769eb75c..6cd74d10d 100644
    --- a/92_Trap/csharp/Program.cs
    +++ b/92_Trap/csharp/Program.cs
    @@ -79,7 +79,7 @@ static void PrintInstructions()
           }
         }
         static void Print(string stringToPrint)
    -    {
    +    { 
           Console.WriteLine(stringToPrint);
         }
         static void Print()
    diff --git a/92_Trap/csharp/Trap.csproj b/92_Trap/csharp/Trap.csproj
    deleted file mode 100644
    index d3fe4757c..000000000
    --- a/92_Trap/csharp/Trap.csproj
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    diff --git a/92_Trap/csharp/Trap.sln b/92_Trap/csharp/Trap.sln
    deleted file mode 100644
    index 6226bef31..000000000
    --- a/92_Trap/csharp/Trap.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/java/src/Trap.java b/92_Trap/java/src/Trap.java
    index 3643ed7ef..d3dd58245 100644
    --- a/92_Trap/java/src/Trap.java
    +++ b/92_Trap/java/src/Trap.java
    @@ -198,4 +198,4 @@ private int randomNumber() {
             return (int) (Math.random()
                     * (HIGH_NUMBER_RANGE) + 1);
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/92_Trap/javascript/trap.html b/92_Trap/javascript/trap.html
    index 379cea393..1084e1def 100644
    --- a/92_Trap/javascript/trap.html
    +++ b/92_Trap/javascript/trap.html
    @@ -1,10 +1,9 @@
     
     
     TRAP
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/92_Trap/javascript/trap.js b/92_Trap/javascript/trap.js
    index 047454633..c2a5a2f30 100644
    --- a/92_Trap/javascript/trap.js
    +++ b/92_Trap/javascript/trap.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    diff --git a/92_Trap/kotlin/README.md b/92_Trap/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/92_Trap/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/92_Trap/lua/README.md b/92_Trap/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/92_Trap/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/92_Trap/pascal/README.md b/92_Trap/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/92_Trap/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/92_Trap/perl/trap.pl b/92_Trap/perl/trap.pl
    index c0f69c8c0..803490565 100755
    --- a/92_Trap/perl/trap.pl
    +++ b/92_Trap/perl/trap.pl
    @@ -56,5 +56,7 @@
     	print "TRY AGAIN.\n";
     	print "\n";
     	}
    -
    +	
     exit;
    +
    +
    diff --git a/92_Trap/python/trap.py b/92_Trap/python/trap.py
    index a85be68e6..772bd3c54 100644
    --- a/92_Trap/python/trap.py
    +++ b/92_Trap/python/trap.py
    @@ -10,7 +10,7 @@
     guess_max = 6
     
     
    -def play_game() -> None:
    +def play_game():
         """Play one round of the game"""
     
         number_computer = random.randint(1, number_max)
    @@ -20,14 +20,13 @@ def play_game() -> None:
             user_guess = [-1, -1]
             while user_guess == [-1, -1]:
                 try:
    -                user_input = [
    -                    int(item)
    -                    for item in input("\nGuess # " + str(turn) + " ? ").split(",")
    -                ]
    -                if len(user_input) != 2:
    -                    raise ValueError
    -                if sum(1 < x < number_max for x in user_input) == 2:
    -                    user_guess = user_input
    +                user_input = [int(item) for item in input(
    +                    "\nGuess # " + str(turn) + " ? ").split(",")]
    +                if len(user_input) == 2:
    +                    if sum(1 < x < number_max for x in user_input) == 2:
    +                        user_guess = user_input
    +                    else:
    +                        raise ValueError
                     else:
                         raise ValueError
                 except (ValueError, IndexError):
    @@ -48,7 +47,7 @@ def play_game() -> None:
                 break
     
     
    -def main() -> None:
    +def main():
         print(" " * 34 + "TRAP")
         print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n")
         if input("Instructions ").lower().startswith("y"):
    @@ -66,7 +65,8 @@ def main() -> None:
         keep_playing = True
         while keep_playing:
             play_game()
    -        keep_playing = input("\nTry again. ").lower().startswith("y")
    +        keep_playing = input(
    +            "\nTry again. ").lower().startswith("y")
     
     
     if __name__ == "__main__":
    diff --git a/92_Trap/ruby/trap.rb b/92_Trap/ruby/trap.rb
    deleted file mode 100644
    index d3a5b7c5f..000000000
    --- a/92_Trap/ruby/trap.rb
    +++ /dev/null
    @@ -1,98 +0,0 @@
    -#!/usr/bin/env ruby
    -
    -# Trap
    -# Steve Ullman, 1972-08-01
    -# Ruby version Glenn Vanderburg, 2022-03-04
    -
    -# Change these values to make the game easier or harder.
    -GUESSES_PER_GAME = 6
    -NUMBER_UPPER_BOUND = 100
    -
    -# Put everything in methods for order of presentation; we
    -# want to be able to refer to methods before declaring them,
    -# so the code reads nicely from top to bottom.
    -def main
    -  print_banner_and_instructions
    -
    -  loop do
    -    play_a_game
    -    break unless yes?("Try again?")
    -  end
    -end
    -
    -def yes?(prompt)
    -  print "\n#{prompt} "
    -  answer = gets
    -  return answer.downcase.start_with?("y")
    -end
    -
    -def print_banner_and_instructions
    -  banner = "Creative Computing -- Morristown, New Jersey"
    -
    -  puts "Trap!".center(banner.size)
    -  puts banner
    -  2.times { puts }
    -
    -  return unless yes?("Instructions?")
    -
    -  puts <<~"END"
    -    I am thinking of a number between 1 and #{NUMBER_UPPER_BOUND}.
    -    Try to guess my number. On each guess,
    -    you are to enter 2 numbers, trying to trap
    -    my number between the two numbers. I will
    -    tell you if you have trapped my number, if my
    -    number is larger than your two numbers, or if
    -    my number is smaller than your two numbers.
    -    If you want to guess one single number, type
    -    your guess for both your trap numbers.
    -    You get #{GUESSES_PER_GAME} guesses to get my number.
    -  END
    -end
    -
    -def play_a_game
    -  n = choose_number
    -
    -  GUESSES_PER_GAME.times do |i|
    -    lower, upper = get_guesses("Guess ##{i+1}?")
    -
    -    case
    -    when n < lower
    -      puts "My number is smaller than your trap numbers."
    -    when n > upper
    -      puts "My number is larger than your trap numbers."
    -    when lower != upper
    -      puts "You have trapped my number."
    -    else
    -      puts "You got it!!!"
    -      return
    -    end
    -  end
    -
    -  puts "Sorry, that's #{GUESSES_PER_GAME} guesses. Number was #{n}"
    -end
    -
    -def choose_number
    -  rand(NUMBER_UPPER_BOUND) + 1
    -end
    -
    -def get_guesses(prompt)
    -  loop do
    -    print "\n#{prompt} "
    -
    -    # This is forgiving of input format; it ignores spaces and
    -    # punctuation, returning only the strings of consecutive
    -    # digits in the input line.
    -    guesses = gets.scan(/\d+/)
    -
    -    if guesses.size != 2
    -      puts "Please enter two numbers for each guess."
    -    else
    -      # convert the strings of digits to integers:
    -      numbers = guesses.map(&:to_i)
    -      # and return them, lowest number first:
    -      return numbers.sort
    -    end
    -  end
    -end
    -
    -main
    diff --git a/92_Trap/rust/Cargo.lock b/92_Trap/rust/Cargo.lock
    deleted file mode 100644
    index 4fe2abbea..000000000
    --- a/92_Trap/rust/Cargo.lock
    +++ /dev/null
    @@ -1,75 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.10"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.147"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/92_Trap/rust/Cargo.toml b/92_Trap/rust/Cargo.toml
    deleted file mode 100644
    index ed59870f5..000000000
    --- a/92_Trap/rust/Cargo.toml
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -[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/92_Trap/rust/README.md b/92_Trap/rust/README.md
    deleted file mode 100644
    index 362bf9221..000000000
    --- a/92_Trap/rust/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Rust](https://www.rust-lang.org/) by Uğur Küpeli [ugurkupeli](https://github.com/ugurkupeli)
    \ No newline at end of file
    diff --git a/92_Trap/rust/src/main.rs b/92_Trap/rust/src/main.rs
    deleted file mode 100644
    index 5fc898767..000000000
    --- a/92_Trap/rust/src/main.rs
    +++ /dev/null
    @@ -1,90 +0,0 @@
    -use std::io::stdin;
    -
    -use rand::Rng;
    -
    -fn main() {
    -    println!("\n\t\tTRAP");
    -    println!("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
    -
    -    let max_guess = 6;
    -    let max_number = 100;
    -
    -    prompt_instructions();
    -
    -    loop {
    -        let number = rand::thread_rng().gen_range(1..(max_number + 1));
    -        let mut guesses = 1u8;
    -
    -        loop {
    -            let (min, max) = prompt_numbers(guesses);
    -
    -            if min == number && max == number {
    -                println!("\nYou got it!!!");
    -                break;
    -            } else if (min..=max).contains(&number) {
    -                println!("You have trapped my number.");
    -            } else if number < min {
    -                println!("My number is smaller than your trap numbers.");
    -            } else if number > max {
    -                println!("My number is bigger than your trap numbers.");
    -            }
    -
    -            guesses += 1;
    -            if guesses > max_guess {
    -                println!("\nSorry, that was {max_guess} guesses. Number was {number}");
    -                break;
    -            }
    -        }
    -
    -        println!("\nTry again.");
    -    }
    -}
    -
    -fn prompt_instructions() {
    -    println!("Instructions?\t");
    -
    -    let mut input = String::new();
    -    if let Ok(_) = stdin().read_line(&mut input) {
    -        match input.to_uppercase().trim() {
    -            "YES" | "Y" => {
    -                println!("\nI am thinking of a number between 1 and 100");
    -                println!("Try to guess my number. On each guess,");
    -                println!("you are to enter 2 numbers, trying to trap");
    -                println!("my number between the two numbers. I will");
    -                println!("tell you if you have trapped my number, if my");
    -                println!("number is larger than your two numbers, or if");
    -                println!("my number is smaller than your two numbers.");
    -                println!("If you want to guess one single number, type");
    -                println!("your guess for both your trap numbers.");
    -                println!("You get 6 guesses to get my number.");
    -            }
    -            _ => (),
    -        }
    -    }
    -}
    -
    -fn prompt_numbers(guess: u8) -> (u8, u8) {
    -    loop {
    -        let mut nums: Vec = Vec::new();
    -        println!("\nGuess # {guess} ?");
    -
    -        let mut input = String::new();
    -        if let Ok(_) = stdin().read_line(&mut input) {
    -            let input: Vec<&str> = input.trim().split(",").collect();
    -
    -            for string in input {
    -                if let Ok(number) = string.parse::() {
    -                    nums.push(number);
    -                } else {
    -                    break;
    -                }
    -            }
    -
    -            if nums.len() == 2 {
    -                if nums[0] <= nums[1] {
    -                    return (nums[0], nums[1]);
    -                }
    -            }
    -        }
    -    }
    -}
    diff --git a/92_Trap/trap.bas b/92_Trap/trap.bas
    index 7827f8ca0..2d5624b59 100644
    --- a/92_Trap/trap.bas
    +++ b/92_Trap/trap.bas
    @@ -20,7 +20,7 @@
     170 PRINT "YOU GET";G;"GUESSES TO GET MY NUMBER."
     180 X=INT(N*RND(1))+1
     190 FOR Q=1 TO G
    -200 PRINT
    +200 PRINT 
     210 PRINT "GUESS #";Q;
     220 INPUT A,B
     230 IF A=B AND X=A THEN 400
    @@ -40,9 +40,9 @@
     360 R=A
     370 A=B
     380 B=R
    -390 RETURN
    +390 RETURN 
     400 PRINT "YOU GOT IT!!!"
    -410 PRINT
    +410 PRINT 
     420 PRINT "TRY AGAIN."
     430 PRINT
     440 GOTO 180
    diff --git a/92_Trap/vbnet/Trap.sln b/92_Trap/vbnet/Trap.sln
    deleted file mode 100644
    index 65f0a10d8..000000000
    --- a/92_Trap/vbnet/Trap.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index f9d5a7903..000000000
    --- a/92_Trap/vbnet/Trap.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Trap
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/93_23_Matches/README.md b/93_23_Matches/README.md
    index e4ece5fd5..3e48212e8 100644
    --- a/93_23_Matches/README.md
    +++ b/93_23_Matches/README.md
    @@ -16,7 +16,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -There is an oddity (you can call it a bug, but it is no big deal) in the original code. If there are only two or three matches left at the player's turn and the player picks all of them (or more), the game would still register that as a win for the player.
    diff --git a/93_23_Matches/csharp/23Matches.cs b/93_23_Matches/csharp/23Matches.cs
    deleted file mode 100644
    index f2aeeaf8b..000000000
    --- a/93_23_Matches/csharp/23Matches.cs
    +++ /dev/null
    @@ -1,167 +0,0 @@
    -using System;
    -
    -namespace Program
    -{
    -  class Program
    -  {
    -
    -    // Initialize 3 public variables so that they can be ascessed anywhere in the code
    -    public static int numberOfMatches;
    -    public static int numberOfMatchesRemovedByPlayer;
    -    public static bool playerGoesFirst = false; // a flag to show if the player won the coin toss
    -    static void Main(string[] args)
    -    {
    -      // Print introduction text
    -
    -      // Prints the title with 31 spaces placed in front of the text using the PadLeft() string function
    -      Console.WriteLine("23 MATCHES".PadLeft(31));
    -      Console.WriteLine("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY".PadLeft(15));
    -      
    -      // Print 3 blank lines with \n escape sequence
    -      Console.Write("\n\n\n");
    -      Console.WriteLine(" THIS IS A GAME CALLED '23 MATCHES'.");
    -      Console.Write("\n");
    -
    -      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.Write("\n");
    -      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.Write("\n");
    -
    -      // Set the number of matches to 23
    -      numberOfMatches = 23;
    -
    -      // Create a random class object to generate the coin toss
    -      Random random = new Random();
    -      // Generates a random number between 0.0 and 1.0
    -      // Multiplies that number by 2 and then
    -      // Converts it into an integer giving either a 0 or a 1
    -      int coinTossResult = (int)(2 * random.NextDouble()); 
    -
    -      if (coinTossResult == 1)
    -      {
    -        Console.WriteLine("TAILS! YOU GO FIRST. ");
    -        // Sets the player coin toss flag to true
    -        playerGoesFirst = true;
    -        PlayerTurn();
    -      }
    -      else
    -      {
    -        Console.WriteLine("HEADS! I WIN! HA! HA!");
    -        Console.WriteLine("PREPARE TO LOSE, MEATBALL-NOSE!!");
    -        Console.Write("\n");
    -        Console.WriteLine("I TAKE 2 MATCHES");
    -        numberOfMatches = numberOfMatches - 2;
    -      }
    -
    -      // loops the code until there is 1 or fewer matches
    -      do
    -      {
    -        // Checks if the player has already gone 
    -        // because they won the coin toss
    -        // if they have not then the player can go
    -        if (playerGoesFirst == false)
    -        {
    -          Console.Write("THE NUMBER OF MATCHES IS NOW " + numberOfMatches);
    -          PlayerTurn();
    -        }
    -        // sets the coint toss flag to false since
    -        // this is only needed on the first loop of the code
    -        playerGoesFirst = false;
    -        ComputerTurn();        
    -      } while (numberOfMatches > 1);
    -
    -    }
    -
    -    static void PlayerTurn()
    -    {
    -      Console.WriteLine("\n");
    -      Console.WriteLine("YOUR TURN -- YOU MAY TAKE 1, 2, OR 3 MATCHES.");
    -      Console.Write("HOW MANY DO YOU WISH TO REMOVE ?? ");
    -      // Get player input
    -      numberOfMatchesRemovedByPlayer = ReadPlayerInput();
    -      // If the input is invalid (not 1, 2, or 3)
    -      // then ask the player to input again
    -      while (numberOfMatchesRemovedByPlayer > 3 || numberOfMatchesRemovedByPlayer <= 0)
    -      {
    -        Console.WriteLine("VERY FUNNY! DUMMY!");
    -        Console.WriteLine("DO YOU WANT TO PLAY OR GOOF AROUND?");
    -        Console.Write("NOW, HOW MANY MATCHES DO YOU WANT                 ?? ");
    -        numberOfMatchesRemovedByPlayer = ReadPlayerInput();
    -      }
    -
    -      // Remove the player specified number of matches
    -      numberOfMatches = numberOfMatches - numberOfMatchesRemovedByPlayer;
    -
    -      Console.WriteLine("THE ARE NOW " + numberOfMatches + " MATCHES REMAINING");      
    -    }
    -    static void ComputerTurn()
    -    {
    -      // Initialize the numberOfMatchesRemovedByComputer
    -      int numberOfMatchesRemovedByComputer = 0;
    -      switch (numberOfMatches)
    -      {
    -        case 4:
    -          numberOfMatchesRemovedByComputer = 3;
    -          break;
    -        case 3:
    -          numberOfMatchesRemovedByComputer = 2;
    -          break;
    -        case 2:
    -          numberOfMatchesRemovedByComputer = 1;
    -          break;
    -        case 1: case 0: // If the computer losses call this case
    -          Console.WriteLine("YOU WON, FLOPPY EARS !");
    -          Console.WriteLine("THING YOU'RE PRETTY SMART !");
    -          Console.WriteLine("LETS PLAY AGAIN AND I'LL BLOW YOUR SHOES OFF !!");
    -          break;
    -        default: // If there are > than 4 matches call this case
    -          numberOfMatchesRemovedByComputer = 4 - numberOfMatchesRemovedByPlayer;
    -          break;
    -      }
    -      // If the numberOfMatchesRemovedByComputer has been updated run this code,
    -      // if not them the computer has lost
    -      if (numberOfMatchesRemovedByComputer != 0)
    -      {
    -        Console.WriteLine("MY TURN ! I REMOVE " + numberOfMatchesRemovedByComputer + " MATCHES");
    -        numberOfMatches = numberOfMatches - numberOfMatchesRemovedByComputer;
    -        // If there are less than or equal to 1 matches
    -        // then the player has lost        
    -        if (numberOfMatches <= 1)
    -        {
    -          Console.Write("\n");
    -          Console.WriteLine("YOU POOR BOOB! YOU TOOK THE LAST MATCH! I GOTCHA!!");
    -          Console.WriteLine("HA ! HA ! I BEAT YOU !!!");
    -          Console.Write("\n");
    -          Console.WriteLine("GOOD BYE LOSER!");
    -        }
    -      }
    -    }
    -
    -
    -    // This method handles the player input 
    -    // and will handle inncorrect input
    -    static int ReadPlayerInput()
    -    {
    -      // Read user input and convert to integer
    -      int playerInput = 0;
    -      // Try to read player input
    -      try
    -      {
    -        playerInput = Convert.ToInt32(Console.ReadLine());
    -      }
    -      // If there is an error in the player input
    -      catch (System.Exception)
    -      {
    -        Console.WriteLine("?REENTER");
    -        Console.Write("?? ");
    -        // Ask the player to reenter their input
    -        playerInput = ReadPlayerInput();
    -      }
    -      return playerInput;      
    -    }
    -
    -  }
    -}
    \ No newline at end of file
    diff --git a/93_23_Matches/csharp/23matches.csproj b/93_23_Matches/csharp/23matches.csproj
    new file mode 100644
    index 000000000..11091f717
    --- /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 000000000..78fce16eb
    --- /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 000000000..e23be8a47
    --- /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 000000000..7b88d7b77
    --- /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
    new file mode 100644
    index 000000000..0f4d812af
    --- /dev/null
    +++ b/93_23_Matches/csharp/README.md
    @@ -0,0 +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
    diff --git a/93_23_Matches/java/Messages.java b/93_23_Matches/java/Messages.java
    index 739486913..c0e52b7c3 100644
    --- a/93_23_Matches/java/Messages.java
    +++ b/93_23_Matches/java/Messages.java
    @@ -9,15 +9,15 @@ private Messages() {
         public static final String INTRO = """
                                               23 MATCHES
                               CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY
    -
    -
    -
    +                        
    +                        
    +                        
                  THIS IS A GAME CALLED '23 MATCHES'.
    -
    +                        
                 WHEN IT IS YOUR TURN, YOU MAY TAKE ONE, TWO, OR THREE
                 MATCHES. THE OBJECT OF THE GAME IS NOT TO HAVE TO TAKE
                 THE LAST MATCH.
    -
    +                        
                 LET'S FLIP A COIN TO SEE WHO GOES FIRST.
                 IF IT COMES UP HEADS, I WILL WIN THE TOSS.
                 """;
    @@ -25,7 +25,7 @@ private Messages() {
         public static final String HEADS = """
                 HEADS! I WIN! HA! HA!
                 PREPARE TO LOSE, MEATBALL-NOSE!!
    -
    +                      
                 I TAKE 2 MATCHES
                 """;
     
    @@ -35,7 +35,7 @@ private Messages() {
     
         public static final String MATCHES_LEFT = """
                 THE NUMBER OF MATCHES IS NOW %d
    -
    +            
                 YOUR TURN -- YOU MAY TAKE 1, 2 OR 3 MATCHES.
                 """;
     
    @@ -64,7 +64,7 @@ private Messages() {
         public static final String LOSE = """
                 YOU POOR BOOB! YOU TOOK THE LAST MATCH! I GOTCHA!!
                 HA ! HA ! I BEAT YOU !!!
    -
    +                      
                 GOOD BYE LOSER!
                 """;
     }
    diff --git a/93_23_Matches/javascript/23matches.html b/93_23_Matches/javascript/23matches.html
    index 17d6fd328..70d67217b 100644
    --- a/93_23_Matches/javascript/23matches.html
    +++ b/93_23_Matches/javascript/23matches.html
    @@ -1,10 +1,9 @@
     
     
     23 MATCHES
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/93_23_Matches/javascript/23matches.js b/93_23_Matches/javascript/23matches.js
    index faf2b0424..2233cda6e 100644
    --- a/93_23_Matches/javascript/23matches.js
    +++ b/93_23_Matches/javascript/23matches.js
    @@ -12,10 +12,10 @@ function input()
     {
         var input_element;
         var input_str;
    -
    +    
         return new Promise(function (resolve) {
                            input_element = document.createElement("INPUT");
    -
    +                       
                            print("? ");
                            input_element.setAttribute("type", "text");
                            input_element.setAttribute("length", "50");
    @@ -116,7 +116,7 @@ async function main()
             }
             q = 1;
         }
    -
    +    
     }
     
     main();
    diff --git a/93_23_Matches/kotlin/README.md b/93_23_Matches/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/93_23_Matches/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/93_23_Matches/lua/README.md b/93_23_Matches/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/93_23_Matches/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/93_23_Matches/pascal/README.md b/93_23_Matches/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/93_23_Matches/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/93_23_Matches/python/23matches.py b/93_23_Matches/python/23matches.py
    index 293cfa1f3..189f5aa66 100755
    --- a/93_23_Matches/python/23matches.py
    +++ b/93_23_Matches/python/23matches.py
    @@ -6,7 +6,7 @@
     import random
     
     
    -def play_game() -> None:
    +def play_game():
         """Play one round of the game"""
     
         matches = 23
    @@ -35,7 +35,7 @@ def play_game() -> None:
                     except ValueError:
                         print("Please enter a number.")
                         prompt_human = "How many do you wish to remove "
    -            matches -= choice_human
    +            matches = matches - choice_human
                 if matches == 0:
                     print("You poor boob! You took the last match! I gotcha!!")
                     print("Ha ! Ha ! I beat you !!\n")
    @@ -48,7 +48,7 @@ def play_game() -> None:
                     choice_computer = 1
                 elif 1 < matches < 4:
                     choice_computer = matches - 1
    -            matches -= choice_computer
    +            matches = matches - choice_computer
                 if matches == 0:
                     print("You won, floppy ears !")
                     print("Think you're pretty smart !")
    @@ -60,7 +60,7 @@ def play_game() -> None:
             prompt_human = "Your turn -- you may take 1, 2 or 3 matches.\nHow many do you wish to remove "
     
     
    -def main() -> None:
    +def main():
         print(" " * 31 + "23 MATCHHES")
         print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n")
         print("This is a game called '23 Matches'.\n")
    @@ -73,7 +73,8 @@ def main() -> None:
         keep_playing = True
         while keep_playing:
             play_game()
    -        keep_playing = input("\nPlay again? (yes or no) ").lower().startswith("y")
    +        keep_playing = input(
    +            "\nPlay again? (yes or no) ").lower().startswith("y")
     
     
     if __name__ == "__main__":
    diff --git a/93_23_Matches/ruby/23_matches.rb b/93_23_Matches/ruby/23_matches.rb
    deleted file mode 100644
    index c362a9c00..000000000
    --- a/93_23_Matches/ruby/23_matches.rb
    +++ /dev/null
    @@ -1,88 +0,0 @@
    -class Matches
    -    def initialize
    -        puts " " * 31 + "23 MATCHES"
    -        puts "This is a game called '23 Matches'."
    -        puts "When it is your turn, you may take one, two, or three"
    -        puts "matches. The object of the game is not to have to take"
    -        puts "the last match."
    -        puts "Let's flip a coin to see who goes first."
    -        puts "If it comes up heads, I will win the toss."
    -
    -        while true
    -            play_game
    -            print "Play again? (yes or no) "
    -            answer = gets.chomp!.upcase
    -            break unless ["Y", "YES"].include? answer
    -        end
    -    end
    -
    -    private
    -        def play_game
    -            matches = 23
    -            humans_turn = rand(0..1) == 1
    -            if humans_turn
    -                puts "Tails! You go first."
    -                prompt_human = "How many do you wish to remove? "
    -            else
    -                puts "Heads! I win! Ha! Ha!"
    -                puts "Prepare to lose, meatball-nose!!"
    -            end
    -
    -            choice_human = 2
    -
    -            while matches > 0
    -                if humans_turn
    -                    choice_human = 0
    -                    if matches == 1
    -                        choice_human = 1
    -                    end
    -
    -                    while choice_human == 0
    -                        print "#{prompt_human}[1,2,3] "
    -                        choice_human = gets.chomp!
    -
    -                        if ![1, 2, 3].include?(choice_human.to_i) || choice_human.to_i > matches
    -                            choice_human = 0
    -                            puts "Very funny! Dummy!"
    -                            puts "Do you want to play or goof around?"
    -                            prompt_human = "Now, how many matches do you want "
    -                        end
    -                    end
    -
    -                    matches = matches - choice_human.to_i
    -
    -                    if matches == 0
    -                        puts "You poor boob! You took the last match! I gotcha!!"
    -                        puts "Ha ! Ha ! I beat you !!"
    -                        puts "Good bye loser!"
    -                    else
    -                        puts "There are now #{matches} matches remaining."
    -                    end
    -                else
    -                    choice_computer = 4 - choice_human.to_i
    -                    if matches == 1
    -                        choice_computer = 1
    -                    elsif (1 < matches) && (matches < 4)
    -                        choice_computer = matches - 1
    -                    end
    -
    -                    matches = matches - choice_computer
    -                    if matches == 0
    -                        puts "You won, floppy ears !"
    -                        puts "Think you're pretty smart !"
    -                        puts "Let's play again and I'll blow your shoes off !!"
    -                    else
    -                        puts "My turn ! I remove #{choice_computer} matches"
    -                        puts "The number of matches is now #{matches}"
    -                    end
    -                end
    -
    -                humans_turn = !humans_turn
    -                prompt_human = "Your turn -- you may take 1, 2 or 3 matches.\nHow many do you wish to remove "
    -            end
    -        end
    -end
    -
    -if __FILE__ == $0
    -    Matches.new
    -end
    \ No newline at end of file
    diff --git a/93_23_Matches/rust/Cargo.lock b/93_23_Matches/rust/Cargo.lock
    deleted file mode 100644
    index 96e2f79ef..000000000
    --- a/93_23_Matches/rust/Cargo.lock
    +++ /dev/null
    @@ -1,16 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "fastrand"
    -version = "2.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764"
    -
    -[[package]]
    -name = "twenty-three-matches"
    -version = "0.1.0"
    -dependencies = [
    - "fastrand",
    -]
    diff --git a/93_23_Matches/rust/Cargo.toml b/93_23_Matches/rust/Cargo.toml
    deleted file mode 100644
    index a4227bbd4..000000000
    --- a/93_23_Matches/rust/Cargo.toml
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -[package]
    -name = "twenty-three-matches"
    -version = "0.1.0"
    -edition = "2021"
    -
    -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
    -
    -[dependencies]
    -fastrand = "^2.0.0"
    diff --git a/93_23_Matches/rust/README.md b/93_23_Matches/rust/README.md
    deleted file mode 100644
    index 6249450a1..000000000
    --- a/93_23_Matches/rust/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [rust](https://www.rust-lang.org/)
    diff --git a/93_23_Matches/rust/src/main.rs b/93_23_Matches/rust/src/main.rs
    deleted file mode 100644
    index a14c39f58..000000000
    --- a/93_23_Matches/rust/src/main.rs
    +++ /dev/null
    @@ -1,108 +0,0 @@
    -use std::io;
    -use std::io::{stdin, stdout, BufRead, Write};
    -
    -fn main() -> io::Result<()> {
    -    intro();
    -    let mut input = stdin().lock();
    -    let mut buf = String::with_capacity(16);
    -    // variable `N` in the original game
    -    let mut matches: u8 = 23;
    -    if fastrand::bool() {
    -        println!("TAILS! YOU GO FIRST. \n");
    -    } else {
    -        println!("HEADS! I WIN! HA! HA!\nPREPARE TO LOSE, MEATBALL-NOSE!!\n\nI TAKE 2 MATCHES");
    -        matches -= 2;
    -        println!("THE NUMBER OF MATCHES IS NOW {matches}\n");
    -        println!("YOUR TURN -- YOU MAY TAKE 1, 2 OR 3 MATCHES.");
    -    }
    -    loop {
    -        // variable `K` in the original game
    -        let human_picked = read_matches(&mut input, &mut buf)?;
    -        matches = matches.saturating_sub(human_picked);
    -        if matches == 0 {
    -            // this can only happen if the player could win with the next turn but they take too
    -            // many matches (e.g. if there are three matches left and the player takes three instead of
    -            // two). In the original game, this would count as a win for the player.
    -            println!("\nYOU POOR BOOB! YOU TOOK THE LAST MATCH! I GOTCHA!!\nHA ! HA ! I BEAT YOU !!!\n\nGOOD BYE LOSER!");
    -            return Ok(());
    -        }
    -
    -        println!("THERE ARE NOW {matches} MATCHES REMAINING.");
    -
    -        if matches <= 1 {
    -            println!("YOU WON, FLOPPY EARS !\nTHINK YOU'RE PRETTY SMART !\nLETS PLAY AGAIN AND I'LL BLOW YOUR SHOES OFF !!");
    -            return Ok(());
    -        }
    -
    -        // variable `Z` in the original game
    -        let ai_picked = ai_pick(matches, human_picked);
    -        println!("MY TURN ! I REMOVE {ai_picked} MATCHES");
    -        matches = matches.saturating_sub(ai_picked);
    -        // The AI will never pick the last match except for the case where only one match is left (which is handled above)
    -        if matches == 1 {
    -            println!("\nYOU POOR BOOB! YOU TOOK THE LAST MATCH! I GOTCHA!!\nHA ! HA ! I BEAT YOU !!!\n\nGOOD BYE LOSER!");
    -            return Ok(());
    -        }
    -        println!("THE NUMBER OF MATCHES IS NOW {matches}\n");
    -        println!("YOUR TURN -- YOU MAY TAKE 1, 2 OR 3 MATCHES.");
    -    }
    -}
    -
    -fn intro() {
    -    println!(
    -        r"                               23 MATCHES
    -               CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY
    -
    -
    -
    - THIS IS A GAME CALLED '23 MATCHES'.
    -
    -WHEN IT IS YOUR TURN, YOU MAY TAKE ONE, TWO, OR THREE
    -MATCHES. THE OBJECT OF THE GAME IS NOT TO HAVE TO TAKE
    -THE LAST MATCH.
    -
    -LET'S FLIP A COIN TO SEE WHO GOES FIRST.
    -IF IT COMES UP HEADS, I WILL WIN THE TOSS.
    -"
    -    );
    -}
    -
    -fn read_matches(mut input: R, buf: &mut String) -> io::Result {
    -    print!("HOW MANY DO YOU WISH TO REMOVE ?? ");
    -    stdout().flush()?;
    -    loop {
    -        let input = read_int(&mut input, buf)?;
    -        if input <= 0 || input > 3 {
    -            print!("VERY FUNNY! DUMMY!\nDO YOU WANT TO PLAY OR GOOF AROUND?\nNOW, HOW MANY MATCHES DO YOU WANT              ?? ");
    -            stdout().flush()?;
    -        } else {
    -            return Ok(input as u8);
    -        }
    -    }
    -}
    -
    -fn read_int(mut input: R, buf: &mut String) -> io::Result {
    -    loop {
    -        buf.clear();
    -        input.read_line(buf)?;
    -        let line = buf.trim();
    -        // This is implicit behaviour in the original code: empty input is equal to 0
    -        if line.is_empty() {
    -            return Ok(0);
    -        }
    -        if let Ok(n) = line.parse::() {
    -            return Ok(n);
    -        } else {
    -            print!("??REENTER\n?? ");
    -            stdout().flush()?;
    -        }
    -    }
    -}
    -
    -fn ai_pick(matches: u8, human_picked: u8) -> u8 {
    -    if matches < 4 {
    -        matches - 1
    -    } else {
    -        4 - human_picked
    -    }
    -}
    diff --git a/93_23_Matches/vbnet/TwentyThreeMatches.sln b/93_23_Matches/vbnet/TwentyThreeMatches.sln
    deleted file mode 100644
    index a378cf3f4..000000000
    --- a/93_23_Matches/vbnet/TwentyThreeMatches.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index cf8620c94..000000000
    --- a/93_23_Matches/vbnet/TwentyThreeMatches.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    TwentyThreeMatches
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/94_War/README.md b/94_War/README.md
    index 448d84b6f..a850f73ec 100644
    --- a/94_War/README.md
    +++ b/94_War/README.md
    @@ -12,8 +12,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/94_War/csharp/War.sln b/94_War/csharp/War/War.sln
    similarity index 100%
    rename from 94_War/csharp/War.sln
    rename to 94_War/csharp/War/War.sln
    diff --git a/94_War/csharp/War/Cards.cs b/94_War/csharp/War/War/Cards.cs
    similarity index 100%
    rename from 94_War/csharp/War/Cards.cs
    rename to 94_War/csharp/War/War/Cards.cs
    diff --git a/94_War/csharp/War/Program.cs b/94_War/csharp/War/War/Program.cs
    similarity index 100%
    rename from 94_War/csharp/War/Program.cs
    rename to 94_War/csharp/War/War/Program.cs
    diff --git a/94_War/csharp/War/UserInterface.cs b/94_War/csharp/War/War/UserInterface.cs
    similarity index 100%
    rename from 94_War/csharp/War/UserInterface.cs
    rename to 94_War/csharp/War/War/UserInterface.cs
    diff --git a/94_War/csharp/War/War.csproj b/94_War/csharp/War/War/War.csproj
    similarity index 100%
    rename from 94_War/csharp/War/War.csproj
    rename to 94_War/csharp/War/War/War.csproj
    diff --git a/94_War/csharp/WarTester/Tests.cs b/94_War/csharp/War/WarTester/Tests.cs
    similarity index 100%
    rename from 94_War/csharp/WarTester/Tests.cs
    rename to 94_War/csharp/War/WarTester/Tests.cs
    diff --git a/94_War/csharp/WarTester/WarTester.csproj b/94_War/csharp/War/WarTester/WarTester.csproj
    similarity index 100%
    rename from 94_War/csharp/WarTester/WarTester.csproj
    rename to 94_War/csharp/War/WarTester/WarTester.csproj
    diff --git a/94_War/d/.gitignore b/94_War/d/.gitignore
    deleted file mode 100644
    index d969f6b2c..000000000
    --- a/94_War/d/.gitignore
    +++ /dev/null
    @@ -1,2 +0,0 @@
    -*.exe
    -*.obj
    diff --git a/94_War/d/README.md b/94_War/d/README.md
    deleted file mode 100644
    index 2bc48a124..000000000
    --- a/94_War/d/README.md
    +++ /dev/null
    @@ -1,125 +0,0 @@
    -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
    deleted file mode 100644
    index d5a453faf..000000000
    --- a/94_War/d/war.d
    +++ /dev/null
    @@ -1,80 +0,0 @@
    -@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);
    -    }
    -}
    diff --git a/94_War/java/War.java b/94_War/java/War.java
    index ce5f3560c..b09a46160 100644
    --- a/94_War/java/War.java
    +++ b/94_War/java/War.java
    @@ -5,7 +5,7 @@
     
     /**
      * Converted FROM BASIC to Java by Nahid Mondol.
    - *
    + * 
      * Based on Trevor Hobsons approach.
      */
     public class War {
    @@ -77,7 +77,7 @@ private static void playGame() {
                 invalidInput = true;
                 while (invalidInput) {
                     if (endedEarly()) {
    -                    // Player ended game early.
    +                    // Player ended game early. 
                         // Break out of game loop and show end game output.
                         gameEndedEarly = true;
                         break outerloop;
    @@ -90,7 +90,7 @@ private static void playGame() {
     
         /**
          * Outputs the winner of the current round.
    -     *
    +     * 
          * @param playerCard   Players card.
          * @param computerCard Computers card.
          */
    @@ -153,7 +153,7 @@ private static boolean endedEarly() {
     
         /**
          * Show output based on if the game was ended early or not.
    -     *
    +     * 
          * @param endedEarly true if the game was ended early, false otherwise.
          */
         private static void endGameOutput(boolean endedEarly) {
    @@ -195,4 +195,4 @@ private static int computerWonRound() {
         private static int getComputerScore() {
             return computerTotalScore;
         }
    -}
    +}
    \ No newline at end of file
    diff --git a/94_War/javascript/war.html b/94_War/javascript/war.html
    index 16c25080d..67cab7d20 100644
    --- a/94_War/javascript/war.html
    +++ b/94_War/javascript/war.html
    @@ -1,10 +1,9 @@
     
     
     WAR
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/94_War/javascript/war.js b/94_War/javascript/war.js
    index 727742602..ededa1ed4 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()).toUpperCase();
    -        if (str === "YES") {
    +        const str = await input();
    +        if (str == "YES") {
                 return true;
             }
    -        else if (str === "NO") {
    +        else if (str == "NO") {
                 return false;
             }
             else {
    @@ -124,15 +124,15 @@ const cards = [
     async function main() {
         printTitle();
         await askAboutInstructions();
    -
    +    
         let computerScore = 0;
         let playerScore = 0;
    -
    +    
         // Generate a random deck
         const gameSize = cards.length;    // Number of cards to shuffle into the game deck.  Can be <= cards.length.
         const deck = createGameDeck(cards, gameSize);
         let shouldContinuePlaying = true;
    -
    +    
         while (deck.length > 0 && shouldContinuePlaying) {
             const playerCard = deck.shift();    // Take a card
             const computerCard = deck.shift();    // Take a card
    diff --git a/94_War/lua/README.md b/94_War/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/94_War/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/94_War/pascal/README.md b/94_War/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/94_War/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/94_War/python/cards.json b/94_War/python/cards.json
    deleted file mode 100644
    index b27e9bd4f..000000000
    --- a/94_War/python/cards.json
    +++ /dev/null
    @@ -1,54 +0,0 @@
    -[
    -    "S-2",
    -    "H-2",
    -    "C-2",
    -    "D-2",
    -    "S-3",
    -    "H-3",
    -    "C-3",
    -    "D-3",
    -    "S-4",
    -    "H-4",
    -    "C-4",
    -    "D-4",
    -    "S-5",
    -    "H-5",
    -    "C-5",
    -    "D-5",
    -    "S-6",
    -    "H-6",
    -    "C-6",
    -    "D-6",
    -    "S-7",
    -    "H-7",
    -    "C-7",
    -    "D-7",
    -    "S-8",
    -    "H-8",
    -    "C-8",
    -    "D-8",
    -    "S-9",
    -    "H-9",
    -    "C-9",
    -    "D-9",
    -    "S-10",
    -    "H-10",
    -    "C-10",
    -    "D-10",
    -    "S-J",
    -    "H-J",
    -    "C-J",
    -    "D-J",
    -    "S-Q",
    -    "H-Q",
    -    "C-Q",
    -    "D-Q",
    -    "S-K",
    -    "H-K",
    -    "C-K",
    -    "D-K",
    -    "S-A",
    -    "H-A",
    -    "C-A",
    -    "D-A"
    -]
    diff --git a/94_War/python/war.py b/94_War/python/war.py
    index 48137c383..f512a6fa0 100755
    --- a/94_War/python/war.py
    +++ b/94_War/python/war.py
    @@ -1,27 +1,27 @@
     #!/usr/bin/env python3
    +# WAR
    +#
    +# Converted from BASIC to Python by Trevor Hobson
     
    -"""
    -WAR
    +import random
     
    -Converted from BASIC to Python by Trevor Hobson
    -"""
     
    -import json
    -import random
    -from pathlib import Path
    -from typing import List
    +def card_value(input):
    +    return ["2", "3", "4", "5", "6", "7", "8",
    +            "9", "10", "J", "Q", "K", "A"].index(input.split("-")[1])
     
     
    -def card_value(input: str) -> int:
    -    return ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"].index(
    -        input.split("-")[1]
    -    )
    +cards = ["S-2", "H-2", "C-2", "D-2", "S-3", "H-3", "C-3", "D-3",
    +         "S-4", "H-4", "C-4", "D-4", "S-5", "H-5", "C-5", "D-5",
    +         "S-6", "H-6", "C-6", "D-6", "S-7", "H-7", "C-7", "D-7",
    +         "S-8", "H-8", "C-8", "D-8", "S-9", "H-9", "C-9", "D-9",
    +         "S-10", "H-10", "C-10", "D-10", "S-J", "H-J", "C-J", "D-J",
    +         "S-Q", "H-Q", "C-Q", "D-Q", "S-K", "H-K", "C-K", "D-K",
    +         "S-A", "H-A", "C-A", "D-A"]
     
     
    -def play_game() -> None:
    +def play_game():
         """Play one round of the game"""
    -    with open(Path(__file__).parent / "cards.json") as f:
    -        cards: List[str] = json.load(f)
     
         random.shuffle(cards)
         score_you = 0
    @@ -31,38 +31,31 @@ def play_game() -> None:
             print()
             card_you = cards[round]
             card_computer = cards[round * 2]
    -        print("You:", card_you, " " * (8 - len(card_you)) + "Computer:", card_computer)
    +        print("You:", card_you, " " * (8 - len(card_you)) +
    +              "Computer:", card_computer)
             value_you = card_value(card_you)
             value_computer = card_value(card_computer)
             if value_you > value_computer:
                 score_you += 1
    -            print(
    -                "You win. You have", score_you, "and the computer has", score_computer
    -            )
    +            print("You win. You have", score_you,
    +                  "and the computer has", score_computer)
             elif value_computer > value_you:
                 score_computer += 1
    -            print(
    -                "The computer wins!!! You have",
    -                score_you,
    -                "and the computer has",
    -                score_computer,
    -            )
    +            print("The computer wins!!! You have", score_you,
    +                  "and the computer has", score_computer)
             else:
                 print("Tie. No score change.")
             cards_left -= 2
    -        if cards_left > 2 and input("Do you want to continue ").lower().startswith("n"):
    -            break
    +        if cards_left > 2:
    +            if input("Do you want to continue ").lower().startswith("n"):
    +                break
         if cards_left == 0:
    -        print(
    -            "\nWe have run out of cards. Final score: You:",
    -            score_you,
    -            "the computer:",
    -            score_computer,
    -        )
    +        print("\nWe have run out of cards. Final score: You:",
    +              score_you, "the computer:", score_computer)
         print("\nThanks for playing. It was fun.")
     
     
    -def main() -> None:
    +def main():
         print(" " * 33 + "WAR")
         print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n")
         print("This is the card game of war. Each card is given by suit-#")
    @@ -75,7 +68,8 @@ def main() -> None:
         keep_playing = True
         while keep_playing:
             play_game()
    -        keep_playing = input("\nPlay again? (yes or no) ").lower().startswith("y")
    +        keep_playing = input(
    +            "\nPlay again? (yes or no) ").lower().startswith("y")
     
     
     if __name__ == "__main__":
    diff --git a/94_War/ruby/war.rb b/94_War/ruby/war.rb
    deleted file mode 100644
    index cf7e8a59f..000000000
    --- a/94_War/ruby/war.rb
    +++ /dev/null
    @@ -1,118 +0,0 @@
    -#!/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
    diff --git a/94_War/rust/Cargo.lock b/94_War/rust/Cargo.lock
    deleted file mode 100644
    index 4fe2abbea..000000000
    --- a/94_War/rust/Cargo.lock
    +++ /dev/null
    @@ -1,75 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.10"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.147"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/94_War/rust/Cargo.toml b/94_War/rust/Cargo.toml
    deleted file mode 100644
    index 3b1d02f52..000000000
    --- a/94_War/rust/Cargo.toml
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -[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/94_War/rust/README.md b/94_War/rust/README.md
    deleted file mode 100644
    index 7e85f9a15..000000000
    --- a/94_War/rust/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Rust](https://www.rust-lang.org/) by Anthony Rubick [AnthonyMichaelTDM](https://github.com/AnthonyMichaelTDM)
    diff --git a/94_War/rust/src/main.rs b/94_War/rust/src/main.rs
    deleted file mode 100644
    index fb8a55fc1..000000000
    --- a/94_War/rust/src/main.rs
    +++ /dev/null
    @@ -1,158 +0,0 @@
    -use rand::prelude::{thread_rng, SliceRandom};
    -use std::io;
    -
    -//DATA
    -struct CARD {
    -    suit: u8, //1-4     1=hearts    2=diamonds     3=clubs     4=spades
    -    value: u8, //2-14   2,3,4,5,6,7,8,9,10,jack,queen,king,ace
    -}
    -impl CARD {
    -    /**
    -     * creates a new card from the passed card name
    -     */
    -    fn new(suit:u8,value:u8) -> CARD {
    -        return CARD { suit: suit, value: value };
    -    }
    -}
    -impl ToString for CARD {
    -    /**
    -     * returns string representation of the Card
    -     */
    -    fn to_string(&self) -> String {
    -        let mut name: String;
    -        //value
    -        name = match self.value {
    -            2..=10 => self.value.to_string() + " of ",
    -            11 => String::from("Jack of "),
    -            12 => String::from("Queen of "),
    -            13 => String::from("King of "),
    -            14 => String::from("Ace of "),
    -            _ => panic!("card has an invalid value"),
    -        };
    -        //suit
    -        name += match self.suit {
    -            1=>"Hearts",
    -            2=>"Diamonds",
    -            3=>"Clubs",
    -            4=>"Spades",
    -            _ => panic!("card has an invalid suit"),
    -        };
    -        return name;
    -    }
    -}
    -struct GAME {
    -    deck: Vec, //cards in the deck
    -    player_score: usize, //human player score
    -    computer_score:usize,//computer score
    -}
    -impl GAME {
    -    /**
    -     * creates a new game, filling a deck with 52 cards, and setting scores to 0
    -     */
    -    fn new() -> GAME{
    -        //DATA
    -        let mut game = GAME{deck: Vec::new(), player_score: 0, computer_score: 0};
    -        //fill deck
    -        for suit in 1..=4 { //4 suits
    -            for value in 2..=14 { //13 cards
    -                game.deck.push( CARD::new(suit,value) );
    -            }
    -        }
    -        //shuffle deck
    -        game.deck.shuffle(&mut thread_rng());
    -        //return game
    -        return game;
    -    }
    -
    -    /**
    -     * fully play game
    -     */
    -    fn play_game(&mut self) {
    -        //DATA
    -        let mut human_card: CARD;
    -        let mut computer_card: CARD;
    -
    -        //game loop
    -        while self.deck.len() >=2 {
    -            //draw cards
    -            human_card = self.deck.pop().expect("DECK IS EMPTY!");
    -            computer_card = self.deck.pop().expect("DECK IS EMPTY!");
    -
    -            //print cards
    -            println!("\nYou: {}\t\tComputer: {}",human_card.to_string(), computer_card.to_string());
    -
    -            //determine winner
    -            if human_card.value > computer_card.value { //human wins
    -                self.player_score += 1;
    -                println!("You win. You have {} and the computer has {}", human_card.value, computer_card.value);
    -            }
    -            else if human_card.value < computer_card.value { //computer wins
    -                self.computer_score += 1;
    -                println!("The computer wins!!! You have {} and the computer has {}", human_card.value, computer_card.value);
    -            }
    -            else { //tie
    -                println!("Tie. No score change.")
    -            }
    -            if !get_yes_no_from_user_input("Do you want to continue? y/n") {break;}
    -        }
    -        if self.deck.is_empty() {
    -            println!("WE HAVE RUN OUT OF CARDS.  FINAL SCORE:  YOU: {} THE COMPUTER: {}",self.player_score, self.computer_score);
    -        }
    -        println!("\nThanks for playing. It was fun.");
    -    }
    -}
    -
    -fn main() {
    -    //print welcome message
    -    welcome();
    -
    -    //game loop
    -    let mut game = GAME::new();
    -    loop {
    -        game.play_game();
    -        if !get_yes_no_from_user_input("\nPlay again? (yes or no) ") {break;}
    -        game = GAME::new();
    -    }
    -}
    -
    -/**
    - * print welcome message
    - */
    -fn welcome() {
    -    println!("
    -                                War\n
    -              CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n
    -    This is the card game of war. Each card is given by # of suit
    -    ex: Ace of Spades\n
    -    ");
    -    if get_yes_no_from_user_input("Do you want directions?") {
    -        println!("
    -        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
    -        ");
    -    }
    -}
    -
    -/**
    - * returns true if user input starts with y or Y,
    - * false otherwise
    - */
    -fn get_yes_no_from_user_input(prompt: &str) -> bool {
    -    let mut raw_input = String::new(); // temporary variable for user input that can be parsed later
    -
    -    //print prompt
    -    println!("{}", prompt);
    -    //read user input from standard input, and store it to raw_input
    -    //raw_input.clear(); //clear input
    -    io::stdin().read_line(&mut raw_input).expect( "CANNOT READ INPUT!");
    -
    -    //from input, try to read a valid character
    -    if let Some(i) = raw_input.trim().chars().nth(0) {
    -        if i == 'y' || i == 'Y' {
    -            return true;
    -        }
    -    }
    -    //default case
    -    return false;
    -}
    diff --git a/94_War/vbnet/War.sln b/94_War/vbnet/War.sln
    deleted file mode 100644
    index 3c0895ad1..000000000
    --- a/94_War/vbnet/War.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index e62cda474..000000000
    --- a/94_War/vbnet/War.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    War
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/95_Weekday/README.md b/95_Weekday/README.md
    index d8c941f28..445c2c4b3 100644
    --- a/95_Weekday/README.md
    +++ b/95_Weekday/README.md
    @@ -14,7 +14,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/95_Weekday/csharp/Program.cs b/95_Weekday/csharp/Program.cs
    deleted file mode 100644
    index e19be76d6..000000000
    --- a/95_Weekday/csharp/Program.cs
    +++ /dev/null
    @@ -1,203 +0,0 @@
    -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();
    -
    -        }
    -    }
    -}
    diff --git a/95_Weekday/csharp/Weekday.csproj b/95_Weekday/csharp/Weekday.csproj
    deleted file mode 100644
    index d3fe4757c..000000000
    --- a/95_Weekday/csharp/Weekday.csproj
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -
    -  
    -    Exe
    -    net6.0
    -    10
    -    enable
    -    enable
    -  
    -
    diff --git a/95_Weekday/csharp/Weekday.sln b/95_Weekday/csharp/Weekday.sln
    deleted file mode 100644
    index 4aad7c311..000000000
    --- a/95_Weekday/csharp/Weekday.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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/javascript/weekday.html b/95_Weekday/javascript/weekday.html
    index 9de279625..928df878d 100644
    --- a/95_Weekday/javascript/weekday.html
    +++ b/95_Weekday/javascript/weekday.html
    @@ -1,10 +1,9 @@
     
     
     WEEKDAY
    -
     
     
    -
    
    +
    
     
     
     
    diff --git a/95_Weekday/javascript/weekday.js b/95_Weekday/javascript/weekday.js
    index 6070c71cc..276e18176 100644
    --- a/95_Weekday/javascript/weekday.js
    +++ b/95_Weekday/javascript/weekday.js
    @@ -3,345 +3,83 @@
     // 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) {
    +function print(str)
    +{
         document.getElementById("output").appendChild(document.createTextNode(str));
     }
     
    -/**
    - * Obtain user input
    - * @returns {Promise}
    - */
    -function input() {
    +function input()
    +{
    +    var input_element;
    +    var input_str;
    +    
         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);
    -            }
    -        });
    -    });
    +                       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);
    +                                                      }
    +                                                      });
    +                       });
     }
     
    -/**
    - * Create a string consisting of the given number of spaces
    - * @param spaceCount
    - * @returns {string}
    - */
    -function tab(spaceCount) {
    -    let str = "";
    -    while (spaceCount-- > 0)
    +function tab(space)
    +{
    +    var str = "";
    +    while (space-- > 0)
             str += " ";
         return str;
     }
     
    -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.
    - */
    -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;
    -    }
    -
    -    get year() {
    -        return this.#year;
    -    }
    -
    -    get month() {
    -        return this.#month;
    -    }
    -
    -    get day() {
    -        return 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() {
    -        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;
    -    }
    -
    -    /**
    -     * 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}
    -     */
    -    toString() {
    -        return this.#month + "/" + this.#day + "/" + this.#year;
    -    }
    +function fna(arg) {
    +    return Math.floor(arg / 4);
     }
     
    -/**
    - * Duration representation.
    - * Note: this class only handles positive durations well
    - */
    -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;
    -        this.#fixRanges();
    -    }
    -
    -    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;
    -        this.#fixRanges();
    -    }
    -
    -    /**
    -     * Move days and months into expected range.
    -     */
    -    #fixRanges() {
    -        if (this.#days < 0) {
    -            this.#days += DAYS_PER_IDEALISED_MONTH;
    -            this.#months--;
    -        }
    -        if (this.#months < 0) {
    -            this.#months += MONTHS_PER_YEAR;
    -            this.#years--;
    -        }
    -    }
    -
    -    /**
    -     * 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.
    -     * @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;
    -        return new Duration(years, months, days);
    -    }
    +function fnb(arg) {
    +    return Math.floor(arg / 7);
    +}
     
    -    /**
    -     * 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);
    -    }
    +var t = [, 0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5];
    +
    +var k5;
    +var k6;
    +var k7;
    +
    +function time_spent(f, a8)
    +{
    +    k1 = Math.floor(f * a8);
    +    i5 = Math.floor(k1 / 365);
    +    k1 -= i5 * 365;
    +    i6 = Math.floor(k1 / 30);
    +    i7 = k1 - (i6 * 30);
    +    k5 -= i5;
    +    k6 -= i6;
    +    k7 -= i7;
    +    if (k7 < 0) {
    +        k7 += 30;
    +        k6--;
    +    }
    +    if (k6 <= 0) {
    +        k6 += 12;
    +        k5--;
    +    }
    +    print(i5 + "\t" + i6 + "\t" + i7 + "\n");
     }
     
     // Main control section
    -async function main() {
    -    /**
    -     * 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);
    -    }
    -
    -    /**
    -     * 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;
    -    }
    -
    +async function main()
    +{
         print(tab(32) + "WEEKDAY\n");
         print(tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n");
         print("\n");
    @@ -351,69 +89,111 @@ 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 inputDate();
    +    str = await input();
    +    m1 = parseInt(str);
    +    d1 = parseInt(str.substr(str.indexOf(",") + 1));
    +    y1 = parseInt(str.substr(str.lastIndexOf(",") + 1));
         // This program determines the day of the week
         //  for a date after 1582
         print("ENTER DAY OF BIRTH (OR OTHER DAY OF INTEREST)");
    -    const dateOfBirth = await inputDate();
    +    str = await input();
    +    m = parseInt(str);
    +    d = parseInt(str.substr(str.indexOf(",") + 1));
    +    y = parseInt(str.substr(str.lastIndexOf(",") + 1));
         print("\n");
    +    i1 = Math.floor((y - 1500) / 100);
         // Test for date before current calendar.
    -    if (!dateOfBirth.isGregorianDate()) {
    -        print("NOT PREPARED TO GIVE DAY OF WEEK PRIOR TO X.XV.MDLXXXII.\n");
    +    if (y - 1582 < 0) {
    +        print("NOT PREPARED TO GIVE DAY OF WEEK PRIOR TO MDLXXXII.\n");
         } else {
    -        const normalisedToday = today.getNormalisedDay();
    -        const normalisedDob = dateOfBirth.getNormalisedDay();
    -
    -        let dayOfWeekText = getDayOfWeekText(dateOfBirth);
    -        if (normalisedToday < normalisedDob) {
    -            print(dateOfBirth + " WILL BE A " + dayOfWeekText + "\n");
    -        } else if (normalisedToday === normalisedDob) {
    -            print(dateOfBirth + " IS A " + dayOfWeekText + "\n");
    +        a = i1 * 5 + (i1 + 3) / 4;
    +        i2 = Math.floor(a - fnb(a) * 7);
    +        y2 = Math.floor(y / 100);
    +        y3 = Math.floor(y - y2 * 100);
    +        a = y3 / 4 + y3 + d + t[m] + i2;
    +        b = Math.floor(a - fnb(a) * 7) + 1;
    +        if (m <= 2) {
    +            if (y3 != 0) {
    +                t1 = Math.floor(y - fna(y) * 4);
    +            } else {
    +                a = i1 - 1;
    +                t1 = Math.floor(a - fna(a) * 4);
    +            }
    +            if (t1 == 0) {
    +                if (b == 0)
    +                    b = 6;
    +                b--;
    +            }
    +        }
    +        if (b == 0)
    +            b = 7;
    +        if ((y1 * 12 + m1) * 31 + d1 < (y * 12 + m) * 31 + d) {
    +            print(m + "/" + d + "/" + y + " WILL BE A ");
    +        } else if ((y1 * 12 + m1) * 31 + d1 == (y * 12 + m) * 31 + d) {
    +            print(m + "/" + d + "/" + y + " IS A ");
             } else {
    -            print(dateOfBirth + " WAS A " + dayOfWeekText + "\n");
    +            print(m + "/" + d + "/" + y + " WAS A ");
             }
    -
    -        if (normalisedToday !== normalisedDob) {
    +        switch (b) {
    +            case 1: print("SUNDAY.\n"); break;
    +            case 2: print("MONDAY.\n"); break;
    +            case 3: print("TUESDAY.\n"); break;
    +            case 4: print("WEDNESDAY.\n"); break;
    +            case 5: print("THURSDAY.\n"); break;
    +            case 6:
    +                if (d == 13) {
    +                    print("FRIDAY THE THIRTEENTH---BEWARE!\n");
    +                } else {
    +                    print("FRIDAY.\n");
    +                }
    +                break;
    +            case 7: print("SATURDAY.\n"); break;
    +        }
    +        if ((y1 * 12 + m1) * 31 + d1 != (y * 12 + m) * 31 + d) {
    +            i5 = y1 - y;
                 print("\n");
    -            let differenceBetweenDates = Duration.between(today, dateOfBirth);
    -            if (differenceBetweenDates.years >= 0) {
    -                if (differenceBetweenDates.days === 0 && differenceBetweenDates.months === 0) {
    +            i6 = m1 - m;
    +            i7 = d1 - d;
    +            if (i7 < 0) {
    +                i6--;
    +                i7 += 30;
    +            }
    +            if (i6 < 0) {
    +                i5--;
    +                i6 += 12;
    +            }
    +            if (i5 >= 0) {
    +                if (i7 == 0 && i6 == 0)
                         print("***HAPPY BIRTHDAY***\n");
    -                }
                     print("                        \tYEARS\tMONTHS\tDAYS\n");
                     print("                        \t-----\t------\t----\n");
    -                print("YOUR AGE (IF BIRTHDATE) \t" + differenceBetweenDates + "\n");
    -
    -                const approximateDaysBetween = differenceBetweenDates.getApproximateDays();
    -                const unaccountedTime = differenceBetweenDates.clone();
    -
    -                // 35% sleeping
    -                const sleepTimeSpent = Duration.fromDays(approximateDaysBetween, 0.35);
    -                print("YOU HAVE SLEPT \t\t\t" + sleepTimeSpent + "\n");
    -                unaccountedTime.remove(sleepTimeSpent);
    -
    -                // 17% eating
    -                const eatenTimeSpent = Duration.fromDays(approximateDaysBetween, 0.17);
    -                print("YOU HAVE EATEN \t\t\t" + eatenTimeSpent + "\n");
    -                unaccountedTime.remove(eatenTimeSpent);
    -
    -                // 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");
    +                print("YOUR AGE (IF BIRTHDATE) \t" + i5 + "\t" + i6 + "\t" + i7 + "\n");
    +                a8 = (i5 * 365) + (i6 * 30) + i7 + Math.floor(i6 / 2);
    +                k5 = i5;
    +                k6 = i6;
    +                k7 = i7;
    +                // Calculate retirement date.
    +                e = y + 65;
    +                // Calculate time spent in the following functions.
    +                print("YOU HAVE SLEPT \t\t\t");
    +                time_spent(0.35, a8);
    +                print("YOU HAVE EATEN \t\t\t");
    +                time_spent(0.17, a8);
    +                if (k5 <= 3) {
    +                    print("YOU HAVE PLAYED \t\t\t");
    +                } else if (k5 <= 9) {
    +                    print("YOU HAVE PLAYED/STUDIED \t\t");
                     } else {
    -                    print("YOU HAVE WORKED/PLAYED \t\t" + workPlayTimeSpent + "\n");
    +                    print("YOU HAVE WORKED/PLAYED \t\t");
                     }
    -                unaccountedTime.remove(workPlayTimeSpent);
    -
    -                // Remaining time spent relaxing
    -                print("YOU HAVE RELAXED \t\t" + unaccountedTime + "\n");
    -
    -                const retirementYear = dateOfBirth.year + 65;
    +                time_spent(0.23, a8);
    +                if (k6 == 12) {
    +                    k5++;
    +                    k6 = 0;
    +                }
    +                print("YOU HAVE RELAXED \t\t" + k5 + "\t" + k6 + "\t" + k7 + "\n");
                     print("\n");
    -                print(tab(16) + "***  YOU MAY RETIRE IN " + retirementYear + " ***\n");
    +                print(tab(16) + "***  YOU MAY RETIRE IN " + e + " ***\n");
                     print("\n");
                 }
             }
    diff --git a/95_Weekday/kotlin/README.md b/95_Weekday/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/95_Weekday/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/95_Weekday/lua/README.md b/95_Weekday/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/95_Weekday/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/95_Weekday/pascal/README.md b/95_Weekday/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/95_Weekday/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/95_Weekday/perl/README.md b/95_Weekday/perl/README.md
    index ac8ee399c..e69c8b819 100644
    --- a/95_Weekday/perl/README.md
    +++ b/95_Weekday/perl/README.md
    @@ -1,20 +1,3 @@
     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
    deleted file mode 100755
    index e1820af6d..000000000
    --- a/95_Weekday/perl/weekday.pl
    +++ /dev/null
    @@ -1,249 +0,0 @@
    -#!/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 :
    diff --git a/95_Weekday/python/weekday.py b/95_Weekday/python/weekday.py
    index 0a6b0aabd..29750279e 100644
    --- a/95_Weekday/python/weekday.py
    +++ b/95_Weekday/python/weekday.py
    @@ -12,30 +12,35 @@
     """
     
     import datetime
    -from typing import Tuple
     
     GET_TODAY_FROM_SYSTEM = True
     
     
    -def get_date_from_user(prompt: str) -> Tuple[int, int, int]:
    +def print_with_tab(space_count, s):
    +    if space_count > 0:
    +        spaces = " " * space_count
    +    else:
    +        spaces = ""
    +    print(spaces + s)
    +
    +
    +def get_date_from_user(prompt):
         while True:
             print(prompt)
             date_str = input()
             try:
    -            month_num, day_num, year_num = (int(x) for x in date_str.split(","))
    -            return month_num, day_num, year_num
    -        except Exception:
    +            month_num, day_num, year_num = [int(x) for x in date_str.split(",")]
    +        except Exception as e:
                 print("I COULDN'T UNDERSTAND THAT. TRY AGAIN.")
    +        return month_num, day_num, year_num
     
     
    -def get_date_from_system() -> Tuple[int, int, int]:
    -    dt = datetime.datetime.now()
    +def get_date_from_system():
    +    dt = datetime.datetime.today()
         return dt.month, dt.day, dt.year
     
     
    -def get_day_of_week(weekday_index, day) -> str:
    -    if weekday_index == 6 and day == 13:
    -        return "FRIDAY THE THIRTEENTH---BEWARE!"
    +def get_day_of_week(weekday_index, day):
         day_names = {
             1: "SUNDAY",
             2: "MONDAY",
    @@ -46,19 +51,25 @@ def get_day_of_week(weekday_index, day) -> str:
             7: "SATURDAY",
         }
     
    +    if weekday_index == 6 and day == 13:
    +        return "FRIDAY THE THIRTEENTH---BEWARE!"
         return day_names[weekday_index]
     
     
    -def previous_day(b) -> int:
    +def previous_day(b):
         if b == 0:
             b = 6
         return b - 1
     
     
    -def is_leap_year(year: int) -> bool:
    +def is_leap_year(year):
         if (year % 4) != 0:
             return False
    -    return True if (year % 100) != 0 else year % 400 == 0
    +    if (year % 100) != 0:
    +        return True
    +    if (year % 400) != 0:
    +        return False
    +    return True
     
     
     def adjust_day_for_leap_year(b, year):
    @@ -82,9 +93,9 @@ def calc_day_value(year, month, day):
     def deduct_time(frac, days, years_remain, months_remain, days_remain):
         # CALCULATE TIME IN YEARS, MONTHS, AND DAYS
         days_available = int(frac * days)
    -    years_used = days_available // 365
    +    years_used = int(days_available / 365)
         days_available -= years_used * 365
    -    months_used = days_available // 30
    +    months_used = int(days_available / 30)
         days_used = days_available - (months_used * 30)
         years_remain = years_remain - years_used
         months_remain = months_remain - months_used
    @@ -102,7 +113,7 @@ def deduct_time(frac, days, years_remain, months_remain, days_remain):
     
     def time_report(msg, years, months, days):
         leading_spaces = 23 - len(msg)
    -    print(" " * leading_spaces + f"{msg}\t{years}\t{months}\t{days}")
    +    print_with_tab(leading_spaces, msg + f"\t{years}\t{months}\t{days}")
     
     
     def make_occupation_label(years):
    @@ -130,14 +141,17 @@ def calculate_day_of_week(year, month, day):
         return b
     
     
    -def end() -> None:
    -    for _ in range(5):
    +def end():
    +    for i in range(5):
             print()
     
     
    -def main() -> None:
    -    print(" " * 32 + "WEEKDAY")
    -    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n\n\n")
    +def main():
    +    print_with_tab(32, "WEEKDAY")
    +    print_with_tab(15, "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
    +    print()
    +    print()
    +    print()
         print("WEEKDAY IS A COMPUTER DEMONSTRATION THAT")
         print("GIVES FACTS ABOUT A DATE OF INTEREST TO YOU.")
         print()
    @@ -172,9 +186,11 @@ def main() -> None:
         target_day_value = calc_day_value(year, month, day)
     
         is_today = False
    +    is_future = False
     
         if today_day_value < target_day_value:
             label = "WILL BE A"
    +        is_future = False
         elif today_day_value == target_day_value:
             label = "IS A"
             is_today = True
    @@ -212,8 +228,8 @@ def main() -> None:
             print("***HAPPY BIRTHDAY***")
     
         # print report
    -    print(" " * 23 + "\tYEARS\tMONTHS\tDAYS")
    -    print(" " * 23 + "\t-----\t------\t----")
    +    print_with_tab(23, "\tYEARS\tMONTHS\tDAYS")
    +    print_with_tab(23, "\t-----\t------\t----")
         print(f"YOUR AGE (IF BIRTHDATE)\t{el_years}\t{el_months}\t{el_days}")
     
         life_days = (el_years * 365) + (el_months * 30) + el_days + int(el_months / 2)
    @@ -234,16 +250,39 @@ def main() -> None:
         rem_years, rem_months, rem_days, used_years, used_months, used_days = deduct_time(
             0.23, life_days, rem_years, rem_months, rem_days
         )
    -    time_report(f"YOU HAVE {label}", used_years, used_months, used_days)
    +    time_report("YOU HAVE " + label, used_years, used_months, used_days)
         time_report("YOU HAVE RELAXED", rem_years, rem_months, rem_days)
     
         print()
     
         # Calculate retirement date
         e = year + 65
    -    print(" " * 16 + f"***  YOU MAY RETIRE IN {e} ***")
    +    print_with_tab(16, f"***  YOU MAY RETIRE IN {e} ***")
         end()
     
     
    +def test_weekday_calc(year, month, day):
    +    dt = datetime.date(year, month, day)
    +    python_weekday = dt.weekday()  # Monday = 0, Sunday = 6
    +
    +    basic_weekday = calculate_day_of_week(year, month, day)  # Sunday = 1, Saturday = 7
    +
    +    test = ((python_weekday + 2) % 7) == (basic_weekday % 7)
    +    if test == False:
    +        print(f"testing yr {year} month {month} day {day}")
    +        print(f"python says {python_weekday}")
    +        print(f"BASIC says {basic_weekday}")
    +        assert False
    +
    +
    +def test_harness():
    +    for yr in range(1600, 2021):
    +        for m in range(1, 12):
    +            for d in range(1, 28):
    +                test_weekday_calc(yr, m, d)
    +
    +
     if __name__ == "__main__":
         main()
    +
    +    # test_harness()
    diff --git a/95_Weekday/rust/Cargo.lock b/95_Weekday/rust/Cargo.lock
    deleted file mode 100644
    index b21cc6a2d..000000000
    --- a/95_Weekday/rust/Cargo.lock
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    diff --git a/95_Weekday/rust/Cargo.toml b/95_Weekday/rust/Cargo.toml
    deleted file mode 100644
    index 1ec696335..000000000
    --- a/95_Weekday/rust/Cargo.toml
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -[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]
    diff --git a/95_Weekday/rust/README.md b/95_Weekday/rust/README.md
    deleted file mode 100644
    index 7e85f9a15..000000000
    --- a/95_Weekday/rust/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Rust](https://www.rust-lang.org/) by Anthony Rubick [AnthonyMichaelTDM](https://github.com/AnthonyMichaelTDM)
    diff --git a/95_Weekday/rust/src/main.rs b/95_Weekday/rust/src/main.rs
    deleted file mode 100644
    index 47d3ae9a9..000000000
    --- a/95_Weekday/rust/src/main.rs
    +++ /dev/null
    @@ -1,305 +0,0 @@
    -use std::io::{self, stdout, Write};
    -
    -struct DATE {
    -    month: u32,
    -    day: u32,
    -    year:u32,
    -    day_of_week:u32,
    -}
    -impl DATE {
    -    /**
    -     * create new date with given paramets
    -     */
    -    fn new(month:u32,day:u32,year:u32,day_of_week:u32) -> DATE {
    -        return DATE { month: month, day: day, year: year, day_of_week: day_of_week };
    -    }
    -    /**
    -     * create date from user input
    -     */
    -    fn new_from_input(prompt:&str) -> DATE {
    -        //DATA
    -        let mut raw_date: Vec;
    -        //get date
    -        //input loop
    -        loop {
    -            //get user input,
    -            raw_date = get_str_from_user(prompt)
    -            .split(',')//split it up by ',''s
    -            .filter_map(|s| s.parse::().ok()).collect();//convert it to numbers, ignore things that fail
    -            
    -            //if they didn't give enough data
    -            if raw_date.len() == 3 { //is it long enough? (3 elements)
    -                //are each ones valid things?
    -                if (1..=12).contains(&raw_date[0]) { //valid month
    -                    if (1..=31).contains(&raw_date[1]) { //valid day
    -                        break;
    -                    }
    -                }
    -            }
    -            //otherwise, print error message and go again
    -            println!("Invalid date, try again!");
    -        }
    -
    -        //create date
    -        let mut date =DATE::new(raw_date[0], raw_date[1], raw_date[2], 0);
    -        date.update_day_of_week();
    -        //return date
    -        return date
    -    }
    -    /**
    -     * create a new date from a number of days
    -     */
    -    fn new_from_days(days:u32) -> DATE{
    -        let mut days_remaining = days;
    -        let d;
    -        let m;
    -        let y;
    -
    -        //get the years
    -        y=(days_remaining as f64 / 365.25) as u32;
    -        //deduct
    -        days_remaining = (days_remaining as f64 % 365.25) as u32;
    -
    -        //get months
    -        m=(days_remaining as f64 / 30.437) as u32;
    -        //deduct
    -        days_remaining = (days_remaining as f64 % 30.437) as u32;
    -
    -        //get days
    -        d = days_remaining;
    -
    -        //return new date
    -        return DATE::new(m, d, y, 0);
    -    }
    -
    -    /**
    -     * caluclates the day of the week (1-7)
    -     * uses the methodology found here: https://cs.uwaterloo.ca/~alopez-o/math-faq/node73.html
    -     */
    -    fn update_day_of_week(&mut self) {
    -        //DATA
    -        let day = self.day as isize;
    -        let month = self.month as isize;
    -        let year = self.year as isize;
    -        let century = year/100;
    -        let year_of_century = year - century*100;
    -        let weekday; //as 0-6
    -
    -        //calculate weekday
    -        if self.month <= 2 { //if jan or feb
    -            weekday = (day + (2.6 * ((month+10) as f64)-0.2)as isize - 2*century + (year_of_century-1) + (year_of_century-1)/4 + century/4) % 7;
    -        } else {
    -            weekday = (day + (2.6 * ((month-2)  as f64)-0.2)as isize - 2*century + year_of_century     + year_of_century/4     + century/4) % 7;
    -        }
    -
    -        //update weekday
    -        self.day_of_week=(weekday+1) as u32; //weekday as 1-7
    -    }
    -
    -    /**
    -     * return the string for the weekday
    -     */
    -    fn day_of_week_as_string(&self) -> String {
    -        match self.day_of_week {
    -            1 => {return String::from("SUNDAY")},
    -            2 => {return String::from("MONDAY")},
    -            3 => {return String::from("TUESDAY")},
    -            4 => {return String::from("WEDNESDAY")},
    -            5 => {return String::from("THURSDAY")},
    -            6 => {
    -                if self.day == 13 {return String::from("FRIDAY THE THIRTEENTH---BEWARE!")}
    -                else {return String::from("FRIDAY")}
    -            },
    -            7 => {return String::from("SATURDAY")}, 
    -            _ => {return String::from("")},
    -        }
    -    }
    -
    -    /**
    -     * is the year a leap_year
    -     */
    -    fn _is_leap_year(&self) -> bool{
    -        if self.year % 4 != 0 {
    -            return false;
    -        } else if self.year %100 != 0 {
    -            return true;
    -        } else if self.year % 400 != 0 {
    -            return false;
    -        } else {
    -            return true;
    -        }
    -    }
    -
    -    /**
    -     * calculates the day value, number of days the date represents
    -     */
    -    fn calc_days(&self) -> u32 {
    -        return (self.year as f64 * 365.25)as u32 + self.month*30 + self.day + self.month/2;
    -    }
    -
    -    /**
    -     * calculates the time difference between self and the passed date,
    -     */
    -    fn time_since(&self, other: &DATE) -> Option {
    -        //DATA
    -        // /*
    -        let diff = self.calc_days()as i32 - other.calc_days()as i32;
    -        if diff < 0 { 
    -            return None;
    -        } else {
    -            return Some(DATE::new_from_days(diff as u32));
    -        }
    -    }
    -
    -    /**
    -     * formats the date in a different format, used for time table
    -     */
    -    fn format_ymd(&self, spacer:&str) -> String {
    -        return format!(
    -            "{}{}{}{}{}",
    -            self.year, spacer,
    -            self.month, spacer,
    -            self.day,
    -        );
    -    }
    -}
    -impl ToString for DATE {
    -    fn to_string(&self) -> String {
    -        return format!("{}/{}/{}",self.month,self.day,self.year);
    -    }
    -}
    -
    -fn main() {
    -    //DATA
    -    let today_date: DATE;
    -    let other_date:DATE;
    -    let delta_date:DATE; //represents the difference between the two dates
    -    let today_value;
    -    let other_day_value;
    -    let mut other_is_today = false;
    -
    -    //print welcome
    -    welcome();
    -    
    -    //get todays date
    -    today_date = DATE::new_from_input("ENTER TODAY'S DATE IN THE FORM: 3,24,1979  ");
    -    //check todays date
    -    if today_date.year < 1582 {
    -        println!("NOT PREPARED TO GIVE DAY OF WEEK PRIOR TO MDLXXXII.");
    -        return;
    -    }
    -
    -    println!();
    -
    -    //get other date
    -    other_date = DATE::new_from_input("ENTER DAY OF BIRTH (OR OTHER DAY OF INTEREST) (like MM,DD,YYYY)");
    -    //check other date
    -    if other_date.year < 1582 {
    -        println!("NOT PREPARED TO GIVE DAY OF WEEK PRIOR TO MDLXXXII.");
    -        return;
    -    }
    -
    -    //do some calculations
    -    today_value = today_date.calc_days();
    -    other_day_value = other_date.calc_days();
    -
    -    //print the other date in a nice format
    -    println!(
    -        "{} {} A {}",
    -        other_date.to_string(),
    -        { //use proper tense of To Be
    -            if today_value < other_day_value {"WILL BE"}
    -            else if today_value == other_day_value {other_is_today=true;"IS"}
    -            else {"WAS"}
    -        },
    -        other_date.day_of_week_as_string(),
    -    );
    -
    -    //end if both days are the same
    -    if other_is_today {
    -        return;
    -    } 
    -
    -    //create date representing the difference between the two dates
    -    delta_date = today_date.time_since(&other_date).unwrap();
    -
    -    //print happy birthday message
    -    if delta_date.month == 0 && delta_date.day == 0 {
    -        println!("***HAPPY BIRTHDAY***");
    -    }
    -
    -    //print report
    -    println!("
    -                      \tYEARS\tMONTHS\tDAYS
    -                      \t-----\t------\t----"
    -    );
    -    println!("YOUR AGE (IF BIRTHDATE)\t{}", delta_date.format_ymd("\t"));
    -    
    -    //how much have they slept
    -    println!(
    -        "YOU HAVE SLEPT\t\t{}",
    -        DATE::new_from_days( (0.35 * delta_date.calc_days() as f64) as u32).format_ymd("\t"), //35% of their life
    -    );
    -
    -    //how much they have eaten
    -    println!(
    -        "YOU HAVE EATEN\t\t{}",
    -        DATE::new_from_days( (0.17 * delta_date.calc_days() as f64) as u32).format_ymd("\t"), //17% of their life
    -    );
    -
    -    //how much they have worked
    -    println!(
    -        "YOU HAVE {}\t{}",
    -        {
    -            if delta_date.year <= 3 {"PLAYED"}
    -            else if delta_date.year <= 9 {"PLAYED/STUDIED"}
    -            else {"WORKED/PLAYED"}
    -        },
    -        DATE::new_from_days( (0.23 * delta_date.calc_days() as f64) as u32).format_ymd("\t"), //23% of their life
    -    );
    -    //how much they have relaxed
    -    println!(
    -        "YOU HAVE RELAXED\t{}",
    -        DATE::new_from_days( ( (1.0-0.35-0.17-0.23) * delta_date.calc_days() as f64) as u32).format_ymd("\t"), //remaining% of their life
    -    );
    -    //when they can retire
    -    println!(
    -        "YOU MAY RETIRE IN\t{}",
    -        DATE::new(other_date.month, other_date.day, other_date.year + 65, 0).time_since(&today_date).unwrap().format_ymd("\t")
    -    );
    -}
    -
    -
    -/**
    - * print welome message
    - */
    -fn welcome() {
    -    println!("
    -                               WEEKDAY
    -              CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY
    -    
    -    
    -    
    -    WEEKDAY IS A COMPUTER DEMONSTRATION THAT
    -    GIVES FACTS ABOUT A DATE OF INTEREST TO YOU.
    -    ");
    -}
    -
    -/**
    - * gets a string from user input
    - */
    -fn get_str_from_user(prompt:&str) -> String {
    -    //DATA
    -    let mut raw_input = String::new();
    -
    -    //print prompt
    -    print!("{}",prompt);
    -    //flust std out //allows prompt to be on same line as input
    -    stdout().flush().expect("failed to flush");
    -
    -    //get input and trim whitespaces
    -    io::stdin().read_line(&mut raw_input).expect("Failed to read input");
    -
    -    //return raw input
    -    return raw_input.trim().to_string();
    -}
    diff --git a/95_Weekday/vbnet/Weekday.sln b/95_Weekday/vbnet/Weekday.sln
    deleted file mode 100644
    index 7bbbb17ae..000000000
    --- a/95_Weekday/vbnet/Weekday.sln
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -
    -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
    deleted file mode 100644
    index dfa9996c1..000000000
    --- a/95_Weekday/vbnet/Weekday.vbproj
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -
    -  
    -    Exe
    -    Weekday
    -    net6.0
    -    16.9
    -  
    -
    diff --git a/95_Weekday/weekday.bas b/95_Weekday/weekday.bas
    index 33f982e88..77efcaea9 100644
    --- a/95_Weekday/weekday.bas
    +++ b/95_Weekday/weekday.bas
    @@ -104,7 +104,7 @@
     1080 GOSUB 1370
     1085 GOTO 1530
     1090 PRINT "YOU HAVE RELAXED ",K5,K6,K7
    -1100 PRINT
    +1100 PRINT 
     1110 PRINT TAB(16);"***  YOU MAY RETIRE IN";E;" ***"
     1120 PRINT
     1140 PRINT
    diff --git a/96_Word/README.md b/96_Word/README.md
    index 5672fe030..8db22c6cc 100644
    --- a/96_Word/README.md
    +++ b/96_Word/README.md
    @@ -14,7 +14,3 @@ As published in Basic Computer Games (1978):
     
     Downloaded from Vintage Basic at
     http://www.vintage-basic.net/games.html
    -
    -#### Porting Notes
    -
    -(please note any difficulties or challenges in porting here)
    diff --git a/96_Word/csharp/Program.cs b/96_Word/csharp/Program.cs
    index 2e2749608..464787c50 100644
    --- a/96_Word/csharp/Program.cs
    +++ b/96_Word/csharp/Program.cs
    @@ -40,7 +40,7 @@ private string get_guess()
                     if ((guess.Length != 5) || (guess.Equals("?")) || (!guess.All(char.IsLetter)))
                     {
                         guess = "";
    -                    Console.WriteLine("You must guess a five letter word. Start again.");
    +                    Console.WriteLine("You must guess a give letter word. Start again.");
                     }
                 }
     
    @@ -58,7 +58,7 @@ private string get_guess()
             /// The integer value showing the number of character matches between guess and target
             private int check_guess(string guess, string target, StringBuilder progress)
             {
    -            // Go through each letter of the guess and see which
    +            // Go through each letter of the guess and see which 
                 // letters match up to the target word.
                 // For each position that matches, update the progress
                 // to reflect the guess
    diff --git a/96_Word/csharp/word.sln b/96_Word/csharp/word.sln
    index 77360e815..59bdec971 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 17
    -VisualStudioVersion = 17.0.32014.148
    +# Visual Studio Version 16
    +VisualStudioVersion = 16.0.31321.278
     MinimumVisualStudioVersion = 10.0.40219.1
    -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Word", "Word.csproj", "{E2CF183B-EBC3-497C-8D34-32EBEE4E2B73}"
    +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "word", "word.csproj", "{E2CF183B-EBC3-497C-8D34-32EBEE4E2B73}"
     EndProject
     Global
     	GlobalSection(SolutionConfigurationPlatforms) = preSolution
    diff --git a/96_Word/java/Word.java b/96_Word/java/Word.java
    index d8bde3d9e..7cae9124b 100644
    --- a/96_Word/java/Word.java
    +++ b/96_Word/java/Word.java
    @@ -9,215 +9,215 @@
      * 

    * Note: The idea was to create a version of the 1970's BASIC game in Java, without introducing * new features - no additional text, error checking, etc has been added. - * + * * Converted from BASIC to Java by Darren Cardenas. */ - + public class Word { - - private final static String[] WORDS = { + + private final static String[] WORDS = { "DINKY", "SMOKE", "WATER", "GRASS", "TRAIN", "MIGHT", "FIRST", "CANDY", "CHAMP", "WOULD", "CLUMP", "DOPEY" }; - + private final Scanner scan; // For user input - + private enum Step { INITIALIZE, MAKE_GUESS, USER_WINS - } - + } + public Word() { + + scan = new Scanner(System.in); - scan = new Scanner(System.in); - - } // End of constructor Word - + } // End of constructor Word + public void play() { showIntro(); startGame(); - } // End of method play - - private void showIntro() { - + } // End of method play + + private void showIntro() { + System.out.println(" ".repeat(32) + "WORD"); System.out.println(" ".repeat(14) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); System.out.println("\n\n"); - + System.out.println("I AM THINKING OF A WORD -- YOU GUESS IT. I WILL GIVE YOU"); System.out.println("CLUES TO HELP YOU GET IT. GOOD LUCK!!"); System.out.println("\n"); + + } // End of method showIntro - } // End of method showIntro - - private void startGame() { - + private void startGame() { + char[] commonLetters = new char[8]; char[] exactLetters = new char[8]; - + int commonIndex = 0; int ii = 0; // Loop iterator - int jj = 0; // Loop iterator + int jj = 0; // Loop iterator int numGuesses = 0; int numMatches = 0; int wordIndex = 0; + + Step nextStep = Step.INITIALIZE; - Step nextStep = Step.INITIALIZE; - - String commonString = ""; + String commonString = ""; String exactString = ""; String guessWord = ""; - String secretWord = ""; + String secretWord = ""; String userResponse = ""; - // Begin outer while loop + // Begin outer while loop while (true) { - + switch (nextStep) { case INITIALIZE: - + System.out.println("\n"); System.out.println("YOU ARE STARTING A NEW GAME..."); // Select a secret word from the list wordIndex = (int) (Math.random() * WORDS.length); - secretWord = WORDS[wordIndex]; - + secretWord = WORDS[wordIndex]; + numGuesses = 0; - + Arrays.fill(exactLetters, 1, 6, '-'); Arrays.fill(commonLetters, 1, 6, '\0'); nextStep = Step.MAKE_GUESS; - break; - + break; + case MAKE_GUESS: - + System.out.print("GUESS A FIVE LETTER WORD? "); guessWord = scan.nextLine().toUpperCase(); numGuesses++; - + // Win condition - if (guessWord.equals(secretWord)) { + if (guessWord.equals(secretWord)) { nextStep = Step.USER_WINS; continue; } - - Arrays.fill(commonLetters, 1, 8, '\0'); + + Arrays.fill(commonLetters, 1, 8, '\0'); // Surrender condition - if (guessWord.equals("?")) { + if (guessWord.equals("?")) { System.out.println("THE SECRET WORD IS " + secretWord); System.out.println(""); nextStep = Step.INITIALIZE; // Play again - continue; + continue; } - + // Check for valid input - if (guessWord.length() != 5) { - System.out.println("YOU MUST GUESS A 5 LETTER WORD. START AGAIN."); + if (guessWord.length() != 5) { + System.out.println("YOU MUST GUESS A 5 LETTER WORD. START AGAIN."); numGuesses--; nextStep = Step.MAKE_GUESS; // Guess again - continue; + continue; } - + numMatches = 0; - commonIndex = 1; - - for (ii = 1; ii <= 5; ii++) { - - for (jj = 1; jj <= 5; jj++) { - - if (secretWord.charAt(ii - 1) != guessWord.charAt(jj - 1)) { - continue; - } + commonIndex = 1; + + for (ii = 1; ii <= 5; ii++) { + + for (jj = 1; jj <= 5; jj++) { + + if (secretWord.charAt(ii - 1) != guessWord.charAt(jj - 1)) { + continue; + } // Avoid out of bounds errors if (commonIndex <= 5) { commonLetters[commonIndex] = guessWord.charAt(jj - 1); commonIndex++; - } + } - if (ii == jj) { - exactLetters[jj] = guessWord.charAt(jj - 1); + if (ii == jj) { + exactLetters[jj] = guessWord.charAt(jj - 1); } - + // Avoid out of bounds errors if (numMatches < 5) { numMatches++; } - } + } } - + exactString = ""; commonString = ""; - + // Build the exact letters string - for (ii = 1; ii <= 5; ii++) { - exactString += exactLetters[ii]; + for (ii = 1; ii <= 5; ii++) { + exactString += exactLetters[ii]; } - + // Build the common letters string - for (ii = 1; ii <= numMatches; ii++) { - commonString += commonLetters[ii]; + for (ii = 1; ii <= numMatches; ii++) { + commonString += commonLetters[ii]; } - - System.out.println("THERE WERE " + numMatches + " MATCHES AND THE COMMON LETTERS WERE..." + + System.out.println("THERE WERE " + numMatches + " MATCHES AND THE COMMON LETTERS WERE..." + commonString); - + System.out.println("FROM THE EXACT LETTER MATCHES, YOU KNOW................" + exactString); - + // Win condition - if (exactString.equals(secretWord)) { + if (exactString.equals(secretWord)) { nextStep = Step.USER_WINS; - continue; + continue; } - + // No matches if (numMatches <= 1) { System.out.println(""); System.out.println("IF YOU GIVE UP, TYPE '?' FOR YOUR NEXT GUESS."); } - + System.out.println(""); nextStep = Step.MAKE_GUESS; - break; - + break; + case USER_WINS: - + System.out.println("YOU HAVE GUESSED THE WORD. IT TOOK " + numGuesses + " GUESSES!"); System.out.println(""); - + System.out.print("WANT TO PLAY AGAIN? "); userResponse = scan.nextLine(); - if (userResponse.toUpperCase().equals("YES")) { - nextStep = Step.INITIALIZE; // Play again - } else { - return; // Quit game - } + if (userResponse.toUpperCase().equals("YES")) { + nextStep = Step.INITIALIZE; // Play again + } else { + return; // Quit game + } break; - + default: System.out.println("INVALID STEP"); - break; - - } - - } // End outer while loop + break; + } + + } // End outer while loop + } // End of method startGame - + public static void main(String[] args) { - + Word word = new Word(); word.play(); - + } // End of method main } // End of class Word diff --git a/96_Word/javascript/word.html b/96_Word/javascript/word.html new file mode 100644 index 000000000..ddc881344 --- /dev/null +++ b/96_Word/javascript/word.html @@ -0,0 +1,9 @@ + + +WORD + + +

    
    +
    +
    +
    diff --git a/96_Word/javascript/word.js b/96_Word/javascript/word.js
    new file mode 100644
    index 000000000..4df5d3fd3
    --- /dev/null
    +++ b/96_Word/javascript/word.js
    @@ -0,0 +1,150 @@
    +// WORD
    +//
    +// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
    +//
    +
    +function print(str)
    +{
    +    document.getElementById("output").appendChild(document.createTextNode(str));
    +}
    +
    +function input()
    +{
    +    var input_element;
    +    var input_str;
    +
    +    return new Promise(function (resolve) {
    +                       input_element = document.createElement("INPUT");
    +
    +                       print("? ");
    +                       input_element.setAttribute("type", "text");
    +                       input_element.setAttribute("length", "50");
    +                       document.getElementById("output").appendChild(input_element);
    +                       input_element.focus();
    +                       input_str = undefined;
    +                       input_element.addEventListener("keydown", function (event) {
    +                                                      if (event.keyCode == 13) {
    +                                                      input_str = input_element.value;
    +                                                      document.getElementById("output").removeChild(input_element);
    +                                                      print(input_str);
    +                                                      print("\n");
    +                                                      resolve(input_str);
    +                                                      }
    +                                                      });
    +                       });
    +}
    +
    +function tab(space)
    +{
    +    var str = "";
    +    while (space-- > 0)
    +        str += " ";
    +    return str;
    +}
    +
    +var words = ["DINKY", "SMOKE", "WATER", "GLASS", "TRAIN",
    +             "MIGHT", "FIRST", "CANDY", "CHAMP", "WOULD",
    +             "CLUMP", "DOPEY"];
    +
    +var s = [];
    +var a = [];
    +var l = [];
    +var d = [];
    +var p = [];
    +
    +// Main control section
    +async function main()
    +{
    +    print(tab(33) + "WORD\n");
    +    print(tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n");
    +    print("\n");
    +    print("\n");
    +    print("\n");
    +    print("I AM THINKING OF A WORD -- YOU GUESS IT.  I WILL GIVE YOU\n");
    +    print("CLUES TO HELP YOU GET IT.  GOOD LUCK!!\n");
    +    print("\n");
    +    print("\n");
    +    while (1) {
    +        print("\n");
    +        print("\n");
    +        print("YOU ARE STARTING A NEW GAME...\n");
    +        n = words.length;
    +        ss = words[Math.floor(Math.random() * n)];
    +        g = 0;
    +        s[0] = ss.length;
    +        for (i = 1; i <= ss.length; i++)
    +            s[i] = ss.charCodeAt(i - 1);
    +        for (i = 1; i <= 5; i++)
    +            a[i] = 45;
    +        for (j = 1; j <= 5; j++)
    +            p[j] = 0;
    +        while (1) {
    +            print("GUESS A FIVE LETTER WORD");
    +            ls = await input();
    +            g++;
    +            if (ss == ls)
    +                break;
    +            for (i = 1; i <= 7; i++)
    +                p[i] = 0;
    +            l[0] = ls.length;
    +            for (i = 1; i <= ls.length; i++) {
    +                l[i] = ls.charCodeAt(i - 1);
    +            }
    +            if (l[1] == 63) {
    +                print("THE SECRET WORD IS " + ss + "\n");
    +                print("\n");
    +                break;
    +            }
    +            if (l[0] != 5) {
    +                print("YOU MUST GUESS A 5 LETTER WORD.  START AGAIN.\n");
    +                print("\n");
    +                g--;
    +                continue;
    +            }
    +            m = 0;
    +            q = 1;
    +            for (i = 1; i <= 5; i++) {
    +                for (j = 1; j <= 5; j++) {
    +                    if (s[i] == l[j]) {
    +                        p[q] = l[j];
    +                        q++;
    +                        if (i == j)
    +                            a[j] = l[j];
    +                        m++;
    +                    }
    +                }
    +            }
    +            a[0] = 5;
    +            p[0] = m;
    +            as = "";
    +            for (i = 1; i <= a[0]; i++)
    +                as += String.fromCharCode(a[i]);
    +            ps = "";
    +            for (i = 1; i <= p[0]; i++)
    +                ps += String.fromCharCode(p[i]);
    +            print("THERE WERE " + m + " MATCHES AND THE COMMON LETTERS WERE... " + ps + "\n");
    +            print("FROM THE EXACT LETTER MATCHES, YOU KNOW............ " + as + "\n");
    +            if (as == ss) {
    +                ls = as;
    +                break;
    +            }
    +            if (m <= 1) {
    +                print("\n");
    +                print("IF YOU GIVE UP, TYPE '?' FOR YOUR NEXT GUESS.\n");
    +                print("\n");
    +            }
    +        }
    +        if (ss == ls) {
    +            print("YOU HAVE GUESSED THE WORD.  IT TOOK " + g + " GUESSES!\n");
    +            print("\n");
    +        } else {
    +            continue;
    +        }
    +        print("WANT TO PLAY AGAIN");
    +        qs = await input();
    +        if (qs != "YES")
    +            break;
    +    }
    +}
    +
    +main();
    diff --git a/96_Word/javascript/word.mjs b/96_Word/javascript/word.mjs
    deleted file mode 100644
    index e4a1bd8ed..000000000
    --- a/96_Word/javascript/word.mjs
    +++ /dev/null
    @@ -1,114 +0,0 @@
    -#!/usr/bin/env node
    -// WORD
    -//
    -// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
    -
    -import { print, tab, input } from '../../00_Common/javascript/common.mjs';
    -
    -// 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 WORD_COUNT = WORDS.length;
    -
    -// Main control section
    -async function main()
    -{
    -    print(tab(33) + "WORD\n");
    -    print(tab(15) + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n");
    -    print("\n");
    -    print("\n");
    -    print("\n");
    -    print("I AM THINKING OF A WORD -- YOU GUESS IT.  I WILL GIVE YOU\n");
    -    print("CLUES TO HELP YOU GET IT.  GOOD LUCK!!\n");
    -    print("\n");
    -    print("\n");
    -    outer: while (1) {
    -        print("\n");
    -        print("\n");
    -        print("YOU ARE STARTING A NEW GAME...\n");
    -
    -        const secretWord = WORDS[Math.floor(Math.random() * WORD_COUNT)];
    -
    -        let guessCount = 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) {
    -                // The player has guessed correctly
    -                break;
    -            }
    -
    -            if (guess.charAt(0) === "?") {
    -                // Player has given up
    -                print("THE SECRET WORD IS " + secretWord + "\n");
    -                print("\n");
    -                // Start a new game by going to the start of the outer while loop
    -                continue outer;
    -            }
    -
    -            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;
    -            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++;
    -                    }
    -                }
    -            }
    -
    -            const lettersInCommonText = lettersInCommon.join("");
    -            print("THERE WERE " + lettersInCommonCount + " MATCHES AND THE COMMON LETTERS WERE... " + lettersInCommonText + "\n");
    -
    -            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");
    -            }
    -        }
    -
    -        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")
    -            break;
    -    }
    -}
    -
    -main();
    diff --git a/96_Word/kotlin/README.md b/96_Word/kotlin/README.md
    deleted file mode 100644
    index f43a5b700..000000000
    --- a/96_Word/kotlin/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Kotlin](https://kotlinlang.org/)
    diff --git a/96_Word/lua/README.md b/96_Word/lua/README.md
    deleted file mode 100644
    index c063f42fd..000000000
    --- a/96_Word/lua/README.md
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    -
    -Conversion to [Lua](https://www.lua.org/)
    diff --git a/96_Word/pascal/README.md b/96_Word/pascal/README.md
    new file mode 100644
    index 000000000..aa1b3ae5d
    --- /dev/null
    +++ b/96_Word/pascal/README.md
    @@ -0,0 +1,3 @@
    +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
    +
    +Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))
    diff --git a/96_Word/python/word.py b/96_Word/python/word.py
    old mode 100755
    new mode 100644
    index 5ff7604a0..a3689f961
    --- a/96_Word/python/word.py
    +++ b/96_Word/python/word.py
    @@ -1,30 +1,15 @@
     #!/usr/bin/env python3
    -
    -"""
    -WORD
    -
    -Converted from BASIC to Python by Trevor Hobson
    -"""
    +# WORD
    +#
    +# Converted from BASIC to Python by Trevor Hobson
     
     import random
     
    -words = [
    -    "DINKY",
    -    "SMOKE",
    -    "WATER",
    -    "GRASS",
    -    "TRAIN",
    -    "MIGHT",
    -    "FIRST",
    -    "CANDY",
    -    "CHAMP",
    -    "WOULD",
    -    "CLUMP",
    -    "DOPEY",
    -]
    +words = ["DINKY", "SMOKE", "WATER", "GRASS", "TRAIN", "MIGHT", "FIRST",
    +         "CANDY", "CHAMP", "WOULD", "CLUMP", "DOPEY"]
     
     
    -def play_game() -> None:
    +def play_game():
         """Play one round of the game"""
     
         random.shuffle(words)
    @@ -35,7 +20,7 @@ def play_game() -> None:
         print("You are starting a new game...")
         while True:
             guess_word = ""
    -        while not guess_word:
    +        while guess_word == "":
                 guess_word = input("\nGuess a five letter word. ").upper()
                 if guess_word == "?":
                     break
    @@ -56,22 +41,19 @@ def play_game() -> None:
                             common_letters = common_letters + guess_word[i]
                             if i == j:
                                 guess_progress[j] = guess_word[i]
    +            print("There were", matches,
    +                  "matches and the common letters were... " + common_letters)
                 print(
    -                f"There were {matches}",
    -                f"matches and the common letters were... {common_letters}",
    -            )
    -            print(
    -                "From the exact letter matches, you know............ "
    -                + "".join(guess_progress)
    -            )
    +                "From the exact letter matches, you know............ " + "".join(guess_progress))
                 if "".join(guess_progress) == guess_word:
    -                print(f"\nYou have guessed the word. It took {guess_count} guesses!")
    +                print("\nYou have guessed the word. It took",
    +                      guess_count, "guesses!")
                     break
                 elif matches == 0:
                     print("\nIf you give up, type '?' for you next guess.")
     
     
    -def main() -> None:
    +def main():
         print(" " * 33 + "WORD")
         print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\n")
     
    @@ -81,7 +63,8 @@ def main() -> None:
         keep_playing = True
         while keep_playing:
             play_game()
    -        keep_playing = input("\nWant to play again? ").lower().startswith("y")
    +        keep_playing = input(
    +            "\nWant to play again? ").lower().startswith("y")
     
     
     if __name__ == "__main__":
    diff --git a/96_Word/rust/Cargo.lock b/96_Word/rust/Cargo.lock
    deleted file mode 100644
    index 4fe2abbea..000000000
    --- a/96_Word/rust/Cargo.lock
    +++ /dev/null
    @@ -1,75 +0,0 @@
    -# This file is automatically @generated by Cargo.
    -# It is not intended for manual editing.
    -version = 3
    -
    -[[package]]
    -name = "cfg-if"
    -version = "1.0.0"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    -
    -[[package]]
    -name = "getrandom"
    -version = "0.2.10"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
    -dependencies = [
    - "cfg-if",
    - "libc",
    - "wasi",
    -]
    -
    -[[package]]
    -name = "libc"
    -version = "0.2.147"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
    -
    -[[package]]
    -name = "ppv-lite86"
    -version = "0.2.17"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
    -
    -[[package]]
    -name = "rand"
    -version = "0.8.5"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    -dependencies = [
    - "libc",
    - "rand_chacha",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_chacha"
    -version = "0.3.1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    -dependencies = [
    - "ppv-lite86",
    - "rand_core",
    -]
    -
    -[[package]]
    -name = "rand_core"
    -version = "0.6.4"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
    -dependencies = [
    - "getrandom",
    -]
    -
    -[[package]]
    -name = "rust"
    -version = "0.1.0"
    -dependencies = [
    - "rand",
    -]
    -
    -[[package]]
    -name = "wasi"
    -version = "0.11.0+wasi-snapshot-preview1"
    -source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    diff --git a/96_Word/rust/Cargo.toml b/96_Word/rust/Cargo.toml
    deleted file mode 100644
    index 3b1d02f52..000000000
    --- a/96_Word/rust/Cargo.toml
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -[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/96_Word/rust/src/main.rs b/96_Word/rust/src/main.rs
    deleted file mode 100644
    index 707779a94..000000000
    --- a/96_Word/rust/src/main.rs
    +++ /dev/null
    @@ -1,52 +0,0 @@
    -use crate::word_game::WordGame;
    -use std::io;
    -mod progress;
    -mod word_game;
    -
    -fn main() {
    -    println!("\n\n~~WORD~~");
    -    println!("Creative Computing Morristown, New Jersey");
    -
    -    println!("\nI am thinking of a word -- you guess it.");
    -    println!("I will give you clues to help you get it.");
    -    println!("Good luck!!\n");
    -
    -    let mut quit = false;
    -
    -    while quit == false {
    -        let mut game = WordGame::new();
    -        let mut game_over = false;
    -
    -        while game_over == false {
    -            game_over = game.tick();
    -        }
    -
    -        quit = !play_again();
    -    }
    -}
    -
    -fn play_again() -> bool {
    -    let mut again = true;
    -    let mut valid_response = false;
    -
    -    while valid_response == false {
    -        println!("Want to play again? (Y/n)");
    -
    -        let mut response = String::new();
    -
    -        io::stdin()
    -            .read_line(&mut response)
    -            .expect("Failed to read line.");
    -
    -        match response.trim().to_uppercase().as_str() {
    -            "Y" | "YES" => valid_response = true,
    -            "N" | "NO" => {
    -                again = false;
    -                valid_response = true;
    -            }
    -            _ => (),
    -        }
    -    }
    -
    -    again
    -}
    diff --git a/96_Word/rust/src/progress.rs b/96_Word/rust/src/progress.rs
    deleted file mode 100644
    index 46bf4d396..000000000
    --- a/96_Word/rust/src/progress.rs
    +++ /dev/null
    @@ -1,29 +0,0 @@
    -pub struct Progress {
    -    chars: [char; 5],
    -}
    -
    -impl Progress {
    -    pub fn new() -> Self {
    -        Progress { chars: ['-'; 5] }
    -    }
    -
    -    pub fn set_char_at(&mut self, c: char, i: usize) {
    -        self.chars[i] = c;
    -    }
    -
    -    pub fn print(&self) {
    -        for c in self.chars {
    -            print!("{}", c);
    -        }
    -    }
    -
    -    pub fn done(&self) -> bool {
    -        for c in self.chars {
    -            if c == '-' {
    -                return false;
    -            }
    -        }
    -
    -        true
    -    }
    -}
    diff --git a/96_Word/rust/src/word_game.rs b/96_Word/rust/src/word_game.rs
    deleted file mode 100644
    index 6df72acb8..000000000
    --- a/96_Word/rust/src/word_game.rs
    +++ /dev/null
    @@ -1,113 +0,0 @@
    -use crate::progress::Progress;
    -use rand::Rng;
    -use std::io;
    -
    -pub struct WordGame<'a> {
    -    word: &'a str,
    -    progress: Progress,
    -    guess: String,
    -    guesses: usize,
    -}
    -
    -impl WordGame<'_> {
    -    pub fn new() -> Self {
    -        const WORDS: [&str; 12] = [
    -            "DINKY", "SMOKE", "WATER", "GRASS", "TRAIN", "MIGHT", "FIRST", "CANDY", "CHAMP",
    -            "WOULD", "CLUMP", "DOPEY",
    -        ];
    -
    -        println!("\nYou are starting a new game...");
    -
    -        let random_index: usize = rand::thread_rng().gen_range(0..WORDS.len());
    -
    -        //println!("word is: {}", WORDS[random_index]);
    -
    -        WordGame {
    -            word: WORDS[random_index],
    -            progress: Progress::new(),
    -            guess: String::new(),
    -            guesses: 0,
    -        }
    -    }
    -
    -    pub fn tick(&mut self) -> bool {
    -        self.guesses += 1;
    -
    -        println!("\n\nGuess a five letter word?");
    -
    -        let mut game_over = false;
    -
    -        if WordGame::<'_>::read_guess(self) {
    -            game_over = WordGame::<'_>::process_guess(self);
    -        }
    -
    -        game_over
    -    }
    -
    -    fn read_guess(&mut self) -> bool {
    -        let mut guess = String::new();
    -
    -        io::stdin()
    -            .read_line(&mut guess)
    -            .expect("Failed to read line.");
    -
    -        let invalid_input = |message: &str| {
    -            println!("\n{} Guess again.", message);
    -            return false;
    -        };
    -
    -        let guess = guess.trim();
    -
    -        for c in guess.chars() {
    -            if c.is_numeric() {
    -                return invalid_input("Your guess cannot include numbers.");
    -            }
    -            if !c.is_ascii_alphabetic() {
    -                return invalid_input("Your guess must only include ASCII characters.");
    -            }
    -        }
    -
    -        if guess.len() != 5 {
    -            return invalid_input("You must guess a 5 letter word.");
    -        }
    -
    -        self.guess = guess.to_string();
    -
    -        true
    -    }
    -
    -    fn process_guess<'a>(&mut self) -> bool {
    -        let guess = self.guess.to_uppercase();
    -
    -        let mut matches: Vec = Vec::new();
    -
    -        for (i, c) in guess.chars().enumerate() {
    -            if self.word.contains(c) {
    -                matches.push(c);
    -
    -                if self.word.chars().nth(i).unwrap() == c {
    -                    self.progress.set_char_at(c, i);
    -                }
    -            }
    -        }
    -
    -        println!(
    -            "There were {} matches and the common letters were....{}",
    -            matches.len(),
    -            matches.into_iter().collect::()
    -        );
    -
    -        print!("From the exact letter matches you know....");
    -        self.progress.print();
    -
    -        if self.progress.done() {
    -            println!(
    -                "\n\nYou have guessed the word. It took {} guesses!\n",
    -                self.guesses
    -            );
    -            return true;
    -        }
    -
    -        false
    -    }
    -}
    diff --git a/96_Word/vbnet/Program.vb b/96_Word/vbnet/Program.vb
    index 4aa585cb4..cc807e567 100644
    --- a/96_Word/vbnet/Program.vb
    +++ b/96_Word/vbnet/Program.vb
    @@ -50,7 +50,7 @@ Module Word
         ' A string showing which specific letters have already been guessed
         ' The integer value showing the number of character matches between guess and target
         Private Function check_guess(guess As String, target As String, progress As StringBuilder) As Integer
    -        ' Go through each letter of the guess And see which
    +        ' Go through each letter of the guess And see which 
             ' letters match up to the target word.
             ' For each position that matches, update the progress
             ' to reflect the guess
    diff --git a/96_Word/vbnet/word.sln b/96_Word/vbnet/word.sln
    index 73674ee49..165841043 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("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "Word", "Word.vbproj", "{F0D2422C-983F-4DF3-9D17-D2480839DF07}"
    +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "word", "word.vbproj", "{F0D2422C-983F-4DF3-9D17-D2480839DF07}"
     EndProject
     Global
     	GlobalSection(SolutionConfigurationPlatforms) = preSolution
    diff --git a/96_Word/vbnet/word.vbproj b/96_Word/vbnet/word.vbproj
    index f80094e4e..9868dd3e4 100644
    --- a/96_Word/vbnet/word.vbproj
    +++ b/96_Word/vbnet/word.vbproj
    @@ -2,9 +2,8 @@
     
       
         Exe
    -    Word
    +    word
         netcoreapp3.1
    -    16.9
       
     
     
    diff --git a/HOW_TO_RUN_THE_GAMES.md b/HOW_TO_RUN_THE_GAMES.md
    index 1d25fe417..fae0656f8 100644
    --- a/HOW_TO_RUN_THE_GAMES.md
    +++ b/HOW_TO_RUN_THE_GAMES.md
    @@ -23,15 +23,16 @@ Alternatively, for non-dotnet compatible translations, you will need [Visual Stu
     
     ## java
     
    -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 [IntelJ][def]
    +**TIP:** You can build all the java and kotlin games at once
    +using the instructions in the [buildJvm directory](buildJvm/README.md)
    +
    +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. `**```python
    -   javac
    -   ```** AceyDuceyGame.java`
    +   * eg. `javac AceyDuceyGame.java`
     1. Run the compiled program with `java`:
        * eg. `java AceyDuceyGame`
     
    @@ -39,38 +40,20 @@ or if you are **using JDK11 or later** you can now execute a self contained java
     
     ## javascript
     
    -There are two ways of javascript implementations:
    -
    -### browser
    -
    -The html examples can be run from within your web browser. Simply open the corresponding `.html` file from your web browser.
    -
    -### node.js
    +The javascript examples can be run from within your web browser:
     
    -Some games are implemented as a [node.js](https://nodejs.org/) script. In this case there is no `*.html` file in the folder.
    -
    -1. [install node.js](https://nodejs.org/en/download/) for your system.
    -1. change directory to the root of this repository (e.g. `cd basic-computer-games`).
    -1. from a terminal call the script you want to run (e.g. `node 78_Sine_Wave/javascript/sinewave.mjs`).
    -
    -_Hint: Normally javascript files have a `*.js` extension. We are using `*.mjs` to let node know , that we are using [ES modules](https://nodejs.org/docs/latest/api/esm.html#modules-ecmascript-modules) instead of [CommonJS](https://nodejs.org/docs/latest/api/modules.html#modules-commonjs-modules)._
    +1. Simply open the corresponding `.html` file from your web browser.
     
     ## kotlin
     
    -Kotlin programs are compiled with the Kotlin compiler, and run with the java runtime, just like java programs.
    -In addition to the java runtime you will need the `kotlinc` compiler, which can be installed using [these instructions](https://kotlinlang.org/docs/command-line.html).
    -
    -1. Navigate to the corresponding directory.
    -1. Compile the program with `kotlinc`:
    -   * eg. `kotlinc AceyDuceyGame.kt -include-runtime -d AceyDuceyGame.jar`
    -1. Run the compiled program with `java`:
    -   * eg. `java -jar AceyDuceyGame.jar`
    +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/).
     
    -The pascal examples include both ___simple_ (single-file) and_o**bject-oriented_ (in the `/object-pascal`directories) examples.
    +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`
    @@ -94,9 +77,7 @@ The python translations can be run from the command line by using the `py` inter
        * eg. `python aceyducey.py`
     
     **Note**
    -{
    -    "MD013": false
    -}
    +
     Some translations include multiple versions for python, such as `acey ducey` which features versions for Python 2 (`aceyducey.py`) and Python 3 (`acey_ducey.py`) as well as an extra object-oriented version (`acey_ducey_oo.py`).
     
     You can manage and use different versions of python with [pip](https://pypi.org/project/pip/).
    @@ -112,13 +93,3 @@ If you don't already have a ruby interpreter, you can download it from the [ruby
     ## vbnet
     
     Follow the same steps as for the [csharp](#csharp) translations. This can be run with `dotnet` or `Visual Studio`.
    -
    -## rust
    -
    -If you don't already have Rust on your computer, you can follow the instruction on [Rust Book](https://doc.rust-lang.org/book/ch01-01-installation.html)
    -
    -1. From the command-line, navigate to the corresponding directory.
    -2. Run the following command.
    -   * `cargo run`
    -
    -[def]: https://www.jetbrains.com/idea/
    diff --git a/README.md b/README.md
    index 39fa38a07..6ed7cb51e 100644
    --- a/README.md
    +++ b/README.md
    @@ -1,9 +1,8 @@
     ### What are we doing?
     
    -We’re updating the first million selling computer book, [BASIC Computer Games](https://en.wikipedia.org/wiki/BASIC_Computer_Games), for 2022 and beyond!
    +We're updating the first million selling computer book, [BASIC Computer Games](https://en.wikipedia.org/wiki/BASIC_Computer_Games), for 2022 and beyond!
     
    -- [Read the original book](https://archive.org/details/basiccomputergam0000unse) (pdf)
    -- [Play the original games in your browser](https://troypress.com/wp-content/uploads/user/js-basic/index.html)
    +[Read book](https://annarchive.com/files/Basic_Computer_Games_Microcomputer_Edition.pdf)
     
     ### Where can we discuss it?
     
    @@ -13,48 +12,34 @@ Please see [the discussion here](https://discourse.codinghorror.com/t/-/7927) fo
     
     I have moved all [the original BASIC source code](http://www.vintage-basic.net/games.html) into a folder for each project in the original book (first volume). Note that Lyle Kopnicky has generously normalized all the code (thanks Lyle!) to run against [Vintage Basic](http://www.vintage-basic.net/download.html) circa 2009:
     
    -> I’ve included all the games here for your tinkering pleasure. I’ve tested and tweaked each one of them to make sure they’ll run with Vintage BASIC, though you may see a few oddities. That’s part of the fun of playing with BASIC: it never works quite the same on two machines. The games will play better if you keep CAPS LOCK on, as they were designed to be used with capital-letter input.
    +> I've included all the games here for your tinkering pleasure. I've tested and tweaked each one of them to make sure they'll run with Vintage BASIC, though you may see a few oddities. That's part of the fun of playing with BASIC: it never works quite the same on two machines. The games will play better if you keep CAPS LOCK on, as they were designed to be used with capital-letter input.
     
    -Each project has subfolders corresponding to the languages we’d like to see the games ported to. This is based on the [2022 TIOBE index of top languages](https://www.tiobe.com/tiobe-index/) that are _**memory safe**_ and _**general purpose scripting languages**_ per [this post](https://discourse.codinghorror.com/t/-/7927/34):
    +Each project has subfolders corresponding to the languages we'd like to see the games ported to. This is based on the [February 2021 TIOBE index of top languages](https://www.tiobe.com/tiobe-index/) that are _memory safe_ and _general purpose scripting language_ per [this post](https://discourse.codinghorror.com/t/-/7927/34):
     
    -1. C#
    -2. Java
    -3. JavaScript
    -4. Kotlin
    -5. Lua
    -6. Perl
    -7. Python
    -8. Ruby
    -9. Rust
    -10. VB.NET
    +- Java
    +- Python
    +- C#
    +- VB.NET
    +- JavaScript
    +- Ruby
    +- Delphi / Object Pascal
    +- Perl
     
    -> 📢 Note that in March 2022 we removed Pascal / Object Pascal and replaced it with Rust as we couldn’t determine if Pascal is effectively memory safe. We’ve also added Lua, as it made the top 20 in TIOBE (as of 2022) and it is both memory safe and a scripting language. The Pascal ports were moved to the alternate languages folder.
     
    -> ⚠️ Please note that we have decided, as a project, that we **do not want any IDE-specific or build-specific files in the repository.** Please refrain from committing any files to the repository that only exist to work with a specific IDE or a specific build system.
    -
    -### Alternate Languages
    -
    -If you wish to port one of the programs to a language not in our list – that is, a language which is either not memory safe, or not a general purpose scripting language, you can do so via the `00_Alternate_Languages` folder. Place your port in the appropriate game subfolder, in a subfolder named for the language. Please note that these ports are appreciated, but they will not count toward the donation total at the end of the project.
     
     ### Project goals
     
    -Feel free to begin converting these classic games into the above list of modern, memory safe languages. In fact, courtesy of @mojoaxel, you can even view the JavaScript versions in your web browser at
    -
    -
    -
    -But first, a few guidelines:
    +Feel free to begin converting these classic games into the above list of modern, memory safe languages. But first, a few guidelines:
     
    -- **These are very old games**. They date from the mid-70s so they’re not exactly examples of what kids (or anyone, really?) would be playing these days. Consider them more like classic programming exercises to teach programming.  We’re paying it forward by converting them into modern languages, so the next generation can learn from the programs in this classic book – and compare implementations across common modern languages.
    +- **These are very old games**. They date from the mid-70s so they're not exactly examples of what kids (or anyone, really?) would be playing these days. Consider them more like classic programming exercises to teach programming.  We're paying it forward by converting them into modern languages, so the next generation can learn from the programs in this classic book -- and compare implementations across common modern languages.
     
    -- **Stay true to the original program**. These are mostly unsophisticated, simple command line / console games, so we should strive to replicate the command line / console output and behavior illustrated in the original book. See the README in the project folder for links to the original scanned source input and output. Try [running the game in your browser](https://troypress.com/wp-content/uploads/user/js-basic/index.html). Avoid the impulse to add features; keep it simple, _except_ for modern conventions, see next item 👇
    +- **Stay true to the original program**. These are mostly unsophisticated, simple command line / console games, so we should strive to replicate the command line / console output and behavior illustrated in the original book. See the README in the project folder for links to the original scanned source input and output. Avoid the impulse to add features; keep it simple.
     
     - **Please DO update for modern coding conventions**. Support uppercase and lowercase. Use structured programming. Use subroutines. Try to be an example of good, modern coding practices!
     
    -- **Use lots of comments to explain what is going on**. Comment liberally! If there were clever tricks in the original code, decompose those tricks into simpler (even if more verbose) code, and use comments to explain what’s happening and why. If there is something particularly tricky about a program, edit the **Porting Notes** section of the `readme.md` to let everyone know. Those `GOTO`s can be very pesky..
    +- **Use lots of comments to explain what is going on**. Comment liberally! If there were clever tricks in the original code, decompose those tricks into simpler (even if more verbose) code, and use comments to explain what's happening and why.
     
    -- **Please 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, or big system "enterprise" coding techniques designed for thousands of lines of code.
    -
    -- **Please don't check in any build specific or IDE specific files**. We want the repository to be simple and clean, so we have ruled out including any IDE or build system specific files from the repository. Git related files are OK, as we are using Git and this is GitHub. 😉
    +- **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
     
    @@ -64,115 +49,10 @@ We want the general behavior of the original programs to be preserved, _however_
     - 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. To verify behavior, try [running the programs in your browser](https://troypress.com/wp-content/uploads/user/js-basic/index.html) with [JS BASIC, effectively Applesoft BASIC](https://github.com/inexorabletash/jsbasic/).
    -
    -### 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!
    -
    -NOTE: per [the official blog post announcement](https://blog.codinghorror.com/updating-the-single-most-influential-book-of-the-basic-era/), I will be **donating $5 for each contributed program in the 10 agreed upon languages to [Girls Who Code](https://girlswhocode.com/)**.
    -
    -### Current Progress
    -
    -
    toggle for game by language table - -| Name | csharp | java | javascript | kotlin | lua | perl | python | ruby | rust | vbnet | -| ---------------------- | ------ | ---- | ---------- | ------ | --- | ---- | ------ | ---- | ---- | ----- | -| 01_Acey_Ducey | x | x | x | x | x | x | x | x | x | x | -| 02_Amazing | x | x | x | | | x | x | x | x | x | -| 03_Animal | x | x | x | x | x | x | x | x | x | x | -| 04_Awari | x | x | x | | | x | x | x | x | x | -| 05_Bagels | x | x | x | x | x | x | x | x | x | x | -| 06_Banner | x | x | x | | | x | x | x | x | x | -| 07_Basketball | x | x | x | | | x | x | x | x | x | -| 08_Batnum | x | x | x | | | x | x | x | x | x | -| 09_Battle | x | x | x | | | | x | | x | x | -| 10_Blackjack | x | x | x | | | | x | x | x | x | -| 11_Bombardment | x | x | x | | | x | x | x | x | x | -| 12_Bombs_Away | x | x | x | | x | x | x | | x | x | -| 13_Bounce | x | x | x | | | x | x | x | x | x | -| 14_Bowling | x | x | x | | | x | x | | x | x | -| 15_Boxing | x | x | x | | | x | x | | | x | -| 16_Bug | x | x | x | | | | x | x | | x | -| 17_Bullfight | x | x | x | x | | | x | | | x | -| 18_Bullseye | x | x | x | | | x | x | | x | x | -| 19_Bunny | x | x | x | | | x | x | x | x | x | -| 20_Buzzword | x | x | x | | x | x | x | x | x | x | -| 21_Calendar | x | x | x | | | x | x | x | x | x | -| 22_Change | x | x | x | | | x | x | | x | x | -| 23_Checkers | x | | x | | | x | x | x | | x | -| 24_Chemist | x | x | x | | | x | x | | x | x | -| 25_Chief | x | x | x | | x | x | x | x | x | x | -| 26_Chomp | x | x | x | | | x | x | | | x | -| 27_Civil_War | x | x | x | | | | x | | | x | -| 28_Combat | x | x | x | | | x | x | | | x | -| 29_Craps | x | x | x | | x | x | x | x | x | x | -| 30_Cube | x | x | x | | | | x | x | x | x | -| 31_Depth_Charge | x | x | x | | | x | x | x | x | x | -| 32_Diamond | x | x | x | x | | x | x | x | x | x | -| 33_Dice | x | x | x | | x | x | x | x | x | x | -| 34_Digits | x | x | x | | | x | x | | | x | -| 35_Even_Wins | x | | x | | | x | x | | x | x | -| 36_Flip_Flop | x | x | x | | | x | x | x | x | x | -| 37_Football | x | | x | | | | x | | | x | -| 38_Fur_Trader | x | x | x | | | x | x | | | x | -| 39_Golf | x | | x | | | | x | | | x | -| 40_Gomoko | x | x | x | | | x | x | | | x | -| 41_Guess | x | x | x | | | x | x | x | x | x | -| 42_Gunner | x | x | x | | | x | x | | | x | -| 43_Hammurabi | x | x | x | | | | x | | x | x | -| 44_Hangman | x | x | x | | | x | x | x | | x | -| 45_Hello | x | x | x | | x | x | x | x | x | x | -| 46_Hexapawn | x | | | | | | x | | | x | -| 47_Hi-Lo | x | | x | x | x | x | x | x | x | x | -| 48_High_IQ | x | x | x | | | | x | | | x | -| 49_Hockey | x | | x | | | | x | | | x | -| 50_Horserace | x | x | x | | | | | | x | x | -| 51_Hurkle | x | x | x | | | x | x | x | x | x | -| 52_Kinema | x | x | x | | | x | x | x | x | x | -| 53_King | x | | x | | | | x | | x | x | -| 54_Letter | x | x | x | | | x | x | x | x | x | -| 55_Life | x | x | x | | | x | x | x | x | x | -| 56_Life_for_Two | x | x | x | | | x | x | | | x | -| 57_Literature_Quiz | x | x | x | | | x | x | | x | x | -| 58_Love | x | x | x | | | x | x | x | x | x | -| 59_Lunar_LEM_Rocket | x | | x | | | | x | | x | x | -| 60_Mastermind | x | x | x | | | x | x | | x | x | -| 61_Math_Dice | x | x | x | | | x | x | x | x | x | -| 62_Mugwump | x | x | x | | | x | x | | x | x | -| 63_Name | x | x | x | x | | x | x | x | x | x | -| 64_Nicomachus | x | x | x | | | x | x | | x | x | -| 65_Nim | x | | x | | | | x | x | x | x | -| 66_Number | x | x | x | | | x | x | | x | x | -| 67_One_Check | x | x | x | | | x | x | | | x | -| 68_Orbit | x | x | x | | | x | x | x | x | x | -| 69_Pizza | x | x | x | | | x | x | x | x | x | -| 70_Poetry | x | x | x | | | x | x | x | | x | -| 71_Poker | x | x | x | | | | | | | x | -| 72_Queen | x | | x | | | x | x | | x | x | -| 73_Reverse | x | x | x | | | x | x | x | x | x | -| 74_Rock_Scissors_Paper | x | x | x | x | | x | x | x | x | x | -| 75_Roulette | x | x | x | | | x | x | | x | x | -| 76_Russian_Roulette | x | x | x | x | | x | x | x | x | x | -| 77_Salvo | x | | x | | | | x | | x | x | -| 78_Sine_Wave | x | x | x | x | | x | x | x | x | x | -| 79_Slalom | x | | x | | | | x | | | x | -| 80_Slots | x | x | x | | | x | x | x | | x | -| 81_Splat | x | x | x | | | x | x | | x | x | -| 82_Stars | x | x | x | | | x | x | x | x | x | -| 83_Stock_Market | x | x | x | | | | x | | | x | -| 84_Super_Star_Trek | x | x | x | | | | x | | x | x | -| 85_Synonym | x | x | x | | | x | x | x | x | x | -| 86_Target | x | x | x | | | x | x | | | x | -| 87_3-D_Plot | x | x | x | | | x | x | x | x | x | -| 88_3-D_Tic-Tac-Toe | x | | x | | | | x | | | x | -| 89_Tic-Tac-Toe | x | x | x | x | | x | x | | x | x | -| 90_Tower | x | x | x | | | x | x | | x | x | -| 91_Train | x | x | x | | | x | x | x | x | x | -| 92_Trap | x | x | x | | | x | x | x | x | x | -| 93_23_Matches | x | x | x | | | x | x | x | x | x | -| 94_War | x | x | x | x | | x | x | x | x | x | -| 95_Weekday | x | x | x | | | x | x | | x | x | -| 96_Word | x | x | x | | | x | x | x | x | x | - -
    +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! + +NOTE: per [the official blog post announcement](https://blog.codinghorror.com/updating-the-single-most-influential-book-of-the-basic-era/), I will be **donating $5 for each contributed program in the 8 agreed upon languages to [Girls Who Code](https://girlswhocode.com/)**. diff --git a/basic-computer-games-gradle b/basic-computer-games-gradle deleted file mode 160000 index 367112cc0..000000000 --- a/basic-computer-games-gradle +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 367112cc067a3623bcca174e354ed671c73c8acb diff --git a/buildJvm/README.md b/buildJvm/README.md new file mode 100644 index 000000000..e2b9da0b9 --- /dev/null +++ b/buildJvm/README.md @@ -0,0 +1,96 @@ +# 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: +```shell + cd buildJvm + ./gradlew -q clean assemble installDist distributeBin distributeLib +``` + +Then, run a game + +### Mac or linux: +```shell +build/distrib/bin/build_53_King_kotlin +``` +### Windows +[not tested yet] + +```shell +build\distrib\bin\build_53_King_kotlin.bat +``` + +--- +## 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 + +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 +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 + } + + sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } + } + + repositories { + mavenCentral() + } + + application { + mainClass = gameMain + } +``` + +And 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. diff --git a/buildJvm/build.gradle.kts b/buildJvm/build.gradle.kts new file mode 100644 index 000000000..d953049e1 --- /dev/null +++ b/buildJvm/build.gradle.kts @@ -0,0 +1,47 @@ +plugins { + kotlin("jvm") version "1.6.0" + id("application") +} + +version = "unspecified" + +repositories { + mavenCentral() +} + +dependencies { + implementation(kotlin("stdlib")) +} + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(17)) + } +} + +task("distributeBin", Copy::class) { + from(filesType("bin")) + into("$buildDir/distrib/bin") + duplicatesStrategy = DuplicatesStrategy.WARN + dependsOn(":build_94_War_kotlin:installDist") +} + +task("distributeLib", Copy::class) { + from(filesType("lib")) + into("$buildDir/distrib/lib") + duplicatesStrategy = DuplicatesStrategy.WARN + dependsOn("installDist") +} + +task("copyAll") { + dependsOn( + ":distributeBin", + ":distributeLib" + ) +} + +fun filesType(type: String) = + fileTree("$buildDir/..").files.filter { + it.path.contains("build/install/build_.*/$type".toRegex()) + && it.isFile + } \ No newline at end of file diff --git a/buildJvm/build_01_Acey_Ducey_java/build.gradle b/buildJvm/build_01_Acey_Ducey_java/build.gradle new file mode 100644 index 000000000..08d34acdc --- /dev/null +++ b/buildJvm/build_01_Acey_Ducey_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs '../../01_Acey_Ducey/java/src' + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = 'AceyDuceyGame' +} diff --git a/buildJvm/build_01_Acey_Ducey_java/gradle.properties b/buildJvm/build_01_Acey_Ducey_java/gradle.properties new file mode 100644 index 000000000..c83649051 --- /dev/null +++ b/buildJvm/build_01_Acey_Ducey_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=01_Acey_Ducey/java/src +gameMain=AceyDucey diff --git a/buildJvm/build_02_Amazing_java/build.gradle b/buildJvm/build_02_Amazing_java/build.gradle new file mode 100644 index 000000000..d66de416e --- /dev/null +++ b/buildJvm/build_02_Amazing_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs '../../02_Amazing/java' + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = 'AmazingGame' +} diff --git a/buildJvm/build_02_Amazing_java/gradle.properties b/buildJvm/build_02_Amazing_java/gradle.properties new file mode 100644 index 000000000..aa5f3f7b2 --- /dev/null +++ b/buildJvm/build_02_Amazing_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=02_Amazing/java +gameMain=AmazingGame diff --git a/buildJvm/build_03_Animal_java/build.gradle b/buildJvm/build_03_Animal_java/build.gradle new file mode 100644 index 000000000..472fdf092 --- /dev/null +++ b/buildJvm/build_03_Animal_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs '../../03_Animal/java' + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = 'Animal' +} diff --git a/buildJvm/build_03_Animal_java/gradle.properties b/buildJvm/build_03_Animal_java/gradle.properties new file mode 100644 index 000000000..679638f29 --- /dev/null +++ b/buildJvm/build_03_Animal_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=03_Animal/java +gameMain=Animal diff --git a/buildJvm/build_03_Animal_kotlin/build.gradle b/buildJvm/build_03_Animal_kotlin/build.gradle new file mode 100644 index 000000000..2a5700f32 --- /dev/null +++ b/buildJvm/build_03_Animal_kotlin/build.gradle @@ -0,0 +1,20 @@ +plugins { + id 'org.jetbrains.kotlin.jvm' + id 'application' +} + +sourceSets { + main { + java { + srcDirs '../../03_Animal/kotlin' + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = 'AnimalKt' +} diff --git a/buildJvm/build_03_Animal_kotlin/gradle.properties b/buildJvm/build_03_Animal_kotlin/gradle.properties new file mode 100644 index 000000000..ea63333f8 --- /dev/null +++ b/buildJvm/build_03_Animal_kotlin/gradle.properties @@ -0,0 +1,2 @@ +gameSource=03_Animal/kotlin +gameMain=AnimalKt diff --git a/buildJvm/build_04_Awari_java/build.gradle b/buildJvm/build_04_Awari_java/build.gradle new file mode 100644 index 000000000..5e60f0073 --- /dev/null +++ b/buildJvm/build_04_Awari_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs '../../04_Awari/java' + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = 'AwariGame' +} diff --git a/buildJvm/build_04_Awari_java/gradle.properties b/buildJvm/build_04_Awari_java/gradle.properties new file mode 100644 index 000000000..510d95ed1 --- /dev/null +++ b/buildJvm/build_04_Awari_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=04_Awari/java +gameMain=Awari diff --git a/buildJvm/build_05_Bagels_java/build.gradle b/buildJvm/build_05_Bagels_java/build.gradle new file mode 100644 index 000000000..ccbaf38b1 --- /dev/null +++ b/buildJvm/build_05_Bagels_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs '../../05_Bagels/java' + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = 'Bagels' +} diff --git a/buildJvm/build_05_Bagels_java/gradle.properties b/buildJvm/build_05_Bagels_java/gradle.properties new file mode 100644 index 000000000..b1b8273d0 --- /dev/null +++ b/buildJvm/build_05_Bagels_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=05_Bagels/java +gameMain=Bagels diff --git a/buildJvm/build_06_Banner_java/build.gradle b/buildJvm/build_06_Banner_java/build.gradle new file mode 100644 index 000000000..6fb283b5e --- /dev/null +++ b/buildJvm/build_06_Banner_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs '../../06_Banner/java' + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = 'Banner' +} diff --git a/buildJvm/build_06_Banner_java/gradle.properties b/buildJvm/build_06_Banner_java/gradle.properties new file mode 100644 index 000000000..8808e9aa9 --- /dev/null +++ b/buildJvm/build_06_Banner_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=06_Banner/java +gameMain=Banner diff --git a/buildJvm/build_08_Batnum_java/build.gradle b/buildJvm/build_08_Batnum_java/build.gradle new file mode 100644 index 000000000..ec9e3d1bf --- /dev/null +++ b/buildJvm/build_08_Batnum_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs '../../08_Batnum/java/src' + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = 'BatNumGame' +} diff --git a/buildJvm/build_08_Batnum_java/gradle.properties b/buildJvm/build_08_Batnum_java/gradle.properties new file mode 100644 index 000000000..27a8528bf --- /dev/null +++ b/buildJvm/build_08_Batnum_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=08_Batnum/java/src +gameMain=Batnum diff --git a/buildJvm/build_11_Bombardment_java/build.gradle b/buildJvm/build_11_Bombardment_java/build.gradle new file mode 100644 index 000000000..1480a432a --- /dev/null +++ b/buildJvm/build_11_Bombardment_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs '../../11_Bombardment/java/src' + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = 'BombardmentGame' +} diff --git a/buildJvm/build_11_Bombardment_java/gradle.properties b/buildJvm/build_11_Bombardment_java/gradle.properties new file mode 100644 index 000000000..37fbfd3f0 --- /dev/null +++ b/buildJvm/build_11_Bombardment_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=11_Bombardment/java/src +gameMain=Bombardment diff --git a/buildJvm/build_12_Bombs_Away_java/build.gradle b/buildJvm/build_12_Bombs_Away_java/build.gradle new file mode 100644 index 000000000..dc7eefea4 --- /dev/null +++ b/buildJvm/build_12_Bombs_Away_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs '../../12_Bombs_Away/java/src' + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = 'BombsAwayGame' +} diff --git a/buildJvm/build_12_Bombs_Away_java/gradle.properties b/buildJvm/build_12_Bombs_Away_java/gradle.properties new file mode 100644 index 000000000..0d63151b8 --- /dev/null +++ b/buildJvm/build_12_Bombs_Away_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=12_Bombs_Away/java/src +gameMain=BombsAway diff --git a/buildJvm/build_13_Bounce_java/build.gradle b/buildJvm/build_13_Bounce_java/build.gradle new file mode 100644 index 000000000..ed258f2a0 --- /dev/null +++ b/buildJvm/build_13_Bounce_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs '../../13_Bounce/java' + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = 'Bounce' +} diff --git a/buildJvm/build_13_Bounce_java/gradle.properties b/buildJvm/build_13_Bounce_java/gradle.properties new file mode 100644 index 000000000..b69fbc282 --- /dev/null +++ b/buildJvm/build_13_Bounce_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=13_Bounce/java +gameMain=Bounce diff --git a/buildJvm/build_14_Bowling_java/build.gradle b/buildJvm/build_14_Bowling_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_14_Bowling_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_14_Bowling_java/gradle.properties b/buildJvm/build_14_Bowling_java/gradle.properties new file mode 100644 index 000000000..2570015c7 --- /dev/null +++ b/buildJvm/build_14_Bowling_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=14_Bowling/java +gameMain=Bowling diff --git a/buildJvm/build_15_Boxing_java/build.gradle b/buildJvm/build_15_Boxing_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_15_Boxing_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_15_Boxing_java/gradle.properties b/buildJvm/build_15_Boxing_java/gradle.properties new file mode 100644 index 000000000..2c8ca8fc2 --- /dev/null +++ b/buildJvm/build_15_Boxing_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=15_Boxing/java +gameMain=BoxingGame diff --git a/buildJvm/build_16_Bug_java/build.gradle b/buildJvm/build_16_Bug_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_16_Bug_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_16_Bug_java/gradle.properties b/buildJvm/build_16_Bug_java/gradle.properties new file mode 100644 index 000000000..215d60ef0 --- /dev/null +++ b/buildJvm/build_16_Bug_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=16_Bug/java/src +gameMain=BugGame diff --git a/buildJvm/build_18_Bullseye_java/build.gradle b/buildJvm/build_18_Bullseye_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_18_Bullseye_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_18_Bullseye_java/gradle.properties b/buildJvm/build_18_Bullseye_java/gradle.properties new file mode 100644 index 000000000..912db9b64 --- /dev/null +++ b/buildJvm/build_18_Bullseye_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=18_Bullseye/java/src +gameMain=BullseyeGame diff --git a/buildJvm/build_19_Bunny_java/build.gradle b/buildJvm/build_19_Bunny_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_19_Bunny_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_19_Bunny_java/gradle.properties b/buildJvm/build_19_Bunny_java/gradle.properties new file mode 100644 index 000000000..a480589c4 --- /dev/null +++ b/buildJvm/build_19_Bunny_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=19_Bunny/java/src +gameMain=Bunny diff --git a/buildJvm/build_20_Buzzword_java/build.gradle b/buildJvm/build_20_Buzzword_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_20_Buzzword_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_20_Buzzword_java/gradle.properties b/buildJvm/build_20_Buzzword_java/gradle.properties new file mode 100644 index 000000000..ce73aa674 --- /dev/null +++ b/buildJvm/build_20_Buzzword_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=20_Buzzword/java/src +gameMain=Buzzword diff --git a/buildJvm/build_21_Calendar_java/build.gradle b/buildJvm/build_21_Calendar_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_21_Calendar_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_21_Calendar_java/gradle.properties b/buildJvm/build_21_Calendar_java/gradle.properties new file mode 100644 index 000000000..048bcabf8 --- /dev/null +++ b/buildJvm/build_21_Calendar_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=21_Calendar/java +gameMain=Calendar diff --git a/buildJvm/build_22_Change_java/build.gradle b/buildJvm/build_22_Change_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_22_Change_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_22_Change_java/gradle.properties b/buildJvm/build_22_Change_java/gradle.properties new file mode 100644 index 000000000..737243aec --- /dev/null +++ b/buildJvm/build_22_Change_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=22_Change/java/src +gameMain=ChangeGame diff --git a/buildJvm/build_24_Chemist_java/build.gradle b/buildJvm/build_24_Chemist_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_24_Chemist_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_24_Chemist_java/gradle.properties b/buildJvm/build_24_Chemist_java/gradle.properties new file mode 100644 index 000000000..84362ea33 --- /dev/null +++ b/buildJvm/build_24_Chemist_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=24_Chemist/java/src +gameMain=ChemistGame \ No newline at end of file diff --git a/buildJvm/build_25_Chief_java/build.gradle b/buildJvm/build_25_Chief_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_25_Chief_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_25_Chief_java/gradle.properties b/buildJvm/build_25_Chief_java/gradle.properties new file mode 100644 index 000000000..af8dd77a3 --- /dev/null +++ b/buildJvm/build_25_Chief_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=25_Chief/java/src +gameMain=ChiefGame \ No newline at end of file diff --git a/buildJvm/build_26_Chomp_java/build.gradle b/buildJvm/build_26_Chomp_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_26_Chomp_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_26_Chomp_java/gradle.properties b/buildJvm/build_26_Chomp_java/gradle.properties new file mode 100644 index 000000000..15f18276a --- /dev/null +++ b/buildJvm/build_26_Chomp_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=26_Chomp/java +gameMain=Chomp diff --git a/buildJvm/build_28_Combat_java/build.gradle b/buildJvm/build_28_Combat_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_28_Combat_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_28_Combat_java/gradle.properties b/buildJvm/build_28_Combat_java/gradle.properties new file mode 100644 index 000000000..5dfb010cb --- /dev/null +++ b/buildJvm/build_28_Combat_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=28_Combat/java +gameMain=Combat diff --git a/buildJvm/build_31_Depth_Charge_java/build.gradle b/buildJvm/build_31_Depth_Charge_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_31_Depth_Charge_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_31_Depth_Charge_java/gradle.properties b/buildJvm/build_31_Depth_Charge_java/gradle.properties new file mode 100644 index 000000000..239dfcb75 --- /dev/null +++ b/buildJvm/build_31_Depth_Charge_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=31_Depth_Charge/java +gameMain=DepthCharge diff --git a/buildJvm/build_32_Diamond_java/build.gradle b/buildJvm/build_32_Diamond_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_32_Diamond_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_32_Diamond_java/gradle.properties b/buildJvm/build_32_Diamond_java/gradle.properties new file mode 100644 index 000000000..7581c0dee --- /dev/null +++ b/buildJvm/build_32_Diamond_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=32_Diamond/java +gameMain=Diamond diff --git a/buildJvm/build_33_Dice_java/build.gradle b/buildJvm/build_33_Dice_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_33_Dice_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_33_Dice_java/gradle.properties b/buildJvm/build_33_Dice_java/gradle.properties new file mode 100644 index 000000000..a04a70cfa --- /dev/null +++ b/buildJvm/build_33_Dice_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=33_Dice/java/src +gameMain=DiceGame \ No newline at end of file diff --git a/buildJvm/build_34_Digits_java/build.gradle b/buildJvm/build_34_Digits_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_34_Digits_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_34_Digits_java/gradle.properties b/buildJvm/build_34_Digits_java/gradle.properties new file mode 100644 index 000000000..ec084f564 --- /dev/null +++ b/buildJvm/build_34_Digits_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=34_Digits/java +gameMain=Digits diff --git a/buildJvm/build_36_Flip_Flop_java/build.gradle b/buildJvm/build_36_Flip_Flop_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_36_Flip_Flop_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_36_Flip_Flop_java/gradle.properties b/buildJvm/build_36_Flip_Flop_java/gradle.properties new file mode 100644 index 000000000..d60259c16 --- /dev/null +++ b/buildJvm/build_36_Flip_Flop_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=36_Flip_Flop/java +gameMain=FlipFlop diff --git a/buildJvm/build_38_Fur_Trader_java/build.gradle b/buildJvm/build_38_Fur_Trader_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_38_Fur_Trader_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_38_Fur_Trader_java/gradle.properties b/buildJvm/build_38_Fur_Trader_java/gradle.properties new file mode 100644 index 000000000..13eafeb46 --- /dev/null +++ b/buildJvm/build_38_Fur_Trader_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=38_Fur_Trader/java/src +gameMain=FurTraderGame \ No newline at end of file diff --git a/buildJvm/build_40_Gomoko_java/build.gradle b/buildJvm/build_40_Gomoko_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_40_Gomoko_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_40_Gomoko_java/gradle.properties b/buildJvm/build_40_Gomoko_java/gradle.properties new file mode 100644 index 000000000..e755deb60 --- /dev/null +++ b/buildJvm/build_40_Gomoko_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=40_Gomoko/java +gameMain=Gomoko diff --git a/buildJvm/build_41_Guess_java/build.gradle b/buildJvm/build_41_Guess_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_41_Guess_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_41_Guess_java/gradle.properties b/buildJvm/build_41_Guess_java/gradle.properties new file mode 100644 index 000000000..f03bfad15 --- /dev/null +++ b/buildJvm/build_41_Guess_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=41_Guess/java/src +gameMain=GuessGame \ No newline at end of file diff --git a/buildJvm/build_42_Gunner_java/build.gradle b/buildJvm/build_42_Gunner_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_42_Gunner_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_42_Gunner_java/gradle.properties b/buildJvm/build_42_Gunner_java/gradle.properties new file mode 100644 index 000000000..0e6429c66 --- /dev/null +++ b/buildJvm/build_42_Gunner_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=42_Gunner/java +gameMain=Gunner diff --git a/buildJvm/build_43_Hammurabi_java/build.gradle b/buildJvm/build_43_Hammurabi_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_43_Hammurabi_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_43_Hammurabi_java/gradle.properties b/buildJvm/build_43_Hammurabi_java/gradle.properties new file mode 100644 index 000000000..3374d23ec --- /dev/null +++ b/buildJvm/build_43_Hammurabi_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=43_Hammurabi/java/src +gameMain=HamurabiGame diff --git a/buildJvm/build_44_Hangman_java/build.gradle b/buildJvm/build_44_Hangman_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_44_Hangman_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_44_Hangman_java/gradle.properties b/buildJvm/build_44_Hangman_java/gradle.properties new file mode 100644 index 000000000..8fb150178 --- /dev/null +++ b/buildJvm/build_44_Hangman_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=44_Hangman/java +gameMain=Hangman diff --git a/buildJvm/build_45_Hello_java/build.gradle b/buildJvm/build_45_Hello_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_45_Hello_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_45_Hello_java/gradle.properties b/buildJvm/build_45_Hello_java/gradle.properties new file mode 100644 index 000000000..2caf52cdf --- /dev/null +++ b/buildJvm/build_45_Hello_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=45_Hello/java +gameMain=Hello diff --git a/buildJvm/build_47_Hi-Lo_java/build.gradle b/buildJvm/build_47_Hi-Lo_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_47_Hi-Lo_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_47_Hi-Lo_java/gradle.properties b/buildJvm/build_47_Hi-Lo_java/gradle.properties new file mode 100644 index 000000000..5ee2a2373 --- /dev/null +++ b/buildJvm/build_47_Hi-Lo_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=47_Hi-Lo/java/src +gameMain=HiLoGame \ No newline at end of file diff --git a/buildJvm/build_47_Hi-Lo_kotlin/build.gradle b/buildJvm/build_47_Hi-Lo_kotlin/build.gradle new file mode 100644 index 000000000..581a09152 --- /dev/null +++ b/buildJvm/build_47_Hi-Lo_kotlin/build.gradle @@ -0,0 +1,20 @@ +plugins { + id 'application' + id 'org.jetbrains.kotlin.jvm' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_47_Hi-Lo_kotlin/gradle.properties b/buildJvm/build_47_Hi-Lo_kotlin/gradle.properties new file mode 100644 index 000000000..0ecd0e05f --- /dev/null +++ b/buildJvm/build_47_Hi-Lo_kotlin/gradle.properties @@ -0,0 +1,2 @@ +gameSource=47_Hi-Lo/kotlin +gameMain=HiLoKt diff --git a/buildJvm/build_51_Hurkle_java/build.gradle b/buildJvm/build_51_Hurkle_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_51_Hurkle_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_51_Hurkle_java/gradle.properties b/buildJvm/build_51_Hurkle_java/gradle.properties new file mode 100644 index 000000000..508804ffc --- /dev/null +++ b/buildJvm/build_51_Hurkle_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=51_Hurkle/java/src +gameMain=HurkleGame \ No newline at end of file diff --git a/buildJvm/build_52_Kinema_java/build.gradle b/buildJvm/build_52_Kinema_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_52_Kinema_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_52_Kinema_java/gradle.properties b/buildJvm/build_52_Kinema_java/gradle.properties new file mode 100644 index 000000000..8ab182cf9 --- /dev/null +++ b/buildJvm/build_52_Kinema_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=52_Kinema/java/src +gameMain=KinemaGame \ No newline at end of file diff --git a/buildJvm/build_53_King_kotlin/build.gradle b/buildJvm/build_53_King_kotlin/build.gradle new file mode 100644 index 000000000..7365fd959 --- /dev/null +++ b/buildJvm/build_53_King_kotlin/build.gradle @@ -0,0 +1,20 @@ +plugins { + id 'org.jetbrains.kotlin.jvm' + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_53_King_kotlin/gradle.properties b/buildJvm/build_53_King_kotlin/gradle.properties new file mode 100644 index 000000000..4b90ac8df --- /dev/null +++ b/buildJvm/build_53_King_kotlin/gradle.properties @@ -0,0 +1,2 @@ +gameSource=53_King/kotlin +gameMain=king53.KingKt diff --git a/buildJvm/build_54_Letter_java/build.gradle b/buildJvm/build_54_Letter_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_54_Letter_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_54_Letter_java/gradle.properties b/buildJvm/build_54_Letter_java/gradle.properties new file mode 100644 index 000000000..bda98ac65 --- /dev/null +++ b/buildJvm/build_54_Letter_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=54_Letter/java/src +gameMain=LetterGame \ No newline at end of file diff --git a/buildJvm/build_57_Literature_Quiz_java/build.gradle b/buildJvm/build_57_Literature_Quiz_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_57_Literature_Quiz_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_57_Literature_Quiz_java/gradle.properties b/buildJvm/build_57_Literature_Quiz_java/gradle.properties new file mode 100644 index 000000000..0102ba469 --- /dev/null +++ b/buildJvm/build_57_Literature_Quiz_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=57_Literature_Quiz/java/src +gameMain=LiteratureQuizGame diff --git a/buildJvm/build_58_Love_java/build.gradle b/buildJvm/build_58_Love_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_58_Love_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_58_Love_java/gradle.properties b/buildJvm/build_58_Love_java/gradle.properties new file mode 100644 index 000000000..620ea65f4 --- /dev/null +++ b/buildJvm/build_58_Love_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=58_Love/java/src +gameMain=Love diff --git a/buildJvm/build_61_Math_Dice_java/build.gradle b/buildJvm/build_61_Math_Dice_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_61_Math_Dice_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_61_Math_Dice_java/gradle.properties b/buildJvm/build_61_Math_Dice_java/gradle.properties new file mode 100644 index 000000000..0439407b0 --- /dev/null +++ b/buildJvm/build_61_Math_Dice_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=61_Math_Dice/java +gameMain=MathDice \ No newline at end of file diff --git a/buildJvm/build_62_Mugwump_java/build.gradle b/buildJvm/build_62_Mugwump_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_62_Mugwump_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_62_Mugwump_java/gradle.properties b/buildJvm/build_62_Mugwump_java/gradle.properties new file mode 100644 index 000000000..5ad87d0b0 --- /dev/null +++ b/buildJvm/build_62_Mugwump_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=62_Mugwump/java/src +gameMain=Mugwump diff --git a/buildJvm/build_64_Nicomachus_java/build.gradle b/buildJvm/build_64_Nicomachus_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_64_Nicomachus_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_64_Nicomachus_java/gradle.properties b/buildJvm/build_64_Nicomachus_java/gradle.properties new file mode 100644 index 000000000..4d385abc2 --- /dev/null +++ b/buildJvm/build_64_Nicomachus_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=64_Nicomachus/java/src +gameMain=Nicomachus diff --git a/buildJvm/build_66_Number_java/build.gradle b/buildJvm/build_66_Number_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_66_Number_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_66_Number_java/gradle.properties b/buildJvm/build_66_Number_java/gradle.properties new file mode 100644 index 000000000..1920c5956 --- /dev/null +++ b/buildJvm/build_66_Number_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=66_Number/java +gameMain=Number diff --git a/buildJvm/build_67_One_Check_java/build.gradle b/buildJvm/build_67_One_Check_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_67_One_Check_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_67_One_Check_java/gradle.properties b/buildJvm/build_67_One_Check_java/gradle.properties new file mode 100644 index 000000000..995bd254e --- /dev/null +++ b/buildJvm/build_67_One_Check_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=67_One_Check/java +gameMain=OneCheck diff --git a/buildJvm/build_68_Orbit_java/build.gradle b/buildJvm/build_68_Orbit_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_68_Orbit_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_68_Orbit_java/gradle.properties b/buildJvm/build_68_Orbit_java/gradle.properties new file mode 100644 index 000000000..aa1fe24eb --- /dev/null +++ b/buildJvm/build_68_Orbit_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=68_Orbit/java +gameMain=Orbit diff --git a/buildJvm/build_69_Pizza_java/build.gradle b/buildJvm/build_69_Pizza_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_69_Pizza_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_69_Pizza_java/gradle.properties b/buildJvm/build_69_Pizza_java/gradle.properties new file mode 100644 index 000000000..959746a6a --- /dev/null +++ b/buildJvm/build_69_Pizza_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=69_Pizza/java/src +gameMain=PizzaGame diff --git a/buildJvm/build_70_Poetry_java/build.gradle b/buildJvm/build_70_Poetry_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_70_Poetry_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_70_Poetry_java/gradle.properties b/buildJvm/build_70_Poetry_java/gradle.properties new file mode 100644 index 000000000..4d8d8585c --- /dev/null +++ b/buildJvm/build_70_Poetry_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=70_Poetry/java +gameMain=Poetry diff --git a/buildJvm/build_73_Reverse_java/build.gradle b/buildJvm/build_73_Reverse_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_73_Reverse_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_73_Reverse_java/gradle.properties b/buildJvm/build_73_Reverse_java/gradle.properties new file mode 100644 index 000000000..6ddce57d0 --- /dev/null +++ b/buildJvm/build_73_Reverse_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=73_Reverse/java +gameMain=Reverse diff --git a/buildJvm/build_74_Rock_Scissors_Paper_java/build.gradle b/buildJvm/build_74_Rock_Scissors_Paper_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_74_Rock_Scissors_Paper_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_74_Rock_Scissors_Paper_java/gradle.properties b/buildJvm/build_74_Rock_Scissors_Paper_java/gradle.properties new file mode 100644 index 000000000..1cdf93a7f --- /dev/null +++ b/buildJvm/build_74_Rock_Scissors_Paper_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=74_Rock_Scissors_Paper/java/src +gameMain=RockScissors diff --git a/buildJvm/build_76_Russian_Roulette_java/build.gradle b/buildJvm/build_76_Russian_Roulette_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_76_Russian_Roulette_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_76_Russian_Roulette_java/gradle.properties b/buildJvm/build_76_Russian_Roulette_java/gradle.properties new file mode 100644 index 000000000..89078da09 --- /dev/null +++ b/buildJvm/build_76_Russian_Roulette_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=76_Russian_Roulette/java/src +gameMain=RussianRoulette diff --git a/buildJvm/build_78_Sine_Wave_java/build.gradle b/buildJvm/build_78_Sine_Wave_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_78_Sine_Wave_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_78_Sine_Wave_java/gradle.properties b/buildJvm/build_78_Sine_Wave_java/gradle.properties new file mode 100644 index 000000000..c5adb119e --- /dev/null +++ b/buildJvm/build_78_Sine_Wave_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=78_Sine_Wave/java/src +gameMain=SineWave diff --git a/buildJvm/build_80_Slots_java/build.gradle b/buildJvm/build_80_Slots_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_80_Slots_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_80_Slots_java/gradle.properties b/buildJvm/build_80_Slots_java/gradle.properties new file mode 100644 index 000000000..f4930f1e6 --- /dev/null +++ b/buildJvm/build_80_Slots_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=80_Slots/java/src +gameMain=SlotsGame diff --git a/buildJvm/build_82_Stars_java/build.gradle b/buildJvm/build_82_Stars_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_82_Stars_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_82_Stars_java/gradle.properties b/buildJvm/build_82_Stars_java/gradle.properties new file mode 100644 index 000000000..5f2e51f6d --- /dev/null +++ b/buildJvm/build_82_Stars_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=82_Stars/java/src +gameMain=StarsGame diff --git a/buildJvm/build_85_Synonym_java/build.gradle b/buildJvm/build_85_Synonym_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_85_Synonym_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_85_Synonym_java/gradle.properties b/buildJvm/build_85_Synonym_java/gradle.properties new file mode 100644 index 000000000..448430db3 --- /dev/null +++ b/buildJvm/build_85_Synonym_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=85_Synonym/java/src +gameMain=SynonymGame diff --git a/buildJvm/build_86_Target_java/build.gradle b/buildJvm/build_86_Target_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_86_Target_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_86_Target_java/gradle.properties b/buildJvm/build_86_Target_java/gradle.properties new file mode 100644 index 000000000..cdb506acf --- /dev/null +++ b/buildJvm/build_86_Target_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=86_Target/java +gameMain=Target diff --git a/buildJvm/build_87_3-D_Plot_java/build.gradle b/buildJvm/build_87_3-D_Plot_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_87_3-D_Plot_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_87_3-D_Plot_java/gradle.properties b/buildJvm/build_87_3-D_Plot_java/gradle.properties new file mode 100644 index 000000000..fb6ce1a90 --- /dev/null +++ b/buildJvm/build_87_3-D_Plot_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=87_3-D_Plot/java +gameMain=Plot3D diff --git a/buildJvm/build_89_Tic-Tac-Toe_java/build.gradle b/buildJvm/build_89_Tic-Tac-Toe_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_89_Tic-Tac-Toe_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_89_Tic-Tac-Toe_java/gradle.properties b/buildJvm/build_89_Tic-Tac-Toe_java/gradle.properties new file mode 100644 index 000000000..5f342b1de --- /dev/null +++ b/buildJvm/build_89_Tic-Tac-Toe_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=89_Tic-Tac-Toe/java/src +gameMain=TicTacToe2 diff --git a/buildJvm/build_89_Tic-Tac-Toe_kotlin/build.gradle b/buildJvm/build_89_Tic-Tac-Toe_kotlin/build.gradle new file mode 100644 index 000000000..7365fd959 --- /dev/null +++ b/buildJvm/build_89_Tic-Tac-Toe_kotlin/build.gradle @@ -0,0 +1,20 @@ +plugins { + id 'org.jetbrains.kotlin.jvm' + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_89_Tic-Tac-Toe_kotlin/gradle.properties b/buildJvm/build_89_Tic-Tac-Toe_kotlin/gradle.properties new file mode 100644 index 000000000..dce0b4f3e --- /dev/null +++ b/buildJvm/build_89_Tic-Tac-Toe_kotlin/gradle.properties @@ -0,0 +1,2 @@ +gameSource=89_Tic-Tac-Toe/kotlin +gameMain=TicTacToe2Kt diff --git a/buildJvm/build_90_Tower_java/build.gradle b/buildJvm/build_90_Tower_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_90_Tower_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_90_Tower_java/gradle.properties b/buildJvm/build_90_Tower_java/gradle.properties new file mode 100644 index 000000000..faf3c4378 --- /dev/null +++ b/buildJvm/build_90_Tower_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=90_Tower/java +gameMain=Tower diff --git a/buildJvm/build_91_Train_java/build.gradle b/buildJvm/build_91_Train_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_91_Train_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_91_Train_java/gradle.properties b/buildJvm/build_91_Train_java/gradle.properties new file mode 100644 index 000000000..8e315af22 --- /dev/null +++ b/buildJvm/build_91_Train_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=91_Train/java/src +gameMain=Train diff --git a/buildJvm/build_92_Trap_java/build.gradle b/buildJvm/build_92_Trap_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_92_Trap_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_92_Trap_java/gradle.properties b/buildJvm/build_92_Trap_java/gradle.properties new file mode 100644 index 000000000..a01ba4ea5 --- /dev/null +++ b/buildJvm/build_92_Trap_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=92_Trap/java/src +gameMain=TrapGame \ No newline at end of file diff --git a/buildJvm/build_93_23_Matches_java/build.gradle b/buildJvm/build_93_23_Matches_java/build.gradle new file mode 100644 index 000000000..a6ad4168c --- /dev/null +++ b/buildJvm/build_93_23_Matches_java/build.gradle @@ -0,0 +1,24 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} +java { + toolchain { + languageVersion = JavaLanguageVersion.of(17) + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_93_23_Matches_java/gradle.properties b/buildJvm/build_93_23_Matches_java/gradle.properties new file mode 100644 index 000000000..c1b1c2697 --- /dev/null +++ b/buildJvm/build_93_23_Matches_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=93_23_Matches/java +gameMain=TwentyThreeMatchesGame \ No newline at end of file diff --git a/buildJvm/build_94_War_java/build.gradle b/buildJvm/build_94_War_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_94_War_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_94_War_java/gradle.properties b/buildJvm/build_94_War_java/gradle.properties new file mode 100644 index 000000000..3cf5ec6d9 --- /dev/null +++ b/buildJvm/build_94_War_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=94_War/java +gameMain=War diff --git a/buildJvm/build_94_War_kotlin/build.gradle b/buildJvm/build_94_War_kotlin/build.gradle new file mode 100644 index 000000000..7365fd959 --- /dev/null +++ b/buildJvm/build_94_War_kotlin/build.gradle @@ -0,0 +1,20 @@ +plugins { + id 'org.jetbrains.kotlin.jvm' + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_94_War_kotlin/gradle.properties b/buildJvm/build_94_War_kotlin/gradle.properties new file mode 100644 index 000000000..e9fdd4bcb --- /dev/null +++ b/buildJvm/build_94_War_kotlin/gradle.properties @@ -0,0 +1,2 @@ +gameSource=94_War/kotlin +gameMain=WarKt diff --git a/buildJvm/build_95_Weekday_java/build.gradle b/buildJvm/build_95_Weekday_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_95_Weekday_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_95_Weekday_java/gradle.properties b/buildJvm/build_95_Weekday_java/gradle.properties new file mode 100644 index 000000000..bef38fdd8 --- /dev/null +++ b/buildJvm/build_95_Weekday_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=95_Weekday/java +gameMain=Weekday diff --git a/buildJvm/build_96_Word_java/build.gradle b/buildJvm/build_96_Word_java/build.gradle new file mode 100644 index 000000000..3432056c7 --- /dev/null +++ b/buildJvm/build_96_Word_java/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +sourceSets { + main { + java { + srcDirs "../../$gameSource" + } + } +} + +repositories { + mavenCentral() +} + +application { + mainClass = gameMain +} diff --git a/buildJvm/build_96_Word_java/gradle.properties b/buildJvm/build_96_Word_java/gradle.properties new file mode 100644 index 000000000..82d745870 --- /dev/null +++ b/buildJvm/build_96_Word_java/gradle.properties @@ -0,0 +1,2 @@ +gameSource=96_Word/java +gameMain=Word diff --git a/.nojekyll b/buildJvm/gradle.properties similarity index 100% rename from .nojekyll rename to buildJvm/gradle.properties diff --git a/buildJvm/gradle/wrapper/gradle-wrapper.jar b/buildJvm/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 000000000..7454180f2 Binary files /dev/null and b/buildJvm/gradle/wrapper/gradle-wrapper.jar differ diff --git a/buildJvm/gradle/wrapper/gradle-wrapper.properties b/buildJvm/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..ffed3a254 --- /dev/null +++ b/buildJvm/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/buildJvm/gradlew b/buildJvm/gradlew new file mode 100755 index 000000000..1b6c78733 --- /dev/null +++ b/buildJvm/gradlew @@ -0,0 +1,234 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +APP_NAME="Gradle" +APP_BASE_NAME=${0##*/} + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/buildJvm/gradlew.bat b/buildJvm/gradlew.bat new file mode 100644 index 000000000..ac1b06f93 --- /dev/null +++ b/buildJvm/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/buildJvm/settings.gradle b/buildJvm/settings.gradle new file mode 100644 index 000000000..d7b28da34 --- /dev/null +++ b/buildJvm/settings.gradle @@ -0,0 +1,74 @@ +rootProject.name = 'BasicComputerGames' + +include ":build_03_Animal_kotlin" +include ":build_53_King_kotlin" +include ":build_47_Hi-Lo_kotlin" +include ":build_53_King_kotlin" +include ":build_89_Tic-Tac-Toe_kotlin" +include ":build_94_War_kotlin" + +include ":build_01_Acey_Ducey_java" +include ":build_02_Amazing_java" +include ":build_03_Animal_java" +include ":build_04_Awari_java" +include ":build_05_Bagels_java" +include ":build_06_Banner_java" +include ":build_08_Batnum_java" +include ":build_11_Bombardment_java" +include ":build_12_Bombs_Away_java" +include ":build_13_Bounce_java" +include ":build_14_Bowling_java" +include ":build_15_Boxing_java" +include ":build_16_Bug_java" +include ":build_18_Bullseye_java" +include ":build_19_Bunny_java" +include ":build_20_Buzzword_java" +include ":build_21_Calendar_java" +include ":build_22_Change_java" +include ":build_24_Chemist_java" +include ":build_25_Chief_java" +include ":build_26_Chomp_java" +include ":build_28_Combat_java" +include ":build_31_Depth_Charge_java" +include ":build_32_Diamond_java" +include ":build_33_Dice_java" +include ":build_34_Digits_java" +include ":build_36_Flip_Flop_java" +include ":build_38_Fur_Trader_java" +include ":build_40_Gomoko_java" +include ":build_41_Guess_java" +include ":build_42_Gunner_java" +include ":build_43_Hammurabi_java" +include ":build_44_Hangman_java" +include ":build_45_Hello_java" +include ":build_47_Hi-Lo_java" +include ":build_51_Hurkle_java" +include ":build_52_Kinema_java" +include ":build_54_Letter_java" +include ":build_57_Literature_Quiz_java" +include ":build_58_Love_java" +include ":build_61_Math_Dice_java" +include ":build_62_Mugwump_java" +include ":build_64_Nicomachus_java" +include ":build_66_Number_java" +include ":build_67_One_Check_java" +include ":build_68_Orbit_java" +include ":build_69_Pizza_java" +include ":build_70_Poetry_java" +include ":build_73_Reverse_java" +include ":build_74_Rock_Scissors_Paper_java" +include ":build_76_Russian_Roulette_java" +include ":build_78_Sine_Wave_java" +include ":build_80_Slots_java" +include ":build_82_Stars_java" +include ":build_85_Synonym_java" +include ":build_86_Target_java" +include ":build_87_3-D_Plot_java" +include ":build_89_Tic-Tac-Toe_java" +include ":build_90_Tower_java" +include ":build_91_Train_java" +include ":build_92_Trap_java" +include ":build_93_23_Matches_java" +include ":build_94_War_java" +include ":build_95_Weekday_java" +include ":build_96_Word_java" diff --git a/index.html b/index.html deleted file mode 100644 index cb9ea8d35..000000000 --- a/index.html +++ /dev/null @@ -1 +0,0 @@ -BASIC Computer Games
    \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml deleted file mode 100644 index dff6b32d0..000000000 --- a/pyproject.toml +++ /dev/null @@ -1,4 +0,0 @@ -[tool.pytest.ini_options] -markers = [ - "slow: marks tests as slow (deselect with '-m \"not slow\"')", -]

    BASIC Computer Games