Basics of Zen C

Descrition del contenete del págine

Conversion de old BASIC-programas a Zen C por aprender lu elementari de ti-ci lingue.

Etiquettes:

3D Plot

/*
3D Plot

Original version in BASIC:
    Creative Computing (Morristown, New Jersey, USA), ca. 1980.

This version in Zen C:
    Copyright (c) 2026, Marcos Cruz (programandala.net)
    SPDX-License-Identifier: Fair

Written on 2026-04-18.

Last modified 20260420T1758+0200.
*/

import "std/io.zc"
import "std/math.zc"

fn clear_screen() {
    print "\x1b[2J\x1b[0m\x1b[H"
}

fn print_credits() {
    println "3D Plot\n"
    println "Original version in BASIC:"
    println "    Creative computing (Morristown, New Jersey, USA), ca. 1980.\n"
    println "This version in Zen C:"
    println "    Copyright (c) 2026, Marcos Cruz (programandala.net)"
    println "    SPDX-License-Identifier: Fair\n"
    print "Press the Enter key to start. "
    read_rune()
}

fn a_(z: f64) -> f64 {
    return 30 * Math::exp(-z * z / 100)
}

fn draw() {
    let l: int
    let z: int
    let y1: int
    def WIDTH = 56
    let line: bool[WIDTH]
    for let x: f64 = -30.0; x <= 30.0; x += 1.5 {
        l = 0
        y1 = 5 * Math::floor(Math::sqrt(900.0 - x * x) / 5)
        for y in y1 ..= -y1 step -5 {
            z = 25 + a_(Math::sqrt(x * x + y * y)) - 0.7 * y
            if z > l {
                l = z
                line[z] = true
            }
        }
        for i in 0 ..< line.len {
            if line[i] {
                print "*"
                line[i] = false
            }
            else {
                print " "
            }
        }
        println ""
    }
}

fn main() {
    clear_screen()
    print_credits()
    clear_screen()
    draw()
}

Bagels

/*
Bagels

Original version in BASIC:
    D. Resek, P. Rowe, 1978.
    Creative Computing (Morristown, New Jersey, USA), 1978.

This version in Zen C:
    Copyright (c) 2026, Marcos Cruz (programandala.net)
    SPDX-License-Identifier: Fair

Written on 2026-04-20.

Last modified: 20260421T0015+0200.
*/

import "ctype.h" // tolower
import "std/random.zc"
import "std/utf8.zc"

def ANSI = "\x1B[" // code prefix

fn clear_screen() {
    print "{ANSI}2J{ANSI}0m{ANSI}H"
}

fn typed(prompt: string) -> string {
    print "{prompt}"
    return readln()
}

fn print_credits() {
    clear_screen()
    println "Bagels"
    println "Number guessing game\n"
    println "Original source unknown but suspected to be:"
    println "    Lawrence Hall of Science, U.C. Berkely.\n"
    println "Original version in BASIC:"
    println "    D. Resek, P. Rowe, 1978."
    println "    Creative computing (Morristown, New Jersey, USA), 1978.\n"
    println "This version in Zen C:"
    println "    Copyright (c) 2026, Marcos Cruz (programandala.net)"
    println "    SPDX-License-Identifier: Fair\n"
    typed("Press Enter to read the instructions. ")
}

fn print_instructions() {
    clear_screen()
    println "Bagels"
    println "Number guessing game\n"
    println "I am thinking of a three-digit number that has no two digits the same."
    println "Try to guess it and I will give you clues as follows:\n"
    println "   PICO   - one digit correct but in the wrong position"
    println "   FERMI  - one digit correct and in the right position"
    println "   BAGELS - no digits correct"
    typed("\nPress Enter to start. ")
}

def DIGITS = 3

fn is_any_repeated<T>(array: T[DIGITS]) -> bool {
    for i in 0 ..< DIGITS - 1 {
        for j in i + 1 ..< DIGITS {
            if array[i] == array[j] {
                return true
            }
        }
    }
    return false
}

// Print the given prompt and update the given array with a three-digit number
// from the user.

