Skip to content

Commit daa961e

Browse files
Merge pull request #927 from marquesrs/kinema-rust-implementation
Rust implementation for the game Kinema
2 parents 244ca46 + 3d677c9 commit daa961e

File tree

2 files changed

+121
-0
lines changed

2 files changed

+121
-0
lines changed

52_Kinema/rust/Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[package]
2+
name = "rust"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
rand = "0.9.0"

52_Kinema/rust/src/main.rs

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/** KINEMA BY RICHARD PAV
2+
* https://github.com/coding-horror/basic-computer-games/blob/main/52_Kinema/kinema.bas
3+
* Direct conversion from BASIC to Rust by Pablo Marques (marquesrs).
4+
* As a faithful translation, many of the code here are done in an unrecommended way by
5+
* today's standards.
6+
*
7+
* ATTENTION: The original code has mathematical imprecision and uses simplifications
8+
* instead of the real formulation, which could lead to incorrect results. I have solved
9+
* this issue, but kept the old lines. To compile the original version, just uncomment the
10+
* code with the OLD label and comment the lines with the NEW label.
11+
* example: gravity is now 9.81 instead of 10; Inputs and outputs are now float not integers...
12+
*
13+
* FORMULATION
14+
* A BALL IS THROWN UPWARDS AT 9,36 METERS PER SECOND.
15+
* HOW HIGH WILL IT GO (IN METERS)? (9,36 ^2) / (2 * 9,81) = 4,465321101
16+
* HOW LONG UNTIL IT RETURNS (IN SECONDS)? 2*(9,36 / 9,81) = 1,908256881
17+
* WHAT WILL ITS VELOCITY BE AFTER 1,09 SECONDS? 9,36- 9,81 * 1,09 = −1,3329
18+
*
19+
* 17/02/25
20+
*/
21+
22+
use std::io::Write;
23+
use rand::Rng;
24+
25+
fn subroutine(a: f64, q: &mut i32) {
26+
std::io::stdout().flush().unwrap();
27+
//500 INPUT G
28+
let mut input = String::new();
29+
let g;
30+
loop {
31+
std::io::stdin().read_line(&mut input).unwrap();
32+
match input.trim().parse::<f64>() {
33+
Ok(e) => { g = e; break; },
34+
Err(_) => { print!("\nINVALID. TRY AGAIN: "); continue; },
35+
};
36+
}
37+
//502 IF ABS((G-A)/A)<.15 THEN 510
38+
if f64::abs((g-a)/a) < 0.15 {
39+
//510 PRINT "CLOSE ENOUGH."
40+
print!("CLOSE ENOUGH.");
41+
//511 Q=Q+1
42+
*q = *q + 1;
43+
}
44+
else {
45+
//504 PRINT "NOT EVEN CLOSE...."
46+
print!("NOT EVEN CLOSE...");
47+
//506 GOTO 512
48+
}
49+
//512 PRINT "CORRECT ANSWER IS ";A
50+
print!("\nCORRECT ANSWER IS {a:.2}\n");
51+
//520 PRINT
52+
//530 RETURN
53+
}
54+
55+
fn main() {
56+
let mut rng = rand::rng();
57+
58+
//10 PRINT TAB(33);"KINEMA"
59+
//20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"
60+
//30 PRINT: PRINT: PRINT
61+
//100 PRINT
62+
//105 PRINT
63+
print!("{}KINEMA\n{}CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n\n\n\n",
64+
" ".repeat(33),
65+
" ".repeat(15)
66+
);
67+
loop {
68+
//106 Q=0
69+
let mut q = 0;
70+
//110 V=5+INT(35*RND(1))
71+
let v: f64 = 5.0 + 35.0 * rng.random_range(0.0..1.0);
72+
//111 PRINT "A BALL IS THROWN UPWARDS AT";V;"METERS PER SECOND."
73+
//112 PRINT
74+
print!("\nA BALL IS THROWN UPWARDS AT {v:.2} METERS PER SECOND.\n");
75+
//115 A=.05*V^2
76+
//let a = 0.05 * v.powf(2.0); // OLD
77+
let mut a = v.powf(2.0) / (2.0 * 9.81); // NEW
78+
//116 PRINT "HOW HIGH WILL IT GO (IN METERS)";
79+
print!("\nHOW HIGH WILL IT GO (IN METERS)? ");
80+
81+
//117 GOSUB 500
82+
subroutine(a, &mut q);
83+
84+
//120 A=V/5
85+
//a = v / 5.0; // OLD
86+
a = 2.0 * v / 9.81; // NEW
87+
//122 PRINT "HOW LONG UNTIL IT RETURNS (IN SECONDS)";
88+
print!("\nHOW LONG UNTIL IT RETURNS (IN SECONDS)? ");
89+
//124 GOSUB 500
90+
subroutine(a, &mut q);
91+
92+
//130 T=1+INT(2*V*RND(1))/10
93+
let t = 1.0 + (2.0 * v * rng.random_range(0.0..1.0) / 10.0);
94+
//132 A=V-10*T
95+
a = v + (-9.81 * t);
96+
//134 PRINT "WHAT WILL ITS VELOCITY BE AFTER";T;"SECONDS";
97+
print!("\nWHAT WILL ITS VELOCITY BE AFTER {t:.2} SECONDS? ");
98+
99+
//136 GOSUB 500
100+
subroutine(a, &mut q);
101+
102+
//140 PRINT
103+
//150 PRINT Q;"RIGHT OUT OF 3.";
104+
print!("\n{q} RIGHT OUT OF 3.\n");
105+
//160 IF Q<2 THEN 100
106+
if q < 2 {
107+
continue;
108+
}
109+
//170 PRINT " NOT BAD."
110+
//print!(" NOT BAD.");
111+
//180 GOTO 100
112+
}
113+
//999 END
114+
}

0 commit comments

Comments
 (0)