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
55_Life/README.md Normal file
View File

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

3
55_Life/csharp/README.md Normal file
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/)

3
55_Life/java/README.md Normal file
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>LIFE</title>
</head>
<body>
<pre id="output" style="font-size: 12pt;"></pre>
<script src="life.js"></script>
</body>
</html>

191
55_Life/javascript/life.js Normal file
View File

@@ -0,0 +1,191 @@
// LIFE
//
// 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;
}
var bs = [];
var a = [];
// Main program
async function main()
{
print(tab(34) + "LIFE\n");
print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
print("\n");
print("\n");
print("\n");
print("ENTER YOUR PATTERN:\n");
x1 = 1;
y1 = 1;
x2 = 24;
y2 = 70;
for (c = 1; c <= 24; c++) {
bs[c] = "";
a[c] = [];
for (d = 1; d <= 70; d++)
a[c][d] = 0;
}
c = 1;
while (1) {
bs[c] = await input();
if (bs[c] == "DONE") {
bs[c] = "";
break;
}
if (bs[c].substr(0, 1) == ".")
bs[c] = " " + bs[c].substr(1);
c++;
}
c--;
l = 0;
for (x = 1; x <= c - 1; x++) {
if (bs[x].length > l)
l = bs[x].length;
}
x1 = 11 - (c >> 1);
y1 = 33 - (l >> 1);
p = 0;
for (x = 1; x <= c; x++) {
for (y = 1; y <= bs[x].length; y++) {
if (bs[x][y - 1] != " ") {
a[x1 + x][y1 + y] = 1;
p++;
}
}
}
print("\n");
print("\n");
print("\n");
i9 = false;
g = 0;
while (g < 100) {
print("GENERATION: " + g + " POPULATION: " + p + " ");
if (i9)
print("INVALID!");
x3 = 24;
y3 = 70;
x4 = 1;
y4 = 1;
p = 0;
g++;
for (x = 1; x <= x1 - 1; x++)
print("\n");
for (x = x1; x <= x2; x++) {
print("\n");
str = "";
for (y = y1; y <= y2; y++) {
if (a[x][y] == 2) {
a[x][y] = 0;
continue;
} else if (a[x][y] == 3) {
a[x][y] = 1;
} else if (a[x][y] != 1) {
continue;
}
while (str.length < y)
str += " ";
str += "*";
if (x < x3)
x3 = x;
if (x > x4)
x4 = x;
if (y < y3)
y3 = y;
if (y > y4)
y4 = y;
}
print(str);
}
for (x = x2 + 1; x <= 24; x++)
print("\n");
x1 = x3;
x2 = x4;
y1 = y3;
y2 = y4;
if (x1 < 3) {
x1 = 3;
i9 = true;
}
if (x2 > 22) {
x2 = 22;
i9 = true;
}
if (y1 < 3) {
y1 = 3;
i9 = true;
}
if (y2 > 68) {
y2 = 68;
i9 = true;
}
p = 0;
for (x = x1 - 1; x <= x2 + 1; x++) {
for (y = y1 - 1; y <= y2 + 1; y++) {
c = 0;
for (i = x - 1; i <= x + 1; i++) {
for (j = y - 1; j <= y + 1; j++) {
if (a[i][j] == 1 || a[i][j] == 2)
c++;
}
}
if (a[x][y] == 0) {
if (c == 3) {
a[x][y] = 3;
p++;
}
} else {
if (c < 3 || c > 4) {
a[x][y] = 2;
} else {
p++;
}
}
}
}
x1--;
y1--;
x2++;
y2++;
}
}
main();

66
55_Life/life.bas Normal file
View File