fn get_input(prompt: string, user_digit: int[DIGITS]) {
    asking:
    loop {
        let input: string = typed(prompt)
        if strlen(input) != DIGITS {
            println "Remember it's a {DIGITS}-digit number."
            continue asking
        }
        for i in 0 ..< DIGITS {
            if Utf8::is_digit(input[i]) {
                user_digit[i] = input[i] - '0'
            } else {
                println "What?"
                continue asking
            }
        }
        if is_any_repeated(user_digit) {
            println "Remember my number has no two digits the same."
            continue asking
        }
        break
    }
}

fn to_lowercase(s: string) -> string {
    for i in 0 .. strlen(s) {
        s[i] = tolower(s[i])
    }
    return s
}

fn is_yes(s: string) -> bool {
    match to_lowercase(s) {
        "ok", "y", "yeah", "yes" => { return true }
        _ => { return false }
    }
}

fn is_no(s: string) -> bool {
    match to_lowercase(s) {
        "n", "no", "nope" => { return true }
        _ => { return false }
    }
}

fn yes(prompt: string) -> bool {
    loop {
        let answer: string = typed(prompt)
        if is_yes(answer) {
            return true
        }
        if is_no(answer) {
            return false
        }
    }
}

fn randomize(digit: int[DIGITS]) {
    let rng = Random::new()
    for let i: int = 0; i < DIGITS; i += 1 {
        choose_digit:
        loop {
            digit[i] = rng.next_int_range(0, 9)
            for let j: int = 0; j < i; j += 1 {
                if i != j && digit[i] == digit[j] {
                    continue choose_digit
                }
            }
            break
        }
    }
}

fn play() {
    def TRIES = 20
    let score: int = 0
    let fermi: int = 0 // counter
    let pico: int = 0 // counter
    let user_number: int[DIGITS]
    loop {
        clear_screen()
        let computer_number: int[DIGITS]
        randomize(computer_number)
        println "O.K.  I have a number in mind."
        for let guess: int = 1; guess <= TRIES; guess += 1 {
            get_input("Guess #{guess:2}: ", user_number)
            fermi = 0
            pico = 0
            for i in 0 ..< DIGITS {
                for j in 0 ..< DIGITS {
                    if user_number[i] == computer_number[j] {
                        if i == j {
                            fermi += 1
                        } else {
                            pico += 1
                        }
                    }
                }
            }
            for _ in 0 ..< pico print "PICO "
            for _ in 0 ..< fermi print "FERMI "
            if pico + fermi == 0 {
                print "BAGELS"
            }
            println ""
            if fermi == DIGITS {
                break
            }
        }
        if fermi == DIGITS {
            println "You got it!!!"
            score += 1
        } else {
            println "Oh well."
            print "That's {TRIES} guesses.  My number was "
            for i in 0 ..< DIGITS {
                print "{computer_number[i]}"
            }
            println "."
        }
        if !yes("Play again? ") {
            break
        }
    }
    if score != 0 {
        println "A {score}-point bagels, buff!!"
    }
    println "Hope you had fun.  Bye."
}

fn main() {
    print_credits()
    print_instructions()
    play()
}

Diamond

/*
Diamond

Original version in BASIC:
    Example included in Vintage BASIC 1.0.3.
    http://www.vintage-basic.net

This version in Zen C:
    Copyright (c) 2026, Marcos Cruz (programandala.net)
    SPDX-License-Identifier: Fair

Written on 2026-04-18.

Last modified 20260420T1758+0200.
*/

def LINES = 17

fn main() {
    for i in 1 ..< LINES / 2 + 2 {
        for _ in 1 ..< (LINES + 1) / 2 - i + 2 {
            print " "
        }
        for _ in 1 ..< i * 2 {
            print "*"
        }
        println ""
    }
    for i in 1 ..< LINES / 2 + 1 {
        for _ in 0 ..< i + 1 {
            print " "
        }
        for _ in 1 ..< ((LINES + 1) / 2 - i) * 2 {
            print "*"
        }
        println ""
    }
}

Math

/*
Math

Original version in BASIC:
    Example included in Vintage BASIC 1.0.3.
    http://www.vintage-basic.net

This version in Zen C:
    Copyright (c) 2026, Marcos Cruz (programandala.net)
    SPDX-License-Identifier: Fair

Written on 2026-04-21.

Last modified: 20260421T1401+0200.
*/

