From 7753f6bf132c9b855cc7be17824e47ebef1f1e0c Mon Sep 17 00:00:00 2001 From: JoeStrout Date: Sun, 10 Sep 2023 15:33:30 -0700 Subject: [PATCH] Added MiniScript versions of 55_Life and 56_Life_for_Two. --- .../55_Life/MiniScript/README.md | 19 +++ .../55_Life/MiniScript/life.ms | 132 ++++++++++++++++++ .../56_Life_for_Two/MiniScript/README.md | 19 +++ .../56_Life_for_Two/MiniScript/lifefortwo.ms | 129 +++++++++++++++++ 56_Life_for_Two/README.md | 3 +- 5 files changed, 301 insertions(+), 1 deletion(-) create mode 100644 00_Alternate_Languages/55_Life/MiniScript/README.md create mode 100644 00_Alternate_Languages/55_Life/MiniScript/life.ms create mode 100644 00_Alternate_Languages/56_Life_for_Two/MiniScript/README.md create mode 100644 00_Alternate_Languages/56_Life_for_Two/MiniScript/lifefortwo.ms diff --git a/00_Alternate_Languages/55_Life/MiniScript/README.md b/00_Alternate_Languages/55_Life/MiniScript/README.md new file mode 100644 index 00000000..4cfd557b --- /dev/null +++ b/00_Alternate_Languages/55_Life/MiniScript/README.md @@ -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 +``` diff --git a/00_Alternate_Languages/55_Life/MiniScript/life.ms b/00_Alternate_Languages/55_Life/MiniScript/life.ms new file mode 100644 index 00000000..69f3bafc --- /dev/null +++ b/00_Alternate_Languages/55_Life/MiniScript/life.ms @@ -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 diff --git a/00_Alternate_Languages/56_Life_for_Two/MiniScript/README.md b/00_Alternate_Languages/56_Life_for_Two/MiniScript/README.md new file mode 100644 index 00000000..93b25b99 --- /dev/null +++ b/00_Alternate_Languages/56_Life_for_Two/MiniScript/README.md @@ -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 +``` diff --git a/00_Alternate_Languages/56_Life_for_Two/MiniScript/lifefortwo.ms b/00_Alternate_Languages/56_Life_for_Two/MiniScript/lifefortwo.ms new file mode 100644 index 00000000..49ac531e --- /dev/null +++ b/00_Alternate_Languages/56_Life_for_Two/MiniScript/lifefortwo.ms @@ -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 \ No newline at end of file diff --git a/56_Life_for_Two/README.md b/56_Life_for_Two/README.md index e68c8d64..5ce081d3 100644 --- a/56_Life_for_Two/README.md +++ b/56_Life_for_Two/README.md @@ -26,7 +26,7 @@ A new cell will be generated at (3,3) which will be a `#` since there are two `# | 4 | | | | | | | 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. @@ -45,6 +45,7 @@ As published in Basic Computer Games (1978): Downloaded from Vintage Basic at http://www.vintage-basic.net/games.html + #### Porting Notes (please note any difficulties or challenges in porting here)