mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-22 23:26:40 -08:00
rust implementation
This commit is contained in:
8
21_Calendar/rust/Cargo.toml
Normal file
8
21_Calendar/rust/Cargo.toml
Normal file
@@ -0,0 +1,8 @@
|
||||
[package]
|
||||
name = "rust"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
3
21_Calendar/rust/README.md
Normal file
3
21_Calendar/rust/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
|
||||
|
||||
Conversion to [Rust](https://www.rust-lang.org/) by [Uğur Küpeli](https://github.com/ugurkupeli)
|
||||
152
21_Calendar/rust/src/main.rs
Normal file
152
21_Calendar/rust/src/main.rs
Normal file
@@ -0,0 +1,152 @@
|
||||
use std::io::stdin;
|
||||
|
||||
const WIDTH: usize = 64;
|
||||
const DAYS_WIDTH: usize = WIDTH / 8;
|
||||
const MONTH_WIDTH: usize = WIDTH - (DAYS_WIDTH * 2);
|
||||
const DAY_NUMS_WIDTH: usize = WIDTH / 7;
|
||||
|
||||
const DAYS: [&str; 7] = [
|
||||
"SUNDAY",
|
||||
"MONDAY",
|
||||
"TUESDAY",
|
||||
"WEDNESDAY",
|
||||
"THURSDAY",
|
||||
"FRIDAY",
|
||||
"SATURDAY",
|
||||
];
|
||||
|
||||
fn main() {
|
||||
println!("\n\t\t CALENDAR");
|
||||
println!("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
|
||||
|
||||
let (starting_day, leap_year) = prompt();
|
||||
let (months, total_days) = get_months_and_days(leap_year);
|
||||
|
||||
let mut days_passed = 0;
|
||||
let mut current_day_index = DAYS.iter().position(|d| *d == starting_day).unwrap();
|
||||
|
||||
for (month, days) in months {
|
||||
print_header(month, days_passed, total_days - days_passed);
|
||||
print_days(&mut current_day_index, days);
|
||||
days_passed += days as u16;
|
||||
println!("\n");
|
||||
}
|
||||
}
|
||||
|
||||
fn prompt() -> (String, bool) {
|
||||
let mut day = String::new();
|
||||
|
||||
loop {
|
||||
println!("\nFirst day of the year?");
|
||||
if let Ok(_) = stdin().read_line(&mut day) {
|
||||
day = day.trim().to_uppercase();
|
||||
if DAYS.contains(&day.as_str()) {
|
||||
break;
|
||||
} else {
|
||||
day.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut leap = false;
|
||||
|
||||
loop {
|
||||
println!("Is this a leap year?");
|
||||
let mut input = String::new();
|
||||
if let Ok(_) = stdin().read_line(&mut input) {
|
||||
match input.to_uppercase().trim() {
|
||||
"Y" | "YES" => {
|
||||
leap = true;
|
||||
break;
|
||||
}
|
||||
"N" | "NO" => break,
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
println!();
|
||||
(day, leap)
|
||||
}
|
||||
|
||||
fn get_months_and_days(leap_year: bool) -> (Vec<(String, u8)>, u16) {
|
||||
let months = [
|
||||
"JANUARY",
|
||||
"FEBUARY",
|
||||
"MARCH",
|
||||
"APRIL",
|
||||
"MAY",
|
||||
"JUNE",
|
||||
"JULY",
|
||||
"AUGUST",
|
||||
"SEPTEMBER",
|
||||
"OCTOBER",
|
||||
"NOVEMBER",
|
||||
"DECEMBER",
|
||||
];
|
||||
|
||||
let mut months_with_days = Vec::new();
|
||||
let mut total_days: u16 = 0;
|
||||
|
||||
for (i, month) in months.iter().enumerate() {
|
||||
let days = if i == 1 {
|
||||
if leap_year {
|
||||
29u8
|
||||
} else {
|
||||
28
|
||||
}
|
||||
} else if if i < 7 { (i % 2) == 0 } else { (i % 2) != 0 } {
|
||||
31
|
||||
} else {
|
||||
30
|
||||
};
|
||||
|
||||
total_days += days as u16;
|
||||
months_with_days.push((month.to_string(), days));
|
||||
}
|
||||
|
||||
(months_with_days, total_days)
|
||||
}
|
||||
|
||||
fn print_between(s: String, w: usize, star: bool) {
|
||||
let s = format!(" {s} ");
|
||||
if star {
|
||||
print!("{:*^w$}", s);
|
||||
return;
|
||||
}
|
||||
print!("{:^w$}", s);
|
||||
}
|
||||
|
||||
fn print_header(month: String, days_passed: u16, days_left: u16) {
|
||||
print_between(days_passed.to_string(), DAYS_WIDTH, true);
|
||||
print_between(month.to_string(), MONTH_WIDTH, true);
|
||||
print_between(days_left.to_string(), DAYS_WIDTH, true);
|
||||
println!();
|
||||
|
||||
for d in DAYS {
|
||||
let d = d.chars().nth(0).unwrap();
|
||||
print_between(d.to_string(), DAY_NUMS_WIDTH, false);
|
||||
}
|
||||
println!();
|
||||
|
||||
println!("{:*>WIDTH$}", "");
|
||||
}
|
||||
|
||||
fn print_days(current_day_index: &mut usize, days: u8) {
|
||||
let mut current_date = 1u8;
|
||||
|
||||
print!("{:>w$}", " ", w = DAY_NUMS_WIDTH * *current_day_index);
|
||||
|
||||
for _ in 1..=days {
|
||||
print_between(current_date.to_string(), DAY_NUMS_WIDTH, false);
|
||||
|
||||
if ((*current_day_index + 1) % 7) == 0 {
|
||||
*current_day_index = 0;
|
||||
println!();
|
||||
} else {
|
||||
*current_day_index += 1;
|
||||
}
|
||||
|
||||
current_date += 1;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user