import "std/math.zc"

fn sign(n: f64) -> f64 {
    return (n > 0) ? 1 : (n < 0) ? -1 : 0;
}

fn main() {
    let n: f64
    ? "Enter a number: " (n)
    println "ABS({n}) -> Math::abs({n}) -> {Math::abs(n)}"
    println "ATN({n}) -> Math::atan({n}) -> {Math::atan(n)}"
    println "COS({n}) -> Math::cos({n}) -> {Math::cos(n)}"
    println "EXP({n}) -> Math::exp({n}) -> {Math::exp(n)}"
    println "INT({n}) -> (int){n} -> {(int)n}"
    println "LOG({n}) -> Math::log({n}) -> {Math::log(n)}"
    println "SGN({n}) -> sign({n}) /* ad hoc function */ -> {sign(n)}"
    println "SQR({n}) -> Math::sqrt({n}) -> {Math::sqrt(n)}"
    println "TAN({n}) -> Math::tan({n}) -> {Math::tan(n)}"
}

Name

/*
Name

Original version in BASIC:
    Example included in Vintage BASIC 1.0.3.
    http://www.vintage-basic.net

This version in Zen C:
    Copyright (c) 2026, Marcos Cruz (programandala.net)
    SPDX-License-Identifier: Fair

Written on 2026-04-19/20.

Last modified: 20260420T2001+0200.
*/

fn typed(prompt: string) -> string {
    print "{prompt}"
    return readln()
}

fn typed_int(prompt: string) -> int {
    def NUMBER_BASE = 10
    def END_OF_STRING = '\0'
    loop {
        let input: string = typed(prompt)
        defer free(input)
        let end_pointer: string
        let number: int = strtol(input, &end_pointer, NUMBER_BASE)
        if *end_pointer != END_OF_STRING {
            println "Number expected."
        } else {
            return number
        }
    }
}

fn main() {
    let name: string = typed("What is your name? ")
    defer free(name)
    let number: int = typed_int("Enter a number: ")
    for _ in 0 ..< number {
        println "Hello, {name}!"
    }
}

Poetry

/*
Poetry

Original version in BASIC:
    Unknown author.
    Modified and reworked by Jim Bailey, Peggy Ewing, and Dave Ahl at DEC.
    Published in "BASIC Computer Games", Creative Computing (Morristown, New Jersey, USA), 1978.
    https://archive.org/details/Basic_Computer_Games_Microcomputer_Edition_1978_Creative_Computing
    https://github.com/chaosotter/basic-games/tree/master/games/BASIC%20Computer%20Games/Poetry
    http://vintage-basic.net/games.html

This improved remake in Zen C:
    Copyright (c) 2026, Marcos Cruz (programandala.net)
    SPDX-License-Identifier: Fair

Written on 2026-04-20.

Last modified: 20260521T2359+0200.
*/

import "std/random.zc"
import "std/time.zc"

def BLACK        = 0
def RED          = 1
def GREEN        = 2
def YELLOW       = 3
def BLUE         = 4
def MAGENTA      = 5
def CYAN         = 6
def WHITE        = 7
def NORMAL_COLOR = 9

def FOREGROUND   = 30 // color modifier
def BACKGROUND   = 40 // color modifier
def BRIGHT       = 60 // color modifier

def NORMAL_STYLE = 0
def BOLD         = 1
def DIM          = 2
def ITALIC       = 3
def UNDERLINE    = 4
def BLINK        = 5
def OVERLINE     = 6
def INVERT       = 7
def HIDDEN       = 8
def STRIKE       = 9

def OFF          = 20 // style modifier

def INPUT_INK = BRIGHT + GREEN + FOREGROUND
def TITLE_INK = BRIGHT + RED + FOREGROUND

def ANSI = "\x1B[" // code prefix

fn clear_screen() {
    print "{ANSI}2J{ANSI}0m{ANSI}H"
}

fn in_ansi(attribute: int) -> string {
    return "{ANSI}{attribute}m"
}

