Welcome to RetroCoders Community
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#define WIDTH 40
#define HEIGHT 20
#define CLEAR "clear" // Use "cls" for Windows
// Function to initialize the grid with random values
void initializeGrid(int grid[HEIGHT][WIDTH]) {
for (int i = 0; i < HEIGHT; i++) {
for (int j = 0; j < WIDTH; j++) {
grid[i][j] = rand() % 2;
}
}
}
// Function to count neighbors of a cell
int countNeighbors(int grid[HEIGHT][WIDTH], int row, int col) {
int count = 0;
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
if (i == 0 && j == 0) continue;
int newRow = row + i;
int newCol = col + j;
// Check boundaries with wraparound
if (newRow < 0) newRow = HEIGHT - 1;
if (newRow >= HEIGHT) newRow = 0;
if (newCol < 0) newCol = WIDTH - 1;
if (newCol >= WIDTH) newCol = 0;
count += grid[newRow][newCol];
}
}
return count;
}
// Function to update the grid based on Conway's rules
void updateGrid(int grid[HEIGHT][WIDTH], int newGrid[HEIGHT][WIDTH]) {
for (int i = 0; i < HEIGHT; i++) {
for (int j = 0; j < WIDTH; j++) {
int neighbors = countNeighbors(grid, i, j);
// Apply Conway's rules
if (grid[i][j]) {
// Live cell
newGrid[i][j] = (neighbors == 2 || neighbors == 3) ? 1 : 0;
} else {
// Dead cell
newGrid[i][j] = (neighbors == 3) ? 1 : 0;
}
}
}
// Copy new grid to original grid
for (int i = 0; i < HEIGHT; i++) {
for (int j = 0; j < WIDTH; j++) {
grid[i][j] = newGrid[i][j];
}
}
}
// Function to display the grid
void displayGrid(int grid[HEIGHT][WIDTH]) {
// system(CLEAR); // Clear screen
for (int i = 0; i < HEIGHT; i++) {
for (int j = 0; j < WIDTH; j++) {
printf("%c ", grid[i][j] ? '#' : '.');
}
printf("\n");
}
}
int main() {
// Seed the random number generator
srand(time(NULL));
// Initialize grids
int grid[HEIGHT][WIDTH];
int newGrid[HEIGHT][WIDTH] = {0};
// Initialize with random values
initializeGrid(grid);
// Main game loop
while (1) {
printf("\x1b[H");
displayGrid(grid);
updateGrid(grid, newGrid);
usleep(100000); // Delay for visualization (100ms)
}
return 0;
}
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <math.h>
int main() {
float A = 0, B = 0;
float i, j;
int k;
float z[1760];
char b[1760];
printf("\x1b[2J");
for(;;) {
memset(b,32,1760);
memset(z,0,7040);
for(j=0; j < 6.28; j += 0.07) {
for(i=0; i < 6.28; i += 0.02) {
float c = sin(i);
float d = cos(j);
float e = sin(A);
float f = sin(j);
float g = cos(A);
float h = d + 2;
float D = 1 / (c * h * e + f * g + 5);
float l = cos(i);
float m = cos(B);
float n = sin(B);
float t = c * h * g - f * e;
int x = 40 + 30 * D * (l * h * m - t * n);
int y= 12 + 15 * D * (l * h * n + t * m);
int o = x + 80 * y;
int N = 8 * ((f * e - c * d * g) * m - c * d * e - f * g - l * d * n);
if(22 > y && y > 0 && x > 0 && 80 > x && D > z[o]) {
z[o] = D;
b[o] = ".,-~:;=!*#$@"[N > 0 ? N : 0];
}
}
}
printf("\x1b[H");
for(k = 0; k < 1761; k++) {
putchar(k % 80 ? b[k] : 10);
}
A += 0.04;
B += 0.02;
usleep(30000);
}
return 0;
}
use std::fs;
use std::io::{self, Write};
use std::thread;
use std::time::Duration;
use std::ffi::CString;
use std::env;
use rand::Rng;
use anyhow::{Result, Context};
use bass_sys::*;
// File paths
const DESC1: &str = "data/des1.txt";
const OPENING_BANNER: &str = "banners/opening1.txt";
const OPENING_POINT: &str = "data/opening1.txt";
const MENU: &str = "data/mainmenu.txt";
const MONEY_MENU: &str = "data/moneyMenu.txt";
const FRIENDS_MENU: &str = "data/friendsmenu.txt";
const OVER: &str = "data/suicide.txt";
const GAME_END: &str = "data/theend.txt";
const FAMILY1: &str = "data/family1.txt";
const SCHOOL1: &str = "data/school1.txt";
// Arrays of file paths
const MONTHS: [&str; 12] = [
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"
];
const SONGS_RAND: [&str; 12] = [
"sound/walrus1.ogg", "sound/walrus2.ogg", "sound/walrus3.ogg",
"sound/walrus4.ogg", "sound/walrus5.ogg", "sound/walrus6.ogg",
"sound/walrus7.ogg", "sound/walrus8.ogg", "sound/walrus9.ogg",
"sound/walrus10.ogg", "sound/walrus11.ogg", "sound/walrus12.ogg"
];
const MARY: [&str; 5] = [
"data/mary1.txt", "data/mary2rehab.txt", "data/mary3pregnant.txt",
"data/mary4jail.txt", "data/mary5dead.txt"
];
const JOE: [&str; 5] = [
"data/joe1.txt", "data/joe2rehab.txt", "data/joe3jail.txt",
"data/joe4.txt", "data/joe5prison.txt"
];
const FELIX: [&str; 5] = [
"data/felix1.txt", "data/felix2.txt", "data/felix3jail.txt",
"data/felix4rehab.txt", "data/felix5crazy.txt"
];
struct GameState {
health: i32,
money: i32,
turns: usize,
year: i32,
is_over: bool,
is_mary: bool,
is_joe: bool,
is_felix: bool,
is_suicide: bool,
stream: u32,
}
impl GameState {
fn new() -> Self {
Self {
health: 100,
money: 5000,
turns: 0,
year: 1991,
is_over: false,
is_mary: true,
is_joe: true,
is_felix: true,
is_suicide: false,
stream: 0,
}
}
fn play_music(&mut self, path: &str) -> Result<()> {
let mut full_path = env::current_dir()?;
full_path.push(path);
let path_str = full_path.to_str().unwrap();
println!("Attempting to play: {}", path_str);
if self.stream != 0 {
BASS_StreamFree(self.stream);
self.stream = 0;
}
let path_c = CString::new(path_str)?;
self.stream = BASS_StreamCreateFile(
0,
path_c.as_ptr() as *const _,
0,
0,
BASS_SAMPLE_LOOP
);
if self.stream == 0 {
println!("BASS Error Code: {}", BASS_ErrorGetCode());
return Ok(());
}
if BASS_ChannelPlay(self.stream, 0) == 0 {
println!("Failed to play: Error code {}", BASS_ErrorGetCode());
return Ok(());
}
Ok(())
}
fn stop_music(&mut self) {
if self.stream != 0 {
BASS_ChannelStop(self.stream);
BASS_StreamFree(self.stream);
self.stream = 0;
}
}
fn read_file(&self, path: &str) -> Result<String> {
let mut full_path = env::current_dir()?;
full_path.push(path);
fs::read_to_string(&full_path)
.with_context(|| format!("Failed to read file: {}", full_path.display()))
}
fn clear_screen(&self) {
print!("\x1B[2J\x1B[1;1H");
io::stdout().flush().unwrap();
}
fn get_input(&self) -> Result<i32> {
let mut input = String::new();
io::stdin().read_line(&mut input)?;
Ok(input.trim().parse()?)
}
fn wait_for_enter(&self) -> Result<()> {
let mut input = String::new();
io::stdin().read_line(&mut input)?;
Ok(())
}
fn friends(&mut self) -> Result<()> {
self.clear_screen();
println!(
"date: {}, {} health: {} money: {}\n\n{}",
MONTHS[self.turns], self.year, self.health, self.money,
self.read_file(FRIENDS_MENU)?
);
match self.get_input()? {
1 => self.visit_mary()?,
2 => self.visit_joe()?,
3 => self.visit_felix()?,
4 => self.visit_school()?,
5 => self.visit_family()?,
_ => {
println!("INVALID INPUT!");
thread::sleep(Duration::from_secs(5));
}
}
Ok(())
}
fn visit_mary(&mut self) -> Result<()> {
self.clear_screen();
if !self.is_mary {
println!("{}", self.read_file(MARY[4])?);
} else {
let mut rng = rand::thread_rng();
let r = rng.gen_range(0..5);
if r == 4 {
self.is_mary = false;
}
println!("{}", self.read_file(MARY[r])?);
}
self.wait_for_enter()?;
Ok(())
}
fn visit_joe(&mut self) -> Result<()> {
self.clear_screen();
if !self.is_joe {
println!("{}", self.read_file(JOE[4])?);
} else {
let mut rng = rand::thread_rng();
let r = rng.gen_range(0..5);
if r == 4 {
self.is_joe = false;
}
println!("{}", self.read_file(JOE[r])?);
}
self.wait_for_enter()?;
Ok(())
}
fn visit_felix(&mut self) -> Result<()> {
self.clear_screen();
if !self.is_felix {
println!("{}", self.read_file(FELIX[4])?);
} else {
let mut rng = rand::thread_rng();
let r = rng.gen_range(0..5);
if r == 4 {
self.is_felix = false;
}
println!("{}", self.read_file(FELIX[r])?);
}
self.wait_for_enter()?;
Ok(())
}
fn visit_school(&mut self) -> Result<()> {
self.clear_screen();
println!("{}", self.read_file(SCHOOL1)?);
self.wait_for_enter()?;
Ok(())
}
fn visit_family(&mut self) -> Result<()> {
self.clear_screen();
println!("{}", self.read_file(FAMILY1)?);
self.wait_for_enter()?;
Ok(())
}
fn drugs(&mut self) -> Result<()> {
self.clear_screen();
let mut rng = rand::thread_rng();
let index = rng.gen_range(0..5);
println!("{}", self.read_file(&format!("data/drug{}.txt", index + 1))?);
match index {
0 => self.money -= 170,
3 => {
self.health -= 5;
self.money -= 350;
}
4 => {
self.health -= 5;
self.money -= 250;
}
_ => {}
}
self.wait_for_enter()?;
Ok(())
}
fn shoplist(&mut self) -> Result<()> {
self.clear_screen();
let mut rng = rand::thread_rng();
let index = rng.gen_range(0..5);
println!("{}", self.read_file(&format!("data/shop{}.txt", index + 1))?);
match index {
0 => self.money += 200,
1 => self.money += 150,
2 => self.health -= 3,
3 => self.money += 200,
4 => self.health -= 3,
_ => {}
}
self.wait_for_enter()?;
Ok(())
}
fn car(&mut self) -> Result<()> {
self.clear_screen();
let mut rng = rand::thread_rng();
let index = rng.gen_range(0..5);
println!("{}", self.read_file(&format!("data/car{}.txt", index + 1))?);
match index {
0 => self.money += 1000,
1 => self.money += 2000,
2 => self.health -= 5,
3 => self.money += 1500,
4 => self.health -= 5,
_ => {}
}
self.wait_for_enter()?;
Ok(())
}
fn burglary(&mut self) -> Result<()> {
self.clear_screen();
let mut rng = rand::thread_rng();
let index = rng.gen_range(0..5);
println!("{}", self.read_file(&format!("data/burglur{}.txt", index + 1))?);
match index {
0 => self.money += 2500,
1 => self.health -= 7,
2 => self.health -= 7,
3 => self.money += 2500,
4 => self.health -= 7,
_ => {}
}
self.wait_for_enter()?;
Ok(())
}
fn get_money(&mut self) -> Result<()> {
self.clear_screen();
println!(
"date: {}, {} health: {} money: {}\n\n{}",
MONTHS[self.turns], self.year, self.health, self.money,
self.read_file(MONEY_MENU)?
);
match self.get_input()? {
1 => self.shoplist()?,
2 => self.car()?,
3 => self.burglary()?,
_ => {}
}
Ok(())
}
fn rehab(&mut self) -> Result<()> {
if self.money < 2800 {
self.clear_screen();
println!(
"\nYOU DON'T HAVE ENOUGH MONEY FOR REHAB...\nIT COSTS 2800 AND YOU ONLY HAVE {}\n",
self.money
);
self.wait_for_enter()?;
return Ok(());
}
self.money -= 2800;
for i in 0..6 {
self.clear_screen();
println!("{}", self.read_file(&format!("data/rehab{}.txt", i + 1))?);
self.wait_for_enter()?;
}
self.health += 65;
if self.health > 100 {
self.health = 100;
}
Ok(())
}
fn mirror(&mut self) -> Result<()> {
self.clear_screen();
let mirror_index = match self.health {
h if h >= 90 => 0,
h if h >= 80 => 1,
h if h >= 70 => 2,
h if h >= 60 => 3,
h if h >= 50 => 4,
h if h >= 40 => 5,
h if h >= 30 => 6,
h if h >= 20 => 7,
h if h >= 10 => 8,
_ => 9,
};
println!("{}", self.read_file(&format!("data/mirror{}.txt", mirror_index + 1))?);
if self.health < 35 {
self.is_suicide = true;
}
self.wait_for_enter()?;
Ok(())
}
fn suicide(&mut self) -> Result<()> {
self.clear_screen();
println!("{}", self.read_file(OVER)?);
self.wait_for_enter()?;
self.is_over = true;
Ok(())
}
}
fn main() -> Result<()> {
// Initialize BASS
if BASS_Init(-1, 44100, 0, std::ptr::null_mut(), std::ptr::null_mut()) == 0 {
let error_code = BASS_ErrorGetCode();
eprintln!("Error initializing BASS library: {}", error_code);
return Ok(());
}
let mut game = GameState::new();
let mut rng = rand::thread_rng();
// Show intro
println!("{}", game.read_file(DESC1)?);
game.wait_for_enter()?;
game.clear_screen();
// Start background music
let song_index = rng.gen_range(0..12);
if let Err(e) = game.play_music(SONGS_RAND[song_index]) {
eprintln!("Failed to play music: {}", e);
}
println!("{}", game.read_file(OPENING_BANNER)?);
game.wait_for_enter()?;
game.clear_screen();
println!("{}", game.read_file(OPENING_POINT)?);
game.wait_for_enter()?;
game.clear_screen();
// Main game loop
while game.health > 0 && !game.is_over {
game.clear_screen();
if game.turns > 11 {
game.turns = 0;
game.year += 1;
}
if game.money < 0 {
game.money = 0;
}
println!(
"date: {}, {} health: {} money: {}\n\n{}",
MONTHS[game.turns], game.year, game.health, game.money,
game.read_file(MENU)?
);
if game.is_suicide {
println!("PRESS 8 TO TRY AND SUICIDE");
}
match game.get_input()? {
1 => {
game.stop_music();
let song_index = rng.gen_range(0..12);
if let Err(e) = game.play_music(SONGS_RAND[song_index]) {
eprintln!("Failed to change music: {}", e);
}
},
2 => game.friends()?,
3 => game.drugs()?,
4 => game.get_money()?,
5 => game.rehab()?,
6 => game.mirror()?,
7 => game.is_over = true,
8 if game.is_suicide => game.suicide()?,
_ => {}
}
game.turns += 1;
}
// Show ending
game.clear_screen();
println!("{}", game.read_file(GAME_END)?);
game.wait_for_enter()?;
// Cleanup
game.stop_music();
BASS_Free();
Ok(())
}
[package]
name = "rust_trainspotting_II_game"
version = "0.1.0"
edition = "2021"
[dependencies]
rand = "0.8"
bass-sys = "2.1"
anyhow = "1.0"
use std::fs::File;
use std::io::{self, BufRead, BufReader, Write};
use std::process::Command;
use std::collections::HashMap;
use rand::prelude::*;
use anyhow::{Result, Context as _};
// const MAX_STRING_LENGTH: usize = 1000;
// const MAX_KEYWORDS: usize = 20;
// const MAX_REPLIES: usize = 50;
const MAX_MEMORY: usize = 15;
#[derive(Default)]
struct ArraySet {
keywords: Vec<String>,
replies: Vec<String>,
}
#[derive(Default)]
struct ChatBot {
key_reply: Vec<ArraySet>,
default_replies: Vec<String>,
memory: Vec<String>,
word_swaps: HashMap<String, String>,
rng: ThreadRng,
single_line_mode: bool,
}
impl ChatBot {
fn new() -> Self {
Self {
key_reply: Vec::new(),
default_replies: Vec::new(),
memory: Vec::with_capacity(MAX_MEMORY),
word_swaps: HashMap::new(),
rng: thread_rng(),
single_line_mode: true,
}
}
fn load_arrays(&mut self, filename: &str) -> Result<()> {
let file = File::open(filename)
.with_context(|| format!("Failed to open file: {}", filename))?;
let reader = BufReader::new(file);
let mut current_set: Option<ArraySet> = None;
for line in reader.lines() {
let line = line?;
if line.starts_with("d1:") {
self.default_replies.push(line[3..].to_string());
} else if line.starts_with("k:") {
if current_set.is_some() && !current_set.as_ref().unwrap().replies.is_empty() {
if let Some(set) = current_set.take() {
self.key_reply.push(set);
}
}
if current_set.is_none() {
current_set = Some(ArraySet::default());
}
if let Some(set) = &mut current_set {
set.keywords.push(line[2..].to_string());
}
} else if line.starts_with("r:") {
if let Some(set) = &mut current_set {
set.replies.push(line[2..].to_string());
}
}
}
if let Some(set) = current_set {
self.key_reply.push(set);
}
println!("Number of keywords-replies pair groups: {}", self.key_reply.len());
Ok(())
}
fn load_swap_words(&mut self, filename: &str) -> Result<()> {
let file = File::open(filename)
.with_context(|| format!("Failed to open swap words file: {}", filename))?;
let reader = BufReader::new(file);
for line in reader.lines() {
let line = line?;
if line.starts_with("s:") {
if let Some(pos) = line[2..].find('>') {
let (word_in, word_out) = line[2..].split_at(pos);
self.word_swaps.insert(
word_in.to_string(),
word_out[1..].to_string()
);
}
}
}
Ok(())
}
fn swap_words(&self, input: &str) -> String {
input
.split_whitespace()
.map(|word| {
self.word_swaps
.get(word)
.map_or(word.to_string(), |w| w.clone())
})
.collect::<Vec<_>>()
.join(" ")
}
fn isolate_punctuation(s: &str) -> String {
s.chars()
.map(|c| {
if "?!,.:;<>(){}[]".contains(c) {
format!(" {} ", c)
} else {
c.to_string()
}
})
.collect()
}
fn process_reply(&mut self, reply: &str, user_input: &str) -> String {
if !reply.ends_with('*') {
return reply.to_string();
}
let reply = &reply[..reply.len() - 1];
if self.memory.len() < MAX_MEMORY {
self.memory.push(user_input.to_string());
}
for set in &self.key_reply {
for keyword in &set.keywords {
if user_input.contains(keyword.as_str()) {
if let Some(rest) = user_input.split(keyword.as_str()).nth(1) {
let swapped = self.swap_words(rest);
return format!("{} {}", reply, swapped);
}
}
}
}
reply.to_string()
}
fn user_question(&mut self, txt: &str) -> String {
let mut matched_replies = Vec::new();
let mut found = false;
for set in &self.key_reply {
for keyword in &set.keywords {
if txt.contains(keyword.as_str()) {
if let Some(reply) = set.replies.choose(&mut self.rng).cloned() {
matched_replies.push(reply);
found = true;
break;
}
}
}
}
let processed_replies: Vec<String> = matched_replies.into_iter()
.map(|reply| self.process_reply(&reply, txt))
.collect();
if !processed_replies.is_empty() {
if self.single_line_mode {
processed_replies.join(" | ")
} else {
processed_replies.join("\n")
}
} else if !found && !self.default_replies.is_empty() {
self.default_replies
.choose(&mut self.rng)
.cloned()
.unwrap_or_else(|| "I don't understand. Can you rephrase that?".to_string())
} else {
"I don't understand. Can you rephrase that?".to_string()
}
}
fn commands(&mut self, txt: &str) -> String {
if txt.starts_with("/") {
match txt {
"/single" => {
self.single_line_mode = true;
return "Switched to single-line mode.".to_string();
}
"/multi" => {
self.single_line_mode = false;
return "Switched to multi-line mode.".to_string();
}
_ => {}
}
}
let isolated = Self::isolate_punctuation(txt);
let lowercase = isolated.to_lowercase();
self.user_question(&lowercase)
}
fn speak(&self, text: &str) -> Result<()> {
Command::new("voice")
.args(["-r", "-1", "-n", "Microsoft David Desktop", text])
.spawn()
.with_context(|| "Failed to start TTS process")?
.wait()
.with_context(|| "Failed to wait for TTS process")?;
Ok(())
}
}
fn main() -> Result<()> {
println!("CHATBOT DANNY IN RUST VERSION 1.0.0");
println!("Commands:");
println!(" /single - Switch to single-line mode");
println!(" /multi - Switch to multi-line mode");
println!(" quit - Exit the program");
let mut chatbot = ChatBot::new();
chatbot.load_arrays("database.txt")?;
chatbot.load_swap_words("swapwords.txt")?;
let stdin = io::stdin();
let mut stdout = io::stdout();
loop {
print!("> ");
stdout.flush()?;
let mut input = String::new();
stdin.lock().read_line(&mut input)?;
let input = input.trim();
if input == "quit" {
break;
}
let response = chatbot.commands(input);
if chatbot.single_line_mode {
println!("{}", response);
chatbot.speak(&response)?;
} else {
for line in response.lines() {
println!("{}", line);
chatbot.speak(line)?;
}
}
}
Ok(())
}
use std::{thread, time::Duration};
fn main() {
let mut a = 0.0f32;
let mut b = 0.0f32;
let mut z = vec![0.0f32; 1760];
let mut buffer = vec![' '; 1760];
// Clear screen
print!("\x1b[2J");
loop {
// Reset buffers
buffer.fill(' ');
z.fill(0.0);
let mut j = 0.0f32;
while j < 6.28 {
let mut i = 0.0f32;
while i < 6.28 {
let c = i.sin();
let d = j.cos();
let e = a.sin();
let f = j.sin();
let g = a.cos();
let h = d + 2.0;
let d = 1.0 / (c * h * e + f * g + 5.0);
let l = i.cos();
let m = b.cos();
let n = b.sin();
let t = c * h * g - f * e;
let x = (40.0 + 30.0 * d * (l * h * m - t * n)) as i32;
let y = (12.0 + 15.0 * d * (l * h * n + t * m)) as i32;
let o = (x + 80 * y) as usize;
let luminance = (8.0 * ((f * e - c * d * g) * m - c * d * e - f * g - l * d * n)) as i32;
if y > 0 && y < 22 && x > 0 && x < 80 && d > z[o] {
z[o] = d;
buffer[o] = ".,-~:;=!*#$@".chars().nth((luminance.max(0) as usize).min(11)).unwrap();
}
i += 0.02;
}
j += 0.07;
}
// Move cursor to home position
print!("\x1b[H");
// Print the frame
for k in 0..1760 {
if k % 80 == 0 {
println!();
} else {
print!("{}", buffer[k]);
}
}
a += 0.04;
b += 0.02;
thread::sleep(Duration::from_micros(30000));
}
}
module example;
import std::math;
import std::io;
import std::thread;
import libc;
fn void main()
{
float a1 = 0;
float b1 = 0;
float i;
float j;
int k;
float[1760] z;
char[1760] b;
io::printf("\x1b[2J");
while (true)
{
// Initialize arrays
for (k = 0; k < 1760; k++)
{
b[k] = ' ';
z[k] = 0;
}
for (j = 0; j < 6.28; j += 0.07)
{
for (i = 0; i < 6.28; i += 0.02)
{
float c = math::sin(i);
float d = math::cos(j);
float e = math::sin(a1);
float f = math::sin(j);
float g = math::cos(a1);
float h = d + 2;
float d2 = 1 / (c * h * e + f * g + 5);
float l = math::cos(i);
float m = math::cos(b1);
float n = math::sin(b1);
float t = c * h * g - f * e;
int x = 40 + (int)(30 * d2 * (l * h * m - t * n));
int y = 12 + (int)(15 * d2 * (l * h * n + t * m));
int o = x + 80 * y;
int n2 = (int)(8 * ((f * e - c * d * g) * m - c * d * e - f * g - l * d * n));
if (y > 0 && y < 22 && x > 0 && x < 80 && d2 > z[o])
{
z[o] = d2;
b[o] = n2 > 0 ? ".,-~:;=!*#$@"[n2] : ".,-~:;=!*#$@"[0];
}
}
}
io::printf("\x1b[H");
for (k = 0; k < 1761; k++)
{
libc::putchar(k % 80 ? b[k] : 10);
}
a1 += 0.04;
b1 += 0.02;
thread::sleep_ms(30); // Replace usleep with thread::sleep_ms
}
}
module c3_danny_std;
import std;
import libc;
import std::math::random;
extern fn char* strdup(char* s);
const int MAX_STRING_LENGTH = 1000;
const int MAX_ARRAY_SIZE = 1000;
const int MAX_KEYWORDS = 50;
const int MAX_REPLIES = 50;
const int MAX_MATCHES = 10;
const int MAX_SWAP_WORDS = 100;
const int MAX_MEMORY = 15;
/*
s:are>am
s:am>are
s:were>was
s:was>were
s:you>i
s:i>you
s:your>my
s:my>your
s:i've>you've
s:you've>i've
s:i'm>you're
s:you're>i'm
s:me>you
s:i'll>you'll
s:you'll>i'll
*/
String[] word_in = {
"are",
"am",
"were",
"was",
"you",
"i",
"your",
"my",
"i've",
"you've",
"i'm",
"you're",
"me",
"i'll",
"you'll",
};
String[] word_out = {
"am",
"are",
"was",
"were",
"i",
"you",
"my",
"your",
"you've",
"i've",
"you're",
"i'm",
"you",
"you'll",
"i'll",
};
String[MAX_SWAP_WORDS] wordIn;
String[MAX_SWAP_WORDS] wordOut;
int wCnt = 0;
String[MAX_MEMORY] memory;
int memoryCount = 0;
struct ArraySet {
String[MAX_KEYWORDS] keywords;
String[MAX_REPLIES] replies;
int keywordCount;
int replyCount;
}
ArraySet[MAX_ARRAY_SIZE] g_Key_Reply;
int g_Key_ReplyCount = 0;
String[MAX_ARRAY_SIZE] default_replies;
int default_reply_count = 0;
fn char* safe_strdup(char* s) {
if (!s) return null;
char* result = strdup(s);
if (!result) {
io::printfn("%s Memory allocation failed in safe_strdup\n", &std::io::stderr);
return null;
}
return result;
}
fn char* isolatePunctuation(char* s) {
char* b = malloc(libc::strlen((ZString)s) * 3 + 1);
if (!b) return null;
int j = 0;
for (int i = 0; s[i]; i++) {
if (libc::strchr("?!,.:;<>(){}[]", s[i])) {
b[j++] = ' ';
b[j++] = s[i];
b[j++] = ' ';
} else {
b[j++] = s[i];
}
}
b[j] = '\0';
return b;
}
fn void loadArrays(String filename) {
File! f = io::file::open(filename, "r");
if (catch error = f) {
io::printfn("Error opening file: %s: %s\n", filename, error);
return;
}
defer (void)f.close();
// String line; no needs for this
int currentSet = -1;
while (try line = io::treadline(&f)) { // line is created here automatically
if (line.len < 3) {
// Skip lines that aren't long enough
continue;
}
if (f.eof()) break;
if (line[0..2] == "d1:") { //(strncmp(line, "d1:", 3) == 0) {
default_replies[default_reply_count++] = line[3..]; //strcpy(default_replies[default_reply_count++], line + 3);
}
if (line[0..1] == "k:") { //(line[0] == 'k' && line[1] == ':') {
if (currentSet == -1 || g_Key_Reply[currentSet].replyCount > 0) {
currentSet++;
}
if (currentSet >= MAX_ARRAY_SIZE) {
io::printfn("Error: too many keyword-reply pairs\n");
break;
}
if (g_Key_Reply[currentSet].keywordCount < 50) {
String keyword = string::tformat(" %s ", line[2..]);
g_Key_Reply[currentSet].keywords[g_Key_Reply[currentSet].keywordCount] = keyword; //line[2..];//strcpy(g_Key_Reply[currentSet].keywords[g_Key_Reply[currentSet].keywordCount], line + 2);
g_Key_Reply[currentSet].keywordCount++;
g_Key_ReplyCount = currentSet + 1;
// g_Key_Reply[currentSet].replyCount = 0;
} else {
io::printfn("Error: too many keywords for keyword-reply pair %d\n", currentSet);
}
} else if (line[0..1] == "r:") { //(line[0] == 'r' && line[1] == ':') {
if (g_Key_Reply[currentSet].replyCount < 50) {
g_Key_Reply[currentSet].replies[g_Key_Reply[currentSet].replyCount] = line[2..];//strcpy(g_Key_Reply[currentSet].replies[g_Key_Reply[currentSet].replyCount], line + 2);
g_Key_Reply[currentSet].replyCount++;
// g_Key_Reply[currentSet].keywordCount = 0;
} else {
io::printfn("Error: too many replies for keyword %s\n", g_Key_Reply[currentSet].keywords[g_Key_Reply[currentSet].keywordCount - 1]);
}
}
}
//fclose(file);
io::printfn("number of keywords-replies pair groups %d\n", currentSet);
}
fn void loadSwapWords(String filename) {
File! f = io::file::open(filename, "r");
if (catch error = f) {
io::printfn("Error opening file: %s: %s\n", filename, error);
return;
}
defer (void)f.close();
String line;
while ((line = io::treadline(&f)!!) && wCnt < MAX_SWAP_WORDS) {
if (line.len < 3) {
// Skip lines that aren't long enough
continue;
}
if (f.eof()) break;
//line[strcspn(line, "\n")] = 0; // Remove newline
if (line[0..1] == "s:") { //(line[0] == 's' && line[1] == ':') {
int indexOfdelimiter = (int)line.index_of(">")!!;
// if (indexOfdelimiter != null) {
wordIn[wCnt] = line[2..indexOfdelimiter];//strcpy(wordIn[wCnt], line + 2);
wordOut[wCnt] = line[indexOfdelimiter + 1..line.len-1];//strcpy(wordOut[wCnt], delimiter + 1);
wCnt++;
// }
// char* delimiter = strchr(line + 2, '>');
// if (delimiter) {
// *delimiter = '\0';
// strcpy(wordIn[wCnt], line + 2);
// strcpy(wordOut[wCnt], delimiter + 1);
// wCnt++;
// }
}
}
//fclose(file);
}
fn String swapWords(String input) {
if (input == "") return "";
// DString output;
String output;
// output.temp_init();
String[] words = input.tsplit(" ");
String temp = "";
foreach (j, word: words) {
String result = word;
bool swapped = false;
foreach (i, swap_word: word_in) {
if (word == word_in[i]) {
result = word_out[i];
break;
}
}
output = String.tconcat(output, result);
// if (j < words.len - 1) output.append(" ");
if (j < words.len - 1) output = String.tconcat(output, " ");
}
// return output.str_view();
return output;
}
fn String processReply(String reply, String userInput) {
if (reply == "" || userInput == "") return reply;
if (reply[reply.len - 1] == '*') {
// If the reply doesn't end with an asterisk, don't swap words
// return reply;
// } else {
reply = reply[0:reply.len-1]; // Remove the asterisk
// reply = reply[0..reply.len-2];
}
String keyword = "";
for (int i = 0; i < g_Key_ReplyCount; i++) {
for (int j = 0; j < g_Key_Reply[i].keywordCount; j++) {
if (userInput.contains(g_Key_Reply[i].keywords[j])) {
keyword = g_Key_Reply[i].keywords[j];
break;
}
}
if (keyword != "") break;
}
if (keyword != "") {
int keywordIndex = (int)userInput.index_of(keyword)!!;
String tail = userInput[keywordIndex + keyword.len..];
String swappedTail = swapWords(tail);
if (swappedTail != "") {
reply = String.tconcat(reply, " ");
reply = String.tconcat(reply, swappedTail);
}
}
// }
return reply;
}
// fn String userQuestion(String txt) {
// String[MAX_MATCHES] matchedReplies;
// int matchCount = 0;
// bool isMatch = false;
// String finalReply = "";
// // Find matching replies
// for (int i = 0; i < g_Key_ReplyCount && matchCount < MAX_MATCHES; i++) {
// bool foundInGroup = false;
// for (int j = 0; j < g_Key_Reply[i].keywordCount; j++) {
// if (txt.contains(g_Key_Reply[i].keywords[j])) {
// if (!foundInGroup) {
// int replyIndex = random::rand(g_Key_Reply[i].replyCount);
// matchedReplies[matchCount++] = g_Key_Reply[i].replies[replyIndex];
// foundInGroup = true;
// isMatch = true;
// }
// }
// }
// }
// // Process replies
// if (matchCount > 0 && isMatch && matchCount <= MAX_MATCHES) {
// foreach (reply : matchedReplies[0..matchCount]) {
// String processed = processReply(reply, txt);
// if (processed != "") {
// if (finalReply != "") {
// finalReply = String.tconcat(finalReply, " ");
// }
// finalReply = String.tconcat(finalReply, processed);
// }
// }
// return finalReply.trim();
// }
// // Default reply
// return default_replies[random::rand(default_reply_count)];
// }
fn String userQuestion(String txt) {
String response = "I don't understand. Can you rephrase that?";
String[MAX_MATCHES] matchedReplies;
int matchCount = 0;
bool isMatch = false;
String combinedReply = "";
for (int i = 0; i < g_Key_ReplyCount && matchCount < MAX_MATCHES; i++) {
for (int j = 0; j < g_Key_Reply[i].keywordCount; j++) {
if (txt.contains(g_Key_Reply[i].keywords[j])) {
int replyIndex = random::rand(g_Key_Reply[i].replyCount);
matchedReplies[matchCount++] = g_Key_Reply[i].replies[replyIndex];
isMatch = true;
break;
}
}
}
if (matchCount > 0 && isMatch && matchCount <= MAX_MATCHES) {
for (int i = 0 ; i < matchCount ; i++) {
String reply = matchedReplies[i];
if (reply[reply.len-1] == '*') {
combinedReply = String.tconcat(combinedReply, processReply(reply, txt));
} else {
combinedReply = String.tconcat(combinedReply, reply);
}
combinedReply = String.tconcat(combinedReply, " ");
}
response = combinedReply;
} else if (!isMatch) {
int defaultIndex = random::rand(default_reply_count);
response = default_replies[defaultIndex];
}
return response;
}
fn String commands(String txt) {
// String isolated = isolatePunctuation(txt);
// for (int i = 0; isolated[i]; i++) {
// isolated[i] = tolower(isolated[i]);
// }
String text = string::tformat(" %s ", txt);
String response = userQuestion(text);
// free(isolated);
return response;
}
fn void speak(String text) {
String command;
command = "voice -r -1 -n \"Microsoft David Desktop\" ";
String text2 = string::tformat("\"%s\"",text);
// command = string::tformat("%s \"%s\"", command, text2);
command = String.tconcat(command, text2);
// command = String.tconcat(text2, "\"");
// String.tconcat(command, text2);
libc::system((ZString)command);
}
fn int main() {
libc::srand((uint)libc::time(null));
loadArrays("./database.txt");
// loadSwapWords("./swapwords.txt");
// for (int i = 0; i < wCnt; i++) {
// io::printfn("wordIn[%d] = %s, wordOut[%d] = %s\n", i, wordIn[i], i, wordOut[i]);
// }
io::printfn("CHATBOT DANNY IN C3 PROGRAMMING LANGUAGE VERSION 1.1.6.5 (C) RON77\n");
String input;
String response;
while (true) {
io::printf("> ");
//if (fgets(input, sizeof(input), stdin) == NULL) {
input = io::treadline()!!;
// input[strcspn(input, "\n")] = 0; // Remove newline
if (input == "quit") break;
response = commands(input);
if (response != "") {
// Split the response into separate lines and speak each one
String line = response;
while (line != "") {
io::printn(line);
io::printn("\n");
speak(line);
line = "";
}
// free(response);
} else {
io::printfn("An error occurred while processing your input.\n");
}
}
return 0;
}