From 95e9d8b2c4c41c23ff842468d6ce055a1ab9b8a9 Mon Sep 17 00:00:00 2001 From: JoeStrout Date: Mon, 18 Sep 2023 07:58:50 -0700 Subject: [PATCH 1/8] A couple of minor tweaks to already-ported-to-MiniScript projects. --- .../59_Lunar_LEM_Rocket/MiniScript/rocket.ms | 1 + 00_Alternate_Languages/85_Synonym/MiniScript/synonym.ms | 2 +- 70_Poetry/README.md | 4 +++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/00_Alternate_Languages/59_Lunar_LEM_Rocket/MiniScript/rocket.ms b/00_Alternate_Languages/59_Lunar_LEM_Rocket/MiniScript/rocket.ms index 3bb4957fc..4131290b5 100644 --- a/00_Alternate_Languages/59_Lunar_LEM_Rocket/MiniScript/rocket.ms +++ b/00_Alternate_Languages/59_Lunar_LEM_Rocket/MiniScript/rocket.ms @@ -41,6 +41,7 @@ end function // Bonus little feature when running in Mini Micro: display a header bar // always at the top of the screen. drawHeaders = function + if version.hostName != "Mini Micro" then return display(2).mode = displayMode.text; td = display(2) td.color = text.color; td.backColor = color.black td.row = 25; td.column = 0 diff --git a/00_Alternate_Languages/85_Synonym/MiniScript/synonym.ms b/00_Alternate_Languages/85_Synonym/MiniScript/synonym.ms index 684482d25..c64c4f52e 100644 --- a/00_Alternate_Languages/85_Synonym/MiniScript/synonym.ms +++ b/00_Alternate_Languages/85_Synonym/MiniScript/synonym.ms @@ -14,7 +14,7 @@ words.shuffle responses = ["Right","Correct","Fine","Good!","Check"] print " " * 33 + "SYNONYM" -print " " * 15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" +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." diff --git a/70_Poetry/README.md b/70_Poetry/README.md index 7684ebecc..be21f8bee 100644 --- a/70_Poetry/README.md +++ b/70_Poetry/README.md @@ -30,4 +30,6 @@ http://www.vintage-basic.net/games.html #### Porting Notes -(please note any difficulties or challenges in porting here) +- The program begins by switching on `I`, which has not been initialized. We should probably initialize this to 0, though this means the output always begins with the phrase "midnight dreary". + +- Though the program contains an END statement (line 999), it is unreachable. The program continues to generate output until it is forcibly interrupted. From 70743baaef9c679819397ea9d7035f71667deb6e Mon Sep 17 00:00:00 2001 From: JoeStrout Date: Mon, 18 Sep 2023 09:48:48 -0700 Subject: [PATCH 2/8] Added MiniScript implementations of 69_Pizza and 70_Poetry. --- .../69_Pizza/MiniScript/README.md | 18 ++++ .../69_Pizza/MiniScript/pizza.ms | 98 +++++++++++++++++++ .../70_Poetry/MiniScript/README.md | 18 ++++ .../70_Poetry/MiniScript/poetry.ms | 51 ++++++++++ 4 files changed, 185 insertions(+) create mode 100644 00_Alternate_Languages/69_Pizza/MiniScript/README.md create mode 100644 00_Alternate_Languages/69_Pizza/MiniScript/pizza.ms create mode 100644 00_Alternate_Languages/70_Poetry/MiniScript/README.md create mode 100644 00_Alternate_Languages/70_Poetry/MiniScript/poetry.ms diff --git a/00_Alternate_Languages/69_Pizza/MiniScript/README.md b/00_Alternate_Languages/69_Pizza/MiniScript/README.md new file mode 100644 index 000000000..993c4056c --- /dev/null +++ b/00_Alternate_Languages/69_Pizza/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 pizza.ms +``` + +2. Mini Micro: +Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: +``` + load "pizza" + run +``` \ No newline at end of file diff --git a/00_Alternate_Languages/69_Pizza/MiniScript/pizza.ms b/00_Alternate_Languages/69_Pizza/MiniScript/pizza.ms new file mode 100644 index 000000000..5d52fbb77 --- /dev/null +++ b/00_Alternate_Languages/69_Pizza/MiniScript/pizza.ms @@ -0,0 +1,98 @@ +print " "*33 + "Pizza" +print " "*15 + "Creative Computing Morristown, New Jersey" +print; print; print +print "Pizza Delivery Game"; print +name = input("What is your first name? "); print +print "Hi, " + name + ". In this game you are to take orders" +print "for pizzas. Then you are to tell a delivery boy" +print "where to deliver the ordered pizzas."; print; print + +// Convert a house name like "G" into coordinates like [3,2]. +nameToCoords = function(name) + idx = name.code - "A".code + row = floor(idx / 4) + col = idx % 4 + return [col+1, row+1] +end function + +// Convert house coordinates like [3,2] into a house name like "G". +coordsToName = function(coords) + idx = (coords[1]-1)*4 + (coords[0]-1) + return char("A".code + idx) +end function + +askYesNo = function(prompt) + while true + yn = input(prompt + "? ").lower + " " + if yn[0] == "y" then return "yes" + if yn[0] == "n" then return "no" + print "'Yes' or 'no' please, now then," + end while +end function + +input "(Press Return.)"; print + +print "Map of the city of Hyattsville"; print +print " -----1-----2-----3-----4-----" +for row in range(4, 1) + print "-"; print "-"; print "-" + s = row + " " + for col in range(1, 4) + s += coordsToName([col, row]) + " " + end for + s += row + print s +end for +print "-"; print "-"; print "-" +print " -----1-----2-----3-----4-----" + +input +print "The output is a map of the homes where" +print "you are to send pizzas."; print +print "Your job is to give a truck driver" +print "the location or coordinates of the" +print "home ordering the pizza."; print +if askYesNo("Do you need more directions") == "yes" then + print; print "Somebody will ask for a pizza to be" + print "delivered. Then a delivery boy will" + print "ask you for the location."; + print " Example:" + print "This is J. Please send a pizza." + print "Driver to " + name + ". Where does j live?" + print "Your answer would be 2,3"; print + if askYesNo("Understand") == "no" then + print "This job is definitely too difficult for you. Thanks anyway" + exit + end if + print "Good. you are now ready to start taking orders."; print + print "Good luck!!"; print +end if + +while true + for turn in range(1,5) + coords = [floor(rnd*4+1), floor(rnd*4+1)] + buyer = coordsToName(coords) + print "Hello " + name + "'s Pizza. This is " + buyer + + ". Please send a pizza." + while true + while true + inp = input(" Driver to " + name + ": Where does " + buyer + " live? ") + inp = inp.replace(",", " ").replace(" ", " ") + inp = inp.split + [0,0] + guess = [inp[0].val, inp[1].val] + if 1 <= guess[0] <= 4 and 1 <= guess[1] <= 4 then break + end while + if guess == coords then + print "Hello " + name + ". This is " + buyer + ", thanks for the pizza." + break + else + print "This is " + coordsToName(guess) + ". I did not order a pizza." + print "I live at " + guess.join(",") + end if + end while + print + end for + if askYesNo("Do you want to deliver more pizzas") == "no" then break +end while + +print; print "O.K. " + name + ", see you later!"; print diff --git a/00_Alternate_Languages/70_Poetry/MiniScript/README.md b/00_Alternate_Languages/70_Poetry/MiniScript/README.md new file mode 100644 index 000000000..52effbcc2 --- /dev/null +++ b/00_Alternate_Languages/70_Poetry/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 poetry.ms +``` + +2. Mini Micro: +Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: +``` + load "poetry" + run +``` \ No newline at end of file diff --git a/00_Alternate_Languages/70_Poetry/MiniScript/poetry.ms b/00_Alternate_Languages/70_Poetry/MiniScript/poetry.ms new file mode 100644 index 000000000..7c136bbb6 --- /dev/null +++ b/00_Alternate_Languages/70_Poetry/MiniScript/poetry.ms @@ -0,0 +1,51 @@ +print ""*30 + "POETRY" +print ""*15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" +print; print; print + +I = 0; J = 0; K = 0; U = 0 + +// Note: infinite loop. Press control-C to break. +while true + if J == 1 then + print ["MIDNIGHT DREARY", "FIERY EYES", + "BIRD OR FIEND", "THING OF EVIL", "PROPHET"][I-1], "" + else if J == 2 then + if I == 1 or I == 4 then U = 2 + if I == 3 then U = 0 + print ["BEGUILING ME", "THRILLED ME", + "STILL SITTING....", "NEVER FLITTING", "BURNED"][I-1], "" + else if J == 3 then + if U != 0 or I < 5 then + print ["AND MY SOUL", "DARKNESS THERE", + "SHALL BE LIFTED", "QUOTH THE RAVEN", "SIGN OF PARTING"][I-1], "" + end if + else if J == 4 then + print ["NOTHING MORE", "YET AGAIN", + "SLOWLY CREEPING", "...EVERMORE", "NEVERMORE"][I-1], "" + end if + if U != 0 and rnd <= 0.19 then + print ",", "" + U = 2 + end if + if rnd <= 0.65 then + print " ", "" + U += 1 + else + print + U = 0 + end if + while true + I =floor(floor(10*rnd)/2)+1 + J += 1 + K += 1 + if U == 0 and floor(J/2) == J/2 then print " ", "" + if J <= 5 then break + J = 0 + print + if K <= 20 then continue + print + U = 0 + K = 0 + break + end while +end while From 75b0ce9c46da2b1ae90112a3df5995315ba15a58 Mon Sep 17 00:00:00 2001 From: JoeStrout Date: Sat, 30 Sep 2023 17:02:12 -0700 Subject: [PATCH 3/8] Added MiniScript implementation of 71_Poker. --- .../70_Poetry/MiniScript/poetry.ms | 4 +- .../71_Poker/MiniScript/README.md | 18 + .../71_Poker/MiniScript/poker.ms | 557 ++++++++++++++++++ 71_Poker/README.md | 11 + 4 files changed, 588 insertions(+), 2 deletions(-) create mode 100644 00_Alternate_Languages/71_Poker/MiniScript/README.md create mode 100644 00_Alternate_Languages/71_Poker/MiniScript/poker.ms diff --git a/00_Alternate_Languages/70_Poetry/MiniScript/poetry.ms b/00_Alternate_Languages/70_Poetry/MiniScript/poetry.ms index 7c136bbb6..f55d32901 100644 --- a/00_Alternate_Languages/70_Poetry/MiniScript/poetry.ms +++ b/00_Alternate_Languages/70_Poetry/MiniScript/poetry.ms @@ -1,5 +1,5 @@ -print ""*30 + "POETRY" -print ""*15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" +print " "*30 + "POETRY" +print " "*15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" print; print; print I = 0; J = 0; K = 0; U = 0 diff --git a/00_Alternate_Languages/71_Poker/MiniScript/README.md b/00_Alternate_Languages/71_Poker/MiniScript/README.md new file mode 100644 index 000000000..95144dcfd --- /dev/null +++ b/00_Alternate_Languages/71_Poker/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 poker.ms +``` + +2. Mini Micro: +Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: +``` + load "poker" + run +``` \ No newline at end of file diff --git a/00_Alternate_Languages/71_Poker/MiniScript/poker.ms b/00_Alternate_Languages/71_Poker/MiniScript/poker.ms new file mode 100644 index 000000000..b367db031 --- /dev/null +++ b/00_Alternate_Languages/71_Poker/MiniScript/poker.ms @@ -0,0 +1,557 @@ +print " "*33 + "POKER" +print " "*15 + "Creative Computing Morristown, New Jersey" +print; print; print + +print "Welcome to the casino. We each have $200." +print "I will open the betting before the draw; you open after." +print "To fold bet 0; to check bet .5." +print "Enough talk -- let's get down to business." +print + +askYesNo = function(prompt) + while true + yn = input(prompt + "? ").lower + " " + if yn[0] == "y" then return "yes" + if yn[0] == "n" then return "no" + print "Answer yes or no, please." + end while +end function +askNumber = function(prompt, maxQty=3, minQty=1, maxErr=null, minErr=null) + while true + value = input(prompt + "? ").val + if minQty <= value <= maxQty then return value + if value < minQty and minErr != null then + print minErr + else if maxErr != null then + print maxErr + else + print "Enter a value between " + minQty + " and " + maxQty + ", please." + end if + end while +end function +random = function(n) + return floor(n * rnd) +end function +rand10 = function + return floor(10 * rnd) +end function +pad = function(s, width) + return s + " " * (width - s.len) +end function + +// Bonus little feature when running in Mini Micro: display a header bar +// always at the top of the screen, showing current balances. Does nothing +// on other platforms. +drawHeaders = function + if version.hostName != "Mini Micro" then return + display(2).mode = displayMode.text; td = display(2) + td.color = color.black; td.backColor = text.color + td.row = 25; td.column = 0 + td.print pad("Computer: $" + computer.balance, 25) + + pad("Table: $" + Table.pot, 25) + + pad("Player: $" + human.balance, 18) +end function + + +// Card class: represents a single playing card +Card = {} +Card.rank = 0 // from 2 to 14 (Ace) +Card.suit = "Clubs" +Card.keep = false // temp flag, used to note which cards to keep vs. discard +Card.make = function(rank, suit) + result = new Card + result.rank = rank + result.suit = suit + return result +end function +Card.rankStr = function(plural=false) + if self.rank > 10 then + return ["Jack", "Queen", "King", "Ace"][self.rank-11] + "s"*plural + else + return str(self.rank) + "'s" * plural + end if +end function +Card.str = function + return self.rankStr + " of " + self.suit +end function + +// Prepare a standard deck of 52 cards, and functions to draw and discard +deck = [] +for suit in ["Clubs", "Diamonds", "Hearts", "Spades"] + for rank in range(2, 14) + deck.push Card.make(rank, suit) + end for +end for +deck.shuffle +discardPile = [] +drawCard = function + if not deck then + globals.deck = discardPile + deck.shuffle + globals.discardPile = [] + end if + return deck.pop +end function +discard = function(cardOrCards) + if cardOrCards isa Hand then + globals.discardPile += cardOrCards.cards + else if cardOrCards isa list then + globals.discardPile += cardOrCards + else + discardPile.push cardOrCards + end if +end function + +// Hand ranks: how we compare Poker hands +HandRank = {} +HandRank.value = 0 +HandRank.str = function(highCard); return ""; end function +HandRank.make = function(value) + result = new HandRank + result.value = value + return result +end function + +HandRank.None = new HandRank +HandRank.Schmaltz = HandRank.make(1) +HandRank.Schmaltz.str = function(c); return "schmaltz, " + c.rankStr + " high"; end function +HandRank.PartialStraight = HandRank.make(2) +HandRank.PartialStraight.str = function(c); return ""; end function // (no display string; this is used only internally) +HandRank.Pair = HandRank.make(3) +HandRank.Pair.str = function(c); return "a pair of " + c.rankStr(true); end function +HandRank.TwoPair = HandRank.make(4) +HandRank.TwoPair.str = function(c); return "two pair, " + c.rankStr(true); end function +HandRank.Three = HandRank.make(5) +HandRank.Three.str = function(c); return "three " + c.rankStr(true); end function +HandRank.Straight = HandRank.make(6) +HandRank.Straight.str = function(c); return "straight, " + c.rankStr + " high"; end function +HandRank.Flush = HandRank.make(7) +HandRank.Flush.str = function(c); return "a flush in " + c.suit; end function +HandRank.FullHouse = HandRank.make(8) +HandRank.FullHouse.str = function(c); return "full house, " + c.rankStr(true); end function +HandRank.Four = HandRank.make(9) +HandRank.Four.str = function(c); return "four " + c.rankStr(true); end function +// Note: original code does not detect a straight flush or royal flush. + +// Hand: represents a set of cards in the hand of one player. +Hand = {} +Hand.cards = null // list of Card +Hand.rank = null // HandRank instance +Hand.highCard = null // reference to which (of self.cards) determines relative value +Hand.afterDraw = false // true if we've already had a chance to draw cards +Hand.make = function(cards) + result = new Hand + result.cards = cards + result.analyze + return result +end function +Hand.deal = function + return Hand.make([drawCard, drawCard, drawCard, drawCard, drawCard]) +end function +Hand.replaceCard = function(index) + discard self.cards[index] + self.cards[index] = drawCard +end function +Hand.rankStr = function + return self.rank.str(self.highCard) +end function +Hand.isWeak = function + return self.rank.value < HandRank.PartialStraight.value or + (self.rank.value == HandRank.PartialStraight.value and self.afterDraw) or + (self.rank <= HandRank.TwoPair.value and self.highCard.rank <= 6) +end function +Hand.beats = function(other) + if self.rank.value > other.rank.value then return true + if self.rank.value < other.rank.value then return false + return self.highCard.rank > other.highCard.rank +end function +Hand.print = function(startingNumber=1) + num = startingNumber + for c in self.cards + s = " " * (num < 10) + num + " -- " + c.str + print " " + s, "" + if num % 2 == 0 then + print + else + print " " * (28-s.len), "" + end if + num += 1 + end for + if num % 2 == 0 then print +end function +Hand.analyze = function + allSameSuit = true + for i in range(1, self.cards.len-1) + if self.cards[i].suit != self.cards[0].suit then allSameSuit = false + end for + if allSameSuit then + self.rank = HandRank.Flush + self.highCard = self.cards[0] + return + end if + + sortedCards = self.cards[:] + sortedCards.sort "rank" + self.rank = HandRank.Schmaltz + for c in sortedCards; c.keep = false; end for + keepAny = false + + for i in range(0, sortedCards.len-2) + matchesNextCard = (sortedCards[i].rank == sortedCards[i+1].rank) + if matchesNextCard then + self.highCard = sortedCards[i] + matchesPrevCard = (i > 0 and sortedCards[i].rank == sortedCards[i-1].rank) + sortedCards[i].keep = true + sortedCards[i+1].keep = true + keepAny = true + if self.rank.value < HandRank.Pair.value then + self.rank = HandRank.Pair + else if matchesPrevCard and self.rank == HandRank.Pair then + self.rank = HandRank.Three + else if self.rank == HandRank.Pair then + self.rank = HandRank.TwoPair + else if self.rank == HandRank.TwoPair then + self.rank = HandRank.FullHouse + else if matchesPrevCard then + self.rank = HandRank.Four + else + self.rank = HandRank.FullHouse + end if + end if + end for + if not keepAny then + if sortedCards[3].rank - sortedCards[0].rank == 3 then + for i in range(0,3); sortedCards[i].keep = true; end for + self.rank = HandRank.PartialStraight + end if + if sortedCards[4].rank - sortedCards[1].rank == 3 then + if self.rank == HandRank.PartialStraight then + self.rank = HandRank.Straight + sortedCards[4].keep = true + self.highCard = sortedCards[4] + else + self.rank = HandRank.PartialStraight + for i in range(1,4); sortedCards[i].keep = true; end for + end if + end if + end if + if self.rank == HandRank.Schmaltz then + self.highCard = sortedCards[4] + sortedCards[4].keep = true + sortedCards[3].keep = true + end if + +end function + +// Some global constants, just to make the code more understandable +Ante = 5 + +// Player -- base class for computer and human +Player = {} +Player.balance = 200 +Player.hand = null +Player.totalBet = 0 +Player.anteUp = function + self.balance -= Ante + return Ante +end function +Player.newHand = function + if self.hand then discard self.hand + self.hand = Hand.deal + self.totalBet = 0 +end function +Player.addToPot = function(amount) + self.balance -= amount + Table.pot += amount + drawHeaders +end function +Player.win = function + self.balance += Table.pot + Table.pot = 0 + drawHeaders +end function + +// strategies the computer player might employ +Strategy = {} +Strategy.make = function(name, value=2, drawCount=null) + result = new Strategy + result.name = name + result.value = value + result.drawCount = drawCount + return result +end function +Strategy.fold = Strategy.make("FOLD") +Strategy.check = Strategy.make("CHECK") +Strategy.raise = Strategy.make("RAISE", 2) +Strategy.bluff = function(value, drawCount); return Strategy.make("BLUFF", value, drawCount); end function +Strategy.bet = function(value); return Strategy.make("BET", value); end function + +// computer player +computer = new Player +computer.strategy = null +computer.newHand = function + super.newHand + if self.hand.isWeak then + if rand10 < 2 then + self.strategy = Strategy.bluff(23, 2) + else if rand10 < 2 then + self.strategy = Strategy.bluff(23, 1) + else if rand10 < 1 then + self.strategy = Strategy.bluff(23, 0) + else + self.strategy = Strategy.fold + end if + else if self.hand.rank.value < HandRank.Three.value then + if rand10 < 2 then self.strategy = Strategy.bluff(23, null) else self.strategy = Strategy.check + else if self.hand.rank.value < HandRank.FullHouse.value then + self.strategy = Strategy.bet(35) + else + if rand10 < 1 then self.strategy = Strategy.bet(35) else self.strategy = Strategy.raise + end if +end function +computer.bet = function(minBet=1, openingBet=false) + //print "My hand: "; self.hand.print; print "Strategy: " + self.strategy + if self.balance < minBet then + print "I fold." + return 0 + end if + if openingBet and (self.strategy == Strategy.check or self.strategy == Strategy.fold) then + print "I check." + return 0.5 + else if self.strategy == Strategy.fold and human.totalBet > 5 then + print "I fold." + return 0 + else if self.strategy == Strategy.check then + print "I'll see you." + return minBet + else if openingBet then + result = self.strategy.value + rand10 + if result > self.balance then result = self.balance + if result == 0 then + print "I check." + return 0.5 + end if + print "I'll open with $" + result + return result + else + bet = self.strategy.value + rand10 + if self.strategy == Strategy.raise then bet += minBet + if bet > self.balance then bet = self.balance + raise = bet - minBet + if raise <= 0 then + print "I'll see you." + return minBet + else + print "I'll see you, and raise you " + raise + return bet + end if + end if +end function +computer.drawCards = function + //print "My hand:"; self.hand.print + drawCount = 0 + for c in self.hand.cards; if not c.keep then drawCount += 1; end for + print "I am taking " + drawCount + " card" + "s" * (drawCount != 1) + for i in self.hand.cards.indexes + if not self.hand.cards[i].keep then self.hand.replaceCard i + end for + self.hand.analyze + //print "My new hand: "; self.hand.print + if self.strategy.name == "BLUFF" then + self.strategy = Strategy.bluff(28) + else if self.hand.isWeak then + self.strategy = Strategy.fold + else if self.hand.rank.value < HandRank.Three.value then + if rand10 == 0 then self.strategy = Strategy.bet(19) else self.strategy = Strategy.raise + else if self.hand.rank.value < HandRank.FullHouse.value then + if rand10 == 0 then self.strategy = Strategy.bet(11) else self.strategy = Strategy.bet(19) + else + self.strategy = Strategy.raise + end if +end function +computer.win = function + print; print "I win." + super.win +end function +computer.checkFunds = function + if self.balance >= Ante then return + if human.balance < 50 then return // BUGFIX + if human.hasWatch or askYesNo("Would you like to buy back your watch for $50") == "no" then + print "I'm busted. Conglatulations!" + exit + end if + self.balance += 50 + // Note: original BASIC code does not take money from the player, but let's fix that: + human.balance -= 50 // BUGFIX + human.hasWatch = true + drawHeaders +end function + + +human = new Player +human.hasWatch = true +human.bet = function(minBet=1, openingBet=false) + while true + betStr = input("What is your bet? ") + bet = betStr.val + if bet == 0 and betStr != "0" then + print "Enter 0 to fold, 0.5 to check, or a value of 1 or more to bet." + continue + else if bet == 0.5 and openingBet then + return bet // (check) + else if 0 < bet < 1 then + print "No small change, please." + continue + else if bet < minBet then + print "If you can't see my bet, then fold." + continue + else if bet > self.balance then + print "You can't bet with what you haven't got." + self.trySellWatch + continue + end if + return bet + end while +end function +human.drawCards = function + qty = askNumber("How many cards do you want", 3, 0, "You can't draw more than three cards.") + if qty == 0 then return + print "What are their numbers: " + for i in range(1, qty) + num = askNumber("", 5, 1) + self.hand.replaceCard num - 1 + end for + print "Your new hand:" + self.hand.print + self.hand.analyze +end function +human.win = function + print; print "You win." + super.win +end function +human.checkFunds = function + if self.balance < Ante then self.trySellWatch + if self.balance < Ante then + print "Your wad is shot. So long, sucker!" + exit + end if +end function +human.trySellWatch = function + if not self.hasWatch then return + if rand10 < 7 then + value = 75 + msg = "I'll give you $" + value + " for it." + else + value = 25 + msg = "That's a pretty crummy watch - I'll give you $" + value + "." + end if + if computer.balance < value then return // BUGFIX + if askYesNo("Would you like to sell your watch") == "no" then return + print msg + self.balance += value + self.hasWatch = false + // Note: the original BASIC program does not actually take any money from the computer. + // But let's do it right here: + computer.balance -= value // BUGFIX + drawHeaders +end function + +Table = {} +Table.pot = 0 + + +deal = function + Table.pot += computer.anteUp + human.anteUp + drawHeaders + computer.newHand + human.newHand +end function + +// Do a round of betting. Return true to continue, or false +// if either player folds (ending the hand). +takeBets = function(computerFirst) + if computerFirst then + bet = computer.bet(1, true) + if bet == 0 then + human.win + return false + end if + if bet == 0.5 then bet = 0 // "check" (no bet, but stay in the hand) + computer.addToPot bet + else + bet = 0 + end if + raise = bet + canCheck = (bet == 0) + while true + bet = human.bet(raise, canCheck) + if bet == 0 then + computer.win + return false + end if + if bet == 0.5 then // (checked) + if computerFirst then return true + bet = 0 + else + human.addToPot bet + raise = bet - raise + if raise == 0 then return true + end if + if computerFirst or bet > 0 then canCheck = false + + bet = computer.bet(raise, canCheck) + if bet == 0 then + human.win + return false + end if + if bet == 0.5 then return true // (checked) + canCheck = false + computer.addToPot bet + raise = bet - raise + if raise == 0 then return true + end while +end function + +playHand = function + print + computer.checkFunds + human.checkFunds + print "The ante is " + Ante + ". I will deal:" + print + + deal + + print "Your hand:" + human.hand.print + + print + if not takeBets(true) then return + + print; print "Now we draw -- ", "" + human.drawCards + computer.drawCards + + if not takeBets(false) then return + + print; print "Now we compare hands:" + print "My hand:" + computer.hand.print 6 + print + print "You have " + human.hand.rankStr + print "I have " + computer.hand.rankStr + if computer.hand.beats(human.hand) then + computer.win + else if human.hand.beats(computer.hand) then + human.win + else + print "The hand is drawn." + print "All $" + Table.pot + " remains in the pot." + end if +end function + +drawHeaders +while true + playHand + print "Now I have $" + computer.balance + " and you have $" + human.balance + if askYesNo("Do you wish to continue") == "no" then break +end while \ No newline at end of file diff --git a/71_Poker/README.md b/71_Poker/README.md index a80820598..08bc04c63 100644 --- a/71_Poker/README.md +++ b/71_Poker/README.md @@ -15,6 +15,17 @@ As published in Basic Computer Games (1978): Downloaded from Vintage Basic at http://www.vintage-basic.net/games.html +#### Known Bugs + +- If you bet more than the computer has, it will still see you, resulting in a negative balance. (To handle this properly, the computer would need to go "all in" and reduce your bet to an amount it can match; or else lose the game, which is what happens to the human player in the same situation.) + +- If you are low on cash and sell your watch, then make a bet much smaller than the amount you just gained from the watch, it sometimes nonetheless tells you you "blew your wad" and ends the game. + +- When the watch is sold (in either direction), the buyer does not actually lose any money. + +- The code in the program about selling your tie tack is unreachable due to a logic bug. + + #### Porting Notes (please note any difficulties or challenges in porting here) From 22e011349c46545f6b905391c460609ea951ce46 Mon Sep 17 00:00:00 2001 From: JoeStrout Date: Sun, 1 Oct 2023 15:38:34 -0700 Subject: [PATCH 4/8] Added MiniScript versions of 72_Queen and 74_Rock_Scissors_Paper. --- .../72_Queen/MiniScript/README.md | 18 +++ .../72_Queen/MiniScript/queen.ms | 151 ++++++++++++++++++ .../MiniScript/README.md | 21 +++ .../MiniScript/rockscissors.ms | 40 +++++ 4 files changed, 230 insertions(+) create mode 100644 00_Alternate_Languages/72_Queen/MiniScript/README.md create mode 100644 00_Alternate_Languages/72_Queen/MiniScript/queen.ms create mode 100644 00_Alternate_Languages/74_Rock_Scissors_Paper/MiniScript/README.md create mode 100644 00_Alternate_Languages/74_Rock_Scissors_Paper/MiniScript/rockscissors.ms diff --git a/00_Alternate_Languages/72_Queen/MiniScript/README.md b/00_Alternate_Languages/72_Queen/MiniScript/README.md new file mode 100644 index 000000000..cf8463343 --- /dev/null +++ b/00_Alternate_Languages/72_Queen/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 queen.ms +``` + +2. Mini Micro: +Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: +``` + load "queen" + run +``` \ No newline at end of file diff --git a/00_Alternate_Languages/72_Queen/MiniScript/queen.ms b/00_Alternate_Languages/72_Queen/MiniScript/queen.ms new file mode 100644 index 000000000..d3e882b91 --- /dev/null +++ b/00_Alternate_Languages/72_Queen/MiniScript/queen.ms @@ -0,0 +1,151 @@ +print " "*33 + "QUEEN" +print " "*15 + "Creative Computing Morristown New Jersey" +print; print; print + +getYesNo = function(prompt) + while true + inp = input(prompt + "? ").lower + " " + if inp[0] == "y" then return "yes" + if inp[0] == "n" then return "no" + print "Please answer 'yes' or 'no'." + end while +end function + +printDirections = function + print "We are going to play a game based on one of the chess" + print "moves. Our queen will be able to move only to the left " + print "down or diagonally down and to the left." + print + print "The object of the game is to place the queen in the lower" + print "left hand square by alternating moves between you and the" + print "computer. The first one to place the queen there wins." + print + print "You go first and place the queen in any one of the squares" + print "on the top row or right hand column." + print "That will be your first move." + print "We alternate moves." + print "You may forfeit by typing '0' as your move." + print "Be sure to press the return key after each response." + print + input "(Press Return to continue.)" + print +end function + +printCoordinates = function + // Porting note: I cannot imagine what possessed the original author to + // use such a crazy numbering scheme, which is not easy for the human + // player OR the code. But assumptions about it are scattered throughout + // the whole program, so we're stuck with it. + print + print " 81 71 61 51 41 31 21 11" + print " 92 82 72 62 52 42 32 22" + print " 103 93 83 73 63 53 43 33" + print " 114 104 94 84 74 64 54 44" + print " 125 115 105 95 85 75 65 55" + print " 136 126 116 106 96 86 76 66" + print " 147 137 127 117 107 97 87 77" + print " 158 148 138 128 118 108 98 88" + print +end function + +getStartPos = function + while true + m1 = input("Where would you like to start? ").val + tens = floor(m1/10) + ones = m1 % 10 + if ones == 1 or tens == ones or m1 == 0 then return m1 + print "Please read the directions again." + print "You have begun illegally." + print + end while +end function + +isGoodMove = function(ones, tens) + pos = 10 * tens + ones + return [158, 127, 126, 75, 73].indexOf(pos) != null +end function + +getRandomMove = function(queenPos) + tens = floor(queenPos/10) + ones = queenPos % 10 + z = rnd + if z > 0.6 then + return 10 * (tens+1) + ones + else if z > 0.3 then + return 10 * (tens+2) + (ones+1) + else + return 10 * (tens+1) + ones + end if +end function + +getComputerMove = function(queenPos) + tens = floor(queenPos/10) + ones = queenPos % 10 + if [41, 44, 73, 75, 126, 127].indexOf(queenPos) != null then return getRandomMove(queenPos) + for k in range(7, 1) + if isGoodMove(ones, tens+k) then return 10 * (tens+k) + ones // left + if isGoodMove(ones+k, tens+k) then return 10 * (tens+k) + (ones+k) // down + if isGoodMove(ones+k, tens+k*2) then return 10 * (tens+k*2) + (ones+k) // down-left + end for + return getRandomMove(queenPos) +end function + +getHumanMove = function(queenPos) + tens = floor(queenPos/10) + ones = queenPos % 10 + while true + pos = input("What is your move? ").val + if pos == 0 then return 0 + dTens = floor(pos/10) - tens + dOnes = pos % 10 - ones + ok = false + if dOnes == 0 and dTens > 0 then ok = true // moving left + if dOnes == dTens and dOnes > 0 then ok = true // moving down + if dTens == dOnes*2 and dOnes > 0 then ok = true // moving down-left + if ok then return pos + print + print "Y O U C H E A T . . . Try again"; + end while +end function + +playGame = function + queenPos = getStartPos + while true + if queenPos == 0 then + print "It looks like I have won by forfeit." + return + end if + + // computer move + queenPos = getComputerMove(queenPos) + print "Computer moves to square " + queenPos + if queenPos == 158 then + print + print "Nice try, but it looks like I have won." + return + end if + + // human move + queenPos = getHumanMove(queenPos) + if queenPos == 158 then + print + print "C O N G R A T U L A T I O N S . . ." + print + print "You have won--very well played." + print "It looks like I have met my match." + print "Thanks for playing---I can't win all the time." + return + end if + end while +end function + +// Main program +if getYesNo("Do you want instructions") == "yes" then printDirections +while true + printCoordinates + playGame + print + if getYesNo("Anyone else care to try") == "no" then break +end while +print +print "OK --- Thanks again." diff --git a/00_Alternate_Languages/74_Rock_Scissors_Paper/MiniScript/README.md b/00_Alternate_Languages/74_Rock_Scissors_Paper/MiniScript/README.md new file mode 100644 index 000000000..bfec2da94 --- /dev/null +++ b/00_Alternate_Languages/74_Rock_Scissors_Paper/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 rockscissors.ms. Then click the "Run Script" button. Program output (and input) will appear in the green-on-black terminal display to the right of or below the code editor. + +1. Command-Line MiniScript: +Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: +``` + miniscript rockscissors.ms +``` + +2. Mini Micro: +Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: +``` + load "rockscissors" + run +``` \ No newline at end of file diff --git a/00_Alternate_Languages/74_Rock_Scissors_Paper/MiniScript/rockscissors.ms b/00_Alternate_Languages/74_Rock_Scissors_Paper/MiniScript/rockscissors.ms new file mode 100644 index 000000000..322e354b6 --- /dev/null +++ b/00_Alternate_Languages/74_Rock_Scissors_Paper/MiniScript/rockscissors.ms @@ -0,0 +1,40 @@ +print " "*21 + "Game of Rock, Scissors, Paper" +print " "*15 + "Creative Computing Morristown New Jersey" +print; print; print + +while true + numGames = input("How many games? ").val + if 0 < numGames < 11 then break + print "Sorry, but we aren't allowed to play that many." +end while + +computerWins = 0 +playerWins = 0 +for game in range(1, numGames) + print; print "Game number " + game + myChoice = floor(rnd*3 + 1) + while true + print "3=Rock...2=Scissors...1=Paper" + playerChoice = input("1...2...3...What's your choice? ").val + if [1,2,3].indexOf(playerChoice) != null then break + print "Invalid." + end while + print "This is my choice..." + print ["...Paper", "...Scissors", "...Rock"][myChoice-1] + diff = myChoice - playerChoice + if diff == 0 then + print "Tie game. No winner." + else if diff == 1 or diff == -2 then + print "Wow! I win!!!" + computerWins += 1 + else + print "You win!!!" + playerWins += 1 + end if +end for + +print; print "Here is the final game score:" +print "I have won " + computerWins + " game(s)." +print "You have won " + playerWins + " game(s)." +print "And " + (numGames - computerWins - playerWins) + " game(s) ended in a tie." +print; print "Thanks for playing!!" From bd23c4778be8663acf48d6e9747aba0e416ea309 Mon Sep 17 00:00:00 2001 From: JoeStrout Date: Mon, 2 Oct 2023 09:40:53 -0700 Subject: [PATCH 5/8] Added MiniScript version of 75_Roulette. --- .../75_Roulette/MiniScript/README.md | 18 ++ .../75_Roulette/MiniScript/roulette.ms | 200 ++++++++++++++++++ 75_Roulette/README.md | 2 +- 3 files changed, 219 insertions(+), 1 deletion(-) create mode 100644 00_Alternate_Languages/75_Roulette/MiniScript/README.md create mode 100644 00_Alternate_Languages/75_Roulette/MiniScript/roulette.ms diff --git a/00_Alternate_Languages/75_Roulette/MiniScript/README.md b/00_Alternate_Languages/75_Roulette/MiniScript/README.md new file mode 100644 index 000000000..4a2e49289 --- /dev/null +++ b/00_Alternate_Languages/75_Roulette/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 roulette.ms +``` + +2. Mini Micro: +Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: +``` + load "roulette" + run +``` \ No newline at end of file diff --git a/00_Alternate_Languages/75_Roulette/MiniScript/roulette.ms b/00_Alternate_Languages/75_Roulette/MiniScript/roulette.ms new file mode 100644 index 000000000..60e7087bc --- /dev/null +++ b/00_Alternate_Languages/75_Roulette/MiniScript/roulette.ms @@ -0,0 +1,200 @@ +print " "*32 + "Roulette" +print " "*15 + "Creative Computing Morristown New Jersey" +print; print; print + +if version.hostName == "Mini Micro" then + import "dateTime" + globals.date = dateTime.str(dateTime.now, "MMM d, yyyy") +else + globals.date = input("Enter the current date (as in 'Jan 23, 1979') - ") +end if + +yn = input("Do you want instructions? ").lower + " " +if yn[0] != "n" then + print + print "This is the betting layout" + print " (*=Red)" + print + print " 1* 2 3*" + print " 4 5* 6 " + print " 7* 8 9*" + print "10 11 12*" + print "---------------" + print "13 14* 15 " + print "16* 17 18*" + print "19* 20 21*" + print "22 23* 24 " + print "---------------" + print "25* 26 27*" + print "28 29 30*" + print "31 32* 33 " + print "34* 35 36*" + print "---------------" + print " 00 0 " + print + input "(Press Return at each pause.)" + print + print "Types of Bets" + print + print "The numbers 1 to 36 signify a straight bet" + print "on that number." + print "These pay off 35:1" + print + print "The 2:1 bets are:" + print " 37) 1-12 40) first column" + print " 38) 13-24 41) second column" + print " 39) 25-36 42) third column" + print + print "The even money bets are:" + print " 43) 1-18 46) odd" + print " 44) 19-36 47) red" + print " 45) even 48) black" + print + print " 49)0 and 50)00 pay off 35:1" + print " NOTE: 0 and 00 do not count under any" + print " bets except their own." + input + print "When I ask for each bet, type the number" + print "and the amount, separated by a comma." + print "For example: to bet $500 on black, type 48,500" + print "when I ask for a bet." + print + print "The minimum bet is $5, the maximum is $500." + print +end if + +redNumbers = [1,3,5,7,9,12,14,16,18,19,21,23,25,27,30,32,34,36] + +// function to convert a number 1-38 to a number/description, like "00" +// or "7 RED" +numDesc = function(number) + if number == 37 then return "0" + if number == 38 then return "00" + s = str(number) + if redNumbers.indexOf(number) == null then + return s + " BLACK" + else + return s + " RED" + end if +end function + +// function to calculate the payout factor (positive if player wins, +// or -1 if player loses) for the given bet and actual spin. +payoutFactor = function(bet, spin) + if bet <= 36 then // straight bet, pays 35:1 + if bet == spin then return 35 else return -1 + else if bet == 49 then // 0, pays 35:1 + if spin == 37 then return 35 else return -1 + else if bet == 50 then // 00, pays 35:1 + if spin == 38 then return 35 else return -1 + else if bet == 37 then // 1-12, pays 2:1 + if 1 <= spin <= 12 then return 2 else return -1 + else if bet == 38 then // 13-24, pays 2:1 + if 13 <= spin <= 24 then return 2 else return -1 + else if bet == 39 then // 25-36, pays 2:1 + if 25 <= spin <= 36 then return 2 else return -1 + else if bet == 40 then // first column, pays 2:1 + if spin % 3 == 1 then return 2 else return -1 + else if bet == 41 then // second column, pays 2:1 + if spin % 3 == 2 then return 2 else return -1 + else if bet == 42 then // third column, pays 2:1 + if spin % 3 == 0 then return 2 else return -1 + else if bet == 43 then // 1-18, even money + if 1 <= spin <= 18 then return 1 else return -1 + else if bet == 44 then // 19-36, even money + if 19 <= spin <= 36 then return 1 else return -1 + else if bet == 45 then // even number, even money + if spin % 2 == 0 then return 1 else return -1 + else if bet == 46 then // odd number, even money + if spin % 2 == 1 then return 1 else return -1 + else if bet == 47 then // red, even money + if redNumbers.indexOf(spin) != null then return 1 else return -1 + else if bet == 48 then // black, even money + if redNumbers.indexOf(spin) == null then return 1 else return -1 + end if + print "Invalid bet " + bet + " in payoutFactor" +end function + +playerCash = 1000 +houseCash = 100000 +x = [0] * 38 // (keeps track of how often each number comes up) +while playerCash > 0 + // Get the player's bets + numBets = input("How many bets? ").val + if numBets < 1 then continue + bets = []; amounts = [] + for i in range(1, numBets) + while true + s = input("Number " + i + "? ").replace(",", " ").replace(" ", " ").split + if s.len != 2 then continue + bet = s[0].val; amount = s[1].val + if bets.indexOf(bet) != null then + print "You made that bet once already,dum-dum" + continue + end if + if 1 <= bet <= 50 and 5 <= amount <= 500 then + bets.push bet + amounts.push amount + break + end if + end while + end for + + // Spin the wheel! + print "Spinning" + print + print + spin = floor(38 * rnd + 1) + x[spin] += 1 + print numDesc(spin) + print + + // Now, pay out the bets + for i in bets.indexes + f = payoutFactor(bets[i], spin) + if f > 0 then + print "You win " + f*amounts[i] + " on bet " + i + else + print "You lose " + (-f)*amounts[i] + " on bet " + i + end if + playerCash += f * amounts[i] + houseCash -= f * amounts[i] + end for + print + print "Totals: ME YOU" + print " " + (houseCash+" "*12)[:12] + playerCash + if playerCash > 0 and houseCash > 0 then + yn = input("Again? ").lower + " " + if yn[0] != "y" then break + end if +end while + +if houseCash < 1 then + print "You broke the house!" + playerCash = 101000 +end if +if playerCash < 1 then + print "Oops! You just spent your last dollar!" + print "Thanks for your money." + print "I'll use it to buy a solid gold roulette wheel" + print +else + name = input("To whom shall I make the check? ") + print + print "-"*68 + print " "*55 + "Check No. " + floor(rnd*100) + print + print " "*(67 - date.len) + date + print + print + print "Pay to the order of-----" + name + "-----$ " + playerCash + print + print + print " "*10 + "The Memory Bank of New York" + print + print " "*35 + "The Computer" + print " "*35 + "----------X-----" + print + print "-"*68 + print "Come back soon!" +end if diff --git a/75_Roulette/README.md b/75_Roulette/README.md index 4902aa9ba..b68a2ad1b 100644 --- a/75_Roulette/README.md +++ b/75_Roulette/README.md @@ -17,4 +17,4 @@ http://www.vintage-basic.net/games.html #### Porting Notes -(please note any difficulties or challenges in porting here) +- The program keeps a count of how often each number comes up in array `X`, but never makes use of this information. From 91a494df5b3ec3fc16c3b8e9a0f59202d621938d Mon Sep 17 00:00:00 2001 From: JoeStrout Date: Mon, 2 Oct 2023 15:30:55 -0700 Subject: [PATCH 6/8] Added MiniScript version of 76_Russian_Roulette. --- .../76_Russian_Roulette/MiniScript/README.md | 21 +++++++++++ .../MiniScript/russianroulette.ms | 37 +++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 00_Alternate_Languages/76_Russian_Roulette/MiniScript/README.md create mode 100644 00_Alternate_Languages/76_Russian_Roulette/MiniScript/russianroulette.ms diff --git a/00_Alternate_Languages/76_Russian_Roulette/MiniScript/README.md b/00_Alternate_Languages/76_Russian_Roulette/MiniScript/README.md new file mode 100644 index 000000000..79d028a92 --- /dev/null +++ b/00_Alternate_Languages/76_Russian_Roulette/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 russianroulette.ms. Then click the "Run Script" button. Program output (and input) will appear in the green-on-black terminal display to the right of or below the code editor. + +1. Command-Line MiniScript: +Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as: +``` + miniscript russianroulette.ms +``` + +2. Mini Micro: +Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: +``` + load "russianroulette" + run +``` \ No newline at end of file diff --git a/00_Alternate_Languages/76_Russian_Roulette/MiniScript/russianroulette.ms b/00_Alternate_Languages/76_Russian_Roulette/MiniScript/russianroulette.ms new file mode 100644 index 000000000..3eb896f94 --- /dev/null +++ b/00_Alternate_Languages/76_Russian_Roulette/MiniScript/russianroulette.ms @@ -0,0 +1,37 @@ +print " "*28 + "Russian Roulette" +print " "*15 + "Creative Computing Morristown New Jersey" +print; print; print + +print "This is a game of >>>>>>>>>>Russian Roulette." + +while true + print; print "Here is a revolver." + print "Type '1' to spin chamber and pull trigger." + print "Type '2' to give up." + print "GO" + + n = 0 + while n < 10 + inp = input("? ").val + if inp == 2 then + print " CHICKEN!!!!!" + break + else if rnd > 0.833333 then + print " BANG!!!!! You're dead!" + print "Condolences will be sent to your relatives." + break + else + n += 1 + print "- CLICK -" + print + end if + end while + + if n >= 10 then + print "You win!!!!!" + print "Let someone else blow his brains out." + else + print; print; print + print "...Next victim..." + end if +end while From 691664d902192453756c0c8aa471a6d86bf4549e Mon Sep 17 00:00:00 2001 From: JoeStrout Date: Tue, 3 Oct 2023 13:03:47 -0700 Subject: [PATCH 7/8] Added MiniScript version of 77_Salvo. --- .../77_Salvo/MiniScript/README.md | 18 ++ .../77_Salvo/MiniScript/salvo.ms | 240 ++++++++++++++++++ 77_Salvo/README.md | 7 +- 3 files changed, 263 insertions(+), 2 deletions(-) create mode 100644 00_Alternate_Languages/77_Salvo/MiniScript/README.md create mode 100644 00_Alternate_Languages/77_Salvo/MiniScript/salvo.ms diff --git a/00_Alternate_Languages/77_Salvo/MiniScript/README.md b/00_Alternate_Languages/77_Salvo/MiniScript/README.md new file mode 100644 index 000000000..d31694466 --- /dev/null +++ b/00_Alternate_Languages/77_Salvo/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 salvo.ms +``` + +2. Mini Micro: +Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: +``` + load "salvo" + run +``` \ No newline at end of file diff --git a/00_Alternate_Languages/77_Salvo/MiniScript/salvo.ms b/00_Alternate_Languages/77_Salvo/MiniScript/salvo.ms new file mode 100644 index 000000000..e7c2796e7 --- /dev/null +++ b/00_Alternate_Languages/77_Salvo/MiniScript/salvo.ms @@ -0,0 +1,240 @@ +print " "*33 + "Salvo" +print " "*15 + "Creative Computing Morristown New Jersey" +print; print; print + +import "listUtil" + +Ship = {} +Ship.name = "Ship" +Ship.positions = null // list of [x,y] coordinates for this ship +Ship.shots = 1 // how many shots this ship provides +Ship.hitPoints = 1 // how many hits this ship can take before sinking +Ship.make = function(name, shots=1, size=2) + result = new Ship + result.name = name + result.shots = shots + result.positions = [] + result.hitPoints = size + return result +end function + +Board = {} +Board.ships = null // list of Ship instances +Board.splash = null // 2D array of: none, or turn on which it was hit +Board.shipAt = function(xy) + for ship in self.ships + if ship.positions.contains(xy) then return ship + end for +end function +Board.isEmptySpot = function(xy) + return 0 < xy[0] < 11 and 0 < xy[1] < 11 and self.shipAt(xy) == null +end function +Board.make = function + result = new Board + result.ships = [] + result.splash = list.init2d(11, 11) + return result +end function +Board.totalShots = function + sum = 0 + for ship in self.ships + sum += ship.shots + end for + return sum +end function + +computerBoard = Board.make +playerBoard = Board.make + +directions = [[-1,-1], [-1,0], [-1,1], [0,-1], [0,1], [1,-1], [1,0], [1,1]] + +randomPosition = function + return [1 + floor(rnd*10), 1 + floor(rnd*10)] +end function + +inputCoords = function(prompt="?") + while true + inp = input(prompt + "? ").replace(",", " ").replace(" ", " ").split + if inp.len != 2 then + print "Please enter coordinates such as: 5,3" + else + x = inp[0].val + y = inp[1].val + if 0 < x < 11 and 0 < y < 11 then return [x,y] + print "X and Y coordinates must be in the range 1-10." + end if + end while +end function + +inBounds = function(pos) + return 0 < pos[0] < 11 and 0 < pos[1] < 11 +end function + +placeComputerShips = function + placeOne = function(ship) + while true + pos = randomPosition + dir = directions.any + ok = true + p = pos[:] + for i in range(0, ship.hitPoints - 1) + if not computerBoard.isEmptySpot(p) then ok = false + p.add dir + end for + if ok then break + end while + for i in range(0, ship.hitPoints - 1) + ship.positions.push pos[:] + pos.add dir + end for + computerBoard.ships.push ship + end function + placeOne Ship.make("Battleship", 3, 5) + placeOne Ship.make("Cruiser", 2, 3) + placeOne Ship.make("Destroyer", 1, 2) + placeOne Ship.make("Destroyer", 1, 2) +end function + +placePlayerShips = function + placeOne = function(ship) + print ship.name + playerBoard.ships.push ship + // Note: like the original BASIC program, we do no validation on + // the input other than making sure it is in range. So you can + // have a ship scattered all over the map, have ships overlap, etc. + for i in range(1, ship.hitPoints) + ship.positions.push inputCoords + end for + end function + print "Enter coordinates for..." + placeOne Ship.make("Battleship", 3, 5) + placeOne Ship.make("Cruiser", 2, 3) + placeOne Ship.make("Destroyer", 1, 2) + placeOne Ship.make("Destroyer", 1, 2) +end function + +printComputerShips = function + for ship in computerBoard.ships + print ship.name + for pos in ship.positions + print " " + pos.join(" ") + end for + end for +end function + +doPlayerTurn = function(turnNum = 1) + shots = playerBoard.totalShots + print "You have " + shots + " shot" + "s"*(shots!=1) + "." + if shots < 1 then + print "I have won." + exit + end if + hits = [] + for i in range(1, shots) + while true + pos = inputCoords + prevHitOnTurn = computerBoard.splash[pos[0]][pos[1]] + if prevHitOnTurn == null then break + print "You shot there before on turn " + prevHitOnTurn + end while + computerBoard.splash[pos[0]][pos[1]] = turnNum + hit = computerBoard.shipAt(pos) + if hit then hits.push hit + end for + for hit in hits + print "You hit my " + hit.name + "." + hit.hitPoints -= 1 + if hit.hitPoints == 0 then + print "...and sank it!" // (not in original BASIC program) + computerBoard.ships.removeVal hit + end if + end for +end function + +pickShot = function + // Pick a spot for the computer to shoot at. We'll do this by + // computing a "neighbor score" for each spot: the number of + // neighboring spots that (1) we have previously hit, and (2) + // contain an enemy ship. Then we'll pick randomly from the + // set of spots with the highest neighbor score. + bestScore = 0 + spots = [] + for i in range(1,10) + for j in range(1,10) + pos = [i,j] + if playerBoard.splash[pos[0]][pos[1]] then continue + score = 0 + for dir in directions + n = pos.plus(dir) + if inBounds(n) and playerBoard.splash[n[0]][n[1]] and playerBoard.shipAt(n) then + score += 1 + end if + end for + if score > bestScore then + bestScore = score + spots = [pos] + else if score == bestScore then + spots.push pos + end if + end for + end for + return spots.any +end function + +doComputerTurn = function(turnNum = 1) + shots = computerBoard.totalShots + print "I have " + shots + " shot" + "s"*(shots!=1) + "." + if shots < 1 then + print "You have won." + exit + end if + hits = [] + for i in range(1, shots) + pos = pickShot + playerBoard.splash[pos[0]][pos[1]] = turnNum + hit = playerBoard.shipAt(pos) + if hit then hits.push hit + if seeComputerShots then print " " + pos.join(" ") + end for + for hit in hits + print "I hit your " + hit.name + "." + hit.hitPoints -= 1 + if hit.hitPoints == 0 then + print "...and sank it!" // (not in original BASIC program) + playerBoard.ships.removeVal hit + end if + end for +end function + +// Main Program + +placeComputerShips +placePlayerShips +while true + yn = input("Do you want to start? ").lower + if yn == "where are your ships?" then + printComputerShips + else if yn and (yn[0] == "y" or yn[0] == "n") then + break + end if +end while +startWithPlayer = (yn[0] == "y") +while true + yn = input("Do you want to see my shots? ").lower + if yn and (yn[0] == "y" or yn[0] == "n") then break +end while +seeComputerShots = (yn[0] == "y") + +turnNumber = 1 +while true + print + print "Turn " + turnNumber + if startWithPlayer then + doPlayerTurn turnNumber + doComputerTurn turnNumber + else + doComputerTurn turnNumber + doPlayerTurn turnNumber + end if + turnNumber += 1 +end while \ No newline at end of file diff --git a/77_Salvo/README.md b/77_Salvo/README.md index 4bb40487e..3ef9f21c9 100644 --- a/77_Salvo/README.md +++ b/77_Salvo/README.md @@ -26,7 +26,9 @@ http://www.vintage-basic.net/games.html #### Porting Notes -As per the analysis in +The program does no validation of ship positions; your ship coordinates may be scattered around the board in any way you like. (Computer ships will not do this, but they may be placed diagonally in such a way that they cross each other.) Scattering your ships in this way probably defeats whatever all that spaghetti-code logic the computer is using to pick its moves, which is based on the assumption of contiguous ships. + +Moreover: as per the analysis in https://forums.raspberrypi.com/viewtopic.php?p=1997950#p1997950 @@ -40,4 +42,5 @@ This typo is interesting because it causes the program to play by a much weaker `3970 K(R,S)=K(R,S)+E(U)-2*INT(H(U)+.5)` -and to change the JavaScript program accordingly. +and to change the JavaScript program accordingly. (And note that some ports — looking at you, Python — do not implement the original strategy at all, but merely pick random unshot locations for every shot.) + From 55ec0811478b3738cde869339df49701a17d8ce1 Mon Sep 17 00:00:00 2001 From: JoeStrout Date: Tue, 3 Oct 2023 16:10:16 -0700 Subject: [PATCH 8/8] Added MiniScript version of 79_Slalom. --- .../79_Slalom/MiniScript/README.md | 18 ++ .../79_Slalom/MiniScript/slalom.ms | 170 ++++++++++++++++++ 00_Alternate_Languages/79_Slalom/slalom.bas | 2 +- 79_Slalom/README.md | 8 +- 79_Slalom/slalom.bas | 2 +- 5 files changed, 195 insertions(+), 5 deletions(-) create mode 100644 00_Alternate_Languages/79_Slalom/MiniScript/README.md create mode 100644 00_Alternate_Languages/79_Slalom/MiniScript/slalom.ms diff --git a/00_Alternate_Languages/79_Slalom/MiniScript/README.md b/00_Alternate_Languages/79_Slalom/MiniScript/README.md new file mode 100644 index 000000000..c954f090c --- /dev/null +++ b/00_Alternate_Languages/79_Slalom/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 slalom.ms +``` + +2. Mini Micro: +Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter: +``` + load "slalom" + run +``` \ No newline at end of file diff --git a/00_Alternate_Languages/79_Slalom/MiniScript/slalom.ms b/00_Alternate_Languages/79_Slalom/MiniScript/slalom.ms new file mode 100644 index 000000000..41bb0b829 --- /dev/null +++ b/00_Alternate_Languages/79_Slalom/MiniScript/slalom.ms @@ -0,0 +1,170 @@ +print " "*33 + "Slalom" +print " "*15 + "Creative Computing Morristown New Jersey" +print; print; print + +gateSpeeds = [14,18,26,29,18,25,28,32,29,20,29,29,25,21,26,29,20,21,20, + 18,26,25,33,31,22] + +medals = {} +medals.gold = 0 +medals.silver = 0 +medals.bronze = 0 + +while true + qtyGates = input("How many gates does this course have (1 to 25)? ").val + if qtyGates > 25 then + print "25 is the limit." + qtyGates = 25 + end if + if qtyGates >= 1 then break + print "Try again," +end while + +print "Type ""ins"" for instructions" +print "Type ""max"" for approximate maximum speeds" +print "Type ""run"" for the beginning of the race" +while true + cmd = input("Command--").lower + if cmd == "ins" then + print + print "*** Slalom: This is the 1976 Winter Olympic Giant Slalom. You are" + print " the American team's only hope of a gold medal." + print + print " 0 -- type this if you want to see how long you've taken." + print " 1 -- type this if you want to speed up a lot." + print " 2 -- type this if you want to speed up a little." + print " 3 -- type this if you want to speed up a teensy." + print " 4 -- type this if you want to keep going the same speed." + print " 5 -- type this if you want to check a teensy." + print " 6 -- type this if you want to check a little." + print " 7 -- type this if you want to check a lot." + print " 8 -- type this if you want to cheat and try to skip a gate." + print + print " The place to use these options is when the computer asks:" + print + print "Option?" + print + print " Good luck!" + print + else if cmd == "max" then + print "GATE MAX" + print " # M.P.H." + print "-----------" + for i in range(1, qtyGates) + print " " + i + " "*(i<10) + " " + gateSpeeds[i-1] + end for + else if cmd == "run" then + break + end if +end while + +while true + skill = input("Rate yourself as a skier, (1=worst, 3=best)? ").val + if 1 <= skill <= 3 then break + print "The bounds are 1-3" +end while + +doOneRace = function + print "The starter counts down...5...4...3...2...1..GO!" + time = 0 + speed = floor(rnd * 9 + 9) + print + print "You're off!" + gate = 0 + while gate+1 <= qtyGates + gate += 1 + gateSpeed = gateSpeeds[(gate-1) % gateSpeeds.len] + print + print "Here comes gate #" + gate + ":" + print speed + " M.P.H." + prevSpeed = speed + while true + opt = input("Option? ").val + if opt == 0 then + print "You've taken " + time + " seconds." + else if opt < 1 or opt > 8 then + print "What?" + else + break + end if + end while + if opt == 1 then + speed += floor(rnd*(10-5)+5) + else if opt == 2 then + speed += floor(rnd*(5-3)+3) + else if opt == 3 then + speed += floor(rnd*(4-1)+1) + else if opt == 4 then + // (no change) + else if opt == 5 then + speed -= floor(rnd*(4-1)+1) + else if opt == 6 then + speed -= floor(rnd*(5-3)+3) + else if opt == 7 then + speed -= floor(rnd*(10-5)+5) + else if opt == 8 then + print "***CHEAT" + if rnd < 0.7 then + print "An official caught you!" + print "You took " + round(time+rnd, 3) + " seconds." + break + else + print "You made it!" + char(7) + time += 1.5 + continue + end if + end if + print speed + " M.P.H." + if speed > gateSpeed then + if rnd < (speed - gateSpeed)*0.1 + 0.2 then + msg = "You went over the maximum speed and " + if rnd < 0.5 then msg += "snagged a flag!" else msg += "wiped out!" + print msg + print "You took " + round(time+rnd, 3) + " seconds." + else + print "You went over the maximum speed and made it!" + end if + else if speed > gateSpeed - 1 then + print "Close one!" + end if + if speed < 7 then + print "Let's be realistic, OK? Let's go back and try again..." + speed = prevSpeed + gate -= 1 + continue + end if + time += gateSpeed - speed + 1 + if speed > gateSpeed then time += 0.5 + end while + + print + print "You took " + round(time+rnd, 3) + " seconds." + avg = time / qtyGates + if avg < 1.5 - (skill * 0.1) then + print "You won a gold medal!" + medals.gold += 1 + else if avg < 2.9 - (skill * 0.1) then + print "You won a silver medal" + medals.silver += 1 + else if avg < 4.4 - (skill * 0.01) then + print "You won a bronze medal" + medals.bronze += 1 + end if +end function + +while true + doOneRace + while true + yesno = input("Do you want to race again? ").lower + " " + if yesno[0] == "y" or yesno[0] == "n" then break + print "Please type 'yes' or 'no'" + end while + if yesno[0] == "n" then break + print +end while + +print +print "Thanks for the race" +if medals.gold then print "Gold medals: " + medals.gold +if medals.silver then print "Silver medals: " + medals.silver +if medals.bronze then print "Bronze medals: " + medals.bronze diff --git a/00_Alternate_Languages/79_Slalom/slalom.bas b/00_Alternate_Languages/79_Slalom/slalom.bas index b46cc39be..47c6d8010 100644 --- a/00_Alternate_Languages/79_Slalom/slalom.bas +++ b/00_Alternate_Languages/79_Slalom/slalom.bas @@ -58,7 +58,7 @@ 825 PRINT "*** SLALOM: THIS IS THE 1976 WINTER OLYMPIC GIANT SLALOM. YOU ARE" 830 PRINT " THE AMERICAN TEAM'S ONLY HOPE OF A GOLD MEDAL." 840 PRINT -845 PRINT " 0 -- TYPE THIS IS YOU WANT TO SEE HOW LONG YOU'VE TAKEN." +845 PRINT " 0 -- TYPE THIS IF YOU WANT TO SEE HOW LONG YOU'VE TAKEN." 850 PRINT " 1 -- TYPE THIS IF YOU WANT TO SPEED UP A LOT." 860 PRINT " 2 -- TYPE THIS IF YOU WANT TO SPEED UP A LITTLE." 870 PRINT " 3 -- TYPE THIS IF YOU WANT TO SPEED UP A TEENSY." diff --git a/79_Slalom/README.md b/79_Slalom/README.md index 8c45820c0..c95309ceb 100644 --- a/79_Slalom/README.md +++ b/79_Slalom/README.md @@ -15,8 +15,10 @@ As published in Basic Computer Games (1978): Downloaded from Vintage Basic at http://www.vintage-basic.net/games.html -#### Porting Notes +#### Known Bugs + +- In the original version, the data pointer doesn't reset after a race is completed. This causes subsequent races to error at some future point at line 540, `READ Q'. -In the original version, the data pointer doesn't reset after a race is completed. This causes subsequent races to error at some future point at line 540, +- It also doesn't restore the data pointer after executing the MAX command to see the gate speeds, meaning that if you use this command, it effectively skips those gates, and the speeds shown are completely incorrect. - 540 READ Q +#### Porting Notes diff --git a/79_Slalom/slalom.bas b/79_Slalom/slalom.bas index b46cc39be..47c6d8010 100644 --- a/79_Slalom/slalom.bas +++ b/79_Slalom/slalom.bas @@ -58,7 +58,7 @@ 825 PRINT "*** SLALOM: THIS IS THE 1976 WINTER OLYMPIC GIANT SLALOM. YOU ARE" 830 PRINT " THE AMERICAN TEAM'S ONLY HOPE OF A GOLD MEDAL." 840 PRINT -845 PRINT " 0 -- TYPE THIS IS YOU WANT TO SEE HOW LONG YOU'VE TAKEN." +845 PRINT " 0 -- TYPE THIS IF YOU WANT TO SEE HOW LONG YOU'VE TAKEN." 850 PRINT " 1 -- TYPE THIS IF YOU WANT TO SPEED UP A LOT." 860 PRINT " 2 -- TYPE THIS IF YOU WANT TO SPEED UP A LITTLE." 870 PRINT " 3 -- TYPE THIS IF YOU WANT TO SPEED UP A TEENSY."