Removed spaces from top-level directory names.

Spaces tend to cause annoyances in a Unix-style shell environment.
This change fixes that.
This commit is contained in:
Chris Reuter
2021-11-21 18:30:21 -05:00
parent df2e7426eb
commit d26dbf036a
1725 changed files with 0 additions and 0 deletions

7
02_Amazing/README.md Normal file
View File

@@ -0,0 +1,7 @@
### Amazing
As published in Basic Computer Games (1978)
https://www.atariarchives.org/basicgames/showpage.php?page=3
Downloaded from Vintage Basic at
http://www.vintage-basic.net/games.html

138
02_Amazing/amazing.bas Normal file
View File

@@ -0,0 +1,138 @@
10 PRINT TAB(28);"AMAZING PROGRAM"
20 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"
30 PRINT:PRINT:PRINT:PRINT
100 INPUT "WHAT ARE YOUR WIDTH AND LENGTH";H,V
102 IF H<>1 AND V<>1 THEN 110
104 PRINT "MEANINGLESS DIMENSIONS. TRY AGAIN.":GOTO 100
110 DIM W(H,V),V(H,V)
120 PRINT
130 PRINT
140 PRINT
150 PRINT
160 Q=0:Z=0:X=INT(RND(1)*H+1)
165 FOR I=1 TO H
170 IF I=X THEN 173
171 PRINT ".--";:GOTO 180
173 PRINT ". ";
180 NEXT I
190 PRINT "."
195 C=1:W(X,1)=C:C=C+1
200 R=X:S=1:GOTO 260
210 IF R<>H THEN 240
215 IF S<>V THEN 230
220 R=1:S=1:GOTO 250
230 R=1:S=S+1:GOTO 250
240 R=R+1
250 IF W(R,S)=0 THEN 210
260 IF R-1=0 THEN 530
265 IF W(R-1,S)<>0 THEN 530
270 IF S-1=0 THEN 390
280 IF W(R,S-1)<>0 THEN 390
290 IF R=H THEN 330
300 IF W(R+1,S)<>0 THEN 330
310 X=INT(RND(1)*3+1)
320 ON X GOTO 790,820,860
330 IF S<>V THEN 340
334 IF Z=1 THEN 370
338 Q=1:GOTO 350
340 IF W(R,S+1)<>0 THEN 370
350 X=INT(RND(1)*3+1)
360 ON X GOTO 790,820,910
370 X=INT(RND(1)*2+1)
380 ON X GOTO 790,820
390 IF R=H THEN 470
400 IF W(R+1,S)<>0 THEN 470
405 IF S<>V THEN 420
410 IF Z=1 THEN 450
415 Q=1:GOTO 430
420 IF W(R,S+1)<>0 THEN 450
430 X=INT(RND(1)*3+1)
440 ON X GOTO 790,860,910
450 X=INT(RND(1)*2+1)
460 ON X GOTO 790,860
470 IF S<>V THEN 490
480 IF Z=1 THEN 520
485 Q=1:GOTO 500
490 IF W(R,S+1)<>0 THEN 520
500 X=INT(RND(1)*2+1)
510 ON X GOTO 790,910
520 GOTO 790
530 IF S-1=0 THEN 670
540 IF W(R,S-1)<>0 THEN 670
545 IF R=H THEN 610
547 IF W(R+1,S)<>0 THEN 610
550 IF S<>V THEN 560
552 IF Z=1 THEN 590
554 Q=1:GOTO 570
560 IF W(R,S+1)<>0 THEN 590
570 X=INT(RND(1)*3+1)
580 ON X GOTO 820,860,910
590 X=INT(RND(1)*2+1)
600 ON X GOTO 820,860
610 IF S<>V THEN 630
620 IF Z=1 THEN 660
625 Q=1:GOTO 640
630 IF W(R,S+1)<>0 THEN 660
640 X=INT(RND(1)*2+1)
650 ON X GOTO 820,910
660 GOTO 820
670 IF R=H THEN 740
680 IF W(R+1,S)<>0 THEN 740
685 IF S<>V THEN 700
690 IF Z=1 THEN 730
695 Q=1:GOTO 710
700 IF W(R,S+1)<>0 THEN 730
710 X=INT(RND(1)*2+1)
720 ON X GOTO 860,910
730 GOTO 860
740 IF S<>V THEN 760
750 IF Z=1 THEN 780
755 Q=1:GOTO 770
760 IF W(R,S+1)<>0 THEN 780
770 GOTO 910
780 GOTO 1000
790 W(R-1,S)=C
800 C=C+1:V(R-1,S)=2:R=R-1
810 IF C=H*V+1 THEN 1010
815 Q=0:GOTO 260
820 W(R,S-1)=C
830 C=C+1
840 V(R,S-1)=1:S=S-1:IF C=H*V+1 THEN 1010
850 Q=0:GOTO 260
860 W(R+1,S)=C
870 C=C+1:IF V(R,S)=0 THEN 880
875 V(R,S)=3:GOTO 890
880 V(R,S)=2
890 R=R+1
900 IF C=H*V+1 THEN 1010
905 GOTO 530
910 IF Q=1 THEN 960
920 W(R,S+1)=C:C=C+1:IF V(R,S)=0 THEN 940
930 V(R,S)=3:GOTO 950
940 V(R,S)=1
950 S=S+1:IF C=H*V+1 THEN 1010
955 GOTO 260
960 Z=1
970 IF V(R,S)=0 THEN 980
975 V(R,S)=3:Q=0:GOTO 1000
980 V(R,S)=1:Q=0:R=1:S=1:GOTO 250
1000 GOTO 210
1010 FOR J=1 TO V
1011 PRINT "I";
1012 FOR I=1 TO H
1013 IF V(I,J)<2 THEN 1030
1020 PRINT " ";
1021 GOTO 1040
1030 PRINT " I";
1040 NEXT I
1041 PRINT
1043 FOR I=1 TO H
1045 IF V(I,J)=0 THEN 1060
1050 IF V(I,J)=2 THEN 1060
1051 PRINT ": ";
1052 GOTO 1070
1060 PRINT ":--";
1070 NEXT I
1071 PRINT "."
1072 NEXT J
1073 END

View File

