Basics of C3

Description of the page content

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

Tags:

3D Plot

// 3D Plot

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

// This version in C3:
//  Copyright (c) 2025, Marcos Cruz (programandala.net)
//  SPDX-License-Identifier: Fair
//
// Written on 2025-03-07.
//
// Last modified: 20250307T1349+0100.

import std::io;

const SPACE = " ";
const DOT = "*";
const WIDTH = 56;

fn void clearScreen() {
    io::printn("\e[0;0H\e[2J");
}

fn String acceptString(String prompt = "") {
    io::print(prompt);
    String! s = io::readline();
    if (catch excuse = s) {
        return "";
    } else {
        return s;
    }
}

fn void pressEnter(String prompt = "") {
    String discard = acceptString(prompt);
    free(discard);
}

fn void printCredits() {
    io::printn("3D Plot\n");
    io::printn("Original version in BASIC:");
    io::printn("    Creative computing (Morristown, New Jersey, USA), ca. 1980.\n");
    io::printn("This version in C3:");
    io::printn("    Copyright (c) 2025, Marcos Cruz (programandala.net)");
    io::printn("    SPDX-License-Identifier: Fair\n");
    pressEnter("Press Enter to start. ");
}

fn double a(double z) {
    return 30.0 * $$exp(-z * z / 100.0);
}

fn void draw() {

    int l = 0;
    int z = 0;
    int y1 = 0;

    String[WIDTH] line = {};

    for (double x = -30.0; x <= 30.0; x += 1.5) {

        for (int i = 0; i < WIDTH; i += 1) {
            line[i] = SPACE;
        }

        l = 0;
        y1 = 5 * (int)($$sqrt(900.0 - x * x) / 5.0);

        for (int y = y1; y >= -y1; y += -5) {
            z = (int)(25.0 + a($$sqrt(x * x + (double)(y * y))) - 0.7 * (double)y);
            if (z > l) {
                l = z;
                line[z] = DOT;
            }
        } // y loop

        for (int pos = 0; pos < WIDTH; pos += 1) {
            io::print(line[pos]);
        }
        io::printn();

    } // x loop

}

fn void main() {
    clearScreen();
    printCredits();
    clearScreen();
    draw();
}

Diamond

/*
Diamond

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

This version in C3:
    Copyright (c) 2025, Marcos Cruz (programandala.net)
    SPDX-License-Identifier: Fair

Written on 2025-03-05.

Last modified 20250305T0221+0100.
*/

import std::io;

const int LINES = 17;

fn void main() {
    for (int i = 1; i < LINES / 2 + 2; i += 1) {
        for (int j = 1; j < (LINES + 1) / 2 - i + 2; j += 1) {
            io::print(" ");
        }
        for (int j = 1; j < i * 2; j += 1) {
            io::print("*");
        }
        io::printn();
    }
    for (int i = 1; i < LINES / 2 + 1; i += 1) {
        for (int j; j < i + 1; j += 1) {
            io::print(" ");
        }
        for (int j = 1; j < ((LINES + 1) / 2 - i) * 2; j += 1) {
            io::print("*");
        }
        io::printn();
    }
}

Name

// Name

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

// This version in C3:
//  Copyright (c) 2025, Marcos Cruz (programandala.net)
//  SPDX-License-Identifier: Fair
//
// Written on 2025-03-09, 2025-03-12, 2025-03-18.
//
// Last modified: 20250731T1954+0200.

import std::io;

fn String acceptString(String prompt = "") {
    io::print(prompt);
    String! s = io::readline();
    if (catch excuse = s) {
        return "";
    } else {
        return s;
    }
}

fn int! acceptInteger(String prompt = "") {
    String s = acceptString(prompt);
    defer free(s);
    return String.to_int(s);
}

fn int acceptValidInteger(String prompt = "", String error = "Integer expected.\n") {
    while (true) {
        int! n = acceptInteger(prompt);
        if (catch excuse = n) {
            io::print(error);
        } else {
            return n;
        }
    }
}

