Basics of C3
Priskribo de la ĉi-paĝa enhavo
Konverto de malnovaj BASIC-programoj al C3 por lerni la fundamentojn de ĉi-tiu lingvo.
Etikedoj:
3D Plot
// 3D Plot
// Original version in BASIC:
// Creative Computing (Morristown, New Jersey, USA), ca. 1980.
// This version in C3:
// Copyright (c) 2025, 2026, Marcos Cruz (programandala.net)
// SPDX-License-Identifier: Fair
//
// Written on 2025-03-07.
// Updated to C3 0.8.0 on 2026-05-21.
//
// Last modified: 20260521T1708+0200.
import std::io;
import std::math;
const SPACE = " ";
const DOT = "*";
const WIDTH = 56;
fn void clear_screen()
{
io::printn("\e[0;0H\e[2J");
}
fn String accept_string(String prompt = "")
{
io::print(prompt);
String? s = io::readline(mem);
if (catch excuse = s)
{
return "";
}
else
{
return s;
}
}
fn void press_enter(String prompt = "")
{
String discard = accept_string(prompt);
free(discard);
}
fn void print_credits()
{
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, 2026, Marcos Cruz (programandala.net)");
io::printn(" SPDX-License-Identifier: Fair\n");
press_enter("Press Enter to start. ");
}
fn double a(double z)
{
return 30.0 * math::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)(math::sqrt(900.0 - x * x) / 5.0);
for (int y = y1; y >= -y1; y += -5)
{
z = (int)(25.0 + a(math::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()
{
clear_screen();
print_credits();
clear_screen();
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, 2026, Marcos Cruz (programandala.net)
SPDX-License-Identifier: Fair
Written on 2025-03-05.
Last modified 20260521T1542+0200.
*/
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, 2026, Marcos Cruz (programandala.net)
// SPDX-License-Identifier: Fair
//
// Written on 2025-03-09, 2025-03-12, 2025-03-18.
// Updated to C3 0.8.0 on 2026-05-21.
//
// Last modified: 20260521T1708+0200.
import std::io;
fn String accept_string(String prompt = "")
{
io::print(prompt);
String? s = io::readline(mem);
if (catch excuse = s)
{
return "";
}
else
{
return s;
}
}
fn int? accept_integer(String prompt = "")
{
String s = accept_string(prompt);
defer free(s);
return String.to_int(s);
}
fn int accept_valid_integer(String prompt = "", String error = "Integer expected.\n")
{
while (true)
{
int? n = accept_integer(prompt);
if (catch excuse = n)
{
io::print(error);
}
else
{
return n;
}
}
}
fn void main()
{
String name = accept_string("What is your name? ");
defer free(name);
int number = accept_valid_integer("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, 2026, Marcos Cruz (programandala.net)
// SPDX-License-Identifier: Fair
//
// Written on 2025-03-08.
// Updated to C3 0.8.0 on 2026-05-21.
//
// Last modified: 20260521T1709+0200.
// 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 move_cursor_home()
{
io::print("\e[H");
}
fn void set_style(int style)
{
io::printf("\e[%sm", style);
}
fn void reset_attributes()
{
set_style(NORMAL_STYLE);
}
fn void erase_screen()
{
io::print("\e[2J");
}
fn void clear_screen()
{
erase_screen();
reset_attributes();
move_cursor_home();
}
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 accept_string(String prompt = "")
{
io::print(prompt);
String? s = io::readline(mem);
if (catch excuse = s)
{
return "";
}
else
{
return s;
}
}
fn void press_enter(String prompt = "")
{
String discard = accept_string(prompt);
free(discard);
}
// Title and credits {{{1
// =============================================================================
// Print the title at the current cursor position.
//
fn void print_title()
{
set_style(TITLE_INK);
io::printn("Poetry");
set_style(DEFAULT_INK);
}
// Print the credits at the current cursor position.
//
fn void print_credits()
{
print_title();
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, 2026, Marcos Cruz (programandala.net)");
io::printn(" SPDX-License-Identifier: Fair");
}
// Main {{{1
// =============================================================================
DefaultRandom rand;
fn void randomize()
{
random::seed_entropy(&rand);
}
fn bool is_even(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 || is_even(action)))
{
io::print(" ");
}
} // verse loop
}
fn void main()
{
clear_screen();
print_credits();
press_enter("\nPress the Enter key to start. ");
clear_screen();
play();
}
Sine Wave
// Sine Wave
//
// Original version in BASIC:
// Creative Computing (Morristown, New Jersey, USA), ca. 1980.
//
// This version in C3:
// Copyright (c) 2025, 2026, Marcos Cruz (programandala.net)
// SPDX-License-Identifier: Fair
//
// Written on 2025-03-07.
// Updated to C3 0.8.0 on 2026-05-21.
//
// Last modified: 20260521T1709+0200.
import std::io;
import std::math;
fn void clear_screen()
{
io::print("\e[0;0H\e[2J");
}
fn String accept_string(String prompt = "")
{
io::print(prompt);
String? s = io::readline(mem);
if (catch excuse = s)
{
return "";
}
else
{
return s;
}
}
fn void press_enter(String prompt = "")
{
String discard = accept_string(prompt);
free(discard);
}
fn String[2] get_words()
{
clear_screen();
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] = accept_string();
}
}
return word;
}
fn void print_credits()
{
clear_screen();
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, 2026, Marcos Cruz (programandala.net)");
io::printn(" SPDX-License-Identifier: Fair\n");
press_enter("Press Enter to start the program. ");
}
fn void draw()
{
clear_screen();
String[2] word = get_words();
bool even = false;
for (double angle = 0.0; angle <= 40.0; angle += 0.25)
{
int spaces = (int)(26.0 + math::floor(25.0 * math::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()
{
print_credits();
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, 2026, Marcos Cruz (programandala.net)
// SPDX-License-Identifier: Fair
//
// Written on 2025-03-18.
// Updated to C3 0.8.0 on 2026-05-21.
//
// Last modified: 20260521T1710+0200.
import std::io;
fn String accept_string(String prompt = "")
{
io::print(prompt);
String? s = io::readline(mem);
if (catch excuse = s)
{
return "";
}
else
{
return s;
}
}
fn int? accept_integer(String prompt = "")
{
String s = accept_string(prompt);
defer free(s);
return String.to_int(s);
}
fn int accept_valid_integer(String prompt = "", String error = "Integer expected.\n")
{
while (true)
{
int? n = accept_integer(prompt);
if (catch excuse = n)
{
io::print(error);
}
else
{
return n;
}
}
}
fn bool is_yes(String s)
{
String lowercase_s = s.to_upper_copy(mem);
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 = accept_string("What is your name? ");
defer free(name);
io::printfn("Hello, %s.", name);
int stars = 0;
while (true)
{
stars = accept_valid_integer("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 = accept_string();
defer free(answer);
if (!is_yes(answer))
{
break;
}
}
}
