Skip to content

Commit e8fb61f

Browse files
Merge pull request #900 from RFigCon/main
Implementation of Train in Lua and D
2 parents 998110f + a4cff3b commit e8fb61f

File tree

4 files changed

+380
-0
lines changed

4 files changed

+380
-0
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html).
2+
3+
Conversion to [MiniScript](https://dlang.org).
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import std.stdio;
2+
import std.random : uniform;
3+
4+
float abs(float num) {
5+
if(num<0){
6+
return num*-1;
7+
}
8+
9+
return num;
10+
}
11+
12+
void main() {
13+
14+
writeln("\nTIME - SPEED DISTANCE EXERCISE");
15+
16+
bool keep_playing = true;
17+
float error_margin = 5.0;
18+
19+
while(keep_playing){
20+
int car_speed = uniform!"[]"(40,65); //Random number between 40 and 65
21+
int delta_time = uniform!"(]"(4,20); //Between 5 and 20
22+
int train_speed = uniform!"[)"(20,40); //Between 20 and 39; This is the default if not specified: uniform(x,y)
23+
24+
writeln("\nA CAR TRAVELING AT ", car_speed, " MPH CAN MAKE A CERTAIN TRIP IN ", delta_time,
25+
" HOURS LESS THAN A TRAIN TRAVELING AT ", train_speed, "MPH." );
26+
27+
float input;
28+
write("HOW LONG DOES THE TRIP TAKE BY CAR? ");
29+
readf!"%f\n"(input);
30+
31+
float car_time = cast(float)delta_time * train_speed / (car_speed - train_speed);
32+
int percent = cast(int)( abs(car_time-input) * 100 / car_time + .5);
33+
34+
if(percent > error_margin){
35+
writeln("SORRY. YOU WERE OFF BY ", percent, " PERCENT.");
36+
}else{
37+
writeln("GOOD! ANSWER WITHIN ", percent, " PERCENT.");
38+
}
39+
writeln("CORRECT ANSWER IS ", car_time, " HOURS.");
40+
41+
string answer;
42+
write("\nANOTHER PROBLEM (YES OR NO)? ");
43+
readf!"%s\n"(answer);
44+
45+
if( !(answer == "YES" || answer == "Y" || answer == "yes" || answer == "y") ){
46+
keep_playing = false;
47+
}
48+
}
49+
50+
}

90_Tower/lua/tower.lua

Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
print [[
2+
3+
TOWERS
4+
CREATIVE COMPUTING MORRISTOWN, NEW JERSY
5+
6+
7+
]]
8+
9+
local MAX_DISKS <const> = 7
10+
local MAX_DISK_SIZE <const> = 15
11+
local MAX_MOVES <const> = 128
12+
local NUM_TOWERS <const> = 3
13+
14+
local towers = {
15+
{ size = 0, elem = {} },
16+
{ size = 0, elem = {} },
17+
{ size = 0, elem = {} },
18+
}
19+
20+
local total_disks
21+
function ask_how_many_disks()
22+
23+
local keep_asking = true
24+
local input
25+
local errors = 0
26+
27+
while keep_asking do
28+
29+
io.write(string.format("HOW MANY DISKS DO YOU WANT TO MOVE (%d IS MAX)? ", MAX_DISKS) )
30+
input = io.read("*number")
31+
io.read() --get rid of the remaining newline character
32+
33+
if input ~= nil and input>0 and input<=MAX_DISKS then
34+
keep_asking = false
35+
36+
else
37+
errors = errors + 1
38+
if errors > 2 then
39+
print "ALL RIGHT, WISE GUY, IF YOU CAN'T PLAY THE GAME RIGHT, I'LL"
40+
print "JUST TAKE MY PUZZLE AND GO HOME. SO LONG."
41+
os.exit()
42+
end
43+
44+
print "SORRY, BUT I CAN'T DO THAT JOB FOR YOU."
45+
end
46+
end
47+
total_disks = input
48+
end
49+
50+
function init_game()
51+
print("TOWERS OF HANOIR PUZZLE\n") --'\n' indicates a new line
52+
53+
print "YOU MUST TRANSFER THE DISKS FROM THE LEFT TO THE RIGHT TOWER,"
54+
print "ONE AT A TIME, NEVER PUTTING A LARGER DISK ON A SMALLER DISK.\n"
55+
56+
ask_how_many_disks()
57+
58+
print() -- print() already creates a new line at the end, so an empty print leaves an empty line
59+
print "IN THIS PROGRAM, WE SHALL REFER TO DISKS BY NUMERICAL CODE."
60+
print "3 WILL REPRESENT THE SMALLEST DISK, 5 THE NEXT SIZE, 7 THE"
61+
print "NEXT, AND SO ON, UP TO 15. IF YOU DO THE PUZZLE WITH 2 DISKS,"
62+
print "THEIR CODE NAMES WOULD BE 13 AND 15, ETC. THE NEEDLES ARE"
63+
print "NUMBERED FROM LEFT TO RIGHT, 1 TO 3. WE WILL START WITH THE"
64+
print "DISKS ON NEEDLE 1, AND ATTEMPT TO MOVE THEM TO NEEDLE 3.\n"
65+
66+
print "GOOD LUCK!\n"
67+
68+
local i = 1
69+
local max = MAX_DISK_SIZE
70+
while i<= total_disks do
71+
towers[1].elem[i] = max
72+
max = max-2
73+
i = i+1
74+
end
75+
76+
towers[1].size = total_disks
77+
78+
local idx = 2
79+
while idx <= NUM_TOWERS do
80+
towers[idx].size = 0
81+
end
82+
end
83+
84+
function print_towers()
85+
local line = MAX_DISKS
86+
87+
while line > 0 do
88+
local twr = 1
89+
90+
while twr <=3 do
91+
local rpt = 10
92+
local offset = 0
93+
if line <= towers[twr].size then
94+
offset = (towers[twr].elem[line] - 1) / 2
95+
rpt = rpt - offset
96+
end
97+
io.write( string.rep(' ', rpt) )
98+
io.write( string.rep('*', offset) )
99+
io.write '*'
100+
io.write( string.rep('*', offset) )
101+
io.write( string.rep(' ', rpt) )
102+
twr = twr + 1
103+
end
104+
print ''
105+
line = line - 1
106+
end
107+
108+
end
109+
110+
function ask_which_disk()
111+
112+
local keep_asking = true
113+
local input
114+
local errors = 0
115+
while keep_asking do
116+
117+
io.write("WHICH DISK WOULD YOU LIKE TO MOVE? ")
118+
input = io.read("*number")
119+
io.read() --get rid of the remaining newline character
120+
121+
if input==nil or input > MAX_DISK_SIZE or input%2==0 or input <= MAX_DISK_SIZE-(total_disks*2) then
122+
print "ILLEGAL ENTRY... YOU MAY ONLY TYPE 3,5,7,9,11,13 or 15."
123+
errors = errors + 1
124+
if errors > 1 then
125+
print "STOP WASTING MY TIME. GO BOTHER SOMEONE ELSE."
126+
os.exit()
127+
end
128+
129+
--[[
130+
Since there are only 3 towers, it's easier to do an 'if' with three
131+
conditions than to do a loop
132+
]]
133+
elseif towers[1].elem[ towers[1].size ] ~= input and
134+
towers[2].elem[ towers[2].size ] ~= input and
135+
towers[3].elem[ towers[3].size ] ~= input then
136+
137+
print "THAT DISK IS BELOW ANOTHER ONE. MAKE ANOTHER CHOICE."
138+
else
139+
keep_asking = false
140+
end
141+
end
142+
143+
return input
144+
end
145+
146+
function ask_which_needle(dsk)
147+
148+
local keep_asking = true
149+
local input
150+
local errors = 0
151+
152+
while keep_asking do
153+
154+
io.write("PLACE DISK ON WHICH NEEDLE? ")
155+
input = io.read("*number")
156+
io.read() --get rid of the remaining newline character
157+
158+
if input~=nil and towers[input].size > 0 and towers[input].elem[ towers[input].size ] < dsk then
159+
print "YOU CAN'T PLACE A LARGER DISK ON TOP OF A SMALLER ONE,"
160+
print "IT MIGHT CRUSH IT!"
161+
return 0
162+
163+
elseif input~=nil and input>=1 and input<=3 then
164+
keep_asking = false
165+
166+
else
167+
errors = errors + 1
168+
if errors > 1 then
169+
print "I TRIED TO WARN YOU, BUT YOU WOULDN'T LISTEN."
170+
print "BYE BYE, BIG SHOT."
171+
os.exit() --Stop program
172+
else
173+
print "I'LL ASSUME YOU HIT THE WRONG KEY THIS TIME. BUT WATCH IT,"
174+
print "I ONLY ALLOW ONE MISTAKE."
175+
end
176+
end
177+
end
178+
return input
179+
end
180+
181+
function is_game_over()
182+
if towers[1].size == 0 and towers[2].size == 0 then
183+
return true
184+
else
185+
return false
186+
end
187+
end
188+
189+
function game_loop()
190+
local moves = 0
191+
local dsk
192+
local twr_to
193+
local twr_fr
194+
195+
while not is_game_over() do
196+
moves = moves + 1
197+
198+
if moves > MAX_MOVES then
199+
print(string.format("SORRY, BUT I HAVE ORDERS TO STOP IF YOU MAKE MORE THAN %d MOVES.", MAX_MOVES))
200+
os.exit()
201+
end
202+
203+
204+
repeat
205+
dsk = ask_which_disk()
206+
twr_to = ask_which_needle(dsk)
207+
until twr_to ~= 0
208+
209+
210+
if towers[1].elem[ towers[1].size ] == dsk then
211+
twr_fr = 1
212+
elseif towers[2].elem[ towers[2].size ] == dsk then
213+
twr_fr = 2
214+
else
215+
twr_fr = 3
216+
end
217+
218+
towers[twr_fr].size = towers[twr_fr].size - 1
219+
220+
towers[twr_to].size = towers[twr_to].size + 1
221+
towers[twr_to].elem[ towers[twr_to].size ] = dsk
222+
223+
print_towers()
224+
end
225+
226+
return moves
227+
end
228+
229+
function keep_playing()
230+
231+
while true do
232+
io.write("TRY AGAIN (YES OR NO)? ")
233+
local input = io.read("*line")
234+
235+
if input == "YES" or input == "yes" then
236+
return true
237+
elseif input == "NO" or input == "no" then
238+
return false
239+
else
240+
print "'YES' OR 'NO' PLEASE"
241+
end
242+
end
243+
end
244+
245+
function start_loop()
246+
247+
while true do
248+
init_game()
249+
print_towers()
250+
251+
local moves = game_loop()
252+
253+
--check ideal solution
254+
if moves == (2^total_disks) - 1 then
255+
print "CONGRATULATIONS!!"
256+
end
257+
258+
print ( string.format("YOU HAVE PERFORMED THE TASK IN %d MOVES.\n", moves) )
259+
260+
if not keep_playing() then
261+
break
262+
end
263+
end
264+
265+
print "\nTHANKS FOR THE GAME!"
266+
end
267+
268+
start_loop()

91_Train/lua/train.lua

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
print [[
2+
TRAIN
3+
CREATIVE COMPUTING MORRISTOWN, NEW JERSY
4+
5+
6+
7+
TIME - SPEED DISTANCE EXERCISE]]
8+
9+
math.randomseed(os.time())
10+
11+
local ERROR_MARGIN <const> = 5.0
12+
13+
function play()
14+
local car_speed = 25*math.random() + 40--Between 40 and 64
15+
local delta_time = 15*math.random() + 5--Between 5 and 19
16+
local train_speed = 19*math.random() + 20--Between 20 and 38
17+
18+
print( string.format("\nA CAR TRAVELING AT %u MPH CAN MAKE A CERTAIN TRIP IN %u HOURS LESS THAN A TRAIN TRAVELING AT %u MPH.", car_speed, delta_time, train_speed) )
19+
20+
local try = true
21+
local input
22+
while try do
23+
io.write("HOW LONG DOES THE TRIP TAKE BY CAR? ")
24+
input = io.read("n")
25+
if input == nil then
26+
print("<!>PLEASE INSERT A NUMBER<!>")
27+
else
28+
try = false
29+
end
30+
io.read()
31+
end
32+
33+
local car_time = delta_time * train_speed / (car_speed - train_speed)
34+
local percent = ( math.abs(car_time-input) * 100 / car_time + .5)
35+
36+
if percent > ERROR_MARGIN then
37+
print( string.format("SORRY. YOU WERE OFF BY %f PERCENT.", percent) )
38+
else
39+
print( string.format("GOOD! ANSWER WITHIN %f PERCENT.", percent) )
40+
end
41+
42+
print( string.format("CORRECT ANSWER IS %f HOURS.", car_time) )
43+
end
44+
45+
function game_loop()
46+
local keep_playing = true
47+
while keep_playing do
48+
play()
49+
io.write("\nANOTHER PROBLEM (YES OR NO)? ")
50+
answer = io.read("l")
51+
52+
if not (answer == "YES" or answer == "Y" or answer == "yes" or answer == "y") then
53+
keep_playing = false
54+
end
55+
end
56+
57+
end
58+
59+
game_loop()

0 commit comments

Comments
 (0)