fn colorized(s: string, attribute: int) -> string {
    return "{in_ansi(attribute)}{s}{in_ansi(NORMAL_STYLE)}"
}

fn typed(prompt: string) -> string {
    print "{colorized(prompt, INPUT_INK)}"
    return readln()
}

fn wait(prompt: string) {
    free(typed(prompt))
}

fn print_credits() {
    println "{colorized(\"Poetry\", TITLE_INK)}"
    println "\nOriginal version in BASIC:"
    println "    Unknown author."
    println "    Published in \"BASIC Computer Games\","
    println "    Creative Computing (Morristown, New Jersey, USA), 1978.\n"

    println "This improved remake in Zen C:"
    println "    Copyright (c) 2026, Marcos Cruz (programandala.net)"
    println "    SPDX-License-Identifier: Fair"
}

fn is_even(n: int) -> bool {
    return n % 2 == 0
}

fn play() {
    def max_phrases_and_verses = 20

    // counters:
    let action: int = 0
    let phrase: int = 0
    let phrases_and_verses: int = 0
    let verse_chunks: int = 0

    let rng = Random::new()

    verse:
    loop {
        let manage_the_verse_continuation: bool = true
        let maybe_add_comma: bool = true

        match action {
            0, 1 => {
                match phrase {
                    0 => { print "MIDNIGHT DREARY" }
                    1 => { print "FIERY EYES" }
                    2 => { print "BIRD OR FIEND" }
                    3 => { print "THING OF EVIL" }
                    4 => { print "PROPHET" }
                }
            }
            2 => {
                match phrase {
                    0 => {
                        print "BEGUILING ME"
                        verse_chunks = 2
                    }
                    1 => {
                        print "THRILLED ME"
                    }
                    2 => {
                        print "STILL SITTING…"
                        maybe_add_comma = false
                    }
                    3 => {
                        print "NEVER FLITTING"
                        verse_chunks = 2
                    }
                    4 => {
                        print "BURNED"
                    }
                }
            }
            3 => {
                match phrase {
                    0 => { print "AND MY SOUL" }
                    1 => { print "DARKNESS THERE" }
                    2 => { print "SHALL BE LIFTED" }
                    3 => { print "QUOTH THE RAVEN" }
                    4 => {
                        if verse_chunks != 0 {
                            print "SIGN OF PARTING"
                        }
                    }
                }
            }
            4 => {
                match phrase {
                    0 => { print "NOTHING MORE" }
                    1 => { print "YET AGAIN" }
                    2 => { print "SLOWLY CREEPING" }
                    3 => { print "…EVERMORE" }
                    4 => { print "NEVERMORE" }
                }
            }
            5 => {
                action = 0
                println ""
                if phrases_and_verses > max_phrases_and_verses {
                    println ""
                    verse_chunks = 0
                    phrases_and_verses = 0
                    action = 2
                    continue verse
                } else {
                    manage_the_verse_continuation = false
                }
            }
        }

        if manage_the_verse_continuation {
            Time::sleep(Duration::from_ms(250))

            if maybe_add_comma && !(verse_chunks == 0 || rng.next_double() > 0.19) {
                print ","
                verse_chunks = 2
            }

            if rng.next_double() > 0.65 {
                println ""
                verse_chunks = 0
            } else {
                print " "
                verse_chunks += 1
            }
        }

        action += 1
        phrase = rng.next_int_range(0, 4)
        phrases_and_verses += 1

        if !(verse_chunks > 0 || is_even(action)) {
            print "     "
        }
    }
}

fn main() {
    clear_screen()
    print_credits()
    wait("\nPress the Enter key to start. ")
    clear_screen()
    play()
}

Russian Roulette

/*
Russian Roulette

Original version in BASIC:
    Creative Computing (Morristown, New Jersey, USA), ca. 1980.

This version in Zen C:
    Copyright (c) 2026, Marcos Cruz (programandala.net)
    SPDX-License-Identifier: Fair

Written on 2026-04-20.

Last modified 20260420T2012+0200.
*/

import "std/random.zc"

def ANSI = "\x1B[" // code prefix

fn clear_screen() {
    print "{ANSI}2J{ANSI}0m{ANSI}H"
}

