mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-12 15:50:20 -08:00
Added MiniScript versions of 55_Life and 56_Life_for_Two.
This commit is contained in:
19
00_Alternate_Languages/55_Life/MiniScript/README.md
Normal file
19
00_Alternate_Languages/55_Life/MiniScript/README.md
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html).
|
||||||
|
|
||||||
|
Conversion to [MiniScript](https://miniscript.org).
|
||||||
|
|
||||||
|
Ways to play:
|
||||||
|
|
||||||
|
1. Command-Line MiniScript:
|
||||||
|
Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as:
|
||||||
|
|
||||||
|
```
|
||||||
|
miniscript life.ms
|
||||||
|
```
|
||||||
|
2. Mini Micro:
|
||||||
|
Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter:
|
||||||
|
|
||||||
|
```
|
||||||
|
load "life"
|
||||||
|
run
|
||||||
|
```
|
||||||
132
00_Alternate_Languages/55_Life/MiniScript/life.ms
Normal file
132
00_Alternate_Languages/55_Life/MiniScript/life.ms
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
print " "*34 + "LIFE"
|
||||||
|
print " "*15 + "Creative Computing Morristown, New Jersey"
|
||||||
|
print; print; print
|
||||||
|
import "listUtil" // (needed for list.init2d)
|
||||||
|
|
||||||
|
maxx = 66 // (size adjusted for Mini Micro display)
|
||||||
|
maxy = 23
|
||||||
|
A = list.init2d(maxx+1, maxy+1, 0)
|
||||||
|
|
||||||
|
// Stuff the given pattern into the center of the cell array.
|
||||||
|
// Return the number of live cells.
|
||||||
|
stuffIntoCenter = function(pattern)
|
||||||
|
maxLen = 0
|
||||||
|
for p in pattern
|
||||||
|
if p.len > maxLen then maxLen = p.len
|
||||||
|
end for
|
||||||
|
|
||||||
|
population = 0
|
||||||
|
y = floor(maxy/2 - pattern.len/2)
|
||||||
|
for row in pattern
|
||||||
|
x = floor(maxx/2 - maxLen/2)
|
||||||
|
for c in row
|
||||||
|
if c != " " then
|
||||||
|
A[x][y] = 1
|
||||||
|
population += 1
|
||||||
|
end if
|
||||||
|
x += 1
|
||||||
|
end for
|
||||||
|
y += 1
|
||||||
|
end for
|
||||||
|
return population
|
||||||
|
end function
|
||||||
|
|
||||||
|
// Get the initial pattern from the user
|
||||||
|
initToUserPattern = function
|
||||||
|
print "Enter your pattern (enter DONE when done):"
|
||||||
|
userPattern = []
|
||||||
|
while true
|
||||||
|
p = input("?")
|
||||||
|
if p.upper == "DONE" then break
|
||||||
|
if p and p[0] == "." then p = " " + p[1:]
|
||||||
|
userPattern.push p
|
||||||
|
end while
|
||||||
|
return stuffIntoCenter(userPattern)
|
||||||
|
end function
|
||||||
|
|
||||||
|
// For testing purposes, skip asking the user and just use a hard-coded pattern.
|
||||||
|
initToStandardPattern = function
|
||||||
|
pattern = [
|
||||||
|
" **",
|
||||||
|
" * *",
|
||||||
|
" *"]
|
||||||
|
return stuffIntoCenter(pattern)
|
||||||
|
end function
|
||||||
|
|
||||||
|
// Or, just for fun, initialize to a random pattern of junk in the center.
|
||||||
|
initRandom = function
|
||||||
|
for x in range(ceil(maxx*0.3), floor(maxx*0.7))
|
||||||
|
for y in range(ceil(maxy*0.3), floor(maxy*0.7))
|
||||||
|
A[x][y] = rnd > 0.5
|
||||||
|
end for
|
||||||
|
end for
|
||||||
|
end function
|
||||||
|
|
||||||
|
// Define a function to draw the current game state.
|
||||||
|
// This also changes 2 (dying) to 0 (dead), and 3 (being born) to 1 (alive).
|
||||||
|
drawGameState = function(generation=0, population=0, invalid=false)
|
||||||
|
if version.hostName == "Mini Micro" then text.row = 26 else print
|
||||||
|
print "Generation: " + generation + " Population: " + population +
|
||||||
|
" " + "INVALID!" * invalid
|
||||||
|
for y in range(0, maxy)
|
||||||
|
s = ""
|
||||||
|
for x in range(0, maxx)
|
||||||
|
if A[x][y] == 2 then
|
||||||
|
A[x][y] = 0
|
||||||
|
else if A[x][y] == 3 then
|
||||||
|
A[x][y] = 1
|
||||||
|
end if
|
||||||
|
if A[x][y] then s += "*" else s += " "
|
||||||
|
end for
|
||||||
|
print s
|
||||||
|
end for
|
||||||
|
end function
|
||||||
|
|
||||||
|
// Update the game state, setting cells that should be born to 3 and
|
||||||
|
// cells that should die to 2. Return the number of cells that will
|
||||||
|
// be alive after this update. Also, set globals.invalid if any live
|
||||||
|
// cells are found on the edge of the map.
|
||||||
|
updateGameState = function
|
||||||
|
population = 0
|
||||||
|
for x in range(0, maxx)
|
||||||
|
for y in range(0, maxy)
|
||||||
|
c = A[x][y] == 1 or A[x][y] == 2 // center state
|
||||||
|
n = -c // number of neighbors
|
||||||
|
for nx in range(x-1, x+1)
|
||||||
|
if nx < 0 or nx > maxx then continue
|
||||||
|
for ny in range(y-1, y+1)
|
||||||
|
if ny < 0 or ny > maxy then continue
|
||||||
|
n += A[nx][ny] == 1 or A[nx][ny] == 2
|
||||||
|
end for
|
||||||
|
end for
|
||||||
|
if c and n != 2 and n != 3 then // live cell with < 2 or > 3 neighbors...
|
||||||
|
A[x][y] = 2 // dies
|
||||||
|
else if not c and n == 3 then // dead cell with 3 neighbors...
|
||||||
|
A[x][y] = 3 // comes to life
|
||||||
|
if x == 0 or x == maxx or y == 0 or y == maxy then
|
||||||
|
globals.invalid = true
|
||||||
|
end if
|
||||||
|
end if
|
||||||
|
population += (A[x][y] == 1 or A[x][y] == 3)
|
||||||
|
end for
|
||||||
|
end for
|
||||||
|
return population
|
||||||
|
end function
|
||||||
|
|
||||||
|
|
||||||
|
// Initialize the game state (uncomment one of the following three lines)
|
||||||
|
population = initToUserPattern
|
||||||
|
//population = initToStandardPattern
|
||||||
|
//population = initRandom
|
||||||
|
|
||||||
|
// Main loop
|
||||||
|
if version.hostName == "Mini Micro" then clear
|
||||||
|
invalid = false
|
||||||
|
generation = 0
|
||||||
|
while population > 0
|
||||||
|
drawGameState generation, population, invalid
|
||||||
|
population = updateGameState
|
||||||
|
generation += 1
|
||||||
|
//key.get // <-- Uncomment this to single-step with each keypress!
|
||||||
|
end while
|
||||||
|
drawGameState generation, population, invalid
|
||||||
19
00_Alternate_Languages/56_Life_for_Two/MiniScript/README.md
Normal file
19
00_Alternate_Languages/56_Life_for_Two/MiniScript/README.md
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
Original source downloaded from [Vintage Basic](http://www.vintage-basic.net/games.html).
|
||||||
|
|
||||||
|
Conversion to [MiniScript](https://miniscript.org). The only liberty I took with the original design is that, when prompting each player for their turn, I include a reminder of what symbol (* or #) represents their pieces on the board.
|
||||||
|
|
||||||
|
Ways to play:
|
||||||
|
|
||||||
|
1. Command-Line MiniScript:
|
||||||
|
Download for your system from https://miniscript.org/cmdline/, install, and then run the program with a command such as:
|
||||||
|
|
||||||
|
```
|
||||||
|
miniscript lifefortwo.ms
|
||||||
|
```
|
||||||
|
2. Mini Micro:
|
||||||
|
Download Mini Micro from https://miniscript.org/MiniMicro/, launch, and then click the top disk slot and chose "Mount Folder..." Select the folder containing the MiniScript program and this README file. Then, at the Mini Micro command prompt, enter:
|
||||||
|
|
||||||
|
```
|
||||||
|
load "lifefortwo"
|
||||||
|
run
|
||||||
|
```
|
||||||
129
00_Alternate_Languages/56_Life_for_Two/MiniScript/lifefortwo.ms
Normal file
129
00_Alternate_Languages/56_Life_for_Two/MiniScript/lifefortwo.ms
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
print " "*33 + "LIFE2"
|
||||||
|
print " "*15 + "Creative Computing Morristown, New Jersey"
|
||||||
|
print; print; print
|
||||||
|
print " "*10 + "U.B. LIFE GAME"
|
||||||
|
|
||||||
|
// N: counts neighbors and game state, as follows:
|
||||||
|
// 1's digit: player 1 neighbors
|
||||||
|
// 10's digit: player 2 neighbors
|
||||||
|
// 100's digit: player 1 current live cell
|
||||||
|
// 1000's digit: player 2 current live cell
|
||||||
|
N = []
|
||||||
|
for i in range(0,6); N.push [0]*7; end for
|
||||||
|
|
||||||
|
// K: encodes the rule for what cells come to life, based on
|
||||||
|
// the value in N. The first 9 entries mean new life for Player 1;
|
||||||
|
// the second 9 entries mean new life for Player 2.
|
||||||
|
K = [3,102,103,120,130,121,112,111,12,
|
||||||
|
21,30,1020,1030,1011,1021,1003,1002,1012]
|
||||||
|
|
||||||
|
// population: how many live cells each player (1-2) has
|
||||||
|
population = [null, 0, 0]
|
||||||
|
|
||||||
|
// Function to get input coordinates from the player, for any empty space.
|
||||||
|
// Where possible, hide the input so the other player can't see it.
|
||||||
|
getCoords = function
|
||||||
|
while true
|
||||||
|
print "X,Y"
|
||||||
|
inp = input.replace(",", " ").replace(" "," ")
|
||||||
|
if version.hostName == "Mini Micro" then
|
||||||
|
text.row = text.row + 1; print " "*60
|
||||||
|
end if
|
||||||
|
parts = inp.split
|
||||||
|
if parts.len == 2 then
|
||||||
|
x = parts[0].val
|
||||||
|
y = parts[1].val
|
||||||
|
if 0 < x <= 5 and 0 < y <= 5 and N[x][y] == 0 then break
|
||||||
|
end if
|
||||||
|
print "Illegal coords. Retype"
|
||||||
|
end while
|
||||||
|
return [x, y]
|
||||||
|
end function
|
||||||
|
|
||||||
|
// Function to print the board. At the same time, it replaces
|
||||||
|
// any player 1 value (as judged by list K) with 100, and any
|
||||||
|
// player 2 value with 1000. Also update population[] with the
|
||||||
|
// number of pieces of each player.
|
||||||
|
printBoard = function
|
||||||
|
population[1] = 0
|
||||||
|
population[2] = 0
|
||||||
|
for y in range(0, 6)
|
||||||
|
if y == 0 or y == 6 then
|
||||||
|
print " 0 1 2 3 4 5 0"
|
||||||
|
else
|
||||||
|
print " " + y, " "
|
||||||
|
for x in range(1, 5)
|
||||||
|
kIndex = K.indexOf(N[x][y])
|
||||||
|
if kIndex == null then
|
||||||
|
print " ", " "
|
||||||
|
N[x][y] = 0
|
||||||
|
else if kIndex < 9 then
|
||||||
|
print "*", " "
|
||||||
|
N[x][y] = 100
|
||||||
|
population[1] += 1
|
||||||
|
else
|
||||||
|
print "#", " "
|
||||||
|
N[x][y] = 1000
|
||||||
|
population[2] += 1
|
||||||
|
end if
|
||||||
|
end for
|
||||||
|
print y
|
||||||
|
end if
|
||||||
|
end for
|
||||||
|
print
|
||||||
|
end function
|
||||||
|
|
||||||
|
// Function to update the board (N).
|
||||||
|
updateBoard = function
|
||||||
|
for j in range(1,5)
|
||||||
|
for k in range(1,5)
|
||||||
|
if N[j][k] < 100 then continue // not a live cell
|
||||||
|
if N[j][k] > 999 then value = 10 else value = 1
|
||||||
|
for x in range(j-1, j+1)
|
||||||
|
for y in range(k-1, k+1)
|
||||||
|
if x == j and y == k then continue
|
||||||
|
N[x][y] += value
|
||||||
|
//if [x,y] == [2,1] then print "adding " + value + " from " + j+","+k + " to " + x+","+y + ", --> " + N[x][y]
|
||||||
|
end for
|
||||||
|
end for
|
||||||
|
end for
|
||||||
|
end for
|
||||||
|
end function
|
||||||
|
|
||||||
|
|
||||||
|
// Get initial player positions.
|
||||||
|
for player in [1,2]
|
||||||
|
print; print "Player " + player + " - 3 live pieces."
|
||||||
|
if player == 2 then value = 30 else value = 3
|
||||||
|
for k in range(1,3)
|
||||||
|
pos = getCoords
|
||||||
|
N[pos[0]][pos[1]] = value
|
||||||
|
end for
|
||||||
|
end for
|
||||||
|
|
||||||
|
printBoard
|
||||||
|
while true
|
||||||
|
updateBoard
|
||||||
|
printBoard
|
||||||
|
if population[1] == 0 and population[2] == 0 then
|
||||||
|
print "A DRAW"
|
||||||
|
break
|
||||||
|
else if population[1] == 0 then
|
||||||
|
print "PLAYER 2 IS THE WINNER"
|
||||||
|
break
|
||||||
|
else if population[2] == 0 then
|
||||||
|
print "PLAYER 1 IS THE WINNER"
|
||||||
|
break
|
||||||
|
end if
|
||||||
|
|
||||||
|
print; print "Player 1 (*)"
|
||||||
|
p1pos = getCoords
|
||||||
|
print; print "Player 2 (#)"
|
||||||
|
p2pos = getCoords
|
||||||
|
if p1pos == p2pos then
|
||||||
|
print "Same coord. Set to 0"
|
||||||
|
else
|
||||||
|
N[p1pos[0]][p1pos[1]] = 100
|
||||||
|
N[p2pos[0]][p2pos[1]] = 1000
|
||||||
|
end if
|
||||||
|
end while
|
||||||
@@ -26,7 +26,7 @@ A new cell will be generated at (3,3) which will be a `#` since there are two `#
|
|||||||
| 4 | | | | | |
|
| 4 | | | | | |
|
||||||
| 5 | | | | | |
|
| 5 | | | | | |
|
||||||
```
|
```
|
||||||
On the first most each player positions 3 pieces of life on the board by typing in the co-ordinates of the pieces. (In the event of the same cell being chosen by both players that cell is left empty.)
|
On the first move each player positions 3 pieces of life on the board by typing in the co-ordinates of the pieces. (In the event of the same cell being chosen by both players that cell is left empty.)
|
||||||
|
|
||||||
The board is then adjusted to the next generation and printed out.
|
The board is then adjusted to the next generation and printed out.
|
||||||
|
|
||||||
@@ -45,6 +45,7 @@ As published in Basic Computer Games (1978):
|
|||||||
Downloaded from Vintage Basic at
|
Downloaded from Vintage Basic at
|
||||||
http://www.vintage-basic.net/games.html
|
http://www.vintage-basic.net/games.html
|
||||||
|
|
||||||
|
|
||||||
#### Porting Notes
|
#### Porting Notes
|
||||||
|
|
||||||
(please note any difficulties or challenges in porting here)
|
(please note any difficulties or challenges in porting here)
|
||||||
|
|||||||
Reference in New Issue
Block a user