@@ -0,0 +1,66 @@
2 PRINT TAB(34);"LIFE"
4 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"
6 PRINT: PRINT: PRINT
8 PRINT "ENTER YOUR PATTERN:"
9 X1=1: Y1=1: X2=24: Y2=70
10 DIM A(24,70),B$(24)
20 C=1
30 INPUT B$(C)
40 IF B$(C)="DONE" THEN B$(C)="": GOTO 80
50 IF LEFT$(B$(C),1)="." THEN B$(C)=" "+RIGHT$(B$(C),LEN(B$(C))-1)
60 C=C+1
70 GOTO 30
80 C=C-1: L=0
90 FOR X=1 TO C-1
100 IF LEN(B$(X))>L THEN L=LEN(B$(X))
110 NEXT X
120 X1=11-C/2
130 Y1=33-L/2
140 FOR X=1 TO C
150 FOR Y=1 TO LEN(B$(X))
160 IF MID$(B$(X),Y,1)<>" " THEN A(X1+X,Y1+Y)=1:P=P+1
170 NEXT Y
180 NEXT X
200 PRINT:PRINT:PRINT
210 PRINT "GENERATION:";G,"POPULATION:";P;: IF I9 THEN PRINT "INVALID!";
215 X3=24:Y3=70:X4=1: Y4=1: P=0
220 G=G+1
225 FOR X=1 TO X1-1: PRINT: NEXT X
230 FOR X=X1 TO X2
240 PRINT
250 FOR Y=Y1 TO Y2
253 IF A(X,Y)=2 THEN A(X,Y)=0:GOTO 270
256 IF A(X,Y)=3 THEN A(X,Y)=1:GOTO 261
260 IF A(X,Y)<>1 THEN 270
261 PRINT TAB(Y);"*";
262 IF X<X3 THEN X3=X
264 IF X>X4 THEN X4=X
266 IF Y<Y3 THEN Y3=Y
268 IF Y>Y4 THEN Y4=Y
270 NEXT Y
290 NEXT X
295 FOR X=X2+1 TO 24: PRINT: NEXT X
299 X1=X3: X2=X4: Y1=Y3: Y2=Y4
301 IF X1<3 THEN X1=3:I9=-1
303 IF X2>22 THEN X2=22:I9=-1
305 IF Y1<3 THEN Y1=3:I9=-1
307 IF Y2>68 THEN Y2=68:I9=-1
309 P=0
500 FOR X=X1-1 TO X2+1
510 FOR Y=Y1-1 TO Y2+1
520 C=0
530 FOR I=X-1 TO X+1
540 FOR J=Y-1 TO Y+1
550 IF A(I,J)=1 OR A(I,J)=2 THEN C=C+1
560 NEXT J
570 NEXT I
580 IF A(X,Y)=0 THEN 610
590 IF C<3 OR C>4 THEN A(X,Y)=2: GOTO 600
595 P=P+1
600 GOTO 620
610 IF C=3 THEN A(X,Y)=3:P=P+1
620 NEXT Y
630 NEXT X
635 X1=X1-1:Y1=Y1-1:X2=X2+1:Y2=Y2+1
640 GOTO 210
650 END

3
55_Life/pascal/README.md Normal file
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))

3
55_Life/perl/README.md Normal file
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/)

3
55_Life/python/README.md Normal file
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/)

173
55_Life/python/life.py Normal file
View File