fn wait() {
    print "Press enter to start. "
    readln()
}

fn print_credits() {
    clear_screen()
    println "Russian Roulette\n"
    println "Original version in BASIC:"
    println "    Creative computing (Morristown, New Jersey, USA), ca. 1980.\n"
    println "This version in Zen C:"
    println "    Copyright (c) 2026, Marcos Cruz (programandala.net)"
    println "    SPDX-License-Identifier: Fair\n"
    wait()
}

fn print_instructions() {
    clear_screen()
    println "Here is a revolver."
    println "Type \"f\" to spin chamber and pull trigger."
    println "Type \"g\" to give up, and play again."
    println "Type \"q\" to quit.\n"
}

fn play() -> bool {
    let rng = Random::new()
    let times: int = 0
    loop { // game
        print_instructions()
        times = 0
        loop { // turn
            match readln() {
                "f" => { // fire
                    if rng.next_int_range(0, 99) > 83 {
                        println "Bang! You're dead!"
                        println "Condolences will be sent to your relatives."
                        break
                    } else {
                        times += 1
                        if times > 10 {
                            println "You win!"
                            println "Let someone else blow his brains out."
                            break
                        } else {
                            println "Click."
                        }
                    }
                }
                "g" => { // give up
                    println "Chicken!"
                    break
                }
                "q" => { // quit
                    return false
                }
            }
        }
        wait()
    }
    return true // play again, do not quit
}

fn main() {
    print_credits()
    while play() {}
    println "Bye!"
}

Sine Wave

/*
Sine Wave

Original version in BASIC:
    Creative Computing (Morristown, New Jersey, USA), ca. 1980.

This version in Zen C:
    Copyright (c) 2026, Marcos Cruz (programandala.net)
    SPDX-License-Identifier: Fair

Written on 2026-04-19.

Last modified 20260420T1759+0200.
*/

import "std/io.zc"
import "std/math.zc"

fn clear_screen() {
    print "\x1b[2J\x1b[0m\x1b[H"
}

fn print_credits() {
    println "Sine Wave\n"
    println "Original version in BASIC:"
    println "    Creative computing (Morristown, New Jersey, USA), ca. 1980.\n"
    println "This version in Zen C:"
    println "    Copyright (c) 2026, Marcos Cruz (programandala.net)"
    println "    SPDX-License-Identifier: Fair\n"
    print "Press Enter to start the program. "
    read_rune()
}

fn draw() {
    let word: string[2]
    print "Enter the first word:  "
    word[0] = readln()
    print "Enter the second word: "
    word[1] = readln()
    defer {
        free(word[0])
        free(word[1])
    }
    clear_screen()

    let even: bool = false
    for let angle: f64 = 0.0; angle <= 40.0; angle += 0.25 {
        for _ in 0 ..< Math::floor(26.0 + 25.0 * Math::sin(angle)) {
            print " "
        }
        println "{word[even]}"
        even = !even
    }
}

fn main() {
    clear_screen()
    print_credits()
    clear_screen()
    draw()
}

Slots

/*
Slots
    A slot machine simulation.

Original version in BASIC:
    Creative Computing (Morristown, New Jersey, USA).
    Produced by Fred Mirabelle and Bob Harper on 1973-01-29.

This version in Zen C:
    Copyright (c) 2026, Marcos Cruz (programandala.net)
    SPDX-License-Identifier: Fair

Written on 2026-04-20.

Last modified 20260421T1040+0200.
*/

import "std/math.zc"
import "std/random.zc"

def BLACK        = 0
def RED          = 1
def GREEN        = 2
def YELLOW       = 3
def BLUE         = 4
def MAGENTA      = 5
def CYAN         = 6
def WHITE        = 7
def NORMAL_COLOR = 9

def FOREGROUND   = 30 // color modifier
def BACKGROUND   = 40 // color modifier
def BRIGHT       = 60 // color modifier

def NORMAL_STYLE = 0
def BOLD         = 1
def DIM          = 2
def ITALIC       = 3
def UNDERLINE    = 4
def BLINK        = 5
def OVERLINE     = 6
def INVERT       = 7
def HIDDEN       = 8
def STRIKE       = 9

def OFF          = 20 // style modifier

def ANSI = "\x1B[" // code prefix

fn in_ansi(attribute: int) -> string {
    return "{ANSI}{attribute}m"
}

fn colorized(s: string, attribute: int) -> string {
    return "{in_ansi(attribute)}{s}{in_ansi(NORMAL_STYLE)}"
}

fn clear_screen() {
    print "{ANSI}2J{ANSI}0m{ANSI}H"
}

fn hide_cursor() {
    print "{ANSI}?25l"
}

fn show_cursor() {
    print "{ANSI}?25h"
}

fn set_cursor_position(y: int, x: int) {
    print "{ANSI}{y};{x}H"
}

fn move_cursor_home() {
    set_cursor_position(0, 0)
}

def IMAGES = 6

let image: const string[IMAGES] = [" BAR  ", " BELL ", "ORANGE", "LEMON ", " PLUM ", "CHERRY"]
def BAR = 0 // position of "BAR" in `image`.

def MAX_BET = 100
def MIN_BET = 1

fn typed(prompt: string) -> string {
    print "{prompt}"
    return readln()
}

fn typed_int(prompt: string) -> int {
    def NUMBER_BASE = 10
    def END_OF_STRING = '\0'
    loop {
        let input: string = typed(prompt)
        defer free(input)
        let end_pointer: string
        let number: int = strtol(input, &end_pointer, NUMBER_BASE)
        if *end_pointer != END_OF_STRING {
            println "Number expected."
        } else {
            return number
        }
    }
}

fn print_credits() {
    clear_screen()
    println "Slots"
    println "A slot machine simulation.\n"
    println "Original version in BASIC:"
    println "    Creative computing (Morristown, New Jersey, USA)."
    println "    Produced by Fred Mirabelle and Bob Harper on 1973-01-29.\n"
    println "This version in Zen C:"
    println "    Copyright (c) 2026, Marcos Cruz (programandala.net)"
    println "    SPDX-License-Identifier: Fair\n"
    typed("Press enter for instructions. ")
}

fn print_instructions() {
    clear_screen()
    println "You are in the H&M casino, in front of one of our"
    println "one-arm bandits. Bet from {MIN_BET} to {MAX_BET} USD (or 0 to quit).\n"
    typed("Press enter to start. ")
}

fn won(prize: int, bet: int) -> int {
    match prize {
          2 => { println "DOUBLE!" }
          5 => { println "*DOUBLE BAR*" }
         10 => { println "**TOP DOLLAR**" }
        100 => { println "***JACKPOT***" }
    }
    println "You won!"
    return (prize + 1) * bet
}

fn print_standings(usd: int) {
    println "Your standings are {usd} USD."
}

let color: const int[IMAGES] = [
    WHITE + FOREGROUND,
    CYAN + FOREGROUND,
    YELLOW + FOREGROUND,
    BRIGHT + YELLOW + FOREGROUND,
    BRIGHT + WHITE + FOREGROUND,
    BRIGHT + RED + FOREGROUND,
]

def REELS = 3
let reel: [int; REELS] // zero-initialized

fn print_reels() {
    move_cursor_home()
    for i in 0 ..< REELS {
        print "[{colorized(image[reel[i]], color[reel[i]])}] "
    }
    println ""
}

fn init_reels() {
    let rng = Random::new()
    for i in 0 ..< REELS {
        reel[i] = rng.next_int_range(0, IMAGES - 1)
    }
}

fn spin_reels() {
    hide_cursor()
    for spin in 0 ..< 24000 {
        init_reels()
        print_reels()
    }
    show_cursor()
}

fn count_of_images(an_image: int) -> int {
    let count: int = 0
    for r in reel {
        count += r == an_image ? 1 : 0
    }
    return count
}

