Skip to content

Commit ed068bd

Browse files
author
P Marques
committed
kinema game initial rust implementation
1 parent 9e724c1 commit ed068bd

File tree

2 files changed

+114
-0
lines changed

2 files changed

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

0 commit comments

Comments
 (0)