diff --git a/.gitignore b/.gitignore index 62fdc5be..8efd6d4a 100644 --- a/.gitignore +++ b/.gitignore @@ -34,7 +34,6 @@ venv/ .DS_Store .vs/ **/target/ -Cargo.lock **/*.rs.bk /target todo.md diff --git a/00_Alternate_Languages/01_Acey_Ducey/MiniScript/README.md b/00_Alternate_Languages/01_Acey_Ducey/MiniScript/README.md new file mode 100644 index 00000000..06640e03 --- /dev/null +++ b/00_Alternate_Languages/01_Acey_Ducey/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..c00684ce --- /dev/null +++ b/00_Alternate_Languages/01_Acey_Ducey/MiniScript/aceyducey.ms @@ -0,0 +1,59 @@ +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/nim/aceyducey.nim b/00_Alternate_Languages/01_Acey_Ducey/nim/aceyducey.nim new file mode 100644 index 00000000..abc03def --- /dev/null +++ b/00_Alternate_Languages/01_Acey_Ducey/nim/aceyducey.nim @@ -0,0 +1,89 @@ +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/02_Amazing/MiniScript/README.md b/00_Alternate_Languages/02_Amazing/MiniScript/README.md new file mode 100644 index 00000000..35d818ef --- /dev/null +++ b/00_Alternate_Languages/02_Amazing/MiniScript/README.md @@ -0,0 +1,21 @@ +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 new file mode 100644 index 00000000..3c358979 --- /dev/null +++ b/00_Alternate_Languages/02_Amazing/MiniScript/amazing.ms @@ -0,0 +1,108 @@ +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/03_Animal/MiniScript/README.md b/00_Alternate_Languages/03_Animal/MiniScript/README.md new file mode 100644 index 00000000..1e48ea49 --- /dev/null +++ b/00_Alternate_Languages/03_Animal/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..5aafdddb --- /dev/null +++ b/00_Alternate_Languages/03_Animal/MiniScript/animal.ms @@ -0,0 +1,90 @@ +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/04_Awari/MiniScript/README.md b/00_Alternate_Languages/04_Awari/MiniScript/README.md new file mode 100644 index 00000000..f2b6dfe5 --- /dev/null +++ b/00_Alternate_Languages/04_Awari/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..e01c2d6c --- /dev/null +++ b/00_Alternate_Languages/04_Awari/MiniScript/awari.ms @@ -0,0 +1,146 @@ +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/05_Bagels/MiniScript/README.md b/00_Alternate_Languages/05_Bagels/MiniScript/README.md new file mode 100644 index 00000000..743d5160 --- /dev/null +++ b/00_Alternate_Languages/05_Bagels/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..93b33b01 --- /dev/null +++ b/00_Alternate_Languages/05_Bagels/MiniScript/bagels.ms @@ -0,0 +1,83 @@ +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/nim/bagels.nim b/00_Alternate_Languages/05_Bagels/nim/bagels.nim new file mode 100644 index 00000000..f302b375 --- /dev/null +++ b/00_Alternate_Languages/05_Bagels/nim/bagels.nim @@ -0,0 +1,97 @@ +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 new file mode 100644 index 00000000..25a241af --- /dev/null +++ b/00_Alternate_Languages/06_Banner/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..d5d57e18 --- /dev/null +++ b/00_Alternate_Languages/06_Banner/MiniScript/banner.ms @@ -0,0 +1,89 @@ +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/07_Basketball/MiniScript/README.md b/00_Alternate_Languages/07_Basketball/MiniScript/README.md new file mode 100644 index 00000000..5958590e --- /dev/null +++ b/00_Alternate_Languages/07_Basketball/MiniScript/README.md @@ -0,0 +1,19 @@ +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 basketball.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 "basketball" + run +``` \ No newline at end of file diff --git a/00_Alternate_Languages/07_Basketball/MiniScript/basketball.ms b/00_Alternate_Languages/07_Basketball/MiniScript/basketball.ms new file mode 100644 index 00000000..d152cb10 --- /dev/null +++ b/00_Alternate_Languages/07_Basketball/MiniScript/basketball.ms @@ -0,0 +1,299 @@ +print " "*31 + "Basketball" +print " "*15 + "Creative Computing Morristown, New Jersey" +print; print; print +print "This is Dartmouth College basketball. You will be Dartmouth" +print " captain and playmaker. Call shots as follows: 1. Long" +print " (30 ft.) jump shot; 2. Short (15 ft.) jump shot; 3. Lay" +print " up; 4. Set shot." +print "Both teams will use the same defense. Call defense as" +print "follows: 6. Press; 6.5 Man-to-Man; 7. Zone; 7.5 None." +print "To change defense, just type 0 as your next shot." + +inputDefense = function(prompt) + while true + globals.defense = input(prompt).val + if defense >= 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/08_Batnum/MiniScript/README.md b/00_Alternate_Languages/08_Batnum/MiniScript/README.md new file mode 100644 index 00000000..b33a3f84 --- /dev/null +++ b/00_Alternate_Languages/08_Batnum/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..d1019717 --- /dev/null +++ b/00_Alternate_Languages/08_Batnum/MiniScript/batnum.ms @@ -0,0 +1,109 @@ +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/09_Battle/MiniScript/README.md b/00_Alternate_Languages/09_Battle/MiniScript/README.md new file mode 100644 index 00000000..07cd9827 --- /dev/null +++ b/00_Alternate_Languages/09_Battle/MiniScript/README.md @@ -0,0 +1,21 @@ +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 new file mode 100644 index 00000000..e082b25b --- /dev/null +++ b/00_Alternate_Languages/09_Battle/MiniScript/battle.ms @@ -0,0 +1,157 @@ +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/10_Blackjack/MiniScript/README.md b/00_Alternate_Languages/10_Blackjack/MiniScript/README.md new file mode 100644 index 00000000..2f68bb79 --- /dev/null +++ b/00_Alternate_Languages/10_Blackjack/MiniScript/README.md @@ -0,0 +1,21 @@ +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 new file mode 100644 index 00000000..f6d7959b --- /dev/null +++ b/00_Alternate_Languages/10_Blackjack/MiniScript/blackjack.ms @@ -0,0 +1,285 @@ +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/11_Bombardment/MiniScript/README.md b/00_Alternate_Languages/11_Bombardment/MiniScript/README.md new file mode 100644 index 00000000..4a399a7b --- /dev/null +++ b/00_Alternate_Languages/11_Bombardment/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..a6f75009 --- /dev/null +++ b/00_Alternate_Languages/11_Bombardment/MiniScript/bombardment.ms @@ -0,0 +1,101 @@ +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/12_Bombs_Away/MiniScript/README.md b/00_Alternate_Languages/12_Bombs_Away/MiniScript/README.md new file mode 100644 index 00000000..22bcc0b1 --- /dev/null +++ b/00_Alternate_Languages/12_Bombs_Away/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..ea06ea48 --- /dev/null +++ b/00_Alternate_Languages/12_Bombs_Away/MiniScript/bombsaway.ms @@ -0,0 +1,112 @@ + +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/13_Bounce/MiniScript/README.md b/00_Alternate_Languages/13_Bounce/MiniScript/README.md new file mode 100644 index 00000000..e7e8f23a --- /dev/null +++ b/00_Alternate_Languages/13_Bounce/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..64174be6 --- /dev/null +++ b/00_Alternate_Languages/13_Bounce/MiniScript/bounce.ms @@ -0,0 +1,55 @@ +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/14_Bowling/MiniScript/README.md b/00_Alternate_Languages/14_Bowling/MiniScript/README.md new file mode 100644 index 00000000..bfb33e6b --- /dev/null +++ b/00_Alternate_Languages/14_Bowling/MiniScript/README.md @@ -0,0 +1,19 @@ +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 bowling.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 "bowling" + run +``` \ No newline at end of file diff --git a/00_Alternate_Languages/14_Bowling/MiniScript/bowling.ms b/00_Alternate_Languages/14_Bowling/MiniScript/bowling.ms new file mode 100644 index 00000000..139ec225 --- /dev/null +++ b/00_Alternate_Languages/14_Bowling/MiniScript/bowling.ms @@ -0,0 +1,138 @@ +import "listUtil" + +print " "*34 + "Bowl" +print " "*15 + "Creative Computing Morristown, New Jersey" +print; print; print + +pinDown = [0]*10 // state of each pin: 1=down, 0=standing +player = 1 +frame = 1 +ball = 1 +scores = list.init3d(10, 4, 3, 0) // index by [frame][player][ball], all 0-based + +printInstructions = function + 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." +end function + +printPinDiagram = function + print "Player: " + (player+1) + " Frame: " + (frame+1) + " Ball: " + (ball+1) + print + k = 0 + for row in range (0, 3) + line = " " * row + for j in range(1, 4-row) + line += "+O"[pinDown[k]] + " " + k += 1 + end for + print line + end for +end function + +printAnalysis = function(previousDown=0) + pinsLeft = 10 - pinDown.sum + if pinDown.sum == previousDown then print "Gutter!!" + if ball == 0 and pinsLeft == 0 then + print "Strike!!!!!" + char(7)*4 + globals.status = 3 + else if ball == 1 and pinsLeft == 0 then + print "Spare!!!!" + globals.status = 2 + else if ball == 1 and pinsLeft > 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/15_Boxing/MiniScript/README.md b/00_Alternate_Languages/15_Boxing/MiniScript/README.md new file mode 100644 index 00000000..9c0ae8fc --- /dev/null +++ b/00_Alternate_Languages/15_Boxing/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..948a3bdd --- /dev/null +++ b/00_Alternate_Languages/15_Boxing/MiniScript/boxing.ms @@ -0,0 +1,174 @@ +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/16_Bug/MiniScript/README.md b/00_Alternate_Languages/16_Bug/MiniScript/README.md new file mode 100644 index 00000000..554d5e52 --- /dev/null +++ b/00_Alternate_Languages/16_Bug/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..29349b2a --- /dev/null +++ b/00_Alternate_Languages/16_Bug/MiniScript/bug.ms @@ -0,0 +1,192 @@ +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/17_Bullfight/MiniScript/README.md b/00_Alternate_Languages/17_Bullfight/MiniScript/README.md new file mode 100644 index 00000000..2290e6e1 --- /dev/null +++ b/00_Alternate_Languages/17_Bullfight/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..1259d651 --- /dev/null +++ b/00_Alternate_Languages/17_Bullfight/MiniScript/bull.ms @@ -0,0 +1,188 @@ +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/18_Bullseye/MiniScript/README.md b/00_Alternate_Languages/18_Bullseye/MiniScript/README.md new file mode 100644 index 00000000..73a1c749 --- /dev/null +++ b/00_Alternate_Languages/18_Bullseye/MiniScript/README.md @@ -0,0 +1,22 @@ +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 new file mode 100644 index 00000000..10dc95ca --- /dev/null +++ b/00_Alternate_Languages/18_Bullseye/MiniScript/bullseye.ms @@ -0,0 +1,59 @@ +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/19_Bunny/MiniScript/README.md b/00_Alternate_Languages/19_Bunny/MiniScript/README.md new file mode 100644 index 00000000..90a05433 --- /dev/null +++ b/00_Alternate_Languages/19_Bunny/MiniScript/README.md @@ -0,0 +1,22 @@ +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 new file mode 100644 index 00000000..176e1e6c --- /dev/null +++ b/00_Alternate_Languages/19_Bunny/MiniScript/bunny.ms @@ -0,0 +1,43 @@ +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/20_Buzzword/MiniScript/README.md b/00_Alternate_Languages/20_Buzzword/MiniScript/README.md new file mode 100644 index 00000000..90a05433 --- /dev/null +++ b/00_Alternate_Languages/20_Buzzword/MiniScript/README.md @@ -0,0 +1,22 @@ +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 new file mode 100644 index 00000000..26a37775 --- /dev/null +++ b/00_Alternate_Languages/20_Buzzword/MiniScript/buzzword.ms @@ -0,0 +1,38 @@ +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/nim/buzzword.nim b/00_Alternate_Languages/20_Buzzword/nim/buzzword.nim new file mode 100644 index 00000000..dfba31c9 --- /dev/null +++ b/00_Alternate_Languages/20_Buzzword/nim/buzzword.nim @@ -0,0 +1,34 @@ +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 new file mode 100644 index 00000000..fea2264e --- /dev/null +++ b/00_Alternate_Languages/21_Calendar/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..27691bdb --- /dev/null +++ b/00_Alternate_Languages/21_Calendar/MiniScript/calendar.ms @@ -0,0 +1,89 @@ +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/22_Change/MiniScript/README.md b/00_Alternate_Languages/22_Change/MiniScript/README.md new file mode 100644 index 00000000..5708156d --- /dev/null +++ b/00_Alternate_Languages/22_Change/MiniScript/README.md @@ -0,0 +1,22 @@ +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 new file mode 100644 index 00000000..675a179a --- /dev/null +++ b/00_Alternate_Languages/22_Change/MiniScript/change.ms @@ -0,0 +1,57 @@ +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/23_Checkers/MiniScript/README.md b/00_Alternate_Languages/23_Checkers/MiniScript/README.md new file mode 100644 index 00000000..9cb5fd6e --- /dev/null +++ b/00_Alternate_Languages/23_Checkers/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..dc752712 --- /dev/null +++ b/00_Alternate_Languages/23_Checkers/MiniScript/checkers.ms @@ -0,0 +1,243 @@ +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/24_Chemist/MiniScript/README.md b/00_Alternate_Languages/24_Chemist/MiniScript/README.md new file mode 100644 index 00000000..82983edc --- /dev/null +++ b/00_Alternate_Languages/24_Chemist/MiniScript/README.md @@ -0,0 +1,22 @@ +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 new file mode 100644 index 00000000..712792ce --- /dev/null +++ b/00_Alternate_Languages/24_Chemist/MiniScript/chemist.ms @@ -0,0 +1,30 @@ +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/25_Chief/MiniScript/README.md b/00_Alternate_Languages/25_Chief/MiniScript/README.md new file mode 100644 index 00000000..fa28aa67 --- /dev/null +++ b/00_Alternate_Languages/25_Chief/MiniScript/README.md @@ -0,0 +1,24 @@ +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 new file mode 100644 index 00000000..272e6699 --- /dev/null +++ b/00_Alternate_Languages/25_Chief/MiniScript/chief.ms @@ -0,0 +1,50 @@ +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/26_Chomp/MiniScript/README.md b/00_Alternate_Languages/26_Chomp/MiniScript/README.md new file mode 100644 index 00000000..2fce3ec7 --- /dev/null +++ b/00_Alternate_Languages/26_Chomp/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..01b12f81 --- /dev/null +++ b/00_Alternate_Languages/26_Chomp/MiniScript/chomp.ms @@ -0,0 +1,102 @@ +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/27_Civil_War/MiniScript/README.md b/00_Alternate_Languages/27_Civil_War/MiniScript/README.md new file mode 100644 index 00000000..ad8e06ed --- /dev/null +++ b/00_Alternate_Languages/27_Civil_War/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..30b1ce82 --- /dev/null +++ b/00_Alternate_Languages/27_Civil_War/MiniScript/civilwar.ms @@ -0,0 +1,437 @@ +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/28_Combat/MiniScript/README.md b/00_Alternate_Languages/28_Combat/MiniScript/README.md new file mode 100644 index 00000000..0963185f --- /dev/null +++ b/00_Alternate_Languages/28_Combat/MiniScript/README.md @@ -0,0 +1,19 @@ +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 combat.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 "combat" + run +``` \ No newline at end of file diff --git a/00_Alternate_Languages/28_Combat/MiniScript/combat.ms b/00_Alternate_Languages/28_Combat/MiniScript/combat.ms new file mode 100644 index 00000000..c5f6596a --- /dev/null +++ b/00_Alternate_Languages/28_Combat/MiniScript/combat.ms @@ -0,0 +1,165 @@ +print " "*33 + "Combat" +print " "*15 + "Creative Computing Morristown, New Jersey" +print; print; print + +printInColumns2 = function(a, b, lineBreak=true) + print (a+" "*16)[:16] + (b+" "*16)[:16], "" + if lineBreak then print +end function + +printInColumns3 = function(a, b, c, lineBreak=true) + print (a+" "*16)[:16] + (b+" "*16)[:16] + (c+" "*16)[:16], "" + if lineBreak then print +end function + +// computer forces: +d = 30000 // army +e = 20000 // navy +f = 22000 // air force + +print "I am at war with you."; print "We have 72000 soldiers apiece." +while true + print; print "Distribute your forces." + printInColumns3 "", "ME", "YOU" + printInColumns2 "army", d, false + a = input("?").val + printInColumns2 "navy", e, false + b = input("?").val + printInColumns2 "a. f.", f, false + c = input("?").val + if a+b+c <= 72000 then break +end while + + +print "You attack first. Type (1) for army; (2) for navy;" +print "and (3) for air force." +y = input.val +while true + x = input("How many men? ").val + if x < 0 then continue + if y <= 1 or y > 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/29_Craps/MiniScript/README.md b/00_Alternate_Languages/29_Craps/MiniScript/README.md new file mode 100644 index 00000000..e500f4c3 --- /dev/null +++ b/00_Alternate_Languages/29_Craps/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..900ba5d4 --- /dev/null +++ b/00_Alternate_Languages/29_Craps/MiniScript/craps.ms @@ -0,0 +1,87 @@ +// 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/nim/craps.nim b/00_Alternate_Languages/29_Craps/nim/craps.nim new file mode 100644 index 00000000..770b6c0e --- /dev/null +++ b/00_Alternate_Languages/29_Craps/nim/craps.nim @@ -0,0 +1,68 @@ +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/MiniScript/README.md b/00_Alternate_Languages/30_Cube/MiniScript/README.md new file mode 100644 index 00000000..17eeb20b --- /dev/null +++ b/00_Alternate_Languages/30_Cube/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..1639ce43 --- /dev/null +++ b/00_Alternate_Languages/30_Cube/MiniScript/cube.ms @@ -0,0 +1,100 @@ +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/31_Depth_Charge/MiniScript/README.md b/00_Alternate_Languages/31_Depth_Charge/MiniScript/README.md new file mode 100644 index 00000000..0c20ea36 --- /dev/null +++ b/00_Alternate_Languages/31_Depth_Charge/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..3607cb80 --- /dev/null +++ b/00_Alternate_Languages/31_Depth_Charge/MiniScript/depthcharge.ms @@ -0,0 +1,116 @@ +// 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/32_Diamond/MiniScript/README.md b/00_Alternate_Languages/32_Diamond/MiniScript/README.md new file mode 100644 index 00000000..3a8249a0 --- /dev/null +++ b/00_Alternate_Languages/32_Diamond/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..8166b570 --- /dev/null +++ b/00_Alternate_Languages/32_Diamond/MiniScript/diamond.ms @@ -0,0 +1,23 @@ +// 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/33_Dice/MiniScript/README.md b/00_Alternate_Languages/33_Dice/MiniScript/README.md new file mode 100644 index 00000000..b670e30d --- /dev/null +++ b/00_Alternate_Languages/33_Dice/MiniScript/README.md @@ -0,0 +1,21 @@ +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 new file mode 100644 index 00000000..38b41ef3 --- /dev/null +++ b/00_Alternate_Languages/33_Dice/MiniScript/dice.ms @@ -0,0 +1,53 @@ +// 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/nim/dice.nim b/00_Alternate_Languages/33_Dice/nim/dice.nim new file mode 100644 index 00000000..6564ae9b --- /dev/null +++ b/00_Alternate_Languages/33_Dice/nim/dice.nim @@ -0,0 +1,37 @@ +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 new file mode 100644 index 00000000..280be246 --- /dev/null +++ b/00_Alternate_Languages/34_Digits/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..2abde907 --- /dev/null +++ b/00_Alternate_Languages/34_Digits/MiniScript/digits.ms @@ -0,0 +1,99 @@ +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/35_Even_Wins/MiniScript/README.md b/00_Alternate_Languages/35_Even_Wins/MiniScript/README.md new file mode 100644 index 00000000..d5281930 --- /dev/null +++ b/00_Alternate_Languages/35_Even_Wins/MiniScript/README.md @@ -0,0 +1,33 @@ +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 new file mode 100644 index 00000000..0712b830 --- /dev/null +++ b/00_Alternate_Languages/35_Even_Wins/MiniScript/evenwins.ms @@ -0,0 +1,140 @@ +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 new file mode 100644 index 00000000..e533550d --- /dev/null +++ b/00_Alternate_Languages/35_Even_Wins/MiniScript/gameofevenwins.ms @@ -0,0 +1,90 @@ +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/36_Flip_Flop/MiniScript/README.md b/00_Alternate_Languages/36_Flip_Flop/MiniScript/README.md new file mode 100644 index 00000000..e012477d --- /dev/null +++ b/00_Alternate_Languages/36_Flip_Flop/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..6fb07cc0 --- /dev/null +++ b/00_Alternate_Languages/36_Flip_Flop/MiniScript/flipflop.ms @@ -0,0 +1,97 @@ +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/37_Football/MiniScript/README.md b/00_Alternate_Languages/37_Football/MiniScript/README.md new file mode 100644 index 00000000..4d8c3306 --- /dev/null +++ b/00_Alternate_Languages/37_Football/MiniScript/README.md @@ -0,0 +1,34 @@ +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 new file mode 100644 index 00000000..e2b4583f --- /dev/null +++ b/00_Alternate_Languages/37_Football/MiniScript/football.ms @@ -0,0 +1,402 @@ +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 new file mode 100644 index 00000000..31d3f829 --- /dev/null +++ b/00_Alternate_Languages/37_Football/MiniScript/ftball.ms @@ -0,0 +1,431 @@ +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/38_Fur_Trader/MiniScript/README.md b/00_Alternate_Languages/38_Fur_Trader/MiniScript/README.md new file mode 100644 index 00000000..3b15b992 --- /dev/null +++ b/00_Alternate_Languages/38_Fur_Trader/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..6fb85e1a --- /dev/null +++ b/00_Alternate_Languages/38_Fur_Trader/MiniScript/furtrader.ms @@ -0,0 +1,171 @@ +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/39_Golf/MiniScript/README.md b/00_Alternate_Languages/39_Golf/MiniScript/README.md new file mode 100644 index 00000000..8a7e5325 --- /dev/null +++ b/00_Alternate_Languages/39_Golf/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..634ef090 --- /dev/null +++ b/00_Alternate_Languages/39_Golf/MiniScript/golf.ms @@ -0,0 +1,303 @@ +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/40_Gomoko/MiniScript/README.md b/00_Alternate_Languages/40_Gomoko/MiniScript/README.md new file mode 100644 index 00000000..5613d133 --- /dev/null +++ b/00_Alternate_Languages/40_Gomoko/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..3188e22a --- /dev/null +++ b/00_Alternate_Languages/40_Gomoko/MiniScript/gomoko.ms @@ -0,0 +1,94 @@ +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/41_Guess/MiniScript/README.md b/00_Alternate_Languages/41_Guess/MiniScript/README.md new file mode 100644 index 00000000..bf19c759 --- /dev/null +++ b/00_Alternate_Languages/41_Guess/MiniScript/README.md @@ -0,0 +1,21 @@ +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 new file mode 100644 index 00000000..496426ce --- /dev/null +++ b/00_Alternate_Languages/41_Guess/MiniScript/guess.ms @@ -0,0 +1,59 @@ +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/42_Gunner/MiniScript/README.md b/00_Alternate_Languages/42_Gunner/MiniScript/README.md new file mode 100644 index 00000000..32349917 --- /dev/null +++ b/00_Alternate_Languages/42_Gunner/MiniScript/README.md @@ -0,0 +1,19 @@ +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 gunner.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 "gunner" + run +``` \ No newline at end of file diff --git a/00_Alternate_Languages/42_Gunner/MiniScript/gunner.ms b/00_Alternate_Languages/42_Gunner/MiniScript/gunner.ms new file mode 100644 index 00000000..5c52a89e --- /dev/null +++ b/00_Alternate_Languages/42_Gunner/MiniScript/gunner.ms @@ -0,0 +1,78 @@ +print " "*30 + "Gunner" +print " "*15 + "Creative Computing Morristown, New Jersey" +print; print; print +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" +print "of the target will destroy it."; print + +// Select a target and give the player up to 5 tries to hit it. +// Return the number of shots taken, or set globals.gameOver to true. +playOneTarget = function(maxRange) + globals.gameOver = false + targetDist = floor(maxRange * (.1 + .8 * rnd)) + shot = 0 + print "Distance to the target is " + targetDist + " yards." + print + while true + print + degrees = input("Elevation? ").val + if degrees > 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/43_Hammurabi/MiniScript/README.md b/00_Alternate_Languages/43_Hammurabi/MiniScript/README.md new file mode 100644 index 00000000..bb4411bb --- /dev/null +++ b/00_Alternate_Languages/43_Hammurabi/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..f81a1e70 --- /dev/null +++ b/00_Alternate_Languages/43_Hammurabi/MiniScript/hammurabi.ms @@ -0,0 +1,190 @@ +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/hammurabi.bas b/00_Alternate_Languages/43_Hammurabi/hammurabi.bas index e41fe4fb..71afd1c5 100644 --- a/00_Alternate_Languages/43_Hammurabi/hammurabi.bas +++ b/00_Alternate_Languages/43_Hammurabi/hammurabi.bas @@ -1,119 +1,119 @@ -10 PRINT TAB(32);"HAMURABI" -20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" -30 PRINT:PRINT:PRINT +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) +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." +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 +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 +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 QC/2 THEN 530 +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 +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) +533 I = INT(C *(20 * A + S) / P / 100 + 1) 539 REM *** HOW MANY PEOPLE HAD FULL TUMMIES? -540 C=INT(Q/20) +540 C = INT(Q / 20) 541 REM *** HORROS, A 15% CHANCE OF PLAGUE -542 Q=INT(10*(2*RND(1)-.3)) -550 IF P.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!!!" +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 +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." +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" +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 +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 +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 +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 +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" +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 +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/MiniScript/README.md b/00_Alternate_Languages/44_Hangman/MiniScript/README.md new file mode 100644 index 00000000..cf8b2002 --- /dev/null +++ b/00_Alternate_Languages/44_Hangman/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..50c4e446 --- /dev/null +++ b/00_Alternate_Languages/44_Hangman/MiniScript/hangman.ms @@ -0,0 +1,127 @@ +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/45_Hello/MiniScript/README.md b/00_Alternate_Languages/45_Hello/MiniScript/README.md new file mode 100644 index 00000000..c3e534cb --- /dev/null +++ b/00_Alternate_Languages/45_Hello/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..a82344ef --- /dev/null +++ b/00_Alternate_Languages/45_Hello/MiniScript/hello.ms @@ -0,0 +1,108 @@ +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/46_Hexapawn/MiniScript/README.md b/00_Alternate_Languages/46_Hexapawn/MiniScript/README.md new file mode 100644 index 00000000..e2cd714a --- /dev/null +++ b/00_Alternate_Languages/46_Hexapawn/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..f2505ac4 --- /dev/null +++ b/00_Alternate_Languages/46_Hexapawn/MiniScript/hexapawn.ms @@ -0,0 +1,266 @@ +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/47_Hi-Lo/MiniScript/README.md b/00_Alternate_Languages/47_Hi-Lo/MiniScript/README.md new file mode 100644 index 00000000..dc20e7c8 --- /dev/null +++ b/00_Alternate_Languages/47_Hi-Lo/MiniScript/README.md @@ -0,0 +1,22 @@ +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 new file mode 100644 index 00000000..bd0801ee --- /dev/null +++ b/00_Alternate_Languages/47_Hi-Lo/MiniScript/hi-lo.ms @@ -0,0 +1,41 @@ +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/48_High_IQ/MiniScript/README.md b/00_Alternate_Languages/48_High_IQ/MiniScript/README.md new file mode 100644 index 00000000..794d1c57 --- /dev/null +++ b/00_Alternate_Languages/48_High_IQ/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..5d2ab966 --- /dev/null +++ b/00_Alternate_Languages/48_High_IQ/MiniScript/highiq.ms @@ -0,0 +1,163 @@ +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/49_Hockey/MiniScript/README.md b/00_Alternate_Languages/49_Hockey/MiniScript/README.md new file mode 100644 index 00000000..8c92997d --- /dev/null +++ b/00_Alternate_Languages/49_Hockey/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..450736f7 --- /dev/null +++ b/00_Alternate_Languages/49_Hockey/MiniScript/hockey.ms @@ -0,0 +1,396 @@ +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/50_Horserace/MiniScript/README.md b/00_Alternate_Languages/50_Horserace/MiniScript/README.md new file mode 100644 index 00000000..8f5703a2 --- /dev/null +++ b/00_Alternate_Languages/50_Horserace/MiniScript/README.md @@ -0,0 +1,25 @@ +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 new file mode 100644 index 00000000..a8750f5e --- /dev/null +++ b/00_Alternate_Languages/50_Horserace/MiniScript/horserace.ms @@ -0,0 +1,149 @@ +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/51_Hurkle/MiniScript/README.md b/00_Alternate_Languages/51_Hurkle/MiniScript/README.md new file mode 100644 index 00000000..2f774e45 --- /dev/null +++ b/00_Alternate_Languages/51_Hurkle/MiniScript/README.md @@ -0,0 +1,22 @@ +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 new file mode 100644 index 00000000..a1b22822 --- /dev/null +++ b/00_Alternate_Languages/51_Hurkle/MiniScript/hurkle.ms @@ -0,0 +1,56 @@ +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/52_Kinema/MiniScript/README.md b/00_Alternate_Languages/52_Kinema/MiniScript/README.md new file mode 100644 index 00000000..173e59ad --- /dev/null +++ b/00_Alternate_Languages/52_Kinema/MiniScript/README.md @@ -0,0 +1,21 @@ +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 kinema.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 "kinema" + 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 kinema.ms, and click the "Run Script" button. diff --git a/00_Alternate_Languages/52_Kinema/MiniScript/kinema.ms b/00_Alternate_Languages/52_Kinema/MiniScript/kinema.ms new file mode 100644 index 00000000..9fb27071 --- /dev/null +++ b/00_Alternate_Languages/52_Kinema/MiniScript/kinema.ms @@ -0,0 +1,40 @@ +// Kinema +// +// Ported from BASIC to MiniScript by Joe Strout + +print " "*33 + "KINEMA" +print " "*15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" +print; print; print + +checkAnswer = function(prompt, correctValue) + answer = input(prompt).val + right = abs((answer - correctValue)/answer) < 0.15 + if right then + print "Close enough!" + else + print "Not even close...." + end if + print "Correct answer is " + correctValue + return right +end function + +doOneRun = function + print; print + rightCount = 0 + V = 5 + floor(35*rnd) + print "A ball is thrown upwards at " + V + " meters per second." + print + rightCount += checkAnswer("How high will it go (in meters)? ", 0.05 * V^2) + rightCount += checkAnswer("How long until it returns (in seconds)? ", V/5) + t = 1 + floor(2*V*rnd)/10 + rightCount += checkAnswer("What will its velocity be after " + t + + " seconds? ", V-10*t) + print + print rightCount + " right out of 3." + if rightCount >= 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/53_King/MiniScript/README.md b/00_Alternate_Languages/53_King/MiniScript/README.md new file mode 100644 index 00000000..34818a09 --- /dev/null +++ b/00_Alternate_Languages/53_King/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..8d4f106c --- /dev/null +++ b/00_Alternate_Languages/53_King/MiniScript/king.ms @@ -0,0 +1,403 @@ +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/king_variable_update.bas b/00_Alternate_Languages/53_King/king_variable_update.bas index 7f88e101..86c3828c 100644 --- a/00_Alternate_Languages/53_King/king_variable_update.bas +++ b/00_Alternate_Languages/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, RALLODS SMALL COMMUNIST ISLAND 30 BY 70 MILES LONG. YOUR" + 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" @@ -219,7 +219,7 @@ REM I think tourism calculations are actually wrong in the original code! 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=X5 THEN 1900 +1520 IF YEARS_REQUIRED-1=YEAR THEN 1900 1545 GOTO 2000 1550 PRINT 1552 PRINT @@ -277,9 +277,9 @@ REM I think tourism calculations are actually wrong in the original code! 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 +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"; @@ -300,7 +300,7 @@ REM I think tourism calculations are actually wrong in the original code! 1997 PRINT " AND 10,000 SQ. MILES OF FOREST LAND." 1998 GOTO 1990 -2000 X5=X5+1 +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 new file mode 100644 index 00000000..dfc5cf38 --- /dev/null +++ b/00_Alternate_Languages/54_Letter/MiniScript/README.md @@ -0,0 +1,21 @@ +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 new file mode 100644 index 00000000..78a32b3b --- /dev/null +++ b/00_Alternate_Languages/54_Letter/MiniScript/letter.ms @@ -0,0 +1,44 @@ +// 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/55_Life/MiniScript/README.md b/00_Alternate_Languages/55_Life/MiniScript/README.md new file mode 100644 index 00000000..4cfd557b --- /dev/null +++ b/00_Alternate_Languages/55_Life/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..69f3bafc --- /dev/null +++ b/00_Alternate_Languages/55_Life/MiniScript/life.ms @@ -0,0 +1,132 @@ +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/56_Life_for_Two/MiniScript/README.md b/00_Alternate_Languages/56_Life_for_Two/MiniScript/README.md new file mode 100644 index 00000000..93b25b99 --- /dev/null +++ b/00_Alternate_Languages/56_Life_for_Two/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..49ac531e --- /dev/null +++ b/00_Alternate_Languages/56_Life_for_Two/MiniScript/lifefortwo.ms @@ -0,0 +1,129 @@ +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/57_Literature_Quiz/MiniScript/README.md b/00_Alternate_Languages/57_Literature_Quiz/MiniScript/README.md new file mode 100644 index 00000000..e3f12eb4 --- /dev/null +++ b/00_Alternate_Languages/57_Literature_Quiz/MiniScript/README.md @@ -0,0 +1,22 @@ +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 new file mode 100644 index 00000000..e465cc6b --- /dev/null +++ b/00_Alternate_Languages/57_Literature_Quiz/MiniScript/litquiz.ms @@ -0,0 +1,66 @@ +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/58_Love/MiniScript/README.md b/00_Alternate_Languages/58_Love/MiniScript/README.md new file mode 100644 index 00000000..1186963d --- /dev/null +++ b/00_Alternate_Languages/58_Love/MiniScript/README.md @@ -0,0 +1,22 @@ +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 new file mode 100644 index 00000000..64693f12 --- /dev/null +++ b/00_Alternate_Languages/58_Love/MiniScript/love.ms @@ -0,0 +1,41 @@ +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/59_Lunar_LEM_Rocket/MiniScript/README.md b/00_Alternate_Languages/59_Lunar_LEM_Rocket/MiniScript/README.md new file mode 100644 index 00000000..6ba18136 --- /dev/null +++ b/00_Alternate_Languages/59_Lunar_LEM_Rocket/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..92a263e2 --- /dev/null +++ b/00_Alternate_Languages/59_Lunar_LEM_Rocket/MiniScript/lem.ms @@ -0,0 +1,324 @@ +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 new file mode 100644 index 00000000..e8da8d72 --- /dev/null +++ b/00_Alternate_Languages/59_Lunar_LEM_Rocket/MiniScript/lunar.ms @@ -0,0 +1,114 @@ +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 new file mode 100644 index 00000000..3bb4957f --- /dev/null +++ b/00_Alternate_Languages/59_Lunar_LEM_Rocket/MiniScript/rocket.ms @@ -0,0 +1,101 @@ +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 + 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/60_Mastermind/MiniScript/README.md b/00_Alternate_Languages/60_Mastermind/MiniScript/README.md new file mode 100644 index 00000000..088a3301 --- /dev/null +++ b/00_Alternate_Languages/60_Mastermind/MiniScript/README.md @@ -0,0 +1,17 @@ +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 new file mode 100644 index 00000000..93ea3082 --- /dev/null +++ b/00_Alternate_Languages/60_Mastermind/MiniScript/mastermind.ms @@ -0,0 +1,260 @@ +// +// 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/61_Math_Dice/MiniScript/README.md b/00_Alternate_Languages/61_Math_Dice/MiniScript/README.md new file mode 100644 index 00000000..ac7b913c --- /dev/null +++ b/00_Alternate_Languages/61_Math_Dice/MiniScript/README.md @@ -0,0 +1,21 @@ +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 new file mode 100644 index 00000000..74ed6349 --- /dev/null +++ b/00_Alternate_Languages/61_Math_Dice/MiniScript/mathdice.ms @@ -0,0 +1,58 @@ +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/62_Mugwump/MiniScript/README.md b/00_Alternate_Languages/62_Mugwump/MiniScript/README.md new file mode 100644 index 00000000..ac7b913c --- /dev/null +++ b/00_Alternate_Languages/62_Mugwump/MiniScript/README.md @@ -0,0 +1,21 @@ +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 new file mode 100644 index 00000000..8ba5f7fb --- /dev/null +++ b/00_Alternate_Languages/62_Mugwump/MiniScript/mugwump.ms @@ -0,0 +1,65 @@ +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/63_Name/MiniScript/README.md b/00_Alternate_Languages/63_Name/MiniScript/README.md new file mode 100644 index 00000000..819ecf50 --- /dev/null +++ b/00_Alternate_Languages/63_Name/MiniScript/README.md @@ -0,0 +1,21 @@ +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 new file mode 100644 index 00000000..bb3d2da2 --- /dev/null +++ b/00_Alternate_Languages/63_Name/MiniScript/name.ms @@ -0,0 +1,25 @@ +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/64_Nicomachus/MiniScript/README.md b/00_Alternate_Languages/64_Nicomachus/MiniScript/README.md new file mode 100644 index 00000000..5ea2cf13 --- /dev/null +++ b/00_Alternate_Languages/64_Nicomachus/MiniScript/README.md @@ -0,0 +1,21 @@ +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 new file mode 100644 index 00000000..ebbc394b --- /dev/null +++ b/00_Alternate_Languages/64_Nicomachus/MiniScript/nicomachus.ms @@ -0,0 +1,45 @@ +// 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/65_Nim/MiniScript/README.md b/00_Alternate_Languages/65_Nim/MiniScript/README.md new file mode 100644 index 00000000..0265ff51 --- /dev/null +++ b/00_Alternate_Languages/65_Nim/MiniScript/README.md @@ -0,0 +1,18 @@ +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 new file mode 100644 index 00000000..f241c696 --- /dev/null +++ b/00_Alternate_Languages/65_Nim/MiniScript/nim.ms @@ -0,0 +1,194 @@ +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/66_Number/MiniScript/README.md b/00_Alternate_Languages/66_Number/MiniScript/README.md new file mode 100644 index 00000000..e3c8143a --- /dev/null +++ b/00_Alternate_Languages/66_Number/MiniScript/README.md @@ -0,0 +1,21 @@ +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 new file mode 100644 index 00000000..0f242d68 --- /dev/null +++ b/00_Alternate_Languages/66_Number/MiniScript/number.ms @@ -0,0 +1,44 @@ +// 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/67_One_Check/MiniScript/README.md b/00_Alternate_Languages/67_One_Check/MiniScript/README.md new file mode 100644 index 00000000..d79b401f --- /dev/null +++ b/00_Alternate_Languages/67_One_Check/MiniScript/README.md @@ -0,0 +1,18 @@ +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 new file mode 100644 index 00000000..fee41c8c --- /dev/null +++ b/00_Alternate_Languages/67_One_Check/MiniScript/onecheck.ms @@ -0,0 +1,101 @@ +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/68_Orbit/MiniScript/README.md b/00_Alternate_Languages/68_Orbit/MiniScript/README.md new file mode 100644 index 00000000..cc0c2966 --- /dev/null +++ b/00_Alternate_Languages/68_Orbit/MiniScript/README.md @@ -0,0 +1,18 @@ +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 new file mode 100644 index 00000000..5c624c42 --- /dev/null +++ b/00_Alternate_Languages/68_Orbit/MiniScript/orbit.ms @@ -0,0 +1,95 @@ +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/73_Reverse/MiniScript/README.md b/00_Alternate_Languages/73_Reverse/MiniScript/README.md new file mode 100644 index 00000000..18812f30 --- /dev/null +++ b/00_Alternate_Languages/73_Reverse/MiniScript/README.md @@ -0,0 +1,16 @@ +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 new file mode 100644 index 00000000..a83d6b10 --- /dev/null +++ b/00_Alternate_Languages/73_Reverse/MiniScript/reverse.ms @@ -0,0 +1,71 @@ +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 1 + turns = 0 + digits = range(1, num) + digits.shuffle + print;print "Here we go ... the list is:" + while 1 + 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 == "n" then break +end while +print "O.K. Hope you had fun!!" \ No newline at end of file diff --git a/00_Alternate_Languages/74_Rock_Scissors_Paper/nim/rockscissors.nim b/00_Alternate_Languages/74_Rock_Scissors_Paper/nim/rockscissors.nim new file mode 100644 index 00000000..3c0cda0c --- /dev/null +++ b/00_Alternate_Languages/74_Rock_Scissors_Paper/nim/rockscissors.nim @@ -0,0 +1,68 @@ +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/78_Sine_Wave/MiniScript/README.md b/00_Alternate_Languages/78_Sine_Wave/MiniScript/README.md new file mode 100644 index 00000000..a17e5cf1 --- /dev/null +++ b/00_Alternate_Languages/78_Sine_Wave/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..da3e99a7 --- /dev/null +++ b/00_Alternate_Languages/78_Sine_Wave/MiniScript/sinewave.ms @@ -0,0 +1,15 @@ +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/82_Stars/MiniScript/README.md b/00_Alternate_Languages/82_Stars/MiniScript/README.md new file mode 100644 index 00000000..bcbbd39a --- /dev/null +++ b/00_Alternate_Languages/82_Stars/MiniScript/README.md @@ -0,0 +1,16 @@ +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 \ No newline at end of file diff --git a/00_Alternate_Languages/82_Stars/MiniScript/stars.ms b/00_Alternate_Languages/82_Stars/MiniScript/stars.ms new file mode 100644 index 00000000..b4234622 --- /dev/null +++ b/00_Alternate_Languages/82_Stars/MiniScript/stars.ms @@ -0,0 +1,48 @@ +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 1 + 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/85_Synonym/MiniScript/README.md b/00_Alternate_Languages/85_Synonym/MiniScript/README.md new file mode 100644 index 00000000..f887013c --- /dev/null +++ b/00_Alternate_Languages/85_Synonym/MiniScript/README.md @@ -0,0 +1,17 @@ +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 new file mode 100644 index 00000000..684482d2 --- /dev/null +++ b/00_Alternate_Languages/85_Synonym/MiniScript/synonym.ms @@ -0,0 +1,47 @@ +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/86_Target/MiniScript/README.md b/00_Alternate_Languages/86_Target/MiniScript/README.md new file mode 100644 index 00000000..c0619476 --- /dev/null +++ b/00_Alternate_Languages/86_Target/MiniScript/README.md @@ -0,0 +1,17 @@ +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 new file mode 100644 index 00000000..125fe2ff --- /dev/null +++ b/00_Alternate_Languages/86_Target/MiniScript/target.ms @@ -0,0 +1,114 @@ +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/87_3-D_Plot/MiniScript/3dplot.ms b/00_Alternate_Languages/87_3-D_Plot/MiniScript/3dplot.ms new file mode 100644 index 00000000..0cf1e516 --- /dev/null +++ b/00_Alternate_Languages/87_3-D_Plot/MiniScript/3dplot.ms @@ -0,0 +1,26 @@ +// 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 new file mode 100644 index 00000000..2bcec68c --- /dev/null +++ b/00_Alternate_Languages/87_3-D_Plot/MiniScript/README.md @@ -0,0 +1,19 @@ +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/90_Tower/MiniScript/README.md b/00_Alternate_Languages/90_Tower/MiniScript/README.md new file mode 100644 index 00000000..d8c97a89 --- /dev/null +++ b/00_Alternate_Languages/90_Tower/MiniScript/README.md @@ -0,0 +1,16 @@ +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 \ No newline at end of file diff --git a/00_Alternate_Languages/90_Tower/MiniScript/tower.ms b/00_Alternate_Languages/90_Tower/MiniScript/tower.ms new file mode 100644 index 00000000..a1846545 --- /dev/null +++ b/00_Alternate_Languages/90_Tower/MiniScript/tower.ms @@ -0,0 +1,202 @@ +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/91_Train/MiniScript/README.md b/00_Alternate_Languages/91_Train/MiniScript/README.md new file mode 100644 index 00000000..a1970158 --- /dev/null +++ b/00_Alternate_Languages/91_Train/MiniScript/README.md @@ -0,0 +1,21 @@ +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 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 +``` +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 train.ms, and click the "Run Script" button. diff --git a/00_Alternate_Languages/91_Train/MiniScript/train.ms b/00_Alternate_Languages/91_Train/MiniScript/train.ms new file mode 100644 index 00000000..27ce5b98 --- /dev/null +++ b/00_Alternate_Languages/91_Train/MiniScript/train.ms @@ -0,0 +1,28 @@ +// 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/nim/train.nim b/00_Alternate_Languages/91_Train/nim/train.nim new file mode 100644 index 00000000..aa92c1a7 --- /dev/null +++ b/00_Alternate_Languages/91_Train/nim/train.nim @@ -0,0 +1,38 @@ +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/92_Trap/MiniScript/README.md b/00_Alternate_Languages/92_Trap/MiniScript/README.md new file mode 100644 index 00000000..521d3aff --- /dev/null +++ b/00_Alternate_Languages/92_Trap/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..687a7a1e --- /dev/null +++ b/00_Alternate_Languages/92_Trap/MiniScript/trap.ms @@ -0,0 +1,69 @@ +// 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/93_23_Matches/MiniScript/23matches.ms b/00_Alternate_Languages/93_23_Matches/MiniScript/23matches.ms new file mode 100644 index 00000000..645082ac --- /dev/null +++ b/00_Alternate_Languages/93_23_Matches/MiniScript/23matches.ms @@ -0,0 +1,70 @@ +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 new file mode 100644 index 00000000..9156a730 --- /dev/null +++ b/00_Alternate_Languages/93_23_Matches/MiniScript/README.md @@ -0,0 +1,16 @@ +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 \ 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 new file mode 100644 index 00000000..0d964946 --- /dev/null +++ b/00_Alternate_Languages/94_War/MiniScript/README.md @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000..acc43215 --- /dev/null +++ b/00_Alternate_Languages/94_War/MiniScript/war.ms @@ -0,0 +1,65 @@ +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/95_Weekday/MiniScript/README.md b/00_Alternate_Languages/95_Weekday/MiniScript/README.md new file mode 100644 index 00000000..218cb4cc --- /dev/null +++ b/00_Alternate_Languages/95_Weekday/MiniScript/README.md @@ -0,0 +1,17 @@ +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 new file mode 100644 index 00000000..65641ebc --- /dev/null +++ b/00_Alternate_Languages/95_Weekday/MiniScript/weekday.ms @@ -0,0 +1,182 @@ +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/96_Word/MiniScript/README.md b/00_Alternate_Languages/96_Word/MiniScript/README.md new file mode 100644 index 00000000..567a84ba --- /dev/null +++ b/00_Alternate_Languages/96_Word/MiniScript/README.md @@ -0,0 +1,17 @@ +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 new file mode 100644 index 00000000..190ad611 --- /dev/null +++ b/00_Alternate_Languages/96_Word/MiniScript/word.ms @@ -0,0 +1,63 @@ +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/01_Acey_Ducey/README.md b/01_Acey_Ducey/README.md index 26856f71..0fabfb08 100644 --- a/01_Acey_Ducey/README.md +++ b/01_Acey_Ducey/README.md @@ -15,10 +15,13 @@ 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 -(please note any difficulties or challenges in porting here) +- 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 diff --git a/01_Acey_Ducey/elixir/acey_ducey.exs b/01_Acey_Ducey/elixir/acey_ducey.exs new file mode 100644 index 00000000..31308df7 --- /dev/null +++ b/01_Acey_Ducey/elixir/acey_ducey.exs @@ -0,0 +1,97 @@ +######################################################## +# +# 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/python/acey_ducey.py b/01_Acey_Ducey/python/acey_ducey.py index 603e01af..75a1eac2 100755 --- a/01_Acey_Ducey/python/acey_ducey.py +++ b/01_Acey_Ducey/python/acey_ducey.py @@ -6,8 +6,8 @@ https://www.atariarchives.org/basicgames/showpage.php?page=2 import random + cards = { - 1: "1", 2: "2", 3: "3", 4: "4", @@ -16,10 +16,11 @@ cards = { 7: "7", 8: "8", 9: "9", - 10: "Jack", - 11: "Queen", - 12: "King", - 13: "Ace", + 10: "10", + 11: "Jack", + 12: "Queen", + 13: "King", + 14: "Ace", } @@ -28,10 +29,13 @@ def play_game() -> None: while cash > 0: print(f"You now have {cash} dollars\n") 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: + 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 card_a, card_b = card_b, card_a print(f" {cards[card_a]}") print(f" {cards[card_b]}\n") @@ -53,7 +57,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: @@ -82,4 +86,5 @@ If you do not want to bet, input a 0 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 35b26d84..cd5cad76 100644 --- a/01_Acey_Ducey/python/acey_ducey_oo.py +++ b/01_Acey_Ducey/python/acey_ducey_oo.py @@ -8,6 +8,7 @@ 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] @@ -34,8 +35,6 @@ class Deck: self.cards.append(Card(suit, rank)) def shuffle(self) -> None: - import random - random.shuffle(self.cards) def deal(self) -> Card: @@ -72,7 +71,7 @@ class Game: if 0 < bet <= self.money: print(f"Your deal:\t {player_card}") - if card_a.rank < player_card.rank < card_b.rank: + if card_a.rank <= player_card.rank <= card_b.rank: print("You Win!") self.money += bet else: @@ -87,9 +86,6 @@ class Game: else: print("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.") self.not_done = False @@ -129,4 +125,5 @@ def main() -> None: if __name__ == "__main__": + random.seed() main() diff --git a/01_Acey_Ducey/rust/Cargo.lock b/01_Acey_Ducey/rust/Cargo.lock new file mode 100644 index 00000000..4fe2abbe --- /dev/null +++ b/01_Acey_Ducey/rust/Cargo.lock @@ -0,0 +1,75 @@ +# 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/README.md b/02_Amazing/README.md index b53cbbf5..b8e4b9b4 100644 --- a/02_Amazing/README.md +++ b/02_Amazing/README.md @@ -13,6 +13,10 @@ 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/rust/Cargo.lock b/02_Amazing/rust/Cargo.lock new file mode 100644 index 00000000..4fe2abbe --- /dev/null +++ b/02_Amazing/rust/Cargo.lock @@ -0,0 +1,75 @@ +# 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/03_Animal/rust/Cargo.lock b/03_Animal/rust/Cargo.lock new file mode 100644 index 00000000..9c4ba014 --- /dev/null +++ b/03_Animal/rust/Cargo.lock @@ -0,0 +1,7 @@ +# 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/04_Awari/rust/Cargo.lock b/04_Awari/rust/Cargo.lock new file mode 100644 index 00000000..4fe2abbe --- /dev/null +++ b/04_Awari/rust/Cargo.lock @@ -0,0 +1,75 @@ +# 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.lock b/05_Bagels/rust/Cargo.lock new file mode 100644 index 00000000..4fe2abbe --- /dev/null +++ b/05_Bagels/rust/Cargo.lock @@ -0,0 +1,75 @@ +# 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/06_Banner/README.md b/06_Banner/README.md index 3acbf7fc..f01b876d 100644 --- a/06_Banner/README.md +++ b/06_Banner/README.md @@ -15,5 +15,9 @@ 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/08_Batnum/README.md b/08_Batnum/README.md index 84052986..bb74a4ec 100644 --- a/08_Batnum/README.md +++ b/08_Batnum/README.md @@ -19,6 +19,10 @@ 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/09_Battle/README.md b/09_Battle/README.md index 04286452..29d2622e 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 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 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 original author of both the program and these descriptive notes is Ray Westergard of Lawrence Hall of Science, Berkeley, California. @@ -28,4 +28,4 @@ http://www.vintage-basic.net/games.html #### Porting Notes -(please note any difficulties or challenges in porting here) +- 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/10_Blackjack/README.md b/10_Blackjack/README.md index dcbe53bb..66cfee65 100644 --- a/10_Blackjack/README.md +++ b/10_Blackjack/README.md @@ -15,6 +15,16 @@ 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) +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/rust/Cargo.lock b/10_Blackjack/rust/Cargo.lock new file mode 100644 index 00000000..4fe2abbe --- /dev/null +++ b/10_Blackjack/rust/Cargo.lock @@ -0,0 +1,75 @@ +# 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/11_Bombardment/README.md b/11_Bombardment/README.md index d0d05bf9..d4bd08d7 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 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. +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. This program was slightly modified from the original written by Martin Burdash of Parlin, New Jersey. @@ -15,6 +15,12 @@ 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/rust/Cargo.lock b/11_Bombardment/rust/Cargo.lock new file mode 100644 index 00000000..81365033 --- /dev/null +++ b/11_Bombardment/rust/Cargo.lock @@ -0,0 +1,82 @@ +# 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/12_Bombs_Away/README.md b/12_Bombs_Away/README.md index 8a2decaa..603516fb 100644 --- a/12_Bombs_Away/README.md +++ b/12_Bombs_Away/README.md @@ -13,6 +13,10 @@ 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/14_Bowling/README.md b/14_Bowling/README.md index d5492077..52a0ab44 100644 --- a/14_Bowling/README.md +++ b/14_Bowling/README.md @@ -17,6 +17,14 @@ 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 -(please note any difficulties or challenges in porting here) +- The funny control characters in the "STRIKE!" string literal are there to make the terminal beep. diff --git a/15_Boxing/README.md b/15_Boxing/README.md index 12ecab4f..f0e6692d 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 if three rounds wins. +There are approximately seven major punches per round, although this may be varied. The best out of three rounds wins. Jesse Lynch of St. Paul, Minnesota created this program. @@ -15,6 +15,14 @@ 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/17_Bullfight/README.md b/17_Bullfight/README.md index c801b16e..b81aab0b 100644 --- a/17_Bullfight/README.md +++ b/17_Bullfight/README.md @@ -26,6 +26,6 @@ http://www.vintage-basic.net/games.html #### Porting Notes -(please note any difficulties or challenges in porting here) +- 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. -- 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. \ No newline at end of file +- Lines 1800-1820 (part of the pre-fight subroutine) can never be reached. diff --git a/18_Bullseye/rust/Cargo.lock b/18_Bullseye/rust/Cargo.lock new file mode 100644 index 00000000..4fe2abbe --- /dev/null +++ b/18_Bullseye/rust/Cargo.lock @@ -0,0 +1,75 @@ +# 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.lock b/20_Buzzword/rust/Cargo.lock new file mode 100644 index 00000000..4fe2abbe --- /dev/null +++ b/20_Buzzword/rust/Cargo.lock @@ -0,0 +1,75 @@ +# 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 new file mode 100644 index 00000000..3b1d02f5 --- /dev/null +++ b/20_Buzzword/rust/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "rust" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = "0.8.5" diff --git a/20_Buzzword/rust/README.md b/20_Buzzword/rust/README.md new file mode 100644 index 00000000..fc6468b9 --- /dev/null +++ b/20_Buzzword/rust/README.md @@ -0,0 +1,3 @@ +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) + +Conversion to [Rust](https://www.rust-lang.org/) diff --git a/20_Buzzword/rust/src/main.rs b/20_Buzzword/rust/src/main.rs new file mode 100644 index 00000000..dae4b819 --- /dev/null +++ b/20_Buzzword/rust/src/main.rs @@ -0,0 +1,112 @@ +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/21_Calendar/README.md b/21_Calendar/README.md index 05c3ab96..5f5b04ea 100644 --- a/21_Calendar/README.md +++ b/21_Calendar/README.md @@ -24,4 +24,6 @@ http://www.vintage-basic.net/games.html #### Porting Notes -(please note any difficulties or challenges in porting here) +- 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/rust/Cargo.lock b/21_Calendar/rust/Cargo.lock new file mode 100644 index 00000000..b21cc6a2 --- /dev/null +++ b/21_Calendar/rust/Cargo.lock @@ -0,0 +1,7 @@ +# 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.lock b/22_Change/rust/Cargo.lock new file mode 100644 index 00000000..b21cc6a2 --- /dev/null +++ b/22_Change/rust/Cargo.lock @@ -0,0 +1,7 @@ +# 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/23_Checkers/README.md b/23_Checkers/README.md index 1d9143ca..f2263df5 100644 --- a/23_Checkers/README.md +++ b/23_Checkers/README.md @@ -24,5 +24,6 @@ should be more readable. - 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. + - 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.). - Curious writing to "I" variable without ever reading it. (See lines 1700 and 1806) diff --git a/23_Checkers/perl/README.md b/23_Checkers/perl/README.md index e69c8b81..4323cf4a 100644 --- a/23_Checkers/perl/README.md +++ b/23_Checkers/perl/README.md @@ -1,3 +1,9 @@ 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 new file mode 100755 index 00000000..46b8f2d4 --- /dev/null +++ b/23_Checkers/perl/checkers.pl @@ -0,0 +1,351 @@ +#!/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/24_Chemist/README.md b/24_Chemist/README.md index fc62425a..8871a0ac 100644 --- a/24_Chemist/README.md +++ b/24_Chemist/README.md @@ -13,11 +13,13 @@ 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) -There is a type in the original Basic, "...DECIDE **WHO** MUCH WATER..." should be "DECIDE **HOW** MUCH WATER" - #### External Links - C: https://github.com/ericfischer/basic-computer-games/blob/main/24%20Chemist/c/chemist.c diff --git a/24_Chemist/rust/Cargo.lock b/24_Chemist/rust/Cargo.lock new file mode 100644 index 00000000..4fe2abbe --- /dev/null +++ b/24_Chemist/rust/Cargo.lock @@ -0,0 +1,75 @@ +# 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/25_Chief/rust/Cargo.lock b/25_Chief/rust/Cargo.lock new file mode 100644 index 00000000..b21cc6a2 --- /dev/null +++ b/25_Chief/rust/Cargo.lock @@ -0,0 +1,7 @@ +# 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 new file mode 100644 index 00000000..1ec69633 --- /dev/null +++ b/25_Chief/rust/Cargo.toml @@ -0,0 +1,8 @@ +[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 new file mode 100644 index 00000000..8bdbf2e2 --- /dev/null +++ b/25_Chief/rust/README.md @@ -0,0 +1,3 @@ +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) + +Conversion to [Rust](https://www.rust-lang.org/) by [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 new file mode 100644 index 00000000..123f1a67 --- /dev/null +++ b/25_Chief/rust/src/main.rs @@ -0,0 +1,133 @@ +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/27_Civil_War/README.md b/27_Civil_War/README.md index 3a609ea8..7cbd62e2 100644 --- a/27_Civil_War/README.md +++ b/27_Civil_War/README.md @@ -17,6 +17,10 @@ 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/28_Combat/README.md b/28_Combat/README.md index 10918fc4..e4463ab2 100644 --- a/28_Combat/README.md +++ b/28_Combat/README.md @@ -15,6 +15,11 @@ 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/29_Craps/rust/Cargo.lock b/29_Craps/rust/Cargo.lock new file mode 100644 index 00000000..4fe2abbe --- /dev/null +++ b/29_Craps/rust/Cargo.lock @@ -0,0 +1,75 @@ +# 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/README.md b/30_Cube/README.md index c220c8d4..a257f110 100644 --- a/30_Cube/README.md +++ b/30_Cube/README.md @@ -17,6 +17,14 @@ http://www.vintage-basic.net/games.html (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 diff --git a/30_Cube/rust/Cargo.lock b/30_Cube/rust/Cargo.lock new file mode 100644 index 00000000..4fe2abbe --- /dev/null +++ b/30_Cube/rust/Cargo.lock @@ -0,0 +1,75 @@ +# 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/32_Diamond/rust/Cargo.lock b/32_Diamond/rust/Cargo.lock new file mode 100644 index 00000000..b21cc6a2 --- /dev/null +++ b/32_Diamond/rust/Cargo.lock @@ -0,0 +1,7 @@ +# 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/33_Dice/rust/Cargo.lock b/33_Dice/rust/Cargo.lock new file mode 100644 index 00000000..4fe2abbe --- /dev/null +++ b/33_Dice/rust/Cargo.lock @@ -0,0 +1,75 @@ +# 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/34_Digits/README.md b/34_Digits/README.md index 569122c8..6e82efda 100644 --- a/34_Digits/README.md +++ b/34_Digits/README.md @@ -18,4 +18,5 @@ http://www.vintage-basic.net/games.html #### Porting Notes -(please note any difficulties or challenges in porting here) +- 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/35_Even_Wins/rust/Cargo.lock b/35_Even_Wins/rust/Cargo.lock new file mode 100644 index 00000000..b21cc6a2 --- /dev/null +++ b/35_Even_Wins/rust/Cargo.lock @@ -0,0 +1,7 @@ +# 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/36_Flip_Flop/rust/Cargo.lock b/36_Flip_Flop/rust/Cargo.lock new file mode 100644 index 00000000..81365033 --- /dev/null +++ b/36_Flip_Flop/rust/Cargo.lock @@ -0,0 +1,82 @@ +# 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/38_Fur_Trader/README.md b/38_Fur_Trader/README.md index 8406487e..6b08911a 100644 --- a/38_Fur_Trader/README.md +++ b/38_Fur_Trader/README.md @@ -15,6 +15,10 @@ 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/39_Golf/README.md b/39_Golf/README.md index 262e7c38..f8769f99 100644 --- a/39_Golf/README.md +++ b/39_Golf/README.md @@ -14,6 +14,10 @@ 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/40_Gomoko/gomoko.bas b/40_Gomoko/gomoko.bas index 662cca13..d57c10a1 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+F: Y=J+F: GOSUB 910 +540 X=I+E: 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/41_Guess/rust/Cargo.lock b/41_Guess/rust/Cargo.lock new file mode 100644 index 00000000..5329dedd --- /dev/null +++ b/41_Guess/rust/Cargo.lock @@ -0,0 +1,75 @@ +# 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/43_Hammurabi/README.md b/43_Hammurabi/README.md index 2e3d6397..937044c8 100644 --- a/43_Hammurabi/README.md +++ b/43_Hammurabi/README.md @@ -23,8 +23,7 @@ http://www.vintage-basic.net/games.html #### Porting Notes -(please note any difficulties or challenges in porting here) - +- 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 diff --git a/43_Hammurabi/rust/Cargo.lock b/43_Hammurabi/rust/Cargo.lock new file mode 100644 index 00000000..4fe2abbe --- /dev/null +++ b/43_Hammurabi/rust/Cargo.lock @@ -0,0 +1,75 @@ +# 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 new file mode 100644 index 00000000..3b1d02f5 --- /dev/null +++ b/43_Hammurabi/rust/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "rust" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = "0.8.5" diff --git a/43_Hammurabi/rust/README.md b/43_Hammurabi/rust/README.md new file mode 100644 index 00000000..fc6468b9 --- /dev/null +++ b/43_Hammurabi/rust/README.md @@ -0,0 +1,3 @@ +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) + +Conversion to [Rust](https://www.rust-lang.org/) diff --git a/43_Hammurabi/rust/src/main.rs b/43_Hammurabi/rust/src/main.rs new file mode 100644 index 00000000..529a6145 --- /dev/null +++ b/43_Hammurabi/rust/src/main.rs @@ -0,0 +1,262 @@ +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/45_Hello/README.md b/45_Hello/README.md index 87c47f65..243efa70 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. diff --git a/46_Hexapawn/README.md b/46_Hexapawn/README.md index bbcf0ad6..6376c036 100644 --- a/46_Hexapawn/README.md +++ b/46_Hexapawn/README.md @@ -15,6 +15,10 @@ 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/47_Hi-Lo/rust/Cargo.lock b/47_Hi-Lo/rust/Cargo.lock new file mode 100644 index 00000000..937c07c6 --- /dev/null +++ b/47_Hi-Lo/rust/Cargo.lock @@ -0,0 +1,75 @@ +# 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/49_Hockey/README.md b/49_Hockey/README.md index 3decfe1b..98db22d5 100644 --- a/49_Hockey/README.md +++ b/49_Hockey/README.md @@ -15,6 +15,11 @@ 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/50_Horserace/rust/Cargo.lock b/50_Horserace/rust/Cargo.lock new file mode 100644 index 00000000..4fe2abbe --- /dev/null +++ b/50_Horserace/rust/Cargo.lock @@ -0,0 +1,75 @@ +# 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.lock b/51_Hurkle/rust/Cargo.lock new file mode 100644 index 00000000..4fe2abbe --- /dev/null +++ b/51_Hurkle/rust/Cargo.lock @@ -0,0 +1,75 @@ +# 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/53_King/README.md b/53_King/README.md index 14a66fe9..83fb61c3 100644 --- a/53_King/README.md +++ b/53_King/README.md @@ -78,3 +78,18 @@ On basic line 1310 we see this: 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). + +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. diff --git a/53_King/king_variable_update.bas b/53_King/king_variable_update.bas index 7f88e101..0ae19de4 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, RALLODS SMALL COMMUNIST ISLAND 30 BY 70 MILES LONG. YOUR" + 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" @@ -66,7 +66,8 @@ 380 PLANTING_AREA=0 390 MONEY_SPENT_ON_POLLUTION_CONTROL=0 395 RALLODS=0 -399 GOTO 1000 +399 GOTO 600 + 400 RALLODS=INT(RALLODS-WELFARE) 410 PRINT "HOW MANY SQUARE MILES DO YOU WISH TO PLANT"; @@ -88,7 +89,7 @@ 490 MONEY_SPENT_ON_POLLUTION_CONTROL=0 495 RALLODS=0 -499 GOTO 1000 +499 GOTO 600 500 RALLODS=RALLODS-MONEY_SPENT_ON_PLANTING diff --git a/53_King/python/king.py b/53_King/python/king.py index 9c8d075c..4bca76fa 100644 --- a/53_King/python/king.py +++ b/53_King/python/king.py @@ -61,7 +61,7 @@ class GameState: return self.countrymen - self.population_change def sell_land(self, amount: int) -> None: - assert amount < self.farmland + assert amount <= self.farmland self.land -= amount self.rallods += self.land_buy_price * amount @@ -126,20 +126,22 @@ class GameState: def handle_tourist_trade(self) -> None: V1 = int(self.settled_people * 22 + random() * 500) V2 = int((INITIAL_LAND - self.land) * 15) - tourist_trade_earnings = int(V1 - V2) + 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 ") + print(" DECREASE BECAUSE ", end="") reason = randint(0, 10) if reason <= 2: print("FISH POPULATION HAS DWINDLED DUE TO WATER POLLUTION.") - if reason <= 4: + elif reason <= 4: print("AIR POLLUTION IS KILLING GAME BIRD POPULATION.") - if reason <= 6: + elif reason <= 6: print("MINERAL BATHS ARE BEING RUINED BY WATER POLLUTION.") - if reason <= 8: + elif reason <= 8: print("UNPLEASANT SMOG IS DISCOURAGING SUN BATHERS.") - if reason <= 10: + else: print("HOTELS ARE LOOKING SHABBY DUE TO SMOG GRIT.") # NOTE: The following two lines had a bug in the original game: diff --git a/53_King/rust/Cargo.lock b/53_King/rust/Cargo.lock new file mode 100644 index 00000000..db44c2e7 --- /dev/null +++ b/53_King/rust/Cargo.lock @@ -0,0 +1,16 @@ +# 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 new file mode 100644 index 00000000..c4f9c913 --- /dev/null +++ b/53_King/rust/Cargo.toml @@ -0,0 +1,9 @@ +[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 new file mode 100644 index 00000000..529da33b --- /dev/null +++ b/53_King/rust/README.md @@ -0,0 +1,28 @@ +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 new file mode 100644 index 00000000..90b2aac6 --- /dev/null +++ b/53_King/rust/src/main.rs @@ -0,0 +1,577 @@ +#![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/54_Letter/rust/Cargo.lock b/54_Letter/rust/Cargo.lock new file mode 100644 index 00000000..6a34e6ec --- /dev/null +++ b/54_Letter/rust/Cargo.lock @@ -0,0 +1,75 @@ +# 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/55_Life/README.md b/55_Life/README.md index 1834c1e6..195bd795 100644 --- a/55_Life/README.md +++ b/55_Life/README.md @@ -37,4 +37,11 @@ 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/rust/Cargo.lock b/55_Life/rust/Cargo.lock new file mode 100644 index 00000000..b21cc6a2 --- /dev/null +++ b/55_Life/rust/Cargo.lock @@ -0,0 +1,7 @@ +# 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/56_Life_for_Two/README.md b/56_Life_for_Two/README.md index e68c8d64..5ce081d3 100644 --- a/56_Life_for_Two/README.md +++ b/56_Life_for_Two/README.md @@ -26,7 +26,7 @@ A new cell will be generated at (3,3) which will be a `#` since there are two `# | 4 | | | | | | | 5 | | | | | | ``` -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.) +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.) The board is then adjusted to the next generation and printed out. @@ -45,6 +45,7 @@ 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/rust/Cargo.lock b/57_Literature_Quiz/rust/Cargo.lock new file mode 100644 index 00000000..b21cc6a2 --- /dev/null +++ b/57_Literature_Quiz/rust/Cargo.lock @@ -0,0 +1,7 @@ +# 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 new file mode 100644 index 00000000..1ec69633 --- /dev/null +++ b/57_Literature_Quiz/rust/Cargo.toml @@ -0,0 +1,8 @@ +[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 new file mode 100644 index 00000000..fc6468b9 --- /dev/null +++ b/57_Literature_Quiz/rust/README.md @@ -0,0 +1,3 @@ +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) + +Conversion to [Rust](https://www.rust-lang.org/) diff --git a/57_Literature_Quiz/rust/src/main.rs b/57_Literature_Quiz/rust/src/main.rs new file mode 100644 index 00000000..a9e3923e --- /dev/null +++ b/57_Literature_Quiz/rust/src/main.rs @@ -0,0 +1,127 @@ +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/58_Love/rust/Cargo.lock b/58_Love/rust/Cargo.lock new file mode 100644 index 00000000..b21cc6a2 --- /dev/null +++ b/58_Love/rust/Cargo.lock @@ -0,0 +1,7 @@ +# 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 new file mode 100644 index 00000000..1ec69633 --- /dev/null +++ b/58_Love/rust/Cargo.toml @@ -0,0 +1,8 @@ +[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 new file mode 100644 index 00000000..4cd90430 --- /dev/null +++ b/58_Love/rust/README.md @@ -0,0 +1,3 @@ +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) + +Conversion to [Rust](https://www.rust-lang.org/) by Jadi. diff --git a/58_Love/rust/src/main.rs b/58_Love/rust/src/main.rs new file mode 100644 index 00000000..5e8e18d7 --- /dev/null +++ b/58_Love/rust/src/main.rs @@ -0,0 +1,92 @@ +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/59_Lunar_LEM_Rocket/README.md b/59_Lunar_LEM_Rocket/README.md index 91fe1cd6..c0ec8df0 100644 --- a/59_Lunar_LEM_Rocket/README.md +++ b/59_Lunar_LEM_Rocket/README.md @@ -23,6 +23,15 @@ 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) diff --git a/59_Lunar_LEM_Rocket/javascript/lunar.js b/59_Lunar_LEM_Rocket/javascript/lunar.js index 69306aa2..4f693d00 100644 --- a/59_Lunar_LEM_Rocket/javascript/lunar.js +++ b/59_Lunar_LEM_Rocket/javascript/lunar.js @@ -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,500 LBS.\n"); + print("CAPSULE WEIGHT 32,500 LBS; FUEL WEIGHT 16,000 LBS.\n"); print("\n"); print("\n"); print("\n"); @@ -113,7 +113,7 @@ async function main() print("\n"); a = 120; v = 1; - m = 33000; + m = 32500; n = 16500; g = 1e-3; z = 1.8; diff --git a/59_Lunar_LEM_Rocket/lunar.bas b/59_Lunar_LEM_Rocket/lunar.bas index b1203718..256eedff 100644 --- a/59_Lunar_LEM_Rocket/lunar.bas +++ b/59_Lunar_LEM_Rocket/lunar.bas @@ -8,11 +8,11 @@ 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." +100 PRINT "CAPSULE WEIGHT 32,500 LBS; FUEL WEIGHT 16,000 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 +140 A=120:V=1:M=32500: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 diff --git a/59_Lunar_LEM_Rocket/python/lunar.py b/59_Lunar_LEM_Rocket/python/lunar.py index 82f21fc0..fa7da3de 100644 --- a/59_Lunar_LEM_Rocket/python/lunar.py +++ b/59_Lunar_LEM_Rocket/python/lunar.py @@ -85,7 +85,7 @@ def print_intro() -> None: 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,500 LBS.\n\n\n") + print("CAPSULE WEIGHT 32,500 LBS; FUEL WEIGHT 16,000 LBS.\n\n\n") print("GOOD LUCK\n") @@ -127,7 +127,7 @@ class SimulationClock: class Capsule: altitude: float = 120 # in miles above the surface velocity: float = 1 # downward - m: float = 33000 # mass_with_fuel + m: float = 32500 # mass_with_fuel n: float = 16500 # mass_without_fuel g: float = 1e-3 z: float = 1.8 diff --git a/60_Mastermind/README.md b/60_Mastermind/README.md index 7820eed7..05383f10 100644 --- a/60_Mastermind/README.md +++ b/60_Mastermind/README.md @@ -86,7 +86,7 @@ solutions reporting their black and white pegs against `RBW`. | 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** matches 0 black and 2 white. +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 | |----------|-------|-------|-----|----------|-------|-------|-----|----------|-------|-------| @@ -130,7 +130,7 @@ report 1 black and 0 whites. | ~~~WWB~~ | 0 | 1 | | ~~~WRR~~ | 2 | 0 | -Only one solution matches and its our secret code! The computer will guess this +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. @@ -150,4 +150,8 @@ 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. \ No newline at end of file +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/61_Math_Dice/rust/Cargo.lock b/61_Math_Dice/rust/Cargo.lock new file mode 100644 index 00000000..4fe2abbe --- /dev/null +++ b/61_Math_Dice/rust/Cargo.lock @@ -0,0 +1,75 @@ +# 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.lock b/62_Mugwump/rust/Cargo.lock new file mode 100644 index 00000000..4fe2abbe --- /dev/null +++ b/62_Mugwump/rust/Cargo.lock @@ -0,0 +1,75 @@ +# 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/64_Nicomachus/rust/Cargo.lock b/64_Nicomachus/rust/Cargo.lock new file mode 100644 index 00000000..b21cc6a2 --- /dev/null +++ b/64_Nicomachus/rust/Cargo.lock @@ -0,0 +1,7 @@ +# 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/65_Nim/README.md b/65_Nim/README.md index 11243f0f..fae88639 100644 --- a/65_Nim/README.md +++ b/65_Nim/README.md @@ -28,3 +28,7 @@ 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/rust/Cargo.lock b/65_Nim/rust/Cargo.lock new file mode 100644 index 00000000..fc74a49e --- /dev/null +++ b/65_Nim/rust/Cargo.lock @@ -0,0 +1,23 @@ +# 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/66_Number/README.md b/66_Number/README.md index 43d97db3..2df37b6b 100644 --- a/66_Number/README.md +++ b/66_Number/README.md @@ -15,4 +15,4 @@ http://www.vintage-basic.net/games.html #### Porting Notes -(please note any difficulties or challenges in porting here) +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/rust/Cargo.lock b/66_Number/rust/Cargo.lock new file mode 100644 index 00000000..4fe2abbe --- /dev/null +++ b/66_Number/rust/Cargo.lock @@ -0,0 +1,75 @@ +# 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/README.md b/68_Orbit/README.md index 9e4e9afd..be765b55 100644 --- a/68_Orbit/README.md +++ b/68_Orbit/README.md @@ -20,7 +20,7 @@ of orbit < ^ ship ``` -The distance of the bomb from the ship is computed using the law of consines. The law of cosines states: +The distance of the bomb from the ship is computed using the law of cosines. The law of cosines states: ``` D = SQUAREROOT( R**2 + D1**2 - 2*R*D1*COS(A-A1) ) diff --git a/68_Orbit/rust/Cargo.lock b/68_Orbit/rust/Cargo.lock new file mode 100644 index 00000000..4fe2abbe --- /dev/null +++ b/68_Orbit/rust/Cargo.lock @@ -0,0 +1,75 @@ +# 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/69_Pizza/README.md b/69_Pizza/README.md index 56548b64..7f9e3fcf 100644 --- a/69_Pizza/README.md +++ b/69_Pizza/README.md @@ -15,6 +15,10 @@ 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/72_Queen/rust/Cargo.lock b/72_Queen/rust/Cargo.lock new file mode 100644 index 00000000..4fe2abbe --- /dev/null +++ b/72_Queen/rust/Cargo.lock @@ -0,0 +1,75 @@ +# 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/74_Rock_Scissors_Paper/rust/Cargo.lock b/74_Rock_Scissors_Paper/rust/Cargo.lock new file mode 100644 index 00000000..81a95200 --- /dev/null +++ b/74_Rock_Scissors_Paper/rust/Cargo.lock @@ -0,0 +1,91 @@ +# 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/75_Roulette/rust/Cargo.lock b/75_Roulette/rust/Cargo.lock new file mode 100644 index 00000000..81365033 --- /dev/null +++ b/75_Roulette/rust/Cargo.lock @@ -0,0 +1,82 @@ +# 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/76_Russian_Roulette/rust/Cargo.lock b/76_Russian_Roulette/rust/Cargo.lock new file mode 100644 index 00000000..4fe2abbe --- /dev/null +++ b/76_Russian_Roulette/rust/Cargo.lock @@ -0,0 +1,75 @@ +# 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/78_Sine_Wave/README.md b/78_Sine_Wave/README.md index 32789d04..c5c340f3 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 on 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 of different versions. At least those CRTs don’t look so lifeless anymore. --- diff --git a/78_Sine_Wave/rust/Cargo.lock b/78_Sine_Wave/rust/Cargo.lock new file mode 100644 index 00000000..b21cc6a2 --- /dev/null +++ b/78_Sine_Wave/rust/Cargo.lock @@ -0,0 +1,7 @@ +# 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/81_Splat/rust/Cargo.lock b/81_Splat/rust/Cargo.lock new file mode 100644 index 00000000..4fe2abbe --- /dev/null +++ b/81_Splat/rust/Cargo.lock @@ -0,0 +1,75 @@ +# 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/82_Stars/rust/Cargo.lock b/82_Stars/rust/Cargo.lock new file mode 100644 index 00000000..b13b873b --- /dev/null +++ b/82_Stars/rust/Cargo.lock @@ -0,0 +1,75 @@ +# 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/84_Super_Star_Trek/python/superstartrek.py b/84_Super_Star_Trek/python/superstartrek.py index 2a86efba..805c9d93 100644 --- a/84_Super_Star_Trek/python/superstartrek.py +++ b/84_Super_Star_Trek/python/superstartrek.py @@ -335,7 +335,6 @@ class Game: " THE USS ENTERPRISE --- NCC-1701\n" "\n\n\n\n" ) - self.world = World() world = self.world print( "YOUR ORDERS ARE AS FOLLOWS:\n" diff --git a/84_Super_Star_Trek/rust/Cargo.lock b/84_Super_Star_Trek/rust/Cargo.lock new file mode 100644 index 00000000..71bbf0c8 --- /dev/null +++ b/84_Super_Star_Trek/rust/Cargo.lock @@ -0,0 +1,169 @@ +# 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/85_Synonym/rust/Cargo.lock b/85_Synonym/rust/Cargo.lock new file mode 100644 index 00000000..4fe2abbe --- /dev/null +++ b/85_Synonym/rust/Cargo.lock @@ -0,0 +1,75 @@ +# 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 new file mode 100644 index 00000000..3b1d02f5 --- /dev/null +++ b/85_Synonym/rust/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "rust" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = "0.8.5" diff --git a/85_Synonym/rust/README.md b/85_Synonym/rust/README.md new file mode 100644 index 00000000..4c54b94c --- /dev/null +++ b/85_Synonym/rust/README.md @@ -0,0 +1,3 @@ +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) + +Conversion to [Rust](https://www.rust-lang.org/) by [Jadi](https://github.com/jadijadi) diff --git a/85_Synonym/rust/src/main.rs b/85_Synonym/rust/src/main.rs new file mode 100644 index 00000000..184f51bd --- /dev/null +++ b/85_Synonym/rust/src/main.rs @@ -0,0 +1,102 @@ +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/89_Tic-Tac-Toe/rust/Cargo.lock b/89_Tic-Tac-Toe/rust/Cargo.lock new file mode 100644 index 00000000..b21cc6a2 --- /dev/null +++ b/89_Tic-Tac-Toe/rust/Cargo.lock @@ -0,0 +1,7 @@ +# 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.lock b/90_Tower/rust/Cargo.lock new file mode 100644 index 00000000..b21cc6a2 --- /dev/null +++ b/90_Tower/rust/Cargo.lock @@ -0,0 +1,7 @@ +# 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/91_Train/rust/Cargo.lock b/91_Train/rust/Cargo.lock new file mode 100644 index 00000000..4fe2abbe --- /dev/null +++ b/91_Train/rust/Cargo.lock @@ -0,0 +1,75 @@ +# 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.lock b/92_Trap/rust/Cargo.lock new file mode 100644 index 00000000..4fe2abbe --- /dev/null +++ b/92_Trap/rust/Cargo.lock @@ -0,0 +1,75 @@ +# 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/93_23_Matches/README.md b/93_23_Matches/README.md index 8ef8d6f8..e4ece5fd 100644 --- a/93_23_Matches/README.md +++ b/93_23_Matches/README.md @@ -19,4 +19,4 @@ http://www.vintage-basic.net/games.html #### Porting Notes -(please note any difficulties or challenges in porting here) +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/rust/Cargo.lock b/93_23_Matches/rust/Cargo.lock new file mode 100644 index 00000000..96e2f79e --- /dev/null +++ b/93_23_Matches/rust/Cargo.lock @@ -0,0 +1,16 @@ +# 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 new file mode 100644 index 00000000..a4227bbd --- /dev/null +++ b/93_23_Matches/rust/Cargo.toml @@ -0,0 +1,9 @@ +[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 new file mode 100644 index 00000000..6249450a --- /dev/null +++ b/93_23_Matches/rust/README.md @@ -0,0 +1,3 @@ +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) + +Conversion to [rust](https://www.rust-lang.org/) diff --git a/93_23_Matches/rust/src/main.rs b/93_23_Matches/rust/src/main.rs new file mode 100644 index 00000000..a14c39f5 --- /dev/null +++ b/93_23_Matches/rust/src/main.rs @@ -0,0 +1,108 @@ +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/94_War/rust/Cargo.lock b/94_War/rust/Cargo.lock new file mode 100644 index 00000000..4fe2abbe --- /dev/null +++ b/94_War/rust/Cargo.lock @@ -0,0 +1,75 @@ +# 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/95_Weekday/rust/Cargo.lock b/95_Weekday/rust/Cargo.lock new file mode 100644 index 00000000..b21cc6a2 --- /dev/null +++ b/95_Weekday/rust/Cargo.lock @@ -0,0 +1,7 @@ +# 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/96_Word/rust/Cargo.lock b/96_Word/rust/Cargo.lock new file mode 100644 index 00000000..4fe2abbe --- /dev/null +++ b/96_Word/rust/Cargo.lock @@ -0,0 +1,75 @@ +# 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/README.md b/README.md index c56d1886..0ddd2748 100644 --- a/README.md +++ b/README.md @@ -71,3 +71,108 @@ Please note that on the back of the Basic Computer Games book it says **Microsof 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 | +| 07_Basketball | x | x | x | | | x | x | x | | x | +| 08_Batnum | x | x | x | | | x | x | x | | x | +| 09_Battle | 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 | +| 13_Bounce | x | x | x | | | x | x | x | | x | +| 14_Bowling | 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 | +| 18_Bullseye | x | x | x | | | x | x | | x | x | +| 19_Bunny | 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 | +| 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 | +| 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 | +| 44_Hangman | x | x | x | | | x | x | x | | x | +| 45_Hello | 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 | +| 51_Hurkle | x | x | x | | | x | x | x | x | x | +| 52_Kinema | 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 | +| 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 | +| 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 | +| 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 | +| 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 | +| 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 | +| 86_Target | x | x | x | | | x | x | | | x | +| 87_3-D_Plot | 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 | + +