This is my first post, so hopefully everything goes off without a hitch.
These are two screensaver programs I wrote over the last day or so as computercraft tests. Presently there is no way to exit them other than ctrl+t, but for a screensaver that should be a relatively minor issue :)/>
But enough talk, on to the content
Game of Life
Spoiler
After watching https://www.youtube....h?v=m5DUoCiq6Ag I was inspired to write my own simulator for Conway's Game of LifeCode is under CC BY-SA 3.0
http://pastebin.com/YxKq7hqz
Spoiler
--(c) 2013 Felix Maxwell
--License: CC BY-SA 3.0
local fps = 8 --Determines how long the program will wait between each tick
local char = "#" --Live cells will look like this
function getMonitors()
local monitors = {}
if checkMonitorSide( "top" ) then table.insert( monitors, "top" ) end
if checkMonitorSide( "bottom" ) then table.insert( monitors, "bottom" ) end
if checkMonitorSide( "left" ) then table.insert( monitors, "left" ) end
if checkMonitorSide( "right" ) then table.insert( monitors, "right" ) end
if checkMonitorSide( "front" ) then table.insert( monitors, "front" ) end
if checkMonitorSide( "back" ) then table.insert( monitors, "back" ) end
return monitors
end
function checkMonitorSide( side )
if peripheral.isPresent( side ) then
if peripheral.getType(side) == "monitor" then
return true
end
end
return false
end
function printMonitorStats( side )
local x, y = peripheral.call(side, "getSize")
local color = "No"
if peripheral.call(side, "isColor") then
color = "Yes"
end
print("Side:"..side.." Size:("..x..", "..y..") Color?"..color)
end
function askMonitor()
local monitors = getMonitors()
if #monitors == 0 then
print("No monitors found, add more!")
return nill
elseif #monitors == 1 then
return monitors[1]
else
while true do
print("Multiple monitors found, please pick one.")
for i,v in ipairs(monitors) do
write("["..(i).."] ")
printMonitorStats( v )
end
write("Selection: ")
local sel = tonumber(io.read())
if sel < 1 or sel > #monitors then
print("")
print("Invalid number.")
else
return monitors[sel]
end
end
end
end
function printCharAt( monitor, x, y, char )
monitor.setCursorPos( x, y )
monitor.write( char )
end
function printGrid( monitor, grid )
monitor.clear()
for i=1,#grid do
for o=1,#grid[i] do
printCharAt( monitor, i, o, grid[i][o] )
end
end
end
function getNumNeighborhood( grid, x, y )
local neighbors = 0
if x > 1 then
if y > 1 then
if grid[x-1][y-1] == char then neighbors = neighbors + 1 end
end
if grid[x-1][y] == char then neighbors = neighbors + 1 end
if y < #grid[x] then
if grid[x-1][y+1] == char then neighbors = neighbors + 1 end
end
end
if y > 1 then
if grid[x][y-1] == char then neighbors = neighbors + 1 end
end
if y < #grid[x] then
if grid[x][y+1] == char then neighbors = neighbors + 1 end
end
if x < #grid then
if y > 1 then
if grid[x+1][y-1] == char then neighbors = neighbors + 1 end
end
if grid[x+1][y] == char then neighbors = neighbors + 1 end
if y < #grid then
if grid[x+1][y+1] == char then neighbors = neighbors + 1 end
end
end
return neighbors
end
function lifeOrDeath( cur, neighbors )
if neighbors < 2 then
return " "
elseif neighbors > 3 then
return " "
elseif neighbors == 3 then
return char
else
return cur
end
end
function tick( grid )
local retGrid = {}
for x=1,#grid do
retGrid[x] = {}
for y=1,#grid[x] do
local num = getNumNeighborhood( grid, x, y )
retGrid[x][y] = lifeOrDeath( grid[x][y], num )
end
end
return retGrid
end
function setup( w, h )
local grid = {}
for i=1,w do
grid[i] = {}
for o=1,h do
if math.random(1, 5) == 1 then
grid[i][o] = char
else
grid[i][o] = " "
end
end
end
return grid
end
function run()
local monitor = peripheral.wrap( askMonitor() )
if monitor.isColor() then
monitor.setTextColor(colors.lime)
monitor.setBackgroundColor(colors.black)
end
local w, h = monitor.getSize()
local grid = setup( w, h )
while true do
printGrid( monitor, grid )
grid = tick( grid )
os.sleep(1/fps)
end
end
run()
--This one looks kind of cool
-- ###
--# #
--# #
--# #
--
-- ###
Spoiler
After writing the Game of Life, I was inspired by Numerical's screensaver in the video listed in that spoiler, so I decided to see what I could do.I am rather pleased with the end result.
As always, code is under CC BY-SA 3.0
http://pastebin.com/KQjmtASU
Spoiler
--(c) 2013 Felix Maxwell
--License: CC BY-SA 3.0
local fps = 8 --Determines how long the system will wait between each update
local maxLifetime = 40 --Max lifetime of each char
local minLifetime = 8 --Min lifetime of each char
local maxSourcesPerTick = 5 --Maximum number of sources created each tick
local sourceWeight = 0 --Affects the chance that no sources will be generated
local greenWeight = 8 --Threshhold out of 10 that determines when characters will switch from lime to green
local grayWeight = 2 --Same as about, but from green to gray
function getMonitors()
local monitors = {}
if checkMonitorSide( "top" ) then table.insert( monitors, "top" ) end
if checkMonitorSide( "bottom" ) then table.insert( monitors, "bottom" ) end
if checkMonitorSide( "left" ) then table.insert( monitors, "left" ) end
if checkMonitorSide( "right" ) then table.insert( monitors, "right" ) end
if checkMonitorSide( "front" ) then table.insert( monitors, "front" ) end
if checkMonitorSide( "back" ) then table.insert( monitors, "back" ) end
return monitors
end
function checkMonitorSide( side )
if peripheral.isPresent( side ) then
if peripheral.getType(side) == "monitor" then
return true
end
end
return false
end
function printMonitorStats( side )
local x, y = peripheral.call(side, "getSize")
local color = "No"
if peripheral.call(side, "isColor") then
color = "Yes"
end
print("Side:"..side.." Size:("..x..", "..y..") Color?"..color)
end
function askMonitor()
local monitors = getMonitors()
if #monitors == 0 then
print("No monitors found, add more!")
return nill
elseif #monitors == 1 then
return monitors[1]
else
while true do
print("Multiple monitors found, please pick one.")
for i,v in ipairs(monitors) do
write("["..(i).."] ")
printMonitorStats( v )
end
write("Selection: ")
local sel = tonumber(io.read())
if sel < 1 or sel > #monitors then
print("")
print("Invalid number.")
else
return monitors[sel]
end
end
end
end
function printCharAt( monitor, x, y, char )
monitor.setCursorPos( x, y )
monitor.write( char )
end
function printGrid( monitor, grid, color )
for i=1,#grid do
for o=1,#grid[i] do
if color then monitor.setTextColor( grid[i][o]["color"] ) end
printCharAt( monitor, i, o, grid[i][o]["char"] )
end
end
end
function colorLifetime( life, originalLifetime )
local lifetimePart = originalLifetime/10
if life < grayWeight*lifetimePart then
return colors.gray
elseif life < greenWeight*lifetimePart then
return colors.green
else
return colors.lime
end
end
function getRandomChar()
local randTable = {"1","2","3","4","5","6","7","8","9","0","!","@","#","$","%","^","&","*","(",")","_","-","+","=","~","`",",","<",">",".","/","?",":","{","}","[","]","\\","\"","\'"}
return randTable[math.random(1, #randTable)]
end
function tick( screen )
--update lifetimes
for x=1,#screen do
for y=1,#screen[x] do
screen[x][y]["curLife"] = screen[x][y]["curLife"] - 1
end
end
--make the sources 'fall' and delete timed out chars
for x=1,#screen do
for y=1,#screen[x] do
if screen[x][y]["type"] == "source" and screen[x][y]["curLife"] == 0 then
screen[x][y]["type"] = "char"
screen[x][y]["lifetime"] = math.random(minLifetime, maxLifetime)
screen[x][y]["curLife"] = screen[x][y]["lifetime"]
screen[x][y]["color"] = colors.lime
if y < #screen[x] then
screen[x][y+1]["char"] = getRandomChar()
screen[x][y+1]["lifetime"] = 1
screen[x][y+1]["curLife"] = 1
screen[x][y+1]["type"] = "source"
screen[x][y+1]["color"] = colors.white
end
elseif screen[x][y]["curLife"] < 0 then
screen[x][y]["char"] = " "
screen[x][y]["lifetime"] = 0
screen[x][y]["curLife"] = 0
screen[x][y]["type"] = "blank"
screen[x][y]["color"] = colors.black
elseif screen[x][y]["type"] == "char" then
screen[x][y]["color"] = colorLifetime( screen[x][y]["curLife"], screen[x][y]["lifetime"] )
end
end
end
--create new character sources
local newSources = math.random( 0-sourceWeight, maxSourcesPerTick )
for i=1,newSources do
local col = math.random(1, #screen)
screen[col][1]["char"] = getRandomChar()
screen[col][1]["lifetime"] = 1
screen[col][1]["curLife"] = 1
screen[col][1]["type"] = "source"
screen[col][1]["color"] = colors.white
end
return screen
end
function setup( w, h )
local retTab = {}
for x=1,w do
retTab[x] = {}
for y=1,h do
retTab[x][y] = {}
retTab[x][y]["char"] = " "
retTab[x][y]["lifetime"] = 0
retTab[x][y]["curLife"] = 0
retTab[x][y]["type"] = "blank"
retTab[x][y]["color"] = colors.black
end
end
return retTab
end
function run()
local monitor = peripheral.wrap( askMonitor() )
local color = monitor.isColor()
local w, h = monitor.getSize()
local screen = setup( w, h )
while true do
screen = tick( screen )
printGrid( monitor, screen, color )
os.sleep(1/fps)
end
end
run()