fn void main() {

    String name = acceptString("What is your name? ");
    defer free(name);
    int number = acceptValidInteger("Enter a number: ");
    io::printfn("number=%s", number);

    for (int i = 0; i < (number); i += 1) {
        io::printfn("Hello, %s!", 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 C3:
//  Copyright (c) 2025, Marcos Cruz (programandala.net)
//  SPDX-License-Identifier: Fair
//
// Written on 2025-03-08.
//
// Last modified: 20250308T2019+0100.

// Modules {{{1
// =============================================================================

import std::io;
import std::math::random;
import std::thread;

// Terminal {{{1
// =============================================================================

const int BLACK = 0;
const int RED = 1;
const int GREEN = 2;
const int YELLOW = 3;
const int BLUE = 4;
const int MAGENTA = 5;
const int CYAN = 6;
const int WHITE = 7;
const int DEFAULT = 9;

const int STYLE_OFF = 20;
const int FOREGROUND = 30;
const int BACKGROUND = 40;
const int BRIGHT = 60;

const int NORMAL_STYLE = 0;

fn void moveCursorHome() {
    io::print("\e[H");
}

fn void setStyle(int style) {
    io::printf("\e[%sm", style);
}

fn void resetAttributes() {
    setStyle(NORMAL_STYLE);
}

fn void eraseScreen() {
    io::print("\e[2J");
}

fn void clearScreen() {
    eraseScreen();
    resetAttributes();
    moveCursorHome();
}

const int DEFAULT_INK = FOREGROUND + WHITE;
const int INPUT_INK = FOREGROUND + BRIGHT + GREEN;
const int TITLE_INK = FOREGROUND + BRIGHT + RED;

// User input {{{1
// =============================================================================

fn String acceptString(String prompt = "") {
    io::print(prompt);
    String! s = io::readline();
    if (catch excuse = s) {
        return "";
    } else {
        return s;
    }
}

fn void pressEnter(String prompt = "") {
    String discard = acceptString(prompt);
    free(discard);
}

// Title and credits {{{1
// =============================================================================

// Print the title at the current cursor position.
//
fn void printTitle() {

    setStyle(TITLE_INK);
    io::printn("Poetry");
    setStyle(DEFAULT_INK);

}

// Print the credits at the current cursor position.
//
fn void printCredits() {

    printTitle();
    io::printn("\nOriginal version in BASIC:");
    io::printn("    Unknown author.");
    io::printn("    Published in \"BASIC Computer Games\",");
    io::printn("    Creative Computing (Morristown, New Jersey, USA), 1978.\n");

    io::printn("This improved remake in C3:");
    io::printn("    Copyright (c) 2025, Marcos Cruz (programandala.net)");
    io::printn("    SPDX-License-Identifier: Fair");

}

// Main {{{1
// =============================================================================

DefaultRandom rand;

fn void randomize() {
    random::seed_entropy(&rand);
}

fn bool isEven(int n) {
    return n % 2 == 0;
}

fn void play() {

    randomize();

    const int MAX_PHRASES_AND_VERSES = 20;

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

    while VERSE: (true) {

        bool manage_the_verse_continuation = true;
        bool maybe_add_comma = true;

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

        if (manage_the_verse_continuation) {

            thread::sleep_ms(250);

            if (maybe_add_comma && !(verse_chunks == 0 || random::next_double(&rand) > 0.19)) {
                io::print(",");
                verse_chunks = 2;
            }

            if (random::next_double(&rand) > 0.65) {
                io::printn();
                verse_chunks = 0;
            } else {
                io::print(" ");
                verse_chunks += 1;
            }

        }

        action += 1;
        phrase = random::rand(5);
        phrases_and_verses += 1;

        if (!(verse_chunks > 0 || isEven(action))) {
            io::print("     ");
        }

    } // verse loop

}

fn void main() {
    clearScreen();
    printCredits();
    pressEnter("\nPress the Enter key to start. ");
    clearScreen();
    play();
}

Sine Wave

// Sine Wave
//
// Original version in BASIC:
//  Creative Computing (Morristown, New Jersey, USA), ca. 1980.
//
// This version in C3:
//  Copyright (c) 2025, Marcos Cruz (programandala.net)
//  SPDX-License-Identifier: Fair
//
// Written on 2025-03-07.
//
// Last modified: 20250731T1954+0200.

import std::io;

fn void clearScreen() {
    io::print("\e[0;0H\e[2J");
}

fn String acceptString(String prompt = "") {
    io::print(prompt);
    String! s = io::readline();
    if (catch excuse = s) {
        return "";
    } else {
        return s;
    }
}

fn void pressEnter(String prompt = "") {
    String discard = acceptString(prompt);
    free(discard);
}

fn String[2] getWords() {

    clearScreen();

    String[2] word = {"", ""};
    String[2] order = {"first", "second"};

    for (int n = 0; n <= 1; n += 1) {
        while (word[n] == "") {
            io::printf("Enter the %s word: ", order[n]);
            word[n] = acceptString();
        }
    }

    return word;

}

fn void printCredits() {

    clearScreen();
    io::printn("Sine Wave\n");
    io::printn("Original version in BASIC:");
    io::printn("    Creative Computing (Morristown, New Jersey, USA), ca. 1980.\n");
    io::printn("This version in C3:");
    io::printn("    Copyright (c) 2025, Marcos Cruz (programandala.net)");
    io::printn("    SPDX-License-Identifier: Fair\n");
    pressEnter("Press Enter to start the program. ");

}

fn void draw() {
    clearScreen();
    String[2] word = getWords();
    bool even = false;
    for (double angle = 0.0; angle <= 40.0; angle += 0.25) {
        int spaces = (int)(26.0 + $$floor(25.0 * $$sin(angle)));
        for (int i = 0; i < spaces; i += 1) {
            io::print(" ");
        }
        io::printn(word[(int)even]);
        even = !even;
    }
    free(word[0]);
    free(word[1]);
}

fn void main() {
    printCredits();
    draw();
}

Stars

// Stars
//
// Original version in BASIC:
//  Example included in Vintage BASIC 1.0.3.
//  http://www.vintage-basic.net
//
// This version in C3:
//  Copyright (c) 2025, Marcos Cruz (programandala.net)
//  SPDX-License-Identifier: Fair
//
// Written on 2025-03-18.
//
// Last modified: 20250731T1954+0200.

import std::io;

fn String acceptString(String prompt = "") {
    io::print(prompt);
    String! s = io::readline();
    if (catch excuse = s) {
        return "";
    } else {
        return s;
    }
}

fn int! acceptInteger(String prompt = "") {
    String s = acceptString(prompt);
    defer free(s);
    return String.to_int(s);
}

fn int acceptValidInteger(String prompt = "", String error = "Integer expected.\n") {
    while (true) {
        int! n = acceptInteger(prompt);
        if (catch excuse = n) {
            io::print(error);
        } else {
            return n;
        }
    }
}

fn bool isYes(String s) {

    String lowercase_s = String.new_ascii_to_upper(s);
    defer free(lowercase_s);
    switch(lowercase_s) {
        case "OK":
        case "Y":
        case "YEAH":
        case "YES":
            return true;
        default:
            return false;
    }

}

fn void main() {

    String name = acceptString("What is your name? ");
    defer free(name);
    io::printfn("Hello, %s.", name);

    int stars = 0;
    while (true) {
        stars = acceptValidInteger("How many stars do you want? ");
        for (int n = 0; n < stars; n += 1) {
            io::print("*");
        }
        io::print("\nDo you want more stars? ");
        String answer = acceptString();
        defer free(answer);
        if (!isYes(answer)) {
            break;
        }
    }

}

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 Arturo
Conversion of old BASIC programs to Arturo 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 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