Basics of Arturo

Description of the page content

Conversion of old BASIC programs to Arturo in order to learn the basics of this language.

Tags:

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|\""

Related pages

Basics off
Metaproject about the "Basics of…" projects.
Basics of 8th
Conversion of old BASIC programs to 8th in order to learn the basics of this language.
Basics of Ada
Conversion of old BASIC programs to Ada in order to learn the basics of this language.
Basics of C#
Conversion of old BASIC programs to C# in order to learn the basics of this language.
Basics of C3
Conversion of old BASIC programs to C3 in order to learn the basics of this language.
Basics of Chapel
Conversion of old BASIC programs to Chapel in order to learn the basics of this language.
Basics of Clojure
Conversion of old BASIC programs to Clojure in order to learn the basics of this language.
Basics of Crystal
Conversion of old BASIC programs to Crystal in order to learn the basics of this language.
Basics of D
Conversion of old BASIC programs to D in order to learn the basics of this language.
Basics of Elixir
Conversion of old BASIC programs to Elixir in order to learn the basics of this language.
Basics of F#
Conversion of old BASIC programs to F# in order to learn the basics of this language.
Basics of Factor
Conversion of old BASIC programs to Factor in order to learn the basics of this language.
Basics of FreeBASIC
Conversion of old BASIC programs to FreeBASIC in order to learn the basics of this language.
Basics of Gleam
Conversion of old BASIC programs to Gleam in order to learn the basics of this language.
Basics of Go
Conversion of old BASIC programs to Go in order to learn the basics of this language.
Basics of Hare
Conversion of old BASIC programs to Hare in order to learn the basics of this language.
Basics of Haxe
Conversion of old BASIC programs to Haxe in order to learn the basics of this language.
Basics of Icon
Conversion of old BASIC programs to Icon in order to learn the basics of this language.
Basics of Io
Conversion of old BASIC programs to Io in order to learn the basics of this language.
Basics of Janet
Conversion of old BASIC programs to Janet in order to learn the basics of this language.
Basics of Julia
Conversion of old BASIC programs to Julia in order to learn the basics of this language.
Basics of Kotlin
Conversion of old BASIC programs to Kotlin in order to learn the basics of this language.
Basics of Lobster
Conversion of old BASIC programs to Lobster in order to learn the basics of this language.
Basics of Lua
Conversion of old BASIC programs to Lua in order to learn the basics of this language.
Basics of Nature
Conversion of old BASIC programs to Nature in order to learn the basics of this language.
Basics of Neat
Conversion of old BASIC programs to Neat in order to learn the basics of this language.
Basics of Neko
Conversion of old BASIC programs to Neko in order to learn the basics of this language.
Basics of Nelua
Conversion of old BASIC programs to Nelua in order to learn the basics of this language.
Basics of Nim
Conversion of old BASIC programs to Nim in order to learn the basics of this language.
Basics of Nit
Conversion of old BASIC programs to Nit in order to learn the basics of this language.
Basics of Oberon-07
Conversion of old BASIC programs to Oberon-07 in order to learn the basics of this language.
Basics of OCaml
Conversion of old BASIC programs to OCaml in order to learn the basics of this language.
Basics of Odin
Conversion of old BASIC programs to Odin in order to learn the basics of this language.
Basics of Pike
Conversion of old BASIC programs to Pike in order to learn the basics of this language.
Basics of Pony
Conversion of old BASIC programs to Pony in order to learn the basics of this language.
Basics of Python
Conversion of old BASIC programs to Python in order to learn the basics of this language.
Basics of Racket
Conversion of old BASIC programs to Racket in order to learn the basics of this language.
Basics of Raku
Conversion of old BASIC programs to Raku in order to learn the basics of this language.
Basics of Retro
Conversion of old BASIC programs to Retro in order to learn the basics of this language.
Basics of Rexx
Conversion of old BASIC programs to Rexx in order to learn the basics of this language.
Basics of Ring
Conversion of old BASIC programs to Ring in order to learn the basics of this language.
Basics of Rust
Conversion of old BASIC programs to Rust in order to learn the basics of this language.
Basics of Scala
Conversion of old BASIC programs to Scala in order to learn the basics of this language.
Basics of Scheme
Conversion of old BASIC programs to Scheme in order to learn the basics of this language.
Basics of Styx
Conversion of old BASIC programs to Styx in order to learn the basics of this language.
Basics of Swift
Conversion of old BASIC programs to Swift in order to learn the basics of this language.
Basics of V
Conversion of old BASIC programs to V in order to learn the basics of this language.
Basics of Vala
Conversion of old BASIC programs to Vala in order to learn the basics of this language.
Basics of Zig
Conversion of old BASIC programs to Zig in order to learn the basics of this language.

External related links