Basics of Arturo
Priskribo de la ĉi-paĝa enhavo
Konverto de malnovaj BASIC-programoj al Arturo por lerni la fundamentojn de ĉi-tiu lingvo.
Etikedoj:
3D Plot
; 3D Plot
; Original version in BASIC:
; 3-D Plot (by Mark Bramhall), 1978.
; Creative Computing's BASIC Games.
; - http://vintage-basic.net/games.html
; - http://vintage-basic.net/bcg/3dplot.bas
; - https://www.atariarchives.org/basicgames/showpage.php?page=167
; This version in Arturo:
; Copyright (c) 2023, Marcos Cruz (programandala.net)
; SPDX-License-Identifier: Fair
;
; Written on 2023-10-17.
;
; Last modified: 20251205T0043+0100.
SPACE: ` `
DOT: `*`
WIDTH: 56
; Display the credits and wait for a keypress.
printCredits: function [] [
print "3D Plot\n"
print "Original version in BASIC:"
print " Creative computing (Morristown, New Jersey, USA), ca. 1980.\n"
print "This version in Arturo:"
print " Copyright (c) 2023, Marcos Cruz (programandala.net)"
print " SPDX-License-Identifier: Fair\n"
input "Press Enter to start the program."
]
a: function [z] [
mul 30 exp div (mul neg z z) 100
]
draw: function [] [
x: neg 30
while [not? greater? x 30] [
line: array.of: WIDTH SPACE
l: 0
y1: mul 5 floor div sqrt(sub 900 (mul x x)) 5
loop y1 .. (neg y1) .step: 5 'y [
z: floor (add 25 sub a(sqrt(add mul x x mul y y)) (mul 0.7 y))
if greater? z l [
l: z
line\[z]: DOT
]
] ; y loop
loop 0 .. (sub WIDTH 1) 'pos [
prints line\[pos]
]
print ""
add 'x 1.5
] ; x loop
]
clear
printCredits
clear
draw
Bagels
; Bagels
; Original version in BASIC:
; D. Resek, P. Rowe, 1978.
; Creative Computing's BASIC Games.
; - http://vintage-basic.net/games.html
; - http://vintage-basic.net/bcg/bagels.bas
; - http://www.atariarchives.org/basicgames/showpage.php?page=9
; This version in Arturo:
; Copyright (c) 2023, Marcos Cruz (programandala.net)
; SPDX-License-Identifier: Fair
;
; Written on 2023-10-19.
;
; Last modified: 20251205T0044+0100.
; Clear the screen, print the credits and wait for a keypress.
printCredits: function [] [
clear
print "Bagels"
print "Number guessing game\n"
print "Original source unknown but suspected to be:"
print " Lawrence Hall of Science, U.C. Berkely.\n"
print "Original version in BASIC:"
print " D. Resek, P. Rowe, 1978."
print " Creative computing (Morristown, New Jersey, USA), 1978.\n"
print "This version in Arturo:"
print " Copyright (c) 2023, Marcos Cruz (programandala.net)"
print " SPDX-License-Identifier: Fair\n"
input "Press Enter to read the instructions. "
]
; Clear the screen, print the instructions and wait for a keypress.
printInstructions: function [] [
clear
print "Bagels"
print "Number guessing game\n"
print "I am thinking of a three-digit number that has no two digits the same."
print "Try to guess it and I will give you clues as follows:\n"
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\n"
input "Press Enter to start. "
]
DIGITS: 3
randomDigit: array [0 0 0]
; Return an integer array with random digits.
randomNumber: function [] [
number: array []
while [ less? size number DIGITS ] [
digit: random 0 9
if not? contains? number digit [
append 'number digit
]
]
number
]
; Print the given prompt and get a three-digit number from the user.
userInput: function [prompt] [
userDigit: array []
while [ less? size userDigit DIGITS ] [
inputString: input prompt
if? less? size inputString DIGITS [
print ~"Remember it's a |DIGITS|-digit number."
] else [
empty 'userDigit
loop inputString 'char [
if? contains? "0123456789" char [
digit: to :integer to :string char
if? contains? userDigit digit [
print "Remember my number has no two digits the same."
break
] else [
append 'userDigit digit
]
] else [
print "What?"
break
]
]
]
]
userDigit
]
; Return `true` if the given string is "yes" or a synonym.
isYes: function [answer] [
contains? ["ok", "yeah", "yes", "y"] answer
]
; Return `true` if the given string is "no" or a synonym.
isNo: function [answer] [
contains? ["no", "nope", "n"] answer
]
; Print the given prompt, wait until the user enters a valid yes/no
; string, and return `true` for "yes" or `false` for "no".
yes: function [prompt] [
answer: ""
while [ not? or? isYes answer isNo answer ] [ answer: input prompt ]
isYes answer
]
; Init and run the game loop.
play: function [] [
maxTries: 20
score: 0
while [ true ] [
clear
computerNumber: randomNumber
print "O.K. I have a number in mind."
loop range 1 maxTries [ 'guess ] [
userNumber: userInput(~"Guess #|pad .with:`0` to :string guess 2 |: ")
fermi: 0
pico: 0
loop range 0 sub DIGITS 1 [ 'i ] [
loop range 0 sub DIGITS 1 [ 'j ] [
if equal? userNumber\[i] computerNumber\[j] [
if? equal? i j [ add 'fermi 1 ]
else [ add 'pico 1 ]
]
]
]
prints repeat "PICO " pico
prints repeat "FERMI " fermi
if equal? add pico fermi 0 [ prints "BAGELS" ]
print ""
if equal? fermi DIGITS [ break ]
]
if? equal? fermi DIGITS [
print "You got it!!!"
inc score
] else [
print "Oh well."
prints ~"That's |maxTries| guesses. My number was "
loop range 0 sub DIGITS 1 [ 'i ] [ prints computerNumber\[i] ]
print "."
]
if not? yes("Play again? ") [ break ]
]
if notEqual? score 0 [
print ~"A |score|-point bagels, buff!!"
]
print "Hope you had fun. Bye."
]
printCredits
printInstructions
play
Bug
; Bug
; Original version in BASIC:
; Brian Leibowitz, 1978.
; Creative Computing's BASIC Games.
; - http://vintage-basic.net/games.html
; - http://vintage-basic.net/bcg/bug.bas
; - https://www.atariarchives.org/basicgames/showpage.php?page=30
; - http://www.retroarchive.org/cpm/games/ccgames.zip
; This version in Arturo:
; Copyright (c) 2023, Marcos Cruz (programandala.net)
; SPDX-License-Identifier: Fair
;
; Written in 2023-10.
;
; Last modified: 20251205T0045+0100.
bugRecord: dictionary [
body: false
neck: false
head: false
feelers: 0
feelerType: ' '
tail: false
legs: 0
]
playerRecord: dictionary [
pronoun: ""
possessive: ""
bug: bugRecord
]
; Players.
computer: new playerRecord
computer\bug: new bugRecord
human: new playerRecord
human\bug: new bugRecord
; Bug body parts.
partNumber: dictionary [
body: 1
neck: 2
head: 3
feeler: 4
tail: 5
leg: 6
]
partName: array [
""
"body"
"neck"
"head"
"feeler"
"tail"
"leg"
]
; Bug body attributes.
bodyHeight: 2
feelerLength: 4
legLength: 2
maxFeelers: 2
maxLegs: 6
neckLength: 2
; Move the cursor up by the given number of rows (defaults to 1), without
; changing the column position.
cursorUp: function [ rows ] [
prints render "\e[|rows|A"
]
; Erase the current line, without moving the cursor position.
eraseLine: function [ ] [
prints "\e[2K"
]
; Move the cursor to the previous row, without changing the column position,
; and erase its line.
erasePreviousLine: function [ ] [
cursorUp 1
eraseLine
]
; Clear the screen, display the credits and wait for a keypress.
printCredits: function [ ] [
clear
print "Bug\n"
print "Original version in BASIC:"
print " Brian Leibowitz, 1978."
print " Creative computing (Morristown, New Jersey, USA), 1978.\n"
print "This version in Arturo:"
print " Copyright (c) 2023, Marcos Cruz (programandala.net)"
print " SPDX-License-Identifier: Fair\n"
input "Press Enter to read the instructions. "
]
instructions: {:
The object is to finish your bug before I finish mine. Each number
stands for a part of the bug body.
I will roll the die for you, tell you what I rolled for you, what the
number stands for, and if you can get the part. If you can get the
part I will give it to you. The same will happen on my turn.
If there is a change in either bug I will give you the option of
seeing the pictures of the bugs. The numbers stand for parts as
follows:
:}
; Capitalize the first character of `s` and convert the rest of `s` to
; lowercase.
toCapital: function [ s ] [
capitalize lower s
]
; ; Print a table with the bug parts' description.
printPartsTable: function [ ] [
columns: 3
columnWidth: 8
columnSeparation: 2
; Headers
header: [ "Number" "Part" "Quantity" ]
loop range 0 sub columns 1 'i [
prints pad .right header\[ i ] add columnWidth columnSeparation
]
print ""
; Rulers
loop range 1 columns 'i [
prints repeat "-" columnWidth
if? less? i columns [ prints repeat " " columnSeparation ]
]
print ""
; Data
partQuantity: array .of: add size partNumber 1 0
partQuantity\[ partNumber\body ]: 1
partQuantity\[ partNumber\neck ]: 1
partQuantity\[ partNumber\head ]: 1
partQuantity\[ partNumber\feeler ]: 2
partQuantity\[ partNumber\tail ]: 1
partQuantity\[ partNumber\leg ]: 6
loop range partNumber\body partNumber\leg 'part [
prints pad .right to :string part add columnWidth columnSeparation
prints pad .right toCapital partName\[part] add columnWidth columnSeparation
print partQuantity\[ part ]
]
]
; Clear the screen, print the instructions and wait for a keypress.
printInstructions: function [ ] [
clear
print "Bug"
print instructions
printPartsTable
input "\nPress Enter to start. "
]
; Print a bug head.
printHead: function [ ] [
print " HHHHHHH"
print " H H"
print " H O O H"
print " H H"
print " H V H"
print " HHHHHHH"
]
; Print the given bug.
printBug: function [ bug ] [
if greater? bug\feelers 0 [
loop range 0 sub feelerLength 1 'i [
prints " "
loop range 0 sub bug\feelers 1 'j [
prints render " |bug\feelerType|"
]
print ""
]
]
if bug\head [
printHead
]
if bug\neck [
loop range 0 sub neckLength 1 'i [
print " N N"
]
]
if bug\body [
print " BBBBBBBBBBBB"
loop range 0 sub bodyHeight 1 'i [
print " B B"
]
if bug\tail [
print "TTTTTB B"
]
print " BBBBBBBBBBBB"
]
if greater? bug\legs 0 [
loop range 0 sub legLength 1 'i [
prints " "
loop range 0 sub bug\legs 1 'j [
prints " L"
]
print ""
]
]
print ""
]
; Return `true` if the given bug is finished; otherwise return `false`.
isFinished?: function [ bug ] [
and?
and?
equal? bug\feelers maxFeelers
bug\tail
equal? bug\legs maxLegs
]
; Return a random number from 1 to 6 (inclusive).
dice: function [ ] [
random 1 6
]
; Array to convert a number to its equilavent text.
asText: [ "no" "a" "two" "three" "four" "five" "six" ]
; Return the proper plural ending depending of the given number.
pluralEnding: function [ n ] [
if? greater? n 1 [ "s" ] else [ "" ]
]
; Return a string containing the given number and noun in their proper form.
plural: function [ noun number ] [
render "|asText\[number]| |noun||pluralEnding number|"
]
; Add the given part to the given player's bug.
addPart: function [ part player ] [
changed: false
case [ part ]
when? [ equal? partNumber\body ] [
if? player\bug\body [
print render ", but |player\pronoun| already have a body."
] else [
print render "; |player\pronoun| now have a body:"
player\bug\body: true
changed: true
]
]
when? [ equal? partNumber\neck ] [
if? player\bug\neck [
print render ", but |player\pronoun| you already have a neck."
] else [
if? not? player\bug\body [
print render ", but |player\pronoun| need a body first."
] else [
print render "; |player\pronoun| now have a neck:"
player\bug\neck: true
changed: true
]
]
]
when? [ equal? partNumber\head ] [
if? player\bug\head [
print render ", but |player\pronoun| already have a head."
] else [
if? not? player\bug\neck [
print render ", but |player\pronoun| need a a neck first."
] else [
print render "; |player\pronoun| now have a head:"
player\bug\head: true
changed: true
]
]
]
when? [ equal? partNumber\feeler ] [
if? equal? player\bug\feelers maxFeelers [
print render ", but |player\pronoun| have two feelers already."
] else [
if? not? player\bug\head [
print render ", but |player\pronoun| need a head first."
] else [
player\bug\feelers: player\bug\feelers + 1
prints render "; |player\pronoun| now have "
prints plural "feeler" player\bug\feelers
print ":"
changed: true
]
]
]
when? [ equal? partNumber\tail ] [
if? player\bug\tail [
print render ", but |player\pronoun| already have a tail."
] else [
if? not? player\bug\body [
print render ", but |player\pronoun| need a body first."
] else [
print render "; |player\pronoun| now have a tail:"
player\bug\tail: true
changed: true
]
]
]
when? [ equal? partNumber\leg ] [
if? equal? player\bug\legs maxLegs [
print render ", but |player\pronoun| have |asText\[maxLegs]| feet already."
] else [
if? not? player\bug\body [
print render ", but |player\pronoun| need a body first."
] else [
player\bug\legs: player\bug\legs + 1
prints render "; |player\pronoun| now have "
prints plural "leg" player\bug\legs
print ":"
changed: true
]
]
]
else [ ]
changed
]
; Ask the user to press the Enter key, wait for the input, then erase the
; prompt text.
prompt: function [ ] [
input "Press Enter to roll the dice. "
erasePreviousLine
]
; Play one turn for the given player, rolling the dice and updating his bug.
turn: function [ player ] [
prompt
number: dice
prints render "|toCapital player\pronoun| rolled a |number| (|partName\[number]|)"
if addPart number player [
print ""
printBug player\bug
]
]
; Return `true` if both bugs are finished, otherwise return `false`.
tie?: function [ ] [
and? isFinished? human\bug isFinished? computer\bug
]
; Print a message about the winner.
printWinner: function [ ] [
if? tie? [
print "Both of our bugs are finished in the same number of turns!"
] else [
if? isFinished? human\bug [ prints human\possessive ]
else [ prints computer\possessive ]
print " bug is finished."
]
]
; Return `true` if any bug is finished; otherwise return `false`.
gameOver?: function [ ] [
or? isFinished? human\bug isFinished? computer\bug
]
; Execute the game loop.
play: function [ ] [
clear
until [
turn human
turn computer
] [ gameOver? ]
printWinner
]
; Init the players' data before a new game.
init: function [ ] [
human\pronoun: "you"
human\possessive: "Your"
human\bug\feelerType: 'A'
computer\pronoun: "I"
computer\possessive: "My"
computer\bug\feelerType: 'F'
]
init
printCredits
printInstructions
play
print "I hope you enjoyed the game, play it again soon!!"
Bunny
; Bunny
; Original version in BASIC:
; Anonymous, 1978.
; Creative Computing's BASIC Games.
; - http://vintage-basic.net/games.html
; - http://vintage-basic.net/bcg/bunny.bas
; - http://www.retroarchive.org/cpm/games/ccgames.zip
; This version in Arturo:
; Copyright (c) 2023, Marcos Cruz (programandala.net)
; SPDX-License-Identifier: Fair
;
; Written on 2023-10-17.
;
; Last modified: 20251205T0046+0100.
printCredits: function [] [
print "Bunny\n"
print "Original version in BASIC:"
print " Creative Computing (Morristown, New Jersey, USA), 1978.\n"
print "This version in Arturo:"
print " Copyright (c) 2023, Marcos Cruz (programandala.net)"
print " SPDX-License-Identifier: Fair\n"
input "Press Enter to start the program. "
]
SPACE: ` `
WIDTH: 53
; Line buffer.
line: array.of: WIDTH SPACE
letter: array [`B` `U` `N` `N` `Y`]
letters: size letter
; End of line identifier.
EOL: neg 1
data: array [
1, 2, EOL, 0, 2, 45, 50, EOL, 0, 5, 43, 52, EOL, 0, 7, 41, 52, EOL,
1, 9, 37, 50, EOL, 2, 11, 36, 50, EOL, 3, 13, 34, 49, EOL, 4, 14,
32, 48, EOL, 5, 15, 31, 47, EOL, 6, 16, 30, 45, EOL, 7, 17, 29, 44,
EOL, 8, 19, 28, 43, EOL, 9, 20, 27, 41, EOL, 10, 21, 26, 40, EOL,
11, 22, 25, 38, EOL, 12, 22, 24, 36, EOL, 13, 34, EOL, 14, 33, EOL,
15, 31, EOL, 17, 29, EOL, 18, 27, EOL, 19, 26, EOL, 16, 28, EOL,
13, 30, EOL, 11, 31, EOL, 10, 32, EOL, 8, 33, EOL, 7, 34, EOL, 6,
13, 16, 34, EOL, 5, 12, 16, 35, EOL, 4, 12, 16, 35, EOL, 3, 12, 15,
35, EOL, 2, 35, EOL, 1, 35, EOL, 2, 34, EOL, 3, 34, EOL, 4, 33,
EOL, 6, 33, EOL, 10, 32, 34, 34, EOL, 14, 17, 19, 25, 28, 31, 35,
35, EOL, 15, 19, 23, 30, 36, 36, EOL, 14, 18, 21, 21, 24, 30, 37, 37,
EOL, 13, 18, 23, 29, 33, 38, EOL, 12, 29, 31, 33, EOL, 11, 13, 17,
17, 19, 19, 22, 22, 24, 31, EOL, 10, 11, 17, 18, 22, 22, 24, 24, 29,
29, EOL, 22, 23, 26, 29, EOL, 27, 29, EOL, 28, 29, EOL ]
dataSize: size data
; Index of the current datum in the `data` array.
dataIndex: 0
; Retun the current datum.
datum: function [] [
add 'dataIndex 1
return data\[sub dataIndex 1]
]
; Draw the graphic out of `data` and `letter`.
draw: function [] [
while [ less? dataIndex dataSize ] [
firstColumn: datum
if? equal? firstColumn EOL [
loop 0 .. (sub WIDTH 1) 'pos [
prints line\[pos]
]
print ""
'line: array.of: WIDTH SPACE
] else [
lastColumn: datum
loop firstColumn .. lastColumn 'column [
line\[column]: letter\[mod column letters]
]
]
]
]
clear
printCredits
clear
draw
Diamond
; Diamond
; Original version in BASIC:
; Example included in Vintage BASIC 1.0.3.
; http://www.vintage-basic.net
; This version in Arturo:
; Copyright (c) 2023, Marcos Cruz (programandala.net)
; SPDX-License-Identifier: Fair
;
; Written in 2023-10-16/17.
;
; Last modified: 20251205T0054+0100.
lines: 17
; Print a star.
printStar: function[][ print `*` ]
; Print the diamond top part, _i_ lines high.
diamondTop: function[i][
loop 1 .. (((lines + 1) / 2) - i) + 1 'j [ prints " " ]
loop 1 .. (i * 2) - 1 'j [ prints "*" ]
print ""
]
; Print the diamond bottom part, _i_ lines high.
diamondBottom: function[i][
loop 1 .. i + 1 'j [ prints " " ]
loop 1 .. ((((lines + 1) / 2) - i) * 2) - 1 'j [ prints "*" ]
print ""
]
loop 1 .. (lines / 2) + 1 'i [ diamondTop i ]
loop 1 .. lines / 2 'i [ diamondBottom i ]
Math
; Math
; Original version in BASIC:
; Example included in Vintage BASIC 1.0.3.
; http://www.vintage-basic.net
; This version in Arturo:
; Copyright (c) 2023, Marcos Cruz (programandala.net)
; SPDX-License-Identifier: Fair
;
; Written on 2023-10-18.
;
; Last modified: 20251205T0047+0100.
until [
s: input "Enter a number: "
dup numeric? s else [ print "Number expected. Retry." ]
] []
n: to :floating s
print ~"ABS(|n|) -> abs |n| -> |abs n|"
print ~"ATN(|n|) -> atan |n| -> |atan n|"
print ~"COS(|n|) -> cos |n| -> |cos n|"
print ~"EXP(|n|) -> exp |n| -> |exp n|"
print ~"INT(|n|) -> floor |n| -> |floor n|"
print ~"LOG(|n|) -> ln |n| -> |ln n|"
print ~"SGN(|n|) -> if? less? |n| 0 [neg 1] else [1] -> |if? less? n 0 [neg 1] else [1]|"
print ~"SQR(|n|) -> sqrt |n| -> |sqrt n|"
print ~"TAN(|n|) -> tan |n| -> |tan n|"
Mugwump
; Mugwump
; Original version in BASIC:
; Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA), 1978.
; Slightly modified by Bob Albrecht of People's Computer Company.
; Creative Computing's BASIC Games.
; - https://www.atariarchives.org/basicgames/showpage.php?page=114
; - http://vintage-basic.net/games.html
; This version in Arturo:
; Copyright (c) 2023, Marcos Cruz (programandala.net)
; SPDX-License-Identifier: Fair
;
; Written in 2023-10-19/21
;
; Last modified: 20251205T0047+0100.
; Constants
let 'gridSize 10
let 'firstCoord 0
let 'lastCoord sub gridSize 1
let 'maxTurns 10
let 'mugwumps 4
let 'firstMugwump 0
let 'lastMugwump sub mugwumps 1
; Arrays
let 'mugwumpX array .of: mugwumps 0
let 'mugwumpY array .of: mugwumps 0
let 'mugwumpHidden array .of: mugwumps false
; Variables
let 'found 0 ; counter
; Print the given prompt, wait until the user enters a valid integer
; and return it.
getNumber: function [prompt] [
until [
try? [ let 'number to :integer input prompt ]
] []
number
]
; Return `true` if the given string is "yes" or a synonym.
isYes: function [answer] [
contains? ["ok", "yeah", "yes", "y"] answer
]
; Return `true` if the given string is "no" or a synonym.
isNo: function [answer] [
contains? ["no", "nope", "n"] answer
]
; Print the given prompt, wait until the user enters a valid yes/no
; string, and return `true` for "yes" or `false` for "no".
yes: function [prompt] [
until
[ let 'answer input prompt ]
[ or?
isYes answer
isNo answer
]
isYes answer
]
; Clear the screen, print the credits and ask the user to press enter.
printCredits: function [] [
clear
print "Mugwump\n"
print "Original version in BASIC:"
print " Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA)."
print " Slightly modified by Bob Albrecht of People's Computer Company."
print " Published by Creative Computing (Morristown, New Jersey, USA), 1978."
print " - https://www.atariarchives.org/basicgames/showpage.php?page=114"
print " - http://vintage-basic.net/games.html\n"
print "This version in Arturo:"
print " Copyright (c) 2023, Marcos Cruz (programandala.net)"
print " SPDX-License-Identifier: Fair\n"
input "Press Enter to read the instructions. "
]
; Clear the screen, print the instructions and ask the user to press enter.
printInstructions: function [] [
clear
print "Mugwump\n"
print render "The object of this game is to find |mugwumps| mugwumps"
print render "hidden on a |gridSize| by |gridSize| grid. Homebase is position |firstCoord|,|firstCoord|."
print "Any guess you make must be two numbers with each"
print render "number between |firstCoord| and |lastCoord|, inclusive. First number"
print "is distance to right of homebase and second number"
print "is distance above homebase.\n"
print render "You get |maxTurns| tries. After each try, you will see"
print "how far you are from each mugwump.\n"
input "Press Enter to start. "
]
; Init the mugwumps' positions, `hidden` flags and count.
hideMugwumps: function [] [
loop range firstMugwump lastMugwump 'm [
mugwumpX\[m]: random firstCoord lastCoord
mugwumpY\[m]: random firstCoord lastCoord
mugwumpHidden\[m]: true
]
let 'found 0 ; counter
]
; Print the given prompt, wait until the user enters a valid coord
; and return it.
getCoord: function [prompt] [
while [ true ] [
let 'coord getNumber prompt
if contains? range firstCoord lastCoord coord [ return coord ]
print render "Invalid value |coord|: not in range [|firstCoord|, |lastCoord|]."
]
]
; Return `true` if the given mugwump is hidden in the given coords.
isThere?: function [m x y] [
and?
mugwumpHidden\[m]
and?
equal? mugwumpX\[m] x
equal? mugwumpY\[m] y
]
; Return the distance between the given mugwump and the given coords.
distance: function [m x y] [
to
:integer
round
sqrt
add
pow sub mugwumpX\[m] x 2
pow sub mugwumpY\[m] y 2
]
; Return the given plural or singular ending depending of the given number.
plural: function [n pluralSuffix singularSuffix] [
if? greater? n 1 [ pluralSuffix ] else [ singularSuffix ]
]
; Run the game.
play: function [] [
until [ ; game loop
clear
hideMugwumps
loop range 1 maxTurns 'turn [ ; turns loop
print render "Turn number |turn|\n"
print render "What is your guess (in range [|firstCoord|, |lastCoord|])?"
let 'x getCoord "Distance right of homebase (x-axis): "
let 'y getCoord "Distance above homebase (y-axis): "
print render "\nYour guess is (|x|, |y|)."
loop range firstMugwump lastMugwump 'm [
if isThere? m x y [
mugwumpHidden\[m]: false
inc 'found
print render "You have found mugwump |add m 1|!"
if equal? found mugwumps [ break ]
]
]
if equal? found mugwumps [ break ] ; exit the turns loop
loop range firstMugwump lastMugwump 'm [
if mugwumpHidden\[m] [
print render "You are |distance m y y| units from mugwump |add m 1|."
]
]
print ""
] ; turns loop
if? equal? found mugwumps [
print render "\nYou got them all in |turn| turn|plural turn {s} {}|!\n"
print "That was fun! let's play again…"
print render "|mugwumps| more mugwumps are now in hiding."
] else [
print render "\nSorry, that's |maxTurns| tr|plural maxTurns {ies} {y}|.\n"
print "Here is where they're hiding:"
loop range firstMugwump lastMugwump 'm [
if mugwumpHidden\[m] [
print render "Mugwump |add m 1| is at (|mugwumpX\[m]|, |mugwumpY\[m]|)."
]
]
]
print ""
] [ not? yes "Do you want to play again? " ] ; game loop
]
printCredits
printInstructions
play
Name
; Name
; Original version in BASIC:
; Example included in Vintage BASIC 1.0.3.
; http://www.vintage-basic.net
; This version in Arturo:
; Copyright (c) 2023, Marcos Cruz (programandala.net)
; SPDX-License-Identifier: Fair
;
; Written on 2023-10-19.
;
; Last modified: 20251205T0049+0100.
name: input "What is your name? "
until [
numberString: input "Enter a number: "
dup numeric? numberString else [ print "Number expected. Retry." ]
] []
number: floor to :floating numberString
loop range 1 number [] [ print ~"Hello, |name|" ]
Russian Roulette
; Russian Roulette
; Original version in BASIC:
; By Tom Adametx, 1978.
; Creative Computing's BASIC Games.
; - https://www.atariarchives.org/basicgames/showpage.php?page=141
; - http://vintage-basic.net/games.html
; - http://vintage-basic.net/bcg/russianroulette.bas
; - http://www.retroarchive.org/cpm/games/ccgames.zip
; This version in Arturo:
; Copyright (c) 2023, Marcos Cruz (programandala.net)
; SPDX-License-Identifier: Fair
;
; Written in 2023-10.
;
; Last modified: 20251205T0050+0100.
pressEnterToStart: function [] [
input "Press Enter to start. "
]
printCredits: function [] [
clear
print "Russian Roulette\n"
print "Original version in BASIC:"
print " Creative Computing (Morristown, New Jersey, USA), ca. 1980.\n"
print "This version in Arturo:"
print " Copyright (c) 2023, Marcos Cruz (programandala.net)"
print " SPDX-License-Identifier: Fair\n"
pressEnterToStart
]
printInstructions: function [] [
clear
print "Here is a revolver."
print "Type 'f' to spin chamber and pull trigger."
print "Type 'g' to give up, and play again."
print "Type 'q' to quit.\n"
]
play: function [] [
while [ true ] [ ; game loop
printInstructions
times: 0
while [ true ] [ ; play loop
action: input "> "
case [ action ]
when? [ equal? "f" ] [ ; fire
if? greater? random 0 99 83 [
print "Bang! You're dead!"
print "Condolences will be sent to your relatives."
break
] else [
inc 'times
if? greater? times 10 [
print "You win!"
print "Let someone else blow his brains out."
break
] else [
print "Click."
]
]
]
when? [ equal? "g" ] [ ; give up
print "Chicken!"
break
]
when? [ equal? "q" ] [ ; quit
return
]
else [ ]
] ; play loop
pressEnterToStart
] ; game loop
]
printCredits
play
print "Bye!"
Sine Wave
; Sine Wave
; Original version in BASIC:
; Anonymous, 1978.
; Creative Computing's BASIC Games.
; - https://www.atariarchives.org/basicgames/showpage.php?page=146
; - http://vintage-basic.net/games.html
; - http://vintage-basic.net/bcg/sinewave.bas
; - http://www.retroarchive.org/cpm/games/ccgames.zip
; This version in Arturo:
; Copyright (c) 2023, Marcos Cruz (programandala.net)
; SPDX-License-Identifier: Fair
;
; Written on 2023-10-17.
;
; Last modified: 20251205T0051+0100.
word: array ["" ""]
; Ask the user to enter two words and store them.
getWords: function [] [
order: array ["first" "second"]
loop 0 .. 1 'n [
word\[n]: input ~"Enter the |order\[n]| word: "
]
]
printCredits: function [] [
print "Sine Wave\n"
print "Original version in BASIC:"
print " Creative Computing (Morristown, New Jersey, USA), ca. 1980.\n"
print "This version in Arturo:"
print " Copyright (c) 2023, Marcos Cruz (programandala.net)"
print " SPDX-License-Identifier: Fair\n"
input "Press Enter to start the program. "
]
draw: function [] [
even: false
angle: 0
while [ lessOrEqual? angle 40 ] [
prints repeat " " floor add 26 mul 25 sin angle
print word\[to :integer even]
'even: not? even
add 'angle 0.25
]
]
clear
printCredits
clear
getWords
clear
draw
Slots
; Slots
; Original version in BASIC:
; By Fred Mirabelle and Bob Harper, 1973-01-29.
; Creative Computing's BASIC Games, 1978.
; - https://www.atariarchives.org/basicgames/showpage.php?page=149
; - http://vintage-basic.net/games.html
; - http://vintage-basic.net/bcg/slots.bas
; This version in Arturo:
; Copyright (c) 2023, Marcos Cruz (programandala.net)
; SPDX-License-Identifier: Fair
;
; Written in 2023-10.
;
; Last modified: 20251205T0052+0100.
image: array [ "BAR", "BELL", "ORANGE", "LEMON ", "PLUM", "CHERRY" ]
images: size image
firstImage: 0
lastImage: sub images 1
barPosition: firstImage
imageMaxSize: 0
loop image 'i [
if greater? size i imageMaxSize [ let 'imageMaxSize size i ]
]
reel: array [ 0 0 0 ]
reels: size reel
firstReel: 0
lastReel: sub reels 1
minBet: 1
maxBet: 100
printCredits: function [ ] [
clear
print "Slots"
print "A slot machine simulation.\n"
print "Original version in BASIC:"
print " Creative computing (Morristown, New Jersey, USA)."
print " Produced by Fred Mirabelle and Bob Harper on 1973-01-29.\n"
print "This version in Arturo:"
print " Copyright (c) 2023, Marcos Cruz (programandala.net)"
print " SPDX-License-Identifier: Fair\n"
input "Press Enter for instructions. "
]
printInstructions: function [ ] [
clear
print "You are in the H&M casino, in front of one of our"
print render "one-arm bandits. Bet from |minBet| to |maxBet| USD (or 0 to quit).\n"
input "Press Enter to start. "
]
won: function [ prize bet ] [
case [ prize ]
when? [ equal? 2 ] [ print "DOUBLE!" ]
when? [ equal? 5 ] [ print "*DOUBLE BAR*" ]
when? [ equal? 10 ] [ print "**TOP DOLLAR**" ]
when? [ equal? 100 ] [ print "***JACKPOT***" ]
else [ ]
print "You won!"
mul bet add prize 1
]
showStandings: function [ usd ] [
print render "Your standings are |usd| USD."
]
; Print the given image in its proper color.
printImage: function [ n ] [
img: render "[ |pad .center image\[n] imageMaxSize| ] "
case [ n ]
when? [ equal? 0 ] [ prints color #white img ]
when? [ equal? 1 ] [ prints color #cyan img ]
when? [ equal? 2 ] [ prints color #yellow img ]
when? [ equal? 3 ] [ prints color .bold #yellow img ]
when? [ equal? 4 ] [ prints color .bold #white img ]
when? [ equal? 5 ] [ prints color .bold #red img ]
else [ ]
]
; Print the reels.
printReels: function [ ] [
goto 0 0
loop reel 'n [ printImage n ]
print ""
]
; Init the reels with random images.
initReels: function [ ] [
loop .with: 'i reel [ ] [ set reel i random firstImage lastImage ]
]
turnReels: function [ ] [
initReels
printReels
]
; Return the seconds since the Unix epoch (1970-01-01 00:00:00 UTC).
epochSeconds: function [ ] [
to :integer now
]
spinReels: function [ ] [
durationInSeconds: 2
cursor false
let 'firstSecond epochSeconds
while [ less? sub epochSeconds firstSecond durationInSeconds ]
[ turnReels ]
cursor true
]
; Read an integer and return it; if the input is not a valid integer,
; return a zero instead.
inputInteger: function [ ] [
try? [ to :integer input "" ] else [ 0 ]
]
play: function [ ] [
standings: 0
equals: 0
betting: true
playing: true
initReels
while [ playing ] [ ; play loop
while [ and? playing betting ] [ ; bet loop
clear
printReels
prints "Your bet (or 0 to quit): "
bet: inputInteger
case [ bet ]
when? [ less? maxBet ] [
print render "House limits are |maxBet| USD."
input "Press Enter to try again. "
]
when? [ greater? minBet ] [
confirm: input "Type \"q\" to confirm you want to quit. "
if equal? confirm "q" [
; XXX TODO break
betting: false
playing: false
]
]
else [ betting: false ] ; XXX TODO break
] ; bet loop
if playing [
clear
spinReels
bars: 0
loop range firstReel lastReel 'i [
add 'bars to :integer equal? reel\[i] barPosition
]
case [ size unique reel ] ; number of different images
when? [ equal? 1 ] [
if? equal? bars 3 [ add 'standings won 100 bet ]
else [ add 'standings won 10 bet ]
]
when? [ equal? 2 ] [
if? equal? bars 2 [ add 'standings won 5 bet ]
else [ add 'standings won 2 bet ]
]
else [
print "You lost."
sub 'standings bet
]
showStandings standings
input "Press Enter to continue. "
betting: true
]
] ; play loop
showStandings standings
case [ standings ]
when? [ greater? 0 ] [
print "Pay up! Please leave your money on the terminal."
]
when? [ equal? 0 ] [
print "Hey, you broke even."
]
when? [ less? 0 ] [
print "Collect your winnings from the H&M cashier."
]
else [ ]
]
printCredits
printInstructions
play
Stars
; Stars
; Original version in BASIC:
; Example included in Vintage BASIC 1.0.3.
; http://www.vintage-basic.net
; This version in Arturo:
; Copyright (c) 2023, Marcos Cruz (programandala.net)
; SPDX-License-Identifier: Fair
;
; Written in 2023-10.
;
; Last modified: 20251205T0052+0100.
name: input "What is your name? "
print render "Hello, |name|."
while [ true ] [
until [
numberString: input "How many stars do you want? "
dup numeric? numberString else [ print "Number expected. Retry." ]
] []
number: floor to :floating numberString
print repeat "*" number
answer: input "Do you want more stars? "
if not? contains? [ "ok", "yeah", "yes", "y"] answer [ break ]
]
Strings
; Strings
; Original version in BASIC:
; Example included in Vintage BASIC 1.0.3.
; http://www.vintage-basic.net
; This version in Arturo:
; Copyright (c) 2023, Marcos Cruz (programandala.net)
; SPDX-License-Identifier: Fair
;
; Written on 2023-10-18.
;
; Last modified: 20251205T0053+0100.
space: " "
s: input "Enter a string: "
until [
dup try? [
n: to :integer input "Enter an integer: "
]
else [print "Integer expected. Retry."]
][]
print ""
prints ~"ASC(\"|s|\") --> "
prints ~"to :integer first \"|s|\" --> "
print to :integer first s
prints ~"CHR$(|n|) --> "
prints ~"to :string to :char |n| --> "
print to :string to :char n
prints ~"LEFT$(\"|s|\", |n|) --> "
prints ~"slice \"|s|\" 0 min range sub |n| 1 sub size \"|s|\" 1 --> "
print ~"\"|slice s 0 min range sub n 1 sub size s 1|\""
prints ~"MID$(\"|s|\", |n|) --> "
prints ~"slice \"|s|\" min range sub |n| 1 sub size \"|s|\" 1 sub size \"|s|\" 1 --> "
print ~"\"|slice s min range sub n 1 sub size s 1 sub size s 1|\""
prints ~"MID$(\"|s|\", |n|, 3) --> "
prints ~"slice \"s\" min range sub |n| 1 sub size \"|s|\" 1 min range add sub |n| 1 sub 3 1 sub size \"|s|\" 1 --> "
print ~"\"|slice s min range sub n 1 sub size s 1 min range add sub n 1 sub 3 1 sub size s 1|\""
prints ~"RIGHT$(\"|s|\", |n|) --> "
prints ~"slice \"|s|\" max range 0 sub size \"|s|\" |n| sub size \"|s|\" 1 --> "
print ~"\"|slice s max range 0 sub size s n sub size s 1|\""
prints ~"LEN(\"|s|\") --> "
prints ~"size \"|s|\" --> "
print size s
prints ~"VAL(\"|s|\") --> "
prints ~"if? numeric? \"|s|\" [to :floating \"|s|\"] else [0] --> "
print [ if? numeric? s [to :floating s] else [0] ]
prints ~"STR$(|n|) --> "
prints ~"to :string |n| --> "
print ~"\"|to :string n|\""
prints ~"SPC(|n|) --> "
prints ~"repeat \" \" |n| --> "
print ~"\"|repeat space n|\""