@@ -0,0 +1,173 @@
"""
LIFE
An implementation of John Conway's popular cellular automaton
Ported by Dave LeCompte
"""
PAGE_WIDTH = 64
MAX_WIDTH = 70
MAX_HEIGHT = 24
def print_centered(msg):
spaces = " " * ((PAGE_WIDTH - len(msg)) // 2)
print(spaces + msg)
def print_header(title):
print_centered(title)
print_centered("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY")
print()
print()
print()
def get_pattern():
print("ENTER YOUR PATTERN:")
c = 0
pattern = {}
while True:
line = input()
if line == "DONE":
return pattern
# BASIC input would strip of leading whitespace.
# Python input does not. The following allows you to start a
# line with a dot to disable the whitespace stripping. This is
# unnecessary for Python, but for historical accuracy, it's
# staying in.
if line[0] == ".":
line = " " + line[1:]
pattern[c] = line
c += 1
def main():
print_header("LIFE")
pattern = get_pattern()
pattern_height = len(pattern)
pattern_width = 0
for line_num, line in pattern.items():
pattern_width = max(pattern_width, len(line))
min_x = 11 - pattern_height // 2
min_y = 33 - pattern_width // 2
max_x = MAX_HEIGHT - 1
max_y = MAX_WIDTH - 1
a = [[0 for y in range(MAX_WIDTH)] for x in range(MAX_HEIGHT)]
p = 0
g = 0
invalid = False
# line 140
# transcribe the input pattern into the active array
for x in range(0, pattern_height):
for y in range(0, len(pattern[x])):
if pattern[x][y] != " ":
a[min_x + x][min_y + y] = 1
p += 1
print()
print()
print()
while True:
if invalid:
inv_str = "INVALID!"
else:
inv_str = ""
print(f"GENERATION: {g}\tPOPULATION: {p} {inv_str}")
next_min_x = MAX_HEIGHT - 1
next_min_y = MAX_WIDTH - 1
next_max_x = 0
next_max_y = 0
p = 0
g += 1
for x in range(0, min_x):
print()
for x in range(min_x, max_x + 1):
print
line = [" "] * MAX_WIDTH
for y in range(min_y, max_y + 1):
if a[x][y] == 2:
a[x][y] = 0
continue
elif a[x][y] == 3:
a[x][y] = 1
elif a[x][y] != 1:
continue
# line 261
line[y] = "*"
next_min_x = min(x, next_min_x)
next_max_x = max(x, next_max_x)
next_min_y = min(y, next_min_y)
next_max_y = max(y, next_max_y)
print("".join(line))
# line 295
for x in range(max_x + 1, MAX_HEIGHT):
print()
print()
min_x = next_min_x
max_x = next_max_x
min_y = next_min_y
max_y = next_max_y
if min_x < 3:
min_x = 3
invalid = True
if max_x > 22:
max_x = 22
invalid = True
if min_y < 3:
min_y = 3
invalid = True
if max_y > 68:
max_y = 68
invalid = True
# line 309
p = 0
for x in range(min_x - 1, max_x + 2):
for y in range(min_y - 1, max_y + 2):
count = 0
for i in range(x - 1, x + 2):
for j in range(y - 1, y + 2):
if a[i][j] == 1 or a[i][j] == 2:
count += 1
if a[x][y] == 0:
if count == 3:
a[x][y] = 3
p += 1
elif (count < 3) or (count > 4):
a[x][y] = 2
else:
p += 1
# line 635
min_x = min_x - 1
min_y = min_y - 1
max_x = max_x + 1
max_y = max_y + 1
if __name__ == "__main__":
main()

3
55_Life/ruby/README.md Normal file
View File

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

160
55_Life/ruby/life.rb Executable file
View File

@@ -0,0 +1,160 @@
#!ruby
# The Pattern class encapsulates everything we would want to know about a
# pattern in our Game of Life: its size, its current pattern of alive and
# dead cells, which generation it's on and how long it can run, and how
# to accept input for itself, print itself, and most importantly iterate
# from one generation to the next.
PATTERN_WIDTH = 80
PATTERN_HEIGHT = 24
class Pattern
# Begin with a totally empty/dead pattern of fixed size at generation 0.
def initialize(max_generations: 10)
@max_generations = max_generations
@generation = 0
@population = nil
@counter = Array.new(PATTERN_HEIGHT) { Array.new(PATTERN_WIDTH, 0) }
@invalid = false
end
# Take input from the console and enter it into the pattern.
def get_input
input = []
done = false
# Accept the input from the user on the console
loop do
print "? "
line = gets.chomp
break if line == 'DONE'
line.gsub!(/^\./, ' ')
input << line
end
# Emit some blank space
(1..10).each { puts }
# Center the input in the two-dimensional array
input_width = input.map { |line| line.length }.max
width_offset = ((PATTERN_WIDTH - input_width) / 2).floor
height_offset = ((PATTERN_HEIGHT - input.count) / 2).floor
# TODO emit error if width > PATTERN_WIDTH or line count > PATTERN_HEIGHT
# Start by setting each element to 0 if dead or a 1 if alive
input.each_index do |y|
line = input[y].ljust(input_width)
y_offset = y + height_offset
@counter[y_offset] = [
[0] * width_offset,
line.split("").map { |char| char == ' ' ? 0 : 1 },
[0] * PATTERN_WIDTH
].flatten.take(PATTERN_WIDTH)
end
@population = @counter.flatten.sum
end
# Emit the pattern to the console.
def display
puts "GENERATION:#{@generation}\tPOPULATION:#{@population}"
puts "INVALID!"if @invalid
@counter.each do |row|
puts row.map { |cell| ((cell == 0 || cell == 2) ? ' ' : 'X') }.join('')
end
end
# Iterate from one generation to the next, returning true if the
# game of life should continue, and false if it should terminate.
def iterate
@generation = @generation + 1
return false if @generation > @max_generations
# Update the counter array with new values.
# First, change each 2 (dying) to a 0 (dead)
# and each 3 (born) to a 1 (alive)
@counter.map! { |row| row.map! { |cell| cell >= 2 ? cell-2 : cell } }
# Now for each cell, count its neighbors and update it
@population = 0
@counter.each_index do |rownum|
@counter[rownum].each_index do |colnum|
cell_value = @counter[rownum][colnum]
# If any cell on the border is set, our small algorithm is not
# smart enough to correctly check its neighbors, so sadly our
# pattern becomes invalid. We keep going though
@invalid = true if cell_value > 0 && (
rownum == 0 || rownum == PATTERN_HEIGHT-1 || colnum == 0 || colnum == PATTERN_WIDTH-1
)
# Count the cell's neighbors (not including itself)
neighbors = @counter[rownum-1..rownum+1].map { |row| row[colnum-1..colnum+1] }.flatten
neighbor_count = neighbors.inject(0) do |sum, value|
sum += (value == 1 || value == 2) ? 1 : 0
end
neighbor_count = neighbor_count - cell_value
# Update this cell based on its neighbor count, either leaving it
# as a 0 or 1, or setting it to 2 (dying) or 3 (being born)
if cell_value == 0
if neighbor_count == 3
cell_value = 3
@population = @population + 1
end
elsif neighbor_count < 2 || neighbor_count > 3
cell_value = 2
else
@population = @population + 1
end
@counter[rownum][colnum] = cell_value
end
end
# If every cell is dead, we are done. Otherwise, keep going up to the
# maximum number of generations
@population > 0
end
end
# The following program code makes use of the Pattern class to create,
# iterate on, and display the Game of Life.
def display_banner
puts " " * 34 + "LIFE"
puts " " * 15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"
puts
puts "PLEASE ENTER YOUR STARTING PATTERN, USING SPACE FOR AN EMPTY CELL"
puts "AND AN 'X' FOR A FILLED CELL. YOUR PATTERN MAY BE UP TO #{PATTERN_HEIGHT} ROWS"
puts "OF UP TO #{PATTERN_WIDTH} COLUMNS EACH. TYPE 'DONE' WHEN DONE."
puts "ENTER YOUR PATTERN:"
end
def main
display_banner
pattern = Pattern.new
pattern.get_input
pattern.display
pattern.display while pattern.iterate
end
main

3
55_Life/vbnet/README.md Normal file
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)