fn play() {
    let standings: int = 0
    let bet: int = 0
    init_reels()
    play:
    loop {
        loop { // bet
            clear_screen()
            print_reels()
            bet = typed_int("Your bet (or 0 to quit): ")
            if bet > MAX_BET {
                println "House limits are {MAX_BET} USD."
                typed("Press enter to try again. ")
            } else if bet < MIN_BET {
                if typed("Type \"q\" to confirm you want to quit. ") == "q" {
                    break play
                }
            } else {
                break
            }
        }
        clear_screen()
        spin_reels()
        let bars: int = count_of_images(BAR)
        let equals: int = 0
        for i in 0 ..< IMAGES {
            equals = Math::max(equals, count_of_images(i))
        }
        if equals == 3 {
            if bars == 3 {
                standings += won(100, bet)
            } else {
                standings += won(10, bet)
            }
        } else if equals == 2 {
            if bars == 2 {
                standings += won(5, bet)
            } else {
                standings += won(2, bet)
            }
        } else {
            println "You lost."
            standings -= bet
        }
        print_standings(standings)
        typed("Press enter to continue. ")
    }
    print_standings(standings)
    if standings < 0 {
        println "Pay up!  Please leave your money on the terminal."
    } else if standings == 0 {
        println "Hey, you broke even."
    } else {
        println "Collect your winnings from the H&M cashier."
    }
}

fn main() {
    print_credits()
    print_instructions()
    play()
}

Stars

/*
Stars

Original version in BASIC:
    Example included in Vintage BASIC 1.0.3.
    http://www.vintage-basic.net

This version in Zen C:
    Copyright (c) 2026, Marcos Cruz (programandala.net)
    SPDX-License-Identifier: Fair

Written on 2026-04-20.

Last modified: 20260420T2012+0200.
*/

import "ctype.h" // tolower

fn typed(prompt: string) -> string {
    print "{prompt}"
    return readln()
}

fn typed_int(prompt: string) -> int {
    def NUMBER_BASE = 10
    def END_OF_STRING = '\0'
    loop {
        let input: string = typed(prompt)
        defer free(input)
        let end_pointer: string
        let number: int = strtol(input, &end_pointer, NUMBER_BASE)
        if *end_pointer != END_OF_STRING {
            println "Number expected."
        } else {
            return number
        }
    }
}

fn to_lowercase(s: string) -> string {
    for i in 0 .. strlen(s) {
        s[i] = tolower(s[i])
    }
    return s
}

fn main() {
    print "What is your name? "
    let name: string = readln()
    defer free(name)
    println "Hello, {name}."
    loop {
        let stars: i64 = typed_int("How many stars do you want? ")
        for _ in 0 .. stars {
            print "*"
        }
        println ""
        print "Do you want more stars? "
        let answer: string = to_lowercase(readln()) // XXX TODO trim
        defer free(answer)
        match answer {
            "ok", "y", "yeah", "yes" => {},
            _ => { break }
        }
    }
}

Págines relatet

