mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2026-01-16 23:12:08 -08:00
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:
7
02_Amazing/README.md
Normal file
7
02_Amazing/README.md
Normal 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
138
02_Amazing/amazing.bas
Normal 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
|
||||
320
02_Amazing/csharp/Amazing.cs
Normal file
320
02_Amazing/csharp/Amazing.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
8
02_Amazing/csharp/Amazing.csproj
Normal file
8
02_Amazing/csharp/Amazing.csproj
Normal file
@@ -0,0 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
25
02_Amazing/csharp/Amazing.sln
Normal file
25
02_Amazing/csharp/Amazing.sln
Normal 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
|
||||
3
02_Amazing/csharp/README.md
Normal file
3
02_Amazing/csharp/README.md
Normal 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/)
|
||||
262
02_Amazing/java/Amazing.java
Normal file
262
02_Amazing/java/Amazing.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
6
02_Amazing/java/AmazingGame.java
Normal file
6
02_Amazing/java/AmazingGame.java
Normal file
@@ -0,0 +1,6 @@
|
||||
public class AmazingGame {
|
||||
public static void main(String[] args) {
|
||||
Amazing amazing = new Amazing();
|
||||
amazing.play();
|
||||
}
|
||||
}
|
||||
3
02_Amazing/java/README.md
Normal file
3
02_Amazing/java/README.md
Normal 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/)
|
||||
3
02_Amazing/javascript/README.md
Normal file
3
02_Amazing/javascript/README.md
Normal 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)
|
||||
9
02_Amazing/javascript/amazing.html
Normal file
9
02_Amazing/javascript/amazing.html
Normal 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>
|
||||
319
02_Amazing/javascript/amazing.js
Normal file
319
02_Amazing/javascript/amazing.js
Normal 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
36
02_Amazing/pascal/.gitattributes
vendored
Normal 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
63
02_Amazing/pascal/.gitignore
vendored
Normal 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
|
||||
3
02_Amazing/pascal/README.md
Normal file
3
02_Amazing/pascal/README.md
Normal 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)
|
||||
71
02_Amazing/pascal/object-pascal/amazing.lpi
Normal file
71
02_Amazing/pascal/object-pascal/amazing.lpi
Normal 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>
|
||||
17
02_Amazing/pascal/object-pascal/amazing.pas
Normal file
17
02_Amazing/pascal/object-pascal/amazing.pas
Normal 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.
|
||||
|
||||
104
02_Amazing/pascal/object-pascal/amazingapplication.pas
Normal file
104
02_Amazing/pascal/object-pascal/amazingapplication.pas
Normal 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.
|
||||
|
||||
280
02_Amazing/pascal/object-pascal/maze.pas
Normal file
280
02_Amazing/pascal/object-pascal/maze.pas
Normal 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.
|
||||
|
||||
71
02_Amazing/pascal/object-pascal/room.pas
Normal file
71
02_Amazing/pascal/object-pascal/room.pas
Normal 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.
|
||||
|
||||
58
02_Amazing/pascal/simple/amazing.lpi
Normal file
58
02_Amazing/pascal/simple/amazing.lpi
Normal 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>
|
||||
284
02_Amazing/pascal/simple/amazing.pas
Normal file
284
02_Amazing/pascal/simple/amazing.pas
Normal 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.
|
||||
|
||||
3
02_Amazing/perl/README.md
Normal file
3
02_Amazing/perl/README.md
Normal 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/)
|
||||
3
02_Amazing/python/README.md
Normal file
3
02_Amazing/python/README.md
Normal 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/)
|
||||
121
02_Amazing/python/amazing.py
Normal file
121
02_Amazing/python/amazing.py
Normal 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('.')
|
||||
|
||||
|
||||
|
||||
9
02_Amazing/ruby/README.md
Normal file
9
02_Amazing/ruby/README.md
Normal 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
216
02_Amazing/ruby/amazing.rb
Normal 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
|
||||
3
02_Amazing/vbnet/README.md
Normal file
3
02_Amazing/vbnet/README.md
Normal 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)
|
||||
Reference in New Issue
Block a user