-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #900 from RFigCon/main
Implementation of Train in Lua and D
- Loading branch information
Showing
4 changed files
with
380 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html). | ||
|
||
Conversion to [MiniScript](https://dlang.org). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import std.stdio; | ||
import std.random : uniform; | ||
|
||
float abs(float num) { | ||
if(num<0){ | ||
return num*-1; | ||
} | ||
|
||
return num; | ||
} | ||
|
||
void main() { | ||
|
||
writeln("\nTIME - SPEED DISTANCE EXERCISE"); | ||
|
||
bool keep_playing = true; | ||
float error_margin = 5.0; | ||
|
||
while(keep_playing){ | ||
int car_speed = uniform!"[]"(40,65); //Random number between 40 and 65 | ||
int delta_time = uniform!"(]"(4,20); //Between 5 and 20 | ||
int train_speed = uniform!"[)"(20,40); //Between 20 and 39; This is the default if not specified: uniform(x,y) | ||
|
||
writeln("\nA CAR TRAVELING AT ", car_speed, " MPH CAN MAKE A CERTAIN TRIP IN ", delta_time, | ||
" HOURS LESS THAN A TRAIN TRAVELING AT ", train_speed, "MPH." ); | ||
|
||
float input; | ||
write("HOW LONG DOES THE TRIP TAKE BY CAR? "); | ||
readf!"%f\n"(input); | ||
|
||
float car_time = cast(float)delta_time * train_speed / (car_speed - train_speed); | ||
int percent = cast(int)( abs(car_time-input) * 100 / car_time + .5); | ||
|
||
if(percent > error_margin){ | ||
writeln("SORRY. YOU WERE OFF BY ", percent, " PERCENT."); | ||
}else{ | ||
writeln("GOOD! ANSWER WITHIN ", percent, " PERCENT."); | ||
} | ||
writeln("CORRECT ANSWER IS ", car_time, " HOURS."); | ||
|
||
string answer; | ||
write("\nANOTHER PROBLEM (YES OR NO)? "); | ||
readf!"%s\n"(answer); | ||
|
||
if( !(answer == "YES" || answer == "Y" || answer == "yes" || answer == "y") ){ | ||
keep_playing = false; | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,268 @@ | ||
print [[ | ||
TOWERS | ||
CREATIVE COMPUTING MORRISTOWN, NEW JERSY | ||
]] | ||
|
||
local MAX_DISKS <const> = 7 | ||
local MAX_DISK_SIZE <const> = 15 | ||
local MAX_MOVES <const> = 128 | ||
local NUM_TOWERS <const> = 3 | ||
|
||
local towers = { | ||
{ size = 0, elem = {} }, | ||
{ size = 0, elem = {} }, | ||
{ size = 0, elem = {} }, | ||
} | ||
|
||
local total_disks | ||
function ask_how_many_disks() | ||
|
||
local keep_asking = true | ||
local input | ||
local errors = 0 | ||
|
||
while keep_asking do | ||
|
||
io.write(string.format("HOW MANY DISKS DO YOU WANT TO MOVE (%d IS MAX)? ", MAX_DISKS) ) | ||
input = io.read("*number") | ||
io.read() --get rid of the remaining newline character | ||
|
||
if input ~= nil and input>0 and input<=MAX_DISKS then | ||
keep_asking = false | ||
|
||
else | ||
errors = errors + 1 | ||
if errors > 2 then | ||
print "ALL RIGHT, WISE GUY, IF YOU CAN'T PLAY THE GAME RIGHT, I'LL" | ||
print "JUST TAKE MY PUZZLE AND GO HOME. SO LONG." | ||
os.exit() | ||
end | ||
|
||
print "SORRY, BUT I CAN'T DO THAT JOB FOR YOU." | ||
end | ||
end | ||
total_disks = input | ||
end | ||
|
||
function init_game() | ||
print("TOWERS OF HANOIR PUZZLE\n") --'\n' indicates a new line | ||
|
||
print "YOU MUST TRANSFER THE DISKS FROM THE LEFT TO THE RIGHT TOWER," | ||
print "ONE AT A TIME, NEVER PUTTING A LARGER DISK ON A SMALLER DISK.\n" | ||
|
||
ask_how_many_disks() | ||
|
||
print() -- print() already creates a new line at the end, so an empty print leaves an empty line | ||
print "IN THIS PROGRAM, WE SHALL REFER TO DISKS BY NUMERICAL CODE." | ||
print "3 WILL REPRESENT THE SMALLEST DISK, 5 THE NEXT SIZE, 7 THE" | ||
print "NEXT, AND SO ON, UP TO 15. IF YOU DO THE PUZZLE WITH 2 DISKS," | ||
print "THEIR CODE NAMES WOULD BE 13 AND 15, ETC. THE NEEDLES ARE" | ||
print "NUMBERED FROM LEFT TO RIGHT, 1 TO 3. WE WILL START WITH THE" | ||
print "DISKS ON NEEDLE 1, AND ATTEMPT TO MOVE THEM TO NEEDLE 3.\n" | ||
|
||
print "GOOD LUCK!\n" | ||
|
||
local i = 1 | ||
local max = MAX_DISK_SIZE | ||
while i<= total_disks do | ||
towers[1].elem[i] = max | ||
max = max-2 | ||
i = i+1 | ||
end | ||
|
||
towers[1].size = total_disks | ||
|
||
local idx = 2 | ||
while idx <= NUM_TOWERS do | ||
towers[idx].size = 0 | ||
end | ||
end | ||
|
||
function print_towers() | ||
local line = MAX_DISKS | ||
|
||
while line > 0 do | ||
local twr = 1 | ||
|
||
while twr <=3 do | ||
local rpt = 10 | ||
local offset = 0 | ||
if line <= towers[twr].size then | ||
offset = (towers[twr].elem[line] - 1) / 2 | ||
rpt = rpt - offset | ||
end | ||
io.write( string.rep(' ', rpt) ) | ||
io.write( string.rep('*', offset) ) | ||
io.write '*' | ||
io.write( string.rep('*', offset) ) | ||
io.write( string.rep(' ', rpt) ) | ||
twr = twr + 1 | ||
end | ||
print '' | ||
line = line - 1 | ||
end | ||
|
||
end | ||
|
||
function ask_which_disk() | ||
|
||
local keep_asking = true | ||
local input | ||
local errors = 0 | ||
while keep_asking do | ||
|
||
io.write("WHICH DISK WOULD YOU LIKE TO MOVE? ") | ||
input = io.read("*number") | ||
io.read() --get rid of the remaining newline character | ||
|
||
if input==nil or input > MAX_DISK_SIZE or input%2==0 or input <= MAX_DISK_SIZE-(total_disks*2) then | ||
print "ILLEGAL ENTRY... YOU MAY ONLY TYPE 3,5,7,9,11,13 or 15." | ||
errors = errors + 1 | ||
if errors > 1 then | ||
print "STOP WASTING MY TIME. GO BOTHER SOMEONE ELSE." | ||
os.exit() | ||
end | ||
|
||
--[[ | ||
Since there are only 3 towers, it's easier to do an 'if' with three | ||
conditions than to do a loop | ||
]] | ||
elseif towers[1].elem[ towers[1].size ] ~= input and | ||
towers[2].elem[ towers[2].size ] ~= input and | ||
towers[3].elem[ towers[3].size ] ~= input then | ||
|
||
print "THAT DISK IS BELOW ANOTHER ONE. MAKE ANOTHER CHOICE." | ||
else | ||
keep_asking = false | ||
end | ||
end | ||
|
||
return input | ||
end | ||
|
||
function ask_which_needle(dsk) | ||
|
||
local keep_asking = true | ||
local input | ||
local errors = 0 | ||
|
||
while keep_asking do | ||
|
||
io.write("PLACE DISK ON WHICH NEEDLE? ") | ||
input = io.read("*number") | ||
io.read() --get rid of the remaining newline character | ||
|
||
if input~=nil and towers[input].size > 0 and towers[input].elem[ towers[input].size ] < dsk then | ||
print "YOU CAN'T PLACE A LARGER DISK ON TOP OF A SMALLER ONE," | ||
print "IT MIGHT CRUSH IT!" | ||
return 0 | ||
|
||
elseif input~=nil and input>=1 and input<=3 then | ||
keep_asking = false | ||
|
||
else | ||
errors = errors + 1 | ||
if errors > 1 then | ||
print "I TRIED TO WARN YOU, BUT YOU WOULDN'T LISTEN." | ||
print "BYE BYE, BIG SHOT." | ||
os.exit() --Stop program | ||
else | ||
print "I'LL ASSUME YOU HIT THE WRONG KEY THIS TIME. BUT WATCH IT," | ||
print "I ONLY ALLOW ONE MISTAKE." | ||
end | ||
end | ||
end | ||
return input | ||
end | ||
|
||
function is_game_over() | ||
if towers[1].size == 0 and towers[2].size == 0 then | ||
return true | ||
else | ||
return false | ||
end | ||
end | ||
|
||
function game_loop() | ||
local moves = 0 | ||
local dsk | ||
local twr_to | ||
local twr_fr | ||
|
||
while not is_game_over() do | ||
moves = moves + 1 | ||
|
||
if moves > MAX_MOVES then | ||
print(string.format("SORRY, BUT I HAVE ORDERS TO STOP IF YOU MAKE MORE THAN %d MOVES.", MAX_MOVES)) | ||
os.exit() | ||
end | ||
|
||
|
||
repeat | ||
dsk = ask_which_disk() | ||
twr_to = ask_which_needle(dsk) | ||
until twr_to ~= 0 | ||
|
||
|
||
if towers[1].elem[ towers[1].size ] == dsk then | ||
twr_fr = 1 | ||
elseif towers[2].elem[ towers[2].size ] == dsk then | ||
twr_fr = 2 | ||
else | ||
twr_fr = 3 | ||
end | ||
|
||
towers[twr_fr].size = towers[twr_fr].size - 1 | ||
|
||
towers[twr_to].size = towers[twr_to].size + 1 | ||
towers[twr_to].elem[ towers[twr_to].size ] = dsk | ||
|
||
print_towers() | ||
end | ||
|
||
return moves | ||
end | ||
|
||
function keep_playing() | ||
|
||
while true do | ||
io.write("TRY AGAIN (YES OR NO)? ") | ||
local input = io.read("*line") | ||
|
||
if input == "YES" or input == "yes" then | ||
return true | ||
elseif input == "NO" or input == "no" then | ||
return false | ||
else | ||
print "'YES' OR 'NO' PLEASE" | ||
end | ||
end | ||
end | ||
|
||
function start_loop() | ||
|
||
while true do | ||
init_game() | ||
print_towers() | ||
|
||
local moves = game_loop() | ||
|
||
--check ideal solution | ||
if moves == (2^total_disks) - 1 then | ||
print "CONGRATULATIONS!!" | ||
end | ||
|
||
print ( string.format("YOU HAVE PERFORMED THE TASK IN %d MOVES.\n", moves) ) | ||
|
||
if not keep_playing() then | ||
break | ||
end | ||
end | ||
|
||
print "\nTHANKS FOR THE GAME!" | ||
end | ||
|
||
start_loop() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
print [[ | ||
TRAIN | ||
CREATIVE COMPUTING MORRISTOWN, NEW JERSY | ||
TIME - SPEED DISTANCE EXERCISE]] | ||
|
||
math.randomseed(os.time()) | ||
|
||
local ERROR_MARGIN <const> = 5.0 | ||
|
||
function play() | ||
local car_speed = 25*math.random() + 40--Between 40 and 64 | ||
local delta_time = 15*math.random() + 5--Between 5 and 19 | ||
local train_speed = 19*math.random() + 20--Between 20 and 38 | ||
|
||
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) ) | ||
|
||
local try = true | ||
local input | ||
while try do | ||
io.write("HOW LONG DOES THE TRIP TAKE BY CAR? ") | ||
input = io.read("n") | ||
if input == nil then | ||
print("<!>PLEASE INSERT A NUMBER<!>") | ||
else | ||
try = false | ||
end | ||
io.read() | ||
end | ||
|
||
local car_time = delta_time * train_speed / (car_speed - train_speed) | ||
local percent = ( math.abs(car_time-input) * 100 / car_time + .5) | ||
|
||
if percent > ERROR_MARGIN then | ||
print( string.format("SORRY. YOU WERE OFF BY %f PERCENT.", percent) ) | ||
else | ||
print( string.format("GOOD! ANSWER WITHIN %f PERCENT.", percent) ) | ||
end | ||
|
||
print( string.format("CORRECT ANSWER IS %f HOURS.", car_time) ) | ||
end | ||
|
||
function game_loop() | ||
local keep_playing = true | ||
while keep_playing do | ||
play() | ||
io.write("\nANOTHER PROBLEM (YES OR NO)? ") | ||
answer = io.read("l") | ||
|
||
if not (answer == "YES" or answer == "Y" or answer == "yes" or answer == "y") then | ||
keep_playing = false | ||
end | ||
end | ||
|
||
end | ||
|
||
game_loop() |