@@ -0,0 +1,320 @@
using System;
using System.Collections.Generic;
namespace Amazing
{
class AmazingGame
{
private const int FIRST_COL = 0;
private const int FIRST_ROW = 0;
private const int EXIT_UNSET = 0;
private const int EXIT_DOWN = 1;
private const int EXIT_RIGHT = 2;
private static int GetDelimitedValue(String text, int pos)
{
String[] tokens = text.Split(",");
int val;
if (Int32.TryParse(tokens[pos], out val))
{
return val;
}
return 0;
}
private static String Tab(int spaces)
{
return new String(' ', spaces);
}
public static int Random(int min, int max)
{
Random random = new Random();
return random.Next(max - min) + min;
}
public void Play()
{
Console.WriteLine(Tab(28) + "AMAZING PROGRAM");
Console.WriteLine(Tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
Console.WriteLine();
int width = 0;
int length = 0;
do
{
String range = DisplayTextAndGetInput("WHAT ARE YOUR WIDTH AND LENGTH");
if (range.IndexOf(",") > 0)
{
width = GetDelimitedValue(range, 0);
length = GetDelimitedValue(range, 1);
}
}
while (width < 1 || length < 1);
Grid grid = new Grid(length, width);
int enterCol = grid.SetupEntrance();
int totalWalls = width * length + 1;
int count = 2;
Cell cell = grid.StartingCell();
while (count != totalWalls)
{
List<Direction> possibleDirs = GetPossibleDirs(grid, cell);
if (possibleDirs.Count != 0)
{
cell = SetCellExit(grid, cell, possibleDirs);
cell.Count = count++;
}
else
{
cell = grid.GetFirstUnset(cell);
}
}
grid.SetupExit();
WriteMaze(width, grid, enterCol);
}
private Cell SetCellExit(Grid grid, Cell cell, List<Direction> possibleDirs)
{
Direction direction = possibleDirs[Random(0, possibleDirs.Count)];
if (direction == Direction.GO_LEFT)
{
cell = grid.GetPrevCol(cell);
cell.ExitType = EXIT_RIGHT;
}
else if (direction == Direction.GO_UP)
{
cell = grid.GetPrevRow(cell);
cell.ExitType = EXIT_DOWN;
}
else if (direction == Direction.GO_RIGHT)
{
cell.ExitType = cell.ExitType + EXIT_RIGHT;
cell = grid.GetNextCol(cell);
}
else if (direction == Direction.GO_DOWN)
{
cell.ExitType = cell.ExitType + EXIT_DOWN;
cell = grid.GetNextRow(cell);
}
return cell;
}
private void WriteMaze(int width, Grid grid, int enterCol)
{
// top line
for (int i = 0; i < width; i++)
{
if (i == enterCol) Console.Write(". ");
else Console.Write(".--");
}
Console.WriteLine(".");
for (int i = 0; i < grid.Length; i++)
{
Console.Write("I");
for (int j = 0; j < grid.Width; j++)
{
if (grid.Cells[i,j].ExitType == EXIT_UNSET || grid.Cells[i, j].ExitType == EXIT_DOWN)
Console.Write(" I");
else Console.Write(" ");
}
Console.WriteLine();
for (int j = 0; j < grid.Width; j++)
{
if (grid.Cells[i,j].ExitType == EXIT_UNSET || grid.Cells[i, j].ExitType == EXIT_RIGHT)
Console.Write(":--");
else Console.Write(": ");
}
Console.WriteLine(".");
}
}
private List<Direction> GetPossibleDirs(Grid grid, Cell cell)
{
var possibleDirs = new List<Direction>();
foreach (var val in Enum.GetValues(typeof(Direction)))
{
possibleDirs.Add((Direction)val);
}
if (cell.Col == FIRST_COL || grid.IsPrevColSet(cell))
{
possibleDirs.Remove(Direction.GO_LEFT);
}
if (cell.Row == FIRST_ROW || grid.IsPrevRowSet(cell))
{
possibleDirs.Remove(Direction.GO_UP);
}
if (cell.Col == grid.LastCol || grid.IsNextColSet(cell))
{
possibleDirs.Remove(Direction.GO_RIGHT);
}
if (cell.Row == grid.LastRow || grid.IsNextRowSet(cell))
{
possibleDirs.Remove(Direction.GO_DOWN);
}
return possibleDirs;
}
private String DisplayTextAndGetInput(String text)
{
Console.WriteLine(text);
return Console.ReadLine();
}
private enum Direction
{
GO_LEFT,
GO_UP,
GO_RIGHT,
GO_DOWN,
}
public class Cell
{
public int ExitType { get; set; }
public int Count { get; set; }
public int Col { get; set; }
public int Row { get; set; }
public Cell(int row, int col)
{
ExitType = EXIT_UNSET;
Row = row;
Col = col;
}
}
public class Grid
{
public Cell[,] Cells { get; private set; }
public int LastCol { get; set; }
public int LastRow { get; set; }
public int Width { get; private set; }
public int Length { get; private set; }
private int enterCol;
public Grid(int length, int width)
{
LastCol = width - 1;
LastRow = length - 1;
Width = width;
Length = length;
Cells = new Cell[length,width];
for (int i = 0; i < length; i++)
{
for (int j = 0; j < width; j++)
{
this.Cells[i,j] = new Cell(i, j);
}
}
}
public int SetupEntrance()
{
this.enterCol = Random(0, Width);
Cells[0, enterCol].Count = 1;
return this.enterCol;
}
public void SetupExit()
{
int exit = Random(0, Width - 1);
Cells[LastRow, exit].ExitType += 1;
}
public Cell StartingCell()
{
return Cells[0, enterCol];
}
public bool IsPrevColSet(Cell cell)
{
return 0 != Cells[cell.Row, cell.Col - 1].Count;
}
public bool IsPrevRowSet(Cell cell)
{
return 0 != Cells[cell.Row - 1, cell.Col].Count;
}
public bool IsNextColSet(Cell cell)
{
return 0 != Cells[cell.Row, cell.Col + 1].Count;
}
public bool IsNextRowSet(Cell cell)
{
return 0 != Cells[cell.Row + 1, cell.Col].Count;
}
public Cell GetPrevCol(Cell cell)
{
return Cells[cell.Row, cell.Col - 1];
}
public Cell GetPrevRow(Cell cell)
{
return Cells[cell.Row - 1, cell.Col];
}
public Cell GetNextCol(Cell cell)
{
return Cells[cell.Row, cell.Col + 1];
}
public Cell GetNextRow(Cell cell)
{
return Cells[cell.Row + 1, cell.Col];
}
public Cell GetFirstUnset(Cell cell)
{
int col = cell.Col;
int row = cell.Row;
Cell newCell;
do
{
if (col != this.LastCol)
{
col++;
}
else if (row != this.LastRow)
{
row++;
col = 0;
}
else
{
row = 0;
col = 0;
}
}
while ((newCell = Cells[row, col]).Count == 0);
return newCell;
}
}
}
class Program
{
static void Main(string[] args)
{
new AmazingGame().Play();
}
}
}

View File

@@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,25 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.808.10
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Amazing", "Amazing.csproj", "{DD3483B4-F366-493C-8BFE-BAFBFE6F3016}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{DD3483B4-F366-493C-8BFE-BAFBFE6F3016}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DD3483B4-F366-493C-8BFE-BAFBFE6F3016}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DD3483B4-F366-493C-8BFE-BAFBFE6F3016}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DD3483B4-F366-493C-8BFE-BAFBFE6F3016}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {F8762606-E467-47C1-A28F-BD5C4F7BFF5A}
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,3 @@
Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
Conversion to [Microsoft C#](https://docs.microsoft.com/en-us/dotnet/csharp/)

View File

@@ -0,0 +1,262 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;
import static java.lang.System.in;
import static java.lang.System.out;
/**
* Core algorithm copied from amazing.py
*/
public class Amazing {
final static int FIRST_COL = 0;
final static int FIRST_ROW = 0;
final static int EXIT_UNSET = 0;
final static int EXIT_DOWN = 1;
final static int EXIT_RIGHT = 2;
private final Scanner kbScanner;
public Amazing() {
kbScanner = new Scanner(in);
}
private static int getDelimitedValue(String text, int pos) {
String[] tokens = text.split(",");
try {
return Integer.parseInt(tokens[pos]);
} catch (Exception ex) {
return 0;
}
}
private static String tab(int spaces) {
char[] spacesTemp = new char[spaces];
Arrays.fill(spacesTemp, ' ');
return new String(spacesTemp);
}
public static int random(int min, int max) {
Random random = new Random();
return random.nextInt(max - min) + min;
}
public void play() {
out.println(tab(28) + "AMAZING PROGRAM");
out.println(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
out.println();
int width = 0;
int length = 0;
do {
String range = displayTextAndGetInput("WHAT ARE YOUR WIDTH AND LENGTH");
if (range.indexOf(",") > 0) {
width = getDelimitedValue(range, 0);
length = getDelimitedValue(range, 1);
}
} while (width < 1 || length < 1);
Grid grid = new Grid(length, width);
int enterCol = grid.setupEntrance();
int totalWalls = width * length + 1;
int count = 2;
Cell cell = grid.startingCell();
while (count != totalWalls) {
ArrayList<Direction> possibleDirs = getPossibleDirs(grid, cell);
if (possibleDirs.size() != 0) {
cell = setCellExit(grid, cell, possibleDirs);
cell.count = count++;
} else {
cell = grid.getFirstUnset(cell);
}
}
grid.setupExit();
writeMaze(width, grid, enterCol);
}
private Cell setCellExit(Grid grid, Cell cell, ArrayList<Direction> possibleDirs) {
Direction direction = possibleDirs.get(random(0, possibleDirs.size()));
if (direction == Direction.GO_LEFT) {
cell = grid.getPrevCol(cell);
cell.exitType = EXIT_RIGHT;
} else if (direction == Direction.GO_UP) {
cell = grid.getPrevRow(cell);
cell.exitType = EXIT_DOWN;
} else if (direction == Direction.GO_RIGHT) {
cell.exitType = cell.exitType + EXIT_RIGHT;
cell = grid.getNextCol(cell);
} else if (direction == Direction.GO_DOWN) {
cell.exitType = cell.exitType + EXIT_DOWN;
cell = grid.getNextRow(cell);
}
return cell;
}
private void writeMaze(int width, Grid grid, int enterCol) {
// top line
for (int i = 0; i < width; i++) {
if (i == enterCol) {
out.print(". ");
} else {
out.print(".--");
}
}
out.println('.');
for (Cell[] rows : grid.cells) {
out.print("I");
for (Cell cell : rows) {
if (cell.exitType == EXIT_UNSET || cell.exitType == EXIT_DOWN) {
out.print(" I");
} else {
out.print(" ");
}
}
out.println();
for (Cell cell : rows) {
if (cell.exitType == EXIT_UNSET || cell.exitType == EXIT_RIGHT) {
out.print(":--");
} else {
out.print(": ");
}
}
out.println(".");
}
}
private ArrayList<Direction> getPossibleDirs(Grid grid, Cell cell) {
ArrayList<Direction> possibleDirs = new ArrayList<>(Arrays.asList(Direction.values()));
if (cell.col == FIRST_COL || grid.isPrevColSet(cell)) {
possibleDirs.remove(Direction.GO_LEFT);
}
if (cell.row == FIRST_ROW || grid.isPrevRowSet(cell)) {
possibleDirs.remove(Direction.GO_UP);
}
if (cell.col == grid.lastCol || grid.isNextColSet(cell)) {
possibleDirs.remove(Direction.GO_RIGHT);
}
if (cell.row == grid.lastRow || grid.isNextRowSet(cell)) {
possibleDirs.remove(Direction.GO_DOWN);
}
return possibleDirs;
}
private String displayTextAndGetInput(String text) {
out.print(text);
return kbScanner.next();
}
enum Direction {
GO_LEFT,
GO_UP,
GO_RIGHT,
GO_DOWN,
}
public static class Cell {
int exitType = EXIT_UNSET;
int count = 0;
int col;
int row;
public Cell(int row, int col) {
this.row = row;
this.col = col;
}
}
public static class Grid {
Cell[][] cells;
int lastCol;
int lastRow;
int width;
int enterCol;
public Grid(int length, int width) {
this.lastCol = width - 1;
this.lastRow = length - 1;
this.width = width;
this.cells = new Cell[length][width];
for (int i = 0; i < length; i++) {
this.cells[i] = new Cell[width];
for (int j = 0; j < width; j++) {
this.cells[i][j] = new Cell(i, j);
}
}
}
public int setupEntrance() {
this.enterCol = random(0, this.width);
cells[0][this.enterCol].count = 1;
return this.enterCol;
}
public void setupExit() {
int exit = random(0, width - 1);
cells[lastRow][exit].exitType += 1;
}
public Cell startingCell() {
return cells[0][enterCol];
}
public boolean isPrevColSet(Cell cell) {
return 0 != cells[cell.row][cell.col - 1].count;
}
public boolean isPrevRowSet(Cell cell) {
return 0 != cells[cell.row - 1][cell.col].count;
}
public boolean isNextColSet(Cell cell) {
return 0 != cells[cell.row][cell.col + 1].count;
}
public boolean isNextRowSet(Cell cell) {
return 0 != cells[cell.row + 1][cell.col].count;
}
public Cell getPrevCol(Cell cell) {
return cells[cell.row][cell.col - 1];
}
public Cell getPrevRow(Cell cell) {
return cells[cell.row - 1][cell.col];
}
public Cell getNextCol(Cell cell) {
return cells[cell.row][cell.col + 1];
}
public Cell getNextRow(Cell cell) {
return cells[cell.row + 1][cell.col];
}
public Cell getFirstUnset(Cell cell) {
int col = cell.col;
int row = cell.row;
Cell newCell;
do {
if (col != this.lastCol) {
col++;
} else if (row != this.lastRow) {
row++;
col = 0;
} else {
row = 0;
col = 0;
}
} while ((newCell = cells[row][col]).count == 0);
return newCell;
}
}
}

View File

@@ -0,0 +1,6 @@
public class AmazingGame {
public static void main(String[] args) {
Amazing amazing = new Amazing();
amazing.play();
}
}

View File

@@ -0,0 +1,3 @@
Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
Conversion to [Oracle Java](https://openjdk.java.net/)

View File

@@ -0,0 +1,3 @@
Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
Conversion to [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Shells)

View File

@@ -0,0 +1,9 @@
<html>
<head>
<title>AMAZING</title>
</head>
<body>
<pre id="output" style="font-size: 12pt;"></pre>
<script src="amazing.js"></script>
</body>
</html>

View File

@@ -0,0 +1,319 @@
// AMAZING
//
// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
//
function print(str)
{
document.getElementById("output").appendChild(document.createTextNode(str));
}
function input()
{
var input_element;
var input_str;
return new Promise(function (resolve) {
input_element = document.createElement("INPUT");
print("? ");
input_element.setAttribute("type", "text");
input_element.setAttribute("length", "50");
document.getElementById("output").appendChild(input_element);
input_element.focus();
input_str = undefined;
input_element.addEventListener("keydown", function (event) {
if (event.keyCode == 13) {
input_str = input_element.value;
document.getElementById("output").removeChild(input_element);
print(input_str);
print("\n");
resolve(input_str);
}
});
});
}
function tab(space)
{
var str = "";
while (space-- > 0)
str += " ";
return str;
}
print(tab(28) + "AMAZING PROGRAM\n");
print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
print("\n");
print("\n");
print("\n");
print("FOR EXAMPLE TYPE 10,10 AND PRESS ENTER\n");
print("\n");
// Main program
async function main()
{
while (1) {
print("WHAT ARE YOUR WIDTH AND LENGTH");
a = await input();
h = parseInt(a);
v2 = parseInt(a.substr(a.indexOf(",") + 1));
if (h > 1 && v2 > 1)
break;
print("MEANINGLESS DIMENSIONS. TRY AGAIN.\n");
}
w = [];
v = [];
for (i = 1; i <= h; i++) {
w[i] = [];
v[i] = [];
for (j = 1; j <= v2; j++) {
w[i][j] = 0;
v[i][j] = 0;
}
}
print("\n");
print("\n");
print("\n");
print("\n");
q = 0;
z = 0;
x = Math.floor(Math.random() * h + 1);
for (i = 1; i <= h; i++) {
if (i == x)
print(". ");
else
print(".--");
}
print(".\n");
c = 1;
w[x][1] = c;
c++;
r = x;
s = 1;
entry = 0;
while (1) {
if (entry == 2) { // Search for a non-explored cell
do {
if (r < h) {
r++;
} else if (s < v2) {
r = 1;
s++;
} else {
r = 1;
s = 1;
}
} while (w[r][s] == 0) ;
}
if (entry == 0 && r - 1 > 0 && w[r - 1][s] == 0) { // Can go left?
if (s - 1 > 0 && w[r][s - 1] == 0) { // Can go up?
if (r < h && w[r + 1][s] == 0) { // Can go right?
// Choose left/up/right
x = Math.floor(Math.random() * 3 + 1);
} else if (s < v2) {
if (w[r][s + 1] == 0) { // Can go down?
// Choose left/up/down
x = Math.floor(Math.random() * 3 + 1);
if (x == 3)
x = 4;
} else {
x = Math.floor(Math.random() * 2 + 1);
}
} else if (z == 1) {
x = Math.floor(Math.random() * 2 + 1);
} else {
q = 1;
x = Math.floor(Math.random() * 3 + 1);
if (x == 3)
x = 4;
}
} else if (r < h && w[r + 1][s] == 0) { // Can go right?
if (s < v2) {
if (w[r][s + 1] == 0) { // Can go down?
// Choose left/right/down
x = Math.floor(Math.random() * 3 + 1);
} else {
x = Math.floor(Math.random() * 2 + 1);
}
if (x >= 2)
x++;
} else if (z == 1) {
x = Math.floor(Math.random() * 2 + 1);
if (x >= 2)
x++;
} else {
q = 1;
x = Math.floor(Math.random() * 3 + 1);
if (x >= 2)
x++;
}
} else if (s < v2) {
if (w[r][s + 1] == 0) { // Can go down?
// Choose left/down
x = Math.floor(Math.random() * 2 + 1);
if (x == 2)
x = 4;
} else {
x = 1;
}
} else if (z == 1) {
x = 1;
} else {
q = 1;
x = Math.floor(Math.random() * 2 + 1);
if (x == 2)
x = 4;
}
} else if (s - 1 > 0 && w[r][s - 1] == 0) { // Can go up?
if (r < h && w[r + 1][s] == 0) {
if (s < v2) {
if (w[r][s + 1] == 0)
x = Math.floor(Math.random() * 3 + 2);
else
x = Math.floor(Math.random() * 2 + 2);
} else if (z == 1) {
x = Math.floor(Math.random() * 2 + 2);
} else {
q = 1;
x = Math.floor(Math.random() * 3 + 2);
}
} else if (s < v2) {
if (w[r][s + 1] == 0) {
x = Math.floor(Math.random() * 2 + 2);
if (x == 3)
x = 4;
} else {
x = 2;
}
} else if (z == 1) {
x = 2;
} else {
q = 1;
x = Math.floor(Math.random() * 2 + 2);
if (x == 3)
x = 4;
}
} else if (r < h && w[r + 1][s] == 0) { // Can go right?
if (s < v2) {
if (w[r][s + 1] == 0)
x = Math.floor(Math.random() * 2 + 3);
else
x = 3;
} else if (z == 1) {
x = 3;
} else {
q = 1;
x = Math.floor(Math.random() * 2 + 3);
}
} else if (s < v2) {
if (w[r][s + 1] == 0) // Can go down?
x = 4;
else {
entry = 2; // Blocked!
continue;
}
} else if (z == 1) {
entry = 2; // Blocked!
continue;
} else {
q = 1;
x = 4;
}
if (x == 1) { // Left
w[r - 1][s] = c;
c++;
v[r - 1][s] = 2;
r--;
if (c == h * v2 + 1)
break;
q = 0;
entry = 0;
} else if (x == 2) { // Up
w[r][s - 1] = c;
c++;
v[r][s - 1] = 1;
s--;
if (c == h * v2 + 1)
break;
q = 0;
entry = 0;
} else if (x == 3) { // Right
w[r + 1][s] = c;
c++;
if (v[r][s] == 0)
v[r][s] = 2;
else
v[r][s] = 3;
r++;
if (c == h * v2 + 1)
break;
entry = 1;
} else if (x == 4) { // Down
if (q != 1) { // Only if not blocked
w[r][s + 1] = c;
c++;
if (v[r][s] == 0)
v[r][s] = 1;
else
v[r][s] = 3;
s++;
if (c == h * v2 + 1)
break;
entry = 0;
} else {
z = 1;
if (v[r][s] == 0) {
v[r][s] = 1;
q = 0;
r = 1;
s = 1;
while (w[r][s] == 0) {
if (r < h) {
r++;
} else if (s < v2) {
r = 1;
s++;
} else {
r = 1;
s = 1;
}
}
entry = 0;
} else {
v[r][s] = 3;
q = 0;
entry = 2;
}
}
}
}
for (j = 1; j <= v2; j++) {
str = "I";
for (i = 1; i <= h; i++) {
if (v[i][j] < 2)
str += " I";
else
str += " ";
}
print(str + "\n");
str = "";
for (i = 1; i <= h; i++) {
if (v[i][j] == 0 || v[i][j] == 2)
str += ":--";
else
str += ": ";
}
print(str + ".\n");
}
// If you want to see the order of visited cells
// for (j = 1; j <= v2; j++) {
// str = "I";
// for (i = 1; i <= h; i++) {
// str += w[i][j] + " ";
// }
// print(str + "\n");
// }
}
main();

36
02_Amazing/pascal/.gitattributes vendored Normal file
View File

@@ -0,0 +1,36 @@
# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto
# Explicitly declare text files you want to always be normalized and converted
# to native line endings on checkout.
*.inc text
*.pas text
*.pp text
*.lpk text
*.lpi text
*.lps text
*.lpr text
*.def text
*.css text
*.html text
*.xml text
*.sql text
# Declare files that will always have CRLF line endings on checkout.
*.dpk text eol=crlf
*.dproj text eol=crlf
# Declare files that will always have LF line endings on checkout.
# Denote all files that are truly binary and should not be modified.
*.png binary
*.jpg binary
*.exe binary
*.res binary
*.ico binary
*.dll binary
# Keep these files from archive/exports, mainly from production.
.gitignore export-ignore
.gitattributes export-ignore

63
02_Amazing/pascal/.gitignore vendored Normal file
View File

@@ -0,0 +1,63 @@
# Basic Computer Programs project specific
amazing
amazing.exe
# Compiled l10n files: .mo should be ignored
*.mo
# Ghostwriter backups
*.backup
# nano editor backup files
*.swp
# Uncomment these types if you want even more clean repository. But be careful.
# It can make harm to an existing project source. Read explanations below.
#
# Resource files are binaries containing manifest, project icon and version info.
# They can not be viewed as text or compared by diff-tools. Consider replacing them with .rc files.
*.res
# Delphi/Lazarus compiler-generated binaries (safe to delete)
*.exe
*.dll
*.bpl
*.bpi
*.dcp
*.so
*.apk
*.drc
*.map
*.dres
*.rsm
*.tds
*.dcu
*.lib
*.[ao]
*.or
*.ppu
*.dbg
*.compiled
# Delphi autogenerated files (duplicated info)
*.cfg
*Resource.rc
# Delphi local files (user-specific info)
*.local
*.identcache
*.projdata
*.tvsconfig
*.dsk
# Delphi history and backups
__history/
*.~*
# Lazarus history, backups and session
backup/
*.bak
*.lps
# Castalia statistics file
*.stat

View File

@@ -0,0 +1,3 @@
Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language)) by Gustavo Carreno [gcarreno@github](https://github.com/gcarreno)

View File

@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="12"/>
<General>
<Flags>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
<MainUnitHasScaledStatement Value="False"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<Title Value="amazing"/>
<UseAppBundle Value="False"/>
<ResourceType Value="res"/>
</General>
<BuildModes Count="1">
<Item1 Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<UseFileFilters Value="True"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
</RunParams>
<Units Count="4">
<Unit0>
<Filename Value="amazing.pas"/>
<IsPartOfProject Value="True"/>
</Unit0>
<Unit1>
<Filename Value="amazingapplication.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="AmazingApplication"/>
</Unit1>
<Unit2>
<Filename Value="maze.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="Maze"/>
</Unit2>
<Unit3>
<Filename Value="room.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="Room"/>
</Unit3>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<Target>
<Filename Value="amazing"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>
<UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
</CompilerOptions>
<Debugging>
<Exceptions Count="3">
<Item1>
<Name Value="EAbort"/>
</Item1>
<Item2>
<Name Value="ECodetoolError"/>
</Item2>
<Item3>
<Name Value="EFOpenError"/>
</Item3>
</Exceptions>
</Debugging>
</CONFIG>

View File

@@ -0,0 +1,17 @@
program amazing;
{$IFDEF FPC}
{$mode ObjFPC}{$H+}
{$ENDIF}
uses
AmazingApplication, maze, Room;
var
AmazingApp: TAmazingApplication;
begin
AmazingApp:= TAmazingApplication.Create;
AmazingApp.Run;
end.

View File

@@ -0,0 +1,104 @@
unit AmazingApplication;
{$IFDEF FPC}
{$mode ObjFPC}{$H+}
{$ENDIF}
interface
uses
Classes
, SysUtils
, Crt
, Maze
;
type
{ TAmazingApplication }
TAmazingApplication = class(TObject)
private
FMaze: TMaze;
procedure PrintGreeting;
procedure GetDimensions;
procedure BuildMaze;
procedure PrintMaze;
protected
public
constructor Create;
destructor Destroy; override;
procedure Run;
published
end;
implementation
{ TAmazingApplication }
procedure TAmazingApplication.PrintGreeting;
begin
WriteLN(' ':28, 'AMAZING PROGRAM');
WriteLN(' ':15, 'CREATIVE COMPUTING MORRISTOWN, NEW JERSEY');
WriteLN;
WriteLN;
WriteLN;
WriteLN;
end;
procedure TAmazingApplication.GetDimensions;
var
width: Integer;
length: Integer;
begin
repeat
Write('WHAT ARE YOUR WIDTH AND LENGTH (SPACE IN BETWEEN): ');
ReadLN(width, length);
if (width = 1) or (length = 1) then
begin
WriteLN('MEANINGLESS DIMENSIONS. TRY AGAIN.');
end;
until (width > 1) and (length > 1);
FMaze:= TMaze.Create(width, length);
WriteLN;
WriteLN;
WriteLN;
WriteLN;
end;
procedure TAmazingApplication.BuildMaze;
begin
FMaze.Build;
end;
procedure TAmazingApplication.PrintMaze;
begin
FMaze.Print;
WriteLN;
end;
constructor TAmazingApplication.Create;
begin
//
end;
destructor TAmazingApplication.Destroy;
begin
if Assigned(FMaze) then
begin
FMaze.Free;
end;
inherited Destroy;
end;
procedure TAmazingApplication.Run;
begin
//ClrScr;
PrintGreeting;
GetDimensions;
BuildMaze;
PrintMaze;
end;
end.

View File

@@ -0,0 +1,280 @@
unit Maze;
{$IFDEF FPC}
{$mode ObjFPC}{$H+}
{$ENDIF}
interface
uses
Classes
, SysUtils
, Room
;
type
TDirection = (dUp, dRight, dDown, dLeft);
TDirections = set of TDirection;
{ TMaze }
TMaze = class(TObject)
private
FWidth: Integer;
FLength: Integer;
FEntry: Integer;
FLabyrinth: Array of Array of TRoom;
function GetRandomDirection(const ADirections: TDirections): TDirection;
procedure DebugVisited;
procedure DebugWalls;
protected
public
constructor Create(const AWidth, ALength: Integer);
destructor Destroy; override;
procedure Build;
procedure Print;
published
end;
implementation
const
EXIT_DOWN = 1;
EXIT_RIGHT = 2;
{ TMaze }
function TMaze.GetRandomDirection(const ADirections: TDirections): TDirection;
var
count: Integer;
position: Integer;
directions: array [0..3] of TDirection;
begin
count:= 0;
position:= 0;
if dUp in ADirections then
begin
Inc(count);
directions[position]:= dUp;
Inc(position);
end;
if dRight in ADirections then
begin
Inc(count);
directions[position]:= dRight;
Inc(position);
end;
if dDown in ADirections then
begin
Inc(count);
directions[position]:= dDown;
Inc(position);
end;
if dLeft in ADirections then
begin
Inc(count);
directions[position]:= dLeft;
Inc(position);
end;
Result:= directions[Random(count)];
end;
procedure TMaze.DebugVisited;
var
indexW: Integer;
indexL: Integer;
begin
WriteLN('Visited');
for indexL:= 0 to Pred(FLength) do
begin
for indexW:= 0 to Pred(FWidth) do
begin
Write(FLabyrinth[indexW][indexL].Visited:3,' ');
end;
WriteLN;
end;
WriteLN;
end;
procedure TMaze.DebugWalls;
var
indexW: Integer;
indexL: Integer;
begin
WriteLN('Walls');
for indexL:= 0 to Pred(FLength) do
begin
for indexW:= 0 to Pred(FWidth) do
begin
Write(FLabyrinth[indexW][indexL].Walls:3,' ');
end;
WriteLN;
end;
WriteLN;
end;
constructor TMaze.Create(const AWidth, ALength: Integer);
var
indexW: Integer;
indexL: Integer;
begin
Randomize;
FWidth:= AWidth;
FLength:= ALength;
FEntry:= Random(FWidth);
SetLength(FLabyrinth, FWidth, FLength);
for indexW:= 0 to Pred(FWidth) do
begin
for indexL:= 0 to Pred(FLength) do
begin
FLabyrinth[indexW][indexL]:= TRoom.Create;
end;
end;
end;
destructor TMaze.Destroy;
var
indexW: Integer;
indexL: Integer;
begin
for indexW:= 0 to Pred(FWidth) do
begin
for indexL:= 0 to Pred(FLength) do
begin
if Assigned(FLabyrinth[indexW][indexL]) then
begin
FLabyrinth[indexW][indexL].Free;
end;
end;
end;
inherited Destroy;
end;
procedure TMaze.Build;
var
indexW: Integer;
indexL: Integer;
direction: TDirection;
directions: TDirections;
count: Integer;
begin
FEntry:= Random(FWidth);
indexW:= FEntry;
indexL:= 0;
count:= 1;
FLabyrinth[indexW][indexL].Visited:= count;
Inc(count);
repeat
directions:= [dUp, dRight, dDown, dLeft];
if (indexW = 0) or (FLabyrinth[Pred(indexW)][indexL].Visited <> 0) then
begin
Exclude(directions, dLeft);
end;
if (indexL = 0) or (FLabyrinth[indexW][Pred(indexL)].Visited <> 0) then
begin
Exclude(directions, dUp);
end;
if (indexW = Pred(FWidth)) or (FLabyrinth[Succ(indexW)][indexL].Visited <> 0) then
begin
Exclude(directions, dRight);
end;
if (indexL = Pred(FLength)) or (FLabyrinth[indexW][Succ(indexL)].Visited <> 0) then
begin
Exclude(directions, dDown);
end;
if directions <> [] then
begin
direction:= GetRandomDirection(directions);
case direction of
dLeft:begin
Dec(indexW);
FLabyrinth[indexW][indexL].Walls:= EXIT_RIGHT;
end;
dUp:begin
Dec(indexL);
FLabyrinth[indexW][indexL].Walls:= EXIT_DOWN;
end;
dRight:begin
FLabyrinth[indexW][indexL].Walls:= FLabyrinth[indexW][indexL].Walls + EXIT_RIGHT;
Inc(indexW);
end;
dDown:begin
FLabyrinth[indexW][indexL].Walls:= FLabyrinth[indexW][indexL].Walls + EXIT_DOWN;
Inc(indexL);
end;
end;
FLabyrinth[indexW][indexL].Visited:= count;
Inc(count);
end
else
begin
while True do
begin
if indexW <> Pred(FWidth) then
begin
Inc(indexW);
end
else if indexL <> Pred(FLength) then
begin
Inc(indexL);
indexW:= 0;
end
else
begin
indexW:= 0;
indexL:= 0;
end;
if FLabyrinth[indexW][indexL].Visited <> 0 then
begin
break;
end;
end;
end;
until count = (FWidth * FLength) + 1;
indexW:= Random(FWidth);
indexL:= Pred(FLength);
FLabyrinth[indexW][indexL].Walls:= FLabyrinth[indexW][indexL].Walls + 1;
end;
procedure TMaze.Print;
var
indexW:Integer;
indexL: Integer;
begin
//DebugVisited;
//DebugWalls;
for indexW:= 0 to Pred(FWidth) do
begin
if indexW = FEntry then
begin
Write('. ');
end
else
begin
Write('.--');
end;
end;
WriteLN('.');
for indexL:= 0 to Pred(FLength) do
begin
Write('I');
for indexW:= 0 to Pred(FWidth) do
begin
FLabyrinth[indexW][indexL].PrintRoom;
end;
WriteLN;
for indexW:= 0 to Pred(FWidth) do
begin
FLabyrinth[indexW][indexL].PrintWall;
end;
WriteLN('.');
end;
end;
end.

View File

@@ -0,0 +1,71 @@
unit Room;
{$IFDEF FPC}
{$mode ObjFPC}{$H+}
{$ENDIF}
interface
uses
Classes
, SysUtils
;
type
{ TRoom }
TRoom = class(TObject)
private
FVisited: Integer;
FWalls: Integer;
protected
public
constructor Create;
procedure PrintRoom;
procedure PrintWall;
property Visited: Integer
read FVisited
write FVisited;
property Walls: Integer
read FWalls
write FWalls;
published
end;
implementation
{ TRoom }
constructor TRoom.Create;
begin
FVisited:= 0;
FWalls:= 0;
end;
procedure TRoom.PrintRoom;
begin
if FWalls < 2 then
begin
Write(' I');
end
else
begin
Write(' ');
end;
end;
procedure TRoom.PrintWall;
begin
if (FWalls = 0) or (FWalls = 2) then
begin
Write(':--');
end
else
begin
Write(': ');
end;
end;
end.

View File

@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="12"/>
<General>
<Flags>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
<MainUnitHasScaledStatement Value="False"/>
<CompatibilityMode Value="True"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<Title Value="amazing"/>
<UseAppBundle Value="False"/>
<ResourceType Value="res"/>
</General>
<BuildModes Count="1">
<Item1 Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<UseFileFilters Value="True"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
</RunParams>
<Units Count="1">
<Unit0>
<Filename Value="amazing.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="Amazing"/>
</Unit0>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<Target>
<Filename Value="amazing"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>
<UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
</CompilerOptions>
<Debugging>
<Exceptions Count="3">
<Item1>
<Name Value="EAbort"/>
</Item1>
<Item2>
<Name Value="ECodetoolError"/>
</Item2>
<Item3>
<Name Value="EFOpenError"/>
</Item3>
</Exceptions>
</Debugging>
</CONFIG>

View File

@@ -0,0 +1,284 @@
program Amazing;
{$IFDEF FPC}
{$mode objfpc}{$H+}
{$ENDIF}
uses
Crt;
type
TDirection = (dUp, dRight, dDown, dLeft);
TDirections = set of TDirection;
var
Width: Integer; // H
Length: Integer; // V
Entry: Integer;
MatrixWalls: Array of Array of Integer;
MatrixVisited: Array of Array of Integer;
const
EXIT_DOWN = 1;
EXIT_RIGHT = 2;
procedure PrintGreeting;
begin
WriteLN(' ':28, 'AMAZING PROGRAM');
WriteLN(' ':15, 'CREATIVE COMPUTING MORRISTOWN, NEW JERSEY');
WriteLN;
WriteLN;
WriteLN;
WriteLN;
end;
procedure GetDimensions;
begin
repeat
Write('WHAT ARE YOUR WIDTH AND LENGTH (SPACE IN BETWEEN): ');
ReadLN(Width, Length);
if (Width = 1) or (Length = 1) then
begin
WriteLN('MEANINGLESS DIMENSIONS. TRY AGAIN.');
end;
until (Width > 1) and (Length > 1);
WriteLN;
WriteLN;
WriteLN;
WriteLN;
end;
procedure ClearMatrices;
var
indexW: Integer;
indexL: Integer;
begin
SetLength(MatrixWalls, Width, Length);
SetLength(MatrixVisited, Width, Length);
for indexW:= 0 to Pred(Width) do
begin
for indexL:= 0 to Pred(Length) do
begin
MatrixWalls[indexW][indexL]:= 0;
MatrixVisited[indexW][indexL]:= 0;
end;
end;
end;
function GetRandomDirection(const ADirections: TDirections): TDirection;
var
count: Integer;
position: Integer;
directions: array [0..3] of TDirection;
begin
count:= 0;
position:= 0;
if dUp in ADirections then
begin
Inc(count);
directions[position]:= dUp;
Inc(position);
end;
if dRight in ADirections then
begin
Inc(count);
directions[position]:= dRight;
Inc(position);
end;
if dDown in ADirections then
begin
Inc(count);
directions[position]:= dDown;
Inc(position);
end;
if dLeft in ADirections then
begin
Inc(count);
directions[position]:= dLeft;
Inc(position);
end;
Result:= directions[Random(count)];
end;
procedure BuildMaze;
var
indexW: Integer;
indexL: Integer;
direction: TDirection;
directions: TDirections;
count: Integer;
begin
Entry:= Random(Width);
indexW:= Entry;
indexL:= 0;
count:= 1;
MatrixVisited[indexW][indexL]:= count;
Inc(count);
repeat
directions:= [dUp, dRight, dDown, dLeft];
if (indexW = 0) or (MatrixVisited[Pred(indexW)][indexL] <> 0) then
begin
Exclude(directions, dLeft);
end;
if (indexL = 0) or (MatrixVisited[indexW][Pred(indexL)] <> 0) then
begin
Exclude(directions, dUp);
end;
if (indexW = Pred(Width)) or (MatrixVisited[Succ(indexW)][indexL] <> 0) then
begin
Exclude(directions, dRight);
end;
if (indexL = Pred(Length)) or (MatrixVisited[indexW][Succ(indexL)] <> 0) then
begin
Exclude(directions, dDown);
end;
if directions <> [] then
begin
direction:= GetRandomDirection(directions);
case direction of
dLeft:begin
Dec(indexW);
MatrixWalls[indexW][indexL]:= EXIT_RIGHT;
end;
dUp:begin
Dec(indexL);
MatrixWalls[indexW][indexL]:= EXIT_DOWN;
end;
dRight:begin
Inc(MatrixWalls[indexW][indexL], EXIT_RIGHT);
Inc(indexW);
end;
dDown:begin
Inc(MatrixWalls[indexW][indexL], EXIT_DOWN);
Inc(indexL);
end;
end;
MatrixVisited[indexW][indexL]:= count;
Inc(count);
end
else
begin
while True do
begin
if indexW <> Pred(Width) then
begin
Inc(indexW);
end
else if indexL <> Pred(Length) then
begin
Inc(indexL);
indexW:= 0;
end
else
begin
indexW:= 0;
indexL:= 0;
end;
if MatrixVisited[indexW][indexL] <> 0 then
begin
break;
end;
end;
end;
until count = (Width * Length) + 1;
indexW:= Random(Width);
indexL:= Pred(Length);
Inc(MatrixWalls[indexW][indexL]);
end;
procedure DegubVisited;
var
indexW: Integer;
indexL: Integer;
begin
WriteLN('Visited');
for indexL:= 0 to Pred(Length) do
begin
for indexW:= 0 to Pred(Width) do
begin
Write(MatrixVisited[indexW][indexL]:2,' ');
end;
WriteLN;
end;
WriteLN;
end;
procedure DebugWalls;
var
indexW: Integer;
indexL: Integer;
begin
WriteLN('Walls');
for indexL:= 0 to Pred(Length) do
begin
for indexW:= 0 to Pred(Width) do
begin
Write(MatrixWalls[indexW, indexL]:2, ' ');
end;
WriteLN;
end;
WriteLN;
end;
procedure PrintMaze;
var
indexW: Integer;
indexL: Integer;
begin
for indexW:= 0 to Pred(Width) do
begin
if indexW = Entry then
begin
Write('. ');
end
else
begin
Write('.--');
end;
end;
WriteLN('.');
for indexL:= 0 to Pred(Length) do
begin
Write('I');
for indexW:= 0 to Pred(Width) do
begin
if MatrixWalls[indexW, indexL] < 2 then
begin
Write(' I');
end
else
begin
Write(' ');
end;
end;
WriteLN;
for indexW:= 0 to Pred(Width) do
begin
if (MatrixWalls[indexW, indexL] = 0) or (MatrixWalls[indexW, indexL] = 2) then
begin
Write(':--');
end
else
begin
Write(': ');
end;
end;
WriteLN('.');
end;
WriteLN;
end;
begin
Randomize;
ClrScr;
PrintGreeting;
GetDimensions;
ClearMatrices;
BuildMaze;
//DegubVisited;
//DebugWalls;
PrintMaze;
end.

View File

@@ -0,0 +1,3 @@
Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
Conversion to [Perl](https://www.perl.org/)

View File

@@ -0,0 +1,3 @@
Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
Conversion to [Python](https://www.python.org/about/)

View File

@@ -0,0 +1,121 @@
import random
# Python translation by Frank Palazzolo - 2/2021
print(' '*28+'AMAZING PROGRAM')
print(' '*15+'CREATIVE COMPUTING MORRISTOWN, NEW JERSEY')
print()
print()
print()
while True:
width, length = input('What are your width and length?').split(',')
width = int(width)
length = int(length)
if width != 1 and length != 1:
break
print('Meaningless dimensions. Try again.')
# Build two 2D arrays
#
# used:
# Initially set to zero, unprocessed cells
# Filled in with consecutive non-zero numbers as cells are processed
#
# walls:
# Initially set to zero, (all paths blocked)
# Remains 0 if there is no exit down or right
# Set to 1 if there is an exit down
# Set to 2 if there is an exit right
# Set to 3 if there are exits down and right
used = []
walls = []
for i in range(length):
used.append([0]*width)
walls.append([0]*width)
# Use direction variables with nice names
GO_LEFT,GO_UP,GO_RIGHT,GO_DOWN=[0,1,2,3]
# Give Exit directions nice names
EXIT_DOWN = 1
EXIT_RIGHT = 2
# Pick a random entrance, mark as used
enter_col=random.randint(0,width-1)
row,col=0,enter_col
count=1
used[row][col]=count
count=count+1
while count!=width*length+1:
# remove possible directions that are blocked or
# hit cells that we have already processed
possible_dirs = [GO_LEFT,GO_UP,GO_RIGHT,GO_DOWN]
if col==0 or used[row][col-1]!=0:
possible_dirs.remove(GO_LEFT)
if row==0 or used[row-1][col]!=0:
possible_dirs.remove(GO_UP)
if col==width-1 or used[row][col+1]!=0:
possible_dirs.remove(GO_RIGHT)
if row==length-1 or used[row+1][col]!=0:
possible_dirs.remove(GO_DOWN)
# If we can move in a direction, move and make opening
if len(possible_dirs)!=0:
direction=random.choice(possible_dirs)
if direction==GO_LEFT:
col=col-1
walls[row][col]=EXIT_RIGHT
elif direction==GO_UP:
row=row-1
walls[row][col]=EXIT_DOWN
elif direction==GO_RIGHT:
walls[row][col]=walls[row][col]+EXIT_RIGHT
col=col+1
elif direction==GO_DOWN:
walls[row][col]=walls[row][col]+EXIT_DOWN
row=row+1
used[row][col]=count
count=count+1
# otherwise, move to the next used cell, and try again
else:
while True:
if col!=width-1:
col=col+1
elif row!=length-1:
row,col=row+1,0
else:
row,col=0,0
if used[row][col]!=0:
break
# Add a random exit
col=random.randint(0,width-1)
row=length-1
walls[row][col]=walls[row][col]+1
# Print the maze
for col in range(width):
if col==enter_col:
print('. ',end='')
else:
print('.--',end='')
print('.')
for row in range(length):
print('I',end='')
for col in range(width):
if walls[row][col]<2:
print(' I',end='')
else:
print(' ',end='')
print()
for col in range(width):
if walls[row][col]==0 or walls[row][col]==2:
print(':--',end='')
else:
print(': ',end='')
print('.')

View File

@@ -0,0 +1,9 @@
Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
Conversion to [Ruby](https://www.ruby-lang.org/en/)
Converted to Ruby (with tons of inspiration from the Python version) by @marcheiligers
Run `ruby amazing.rb`.
Run `DEBUG=1 ruby amazing.ruby` to see how it works (requires at least Ruby 2.7).

216
02_Amazing/ruby/amazing.rb Normal file
View File

@@ -0,0 +1,216 @@
# frozen_string_literal: true
DEBUG = !ENV['DEBUG'].nil?
require 'io/console' if DEBUG
# BASIC arrays are 1-based, unlike Ruby 0-based arrays,
# and this class simulates that. BASIC arrays are zero-filled,
# which is also done here. While we could easily update the
# algorithm to work with zero-based arrays, this class makes
# the problem easier to reason about, row or col 1 are the
# first row or column.
class BasicArrayTwoD
def initialize(rows, cols)
@val = Array.new(rows) { Array.new(cols, 0) }
end
def [](row, col = nil)
if col
@val[row - 1][col - 1]
else
@val[row - 1]
end
end
def []=(row, col, n)
@val[row - 1][col - 1] = n
end
def to_s(width: max_width, row_hilite: nil, col_hilite: nil)
@val.map.with_index do |row, row_index|
row.map.with_index do |val, col_index|
if row_hilite == row_index + 1 && col_hilite == col_index + 1
"[#{val.to_s.center(width)}]"
else
val.to_s.center(width + 2)
end
end.join
end.join("\n")
end
def max_width
@val.flat_map { |row| row.map { |val| val.to_s.length } }.sort.last
end
end
class Maze
EXIT_DOWN = 1
EXIT_RIGHT = 2
# Set up a constant hash for directions
# The values represent the direction of the move as changes to row, col
# and the type of exit when moving in that direction
DIRECTIONS = {
left: { row: 0, col: -1, exit: EXIT_RIGHT },
up: { row: -1, col: 0, exit: EXIT_DOWN },
right: { row: 0, col: 1, exit: EXIT_RIGHT },
down: { row: 1, col: 0, exit: EXIT_DOWN }
}.freeze
attr_reader :width, :height, :used, :walls, :entry
def initialize(width, height)
@width = width
@height = height
@used = BasicArrayTwoD.new(height, width)
@walls = BasicArrayTwoD.new(height, width)
create
end
def draw
# Print the maze
draw_top(entry, width)
(1..height - 1).each do |row|
draw_row(walls[row])
end
draw_bottom(walls[height])
end
private
def create
# entry represents the location of the opening
@entry = (rand * width).round + 1
# Set up our current row and column, starting at the top and the locations of the opening
row = 1
col = entry
c = 1
used[row, col] = c # This marks the opening in the first row
c += 1
while c != width * height + 1 do
debug walls, row, col
# remove possible directions that are blocked or
# hit cells that we have already processed
possible_dirs = DIRECTIONS.reject do |dir, change|
nrow = row + change[:row]
ncol = col + change[:col]
nrow < 1 || nrow > height || ncol < 1 || ncol > width || used[nrow, ncol] != 0
end.keys
# If we can move in a direction, move and make opening
if possible_dirs.size != 0
direction = possible_dirs.sample
change = DIRECTIONS[direction] # pick a random direction
if %i[left up].include?(direction)
row += change[:row]
col += change[:col]
walls[row, col] = change[:exit]
else
walls[row, col] += change[:exit]
row += change[:row]
col += change[:col]
end
used[row, col] = c
c = c + 1
# otherwise, move to the next used cell, and try again
else
loop do
if col != width
col += 1
elsif row != height
row += 1
col = 1
else
row = col = 1
end
break if used[row, col] != 0
debug walls, row, col
end
end
end
# Add a random exit
walls[height, (rand * width).round] += 1
end
def draw_top(entry, width)
(1..width).each do |i|
if i == entry
print i == 1 ? '┏ ' : '┳ '
else
print i == 1 ? '┏━━' : '┳━━'
end
end
puts '┓'
end
def draw_row(row)
print '┃'
row.each.with_index do |val, col|
print val < 2 ? ' ┃' : ' '
end
puts
row.each.with_index do |val, col|
print val == 0 || val == 2 ? (col == 0 ? '┣━━' : '╋━━') : (col == 0 ? '┃ ' : '┫ ')
end
puts '┫'
end
def draw_bottom(row)
print '┃'
row.each.with_index do |val, col|
print val < 2 ? ' ┃' : ' '
end
puts
row.each.with_index do |val, col|
print val == 0 || val == 2 ? (col == 0 ? '┗━━' : '┻━━') : (col == 0 ? '┗ ' : '┻ ')
end
puts '┛'
end
def debug(walls, row, col)
return unless DEBUG
STDOUT.clear_screen
puts walls.to_s(row_hilite: row, col_hilite: col)
sleep 0.1
end
end
class Amazing
def run
draw_header
width, height = ask_dimensions
while width <= 1 || height <= 1
puts "MEANINGLESS DIMENSIONS. TRY AGAIN."
width, height = ask_dimensions
end
maze = Maze.new(width, height)
puts "\n" * 3
maze.draw
end
def draw_header
puts ' ' * 28 + 'AMAZING PROGRAM'
puts ' ' * 15 + 'CREATIVE COMPUTING MORRISTOWN, NEW JERSEY'
puts "\n" * 3
end
def ask_dimensions
print 'WHAT ARE YOUR WIDTH AND HEIGHT? '
width = gets.to_i
print '?? '
height = gets.to_i
[width, height]
end
end
Amazing.new.run

View File

@@ -0,0 +1,3 @@
Original BASIC source [downloaded from Vintage Basic](http://www.vintage-basic.net/games.html)
Conversion to [Visual Basic .NET](https://en.wikipedia.org/wiki/Visual_Basic_.NET)