Basics off
Metaprojecte pri li projectes «Basics of…».
Basics of 8th
Conversion de old BASIC-programas a 8th por aprender lu elementari de ti-ci lingue.
Basics of Ada
Conversion de old BASIC-programas a Ada por aprender lu elementari de ti-ci lingue.
Basics of Arturo
Conversion de old BASIC-programas a Arturo por aprender lu elementari de ti-ci lingue.
Basics of C#
Conversion de old BASIC-programas a C# por aprender lu elementari de ti-ci lingue.
Basics of C3
Conversion de old BASIC-programas a C3 por aprender lu elementari de ti-ci lingue.
Basics of Chapel
Conversion de old BASIC-programas a Chapel por aprender lu elementari de ti-ci lingue.
Basics of Clojure
Conversion de old BASIC-programas a Clojure por aprender lu elementari de ti-ci lingue.
Basics of Crystal
Conversion de old BASIC-programas a Crystal por aprender lu elementari de ti-ci lingue.
Basics of D
Conversion de old BASIC-programas a D por aprender lu elementari de ti-ci lingue.
Basics of Elixir
Conversion de old BASIC-programas a Elixir por aprender lu elementari de ti-ci lingue.
Basics of F#
Conversion de old BASIC-programas a F# por aprender lu elementari de ti-ci lingue.
Basics of Factor
Conversion de old BASIC-programas a Factor por aprender lu elementari de ti-ci lingue.
Basics of FreeBASIC
Conversion de old BASIC-programas a FreeBASIC por aprender lu elementari de ti-ci lingue.
Basics of Gleam
Conversion de old BASIC-programas a Gleam por aprender lu elementari de ti-ci lingue.
Basics of Go
Conversion de old BASIC-programas a Go por aprender lu elementari de ti-ci lingue.
Basics of Hare
Conversion de old BASIC-programas a Hare por aprender lu elementari de ti-ci lingue.
Basics of Haxe
Conversion de old BASIC-programas a Haxe por aprender lu elementari de ti-ci lingue.
Basics of Icon
Conversion de old BASIC-programas a Icon por aprender lu elementari de ti-ci lingue.
Basics of Io
Conversion de old BASIC-programas a Io por aprender lu elementari de ti-ci lingue.
Basics of Janet
Conversion de old BASIC-programas a Janet por aprender lu elementari de ti-ci lingue.
Basics of Julia
Conversion de old BASIC-programas a Julia por aprender lu elementari de ti-ci lingue.
Basics of Kotlin
Conversion de old BASIC-programas a Kotlin por aprender lu elementari de ti-ci lingue.
Basics of Lobster
Conversion de old BASIC-programas a Lobster por aprender lu elementari de ti-ci lingue.
Basics of Lua
Conversion de old BASIC-programas a Lua por aprender lu elementari de ti-ci lingue.
Basics of Nature
Conversion de old BASIC-programas a Nature por aprender lu elementari de ti-ci lingue.
Basics of Neat
Conversion de old BASIC-programas a Neat por aprender lu elementari de ti-ci lingue.
Basics of Neko
Conversion de old BASIC-programas a Neko por aprender lu elementari de ti-ci lingue.
Basics of Nelua
Conversion de old BASIC-programas a Nelua por aprender lu elementari de ti-ci lingue.
Basics of Nim
Conversion de old BASIC-programas a Nim por aprender lu elementari de ti-ci lingue.
Basics of Nit
Conversion de old BASIC-programas a Nit por aprender lu elementari de ti-ci lingue.
Basics of Oberon-07
Conversion de old BASIC-programas a Oberon-07 por aprender lu elementari de ti-ci lingue.
Basics of OCaml
Conversion de old BASIC-programas a OCaml por aprender lu elementari de ti-ci lingue.
Basics of Odin
Conversion de old BASIC-programas a Odin por aprender lu elementari de ti-ci lingue.
Basics of Pike
Conversion de old BASIC-programas a Pike por aprender lu elementari de ti-ci lingue.
Basics of Pony
Conversion de old BASIC-programas a Pony por aprender lu elementari de ti-ci lingue.
Basics of Python
Conversion de old BASIC-programas a Python por aprender lu elementari de ti-ci lingue.
Basics of Racket
Conversion de old BASIC-programas a Racket por aprender lu elementari de ti-ci lingue.
Basics of Raku
Conversion de old BASIC-programas a Raku por aprender lu elementari de ti-ci lingue.
Basics of Retro
Conversion de old BASIC-programas a Retro por aprender lu elementari de ti-ci lingue.
Basics of Rexx
Conversion de old BASIC-programas a Rexx por aprender lu elementari de ti-ci lingue.
Basics of Ring
Conversion de old BASIC-programas a Ring por aprender lu elementari de ti-ci lingue.
Basics of Rust
Conversion de old BASIC-programas a Rust por aprender lu elementari de ti-ci lingue.
Basics of Scala
Conversion de old BASIC-programas a Scala por aprender lu elementari de ti-ci lingue.
Basics of Scheme
Conversion de old BASIC-programas a Scheme por aprender lu elementari de ti-ci lingue.
Basics of Styx
Conversion de old BASIC-programas a Styx por aprender lu elementari de ti-ci lingue.
Basics of Swift
Conversion de old BASIC-programas a Swift por aprender lu elementari de ti-ci lingue.
Basics of V
Conversion de old BASIC-programas a V por aprender lu elementari de ti-ci lingue.
Basics of Vala
Conversion de old BASIC-programas a Vala por aprender lu elementari de ti-ci lingue.
Basics of Zig
Conversion de old BASIC-programas a Zig por aprender lu elementari de ti-ci lingue.

Extern ligamentes relatet