Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --Define variables
- local colourList = {}
- local coloursUsed = {}
- local coloursUnused = {}
- local dir = 1
- local x = 1
- local y = 1
- local w = 1
- local h = 1
- local grid = {}
- local sequential = true
- local step = 1
- --Miscellaneous helper functions to simplify code later
- --Generate either -1 or 1
- local function randomSign()
- local k = math.random(2)
- return (k * 2 - 3)
- end
- --Turn integers from 1 to 16 into their colour vaues without needing to perform exponents.
- local function colourSwitch(c)
- if c == 1 then return 1
- elseif c == 2 then return 2
- elseif c == 3 then return 4
- elseif c == 4 then return 8
- elseif c == 5 then return 16
- elseif c == 6 then return 32
- elseif c == 7 then return 64
- elseif c == 8 then return 128
- elseif c == 9 then return 256
- elseif c == 10 then return 512
- elseif c == 11 then return 1024
- elseif c == 12 then return 2048
- elseif c == 13 then return 4096
- elseif c == 14 then return 8192
- elseif c == 15 then return 16384
- elseif c == 16 then return 32768
- end
- end
- --Helper functions for creating a ruleset.
- local function initColourLists()
- for i=1,16 do colourList[i] = {} end
- coloursUsed = {16}
- coloursUnused = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}
- end
- local function chooseColours()
- local n = math.random(15)
- local choicesLeft = table.getn(coloursUnused)
- local choice = 1
- --Choose colours randomly from the list of unchosen colours
- for i=1,n do
- choice = math.random(choicesLeft)
- coloursUsed[i+1] = table.remove(coloursUnused, choice)
- choicesLeft = choicesLeft - 1
- end
- --Set up colourList linkage
- for i=1,n do
- colourList[coloursUsed[i]][2] = coloursUsed[i+1]
- end
- colourList[coloursUsed[n]][2] = coloursUsed[1]
- end
- local function chooseDirections()
- local n = table.getn(coloursUsed)
- local total = 0
- local s = 0
- --Randomise the direction for all colours used.
- for i, c in ipairs(coloursUsed) do
- s = randomSign()
- colourList[c][1] = s
- total = total + s
- end
- --If all colours turn in the same direction, switch the direction of one used colour.
- if math.abs(total) == n then
- colourList[coloursUsed[1]][1] = - colourList[coloursUsed[1]][1]
- end
- end
- --Function to create the play-space and position the ant/
- local function initGrid()
- for i=1,w do
- grid[i] = {}
- for j=1,h do
- grid[i][j] = 16
- end
- end
- x = math.ceil(w/2)
- y = math.ceil(h/2)
- dir = math.random(4)
- end
- --Step function for ant movement. Returns true until the ant leaves the grid.
- local function move()
- --Move the ant
- if dir == 1 then x = x + 1
- elseif dir == 2 then y = y + 1
- elseif dir == 3 then x = x - 1
- elseif dir == 4 then y = y - 1
- end
- --If out of bounds, return false to end the program
- if x<1 or x>w or y<1 or y>h then
- return false
- end
- --Change colour of new position and direction
- local c = grid[x][y]
- grid[x][y] = colourList[c][2]
- dir = dir + colourList[c][1]
- --Correct directions outside of possible values
- if dir == 0 then dir = 4
- elseif dir == 5 then dir = 1
- end
- return true
- end
- --Function to generate a ruleset and play it out.
- function play(monitorSide, sequential, step)
- local m = peripheral.wrap(monitorSide)
- if not m.isColor() then error("Advanced monitor required.") end
- m.setTextScale(0.5)
- w, h = m.getSize()
- if sequential ~= false then sequential = true end
- step = tonumber(step) or 1
- --randomise background colour
- --standard can be set by replacing math.random(16) with an integer from 1 to 16
- m.setBackgroundColour(colourSwitch(math.random(16)))
- m.clear()
- --initialize variables and choose generator ruleset
- initColourLists()
- initGrid()
- chooseColours()
- chooseDirections()
- local i = 0
- --play out the ruleset
- while move() do
- m.setCursorPos(x, y)
- m.setBackgroundColour(colourSwitch(grid[x][y]))
- m.write(" ")
- i = i + 1
- --leave breaks so that the program yields and to allow stopping by right-click
- if sequential and i == step then
- i = 0
- os.startTimer(0.1)
- local e = os.pullEvent()
- if e == 'monitor_touch' then return true end
- end
- end
- end
- --The part of the program that runs it if not used as an API
- local tArgs = {...}
- local side = tArgs[1] or "top"
- if tArgs[2] == 'false' then sequential = false end
- if tArgs[3] ~= nil then step = tonumber(tArgs[3]) end
- while true do
- play(side, sequential, step)
- os.pullEvent('monitor_touch')
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement