Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --programm Evolution. Author Taoshi (Zardar)
- local evo={}
- local fast, skipFrames, skip = false, 5, 0
- local computer, component = require('computer'), require('component')
- local unicode = require('unicode')
- local gpu, term = require('component').gpu, require('term')
- local text,show = '',''
- local x_dim, y_dim = gpu.getResolution()
- local xs, ys = x_dim*2-8, y_dim*4-16 --размер в символах брайля
- local iter, dots, changes, neighbors, left, right = 0, 0, 0, 0,'left','right'
- local pullSignal = computer.pullSignal
- local field, snap, screen, actualFieldChanges = {},{},{},{}
- local chars, actions,presets = {},{},{}
- local mode, restart = 'edit', false--текущее состояние программы
- local time = computer.uptime()
- local t, timePlayed, preX, preY = time, 0
- local fg, fgl = gpu.getForeground(),20
- local events = {touch='touch',drag='touch',drop='touch',key_up='keyUp'}
- local buttons = {'(C)lear (E)dit (P)lay (R)estart (T)erminate',
- '(S)top (P)lay (C)lear (T)erminate ЛКМ - рисовать, ПКМ - стереть',
- '(S)top (R)estart (E)dit (T)erminate'
- }--SPECTR
- local ru_keys={[11]='s',[1]='c',[3]='e',[23]='p',[26]='r',[21]='t'}
- local char = {} for f = 0, 255 do char[f] = unicode.char(10240+f) end
- local bits = {}
- bits[1]={1,8,2,16,4,32,64,128} bits[0]={-1,-8,-2,-16,-4,-32,-64,-128}
- --добавим символы для линий и углов
- local vert1, vert2, line = char[184], char[71], char[54]
- local tl, tr = char[176]..char[118], char[182]..char[70]
- local bl, br = char[56]..char[55], char[62]..char[7]
- local cll, line = string.rep(' ',x_dim-2), string.rep(line,x_dim-4)
- local topLine, bottomLine = tl..line..tr, bl..line..br
- vert1, vert2 = string.rep(vert1,y_dim-4), string.rep(vert2,y_dim-4)
- screen.left,screen.right, l, r = {},{}, 'left', 'right'
- component.screen.setPrecise(true)
- ------------------------------ ------------------------------------
- function computer.pullSignal(...)
- local e = {pullSignal(...)}
- if events[e[1]] then
- return actions[events[e[1]]](e)
- end
- return true --table.unpack(e)
- end
- actions.s=function()--select
- if mode == 'edit' then evo.saveChanges() end
- mode = 'select' return evo.select() --true
- end
- actions.p=function()--play
- if mode == 'play' then return true end
- return evo.play()
- end
- actions.e=function(e)--edit
- if mode ~= 'edit' then return evo.gotoEdit() end --true
- return true
- end
- actions.c=function()--clear
- --if mode == 'play' then return true end
- mode = 'select' term.clear() evo.border() evo.tablesInit()
- return evo.select()
- end
- actions.t=function()--terminate
- mode ='terminate' return evo.terminate() --true
- end
- actions.r=function()--restart
- if mode ~= 'select' and mode ~= 'play' then return true end
- if restart then mode = 'restart' end
- return evo.restart() --true
- end
- actions.touch=function(e)
- if mode ~= 'edit' then
- return true
- end
- return evo.edit(e)
- end
- actions.keyUp=function(e)
- local key=math.floor(e[3])
- if key > 127 then
- key = ru_keys[bit32.band(31,key)]
- else
- key=string.lower(string.char(key))
- end
- if actions[key] then
- return actions[key](e)
- end
- return true
- end
- ------------------------------------------------------
- function evo.select()
- --вывод clear, edit, play
- if mode == 'play' then mode = 'pause'
- else mode = 'select' end
- gpu.set(3,y_dim-1,cll) gpu.setForeground(0xf000f0)
- gpu.set(3,y_dim-1,buttons[1])
- return true
- end
- function evo.play()
- gpu.setForeground(fg) gpu.set(3,y_dim-1,cll)
- gpu.set(3,y_dim-1,buttons[3])
- if mode == 'pause' then return evo.main() end
- mode='play' evo.saveChanges()
- evo.toUnicode() evo.showMustGoOne()
- return evo.main()
- end
- function evo.userDraw(x,y,m)
- local charOnScreen= gpu.get(math.floor(x),math.floor(y))
- local byte,byte2,byte3
- if #charOnScreen<3 then byte = 0
- else
- byte2=string.byte(charOnScreen,2) byte3=string.byte(charOnScreen,3)
- byte=bit32.lshift(bit32.band(byte2,3),6)+bit32.band(byte3,63)
- end
- field[math.floor((y-2)*4+1)][math.floor((x-3)*2)+1] = bit32.bxor(1,m)
- local w = math.floor((x-math.floor(x))*2)
- local h = math.floor((y-math.floor(y))*4)
- local pixel= bits[1][1+(w+h*2)]
- if m == 0 then byte = bit32.bor(byte,pixel)
- else pixel = bit32.bxor(pixel,255) byte = bit32.band(byte,pixel) end
- gpu.set(x,y,char[byte])
- return true
- end
- function evo.edit(e)
- local x, y, m = 4*((e[3])+1), 8*((e[4])+1), e[5]
- if y/2>=ys+4 or x/2>=xs+2 or y/8<2 or x/4<3 then return os.sleep(0.001) end
- if m ~= 'drag' then
- if (preX < 0 or (math.abs(x-preX) < 2 and math.abs(y-preY) < 2))
- then evo.userDraw(x/4,y/8,m) preX = x preY = y
- os.sleep(0.001) return true
- end
- end
- if x-preX > 0 then addX = 1 else addX = -1 end
- if y-preY > 0 then addY = 1 else addY = -1 end
- if math.abs(x-preX)>math.abs(y-preY) then
- addY = addY * math.abs(y-preY)/math.abs(x-preX)
- else addX = addX * math.abs(x-preX)/math.abs(y-preY) end
- xpos = preX + addX ypos = preY + addY
- xdist=0 ydist=0
- while ydist <= math.abs(y-preY) and xdist <= math.abs(x-preX) do
- evo.userDraw(xpos/4,ypos/8,m)
- ydist, xdist = ydist + math.abs(addY), xdist + math.abs(addX)
- ypos, xpos = ypos + addY, xpos + addX
- end
- preX, preY = x, y os.sleep(0.001)
- return true
- end
- function evo.clear()
- term.clear() evo.border() evo.tablesInit()
- return evo.select()
- end
- function evo.terminate()
- term.clear()
- computer.pullSignal = pullSignal
- evo = nil return true
- end
- function evo.restart()
- iter = 0 evo.tablesInit()
- for y in pairs (snap) do
- for x in pairs (snap[y]) do
- field[y][x] = snap[y][x]
- end
- end
- return evo.play()
- end
- -------------------------------------------------------
- function evo.border()
- local fg = gpu.getForeground()
- gpu.setForeground(0x20A020)
- gpu.set(1,1,topLine)
- gpu.set(1,y_dim-2,bottomLine)
- gpu.set(1,2,vert1,true)
- gpu.set(2,2,vert2,true)
- gpu.set(x_dim-1,2,vert1,true)
- gpu.set(x_dim,2,vert2,true)
- gpu.setForeground(fg)
- return true
- end
- function evo.clr_snap()
- for y = 1, ys do snap[y] = {} end
- return true
- end
- function evo.tablesInit()
- for y = 1,ys do
- field[y] = {} actualFieldChanges[y] = {}
- screen[l][y] = {}
- for x=1, xs do field[y][x] = 0 end
- end
- local ch_y, ch_x= math.floor(ys/4), math.floor(xs/2)
- for y = 1,ch_y do chars[y]={}
- for x = 1,ch_x do chars[y][x] = 0 end
- end
- return true
- end
- function evo.preset()
- p={}
- p[1]={{0,0},{1,0},{2,0},{1,1},{2,-1}}
- p[2]={{0,0},{0,1},{0,2},{0,3},{0,4},{0,5},
- {1,0},{1,2},{1,3},{1,5},{2,0},{2,1},{2,2},{2,3},
- {2,5},{3,2},{3,3},{3,5},{4,2},{4,3},{4,5},
- {5,2},{5,3},{5,4},{5,5}}
- p[3]={{-1,-2},{0,0},{1,-3},{1,-2},{1,1},{1,2},{1,3}}
- n=3
- for f = 1, #p[n] do
- field[math.ceil(ys/2+p[n][f][1])]
- [math.ceil(xs/2+p[n][f][2])] = 1
- end
- return true
- end
- function evo.saveChanges()
- dots = 0 changes = 0
- local ch_y, ch_x= math.floor(ys/4), math.floor(xs/2)
- for y = 1,ch_y do chars[y]={}
- for x = 1,ch_x do chars[y][x] = 0 end
- end
- for y = 1, ys do
- actualFieldChanges[y] = {}
- snap[y] = {}
- end
- for y in pairs(field) do
- local yl,yr = evo.getAdjoining(y,ys)
- for x in pairs(field[y])do
- if field[y][x] == 1 then
- snap[y][x] = 1
- actualFieldChanges[y][x] = 1
- dots = dots + 1 changes = changes + 1
- local xl,xr = evo.getAdjoining(x,xs)
- evo.setScreen(yl,y,yr,xl,x,xr,l)
- end
- end
- end
- restart = true
- return true
- end
- function evo.gotoEdit()
- evo.clr_snap() iter = 0 gpu.set(3,y_dim,cll)
- gpu.set(3,y_dim-1,cll) gpu.setForeground(0x40f040)
- gpu.set(3,y_dim-1,buttons[2]) gpu.setForeground(0xff00ff)
- mode = 'edit' preX= -1 preY=-1
- return true
- end
- function evo.fail()
- text='Игра окончена'
- gpu.set(3,y_dim,cll)
- gpu.setForeground(0xf02080)
- gpu.set(20,y_dim,text)
- return evo.select()
- end
- --вычисление координат прилегающих клеток
- function evo.getAdjoining(n,ns)
- local yl, yr = 1,1
- if n > 1 and n < ns then
- yl = n-1
- yr = n+1
- else
- if n == 1 then
- yl, yr = ns, n+1
- else
- yl,yr = n-1, 1
- end
- end
- return yl,yr
- end
- --обозначим узел и соседей узла сменившего состояние
- function evo.setScreen(yl,y,yr,xl,x,xr,s)
- screen[s][yl][x] = '*'
- screen[s][y][x] = '*'
- screen[s][yr][x] = '*'
- screen[s][yl][xl] = '*'
- screen[s][y][xl] = '*'
- screen[s][yr][xl] = '*'
- screen[s][yl][xr] = '*'
- screen[s][y][xr] = '*'
- screen[s][yr][xr] = '*'
- return true
- end
- --поиск узлов которые сменят состояние
- function evo.whatNews()
- changes = 0
- for y=1,ys do
- screen[r][y] ={}
- actualFieldChanges[y] = {}
- end
- --получаем из левого экрана сведения о узлах
- --реалии которых нам интересны
- for y in pairs (screen[l]) do
- local yl,yr=evo.getAdjoining(y,ys)
- for x in pairs(screen[l][y]) do
- local xl,xr=evo.getAdjoining(x,xs)
- neighbors =
- field[y][xl] + field[y][xr] +
- field[yl][xl] + field[yl][x] + field[yl][xr] +
- field[yr][xl] + field[yr][x] + field[yr][xr]
- if neighbors == 3 then
- if field[y][x] == 0 then
- evo.setScreen(yl,y,yr,xl,x,xr,r)
- --узел ожил
- dots = dots+1
- changes=changes+1
- actualFieldChanges[y][x] = 1
- end
- else
- if neighbors ~= 2 then
- if field[y][x] == 1 then
- evo.setScreen(yl,y,yr,xl,x,xr,r)
- --узел погиб
- dots = dots-1
- changes = changes+1
- actualFieldChanges[y][x] = 0
- end
- end
- end
- end
- end
- --вычисления следующего состояния колонии завершены
- --произведём имплементацию изменений
- --function implement dots
- for y in pairs(actualFieldChanges) do
- for x in pairs(actualFieldChanges[y]) do
- field[y][x] = actualFieldChanges[y][x]
- end
- end
- if changes == 0 then return evo.fail()
- else return true
- end
- end
- --попробуем описать трансформацию значений массива в шрифт брайля
- function evo.toUnicode()
- local ch_x,ch_y,yy,xx=0,0,0,0
- for y in pairs(actualFieldChanges) do
- ch_y=y+3 yy=y-1
- ch_y=math.floor(ch_y/4)
- for x in pairs(actualFieldChanges[y]) do
- ch_x=x+1 xx=x-1
- ch_x=math.floor(ch_x/2)
- chars[ch_y][ch_x]=chars[ch_y][ch_x]
- +bits[actualFieldChanges[y][x]][1+(yy%4)*2+xx%2]
- end
- end
- return true
- end
- --теперь выведем на экран символы брайля
- function evo.showMustGoOne()
- if fast == true and skip > 0 then skip = skip - 1 return true
- else skip = skipFrames end
- local line, show, z
- for y in pairs(chars)do
- line, show, z = '', '', 0
- for x in pairs(chars[y]) do
- if chars[y][x] > 255 or chars[y][x]<0 then
- gpu.set(y_dim,40,tostring(chars[y][x])..' ')
- end
- show = show..char[chars[y][x]]
- z = z + 1
- if z > 15 then z = 0 line = line .. show show = '' end
- end
- line = line .. show gpu.set(3,y+1,line)
- end
- return true
- end
- function evo.iteration()gpu.set(x_dim-20,y_dim,('iteration:' .. tostring(iter)))
- text = 'поколение:'..tostring(iter)..' узлы:'..tostring(dots)..' '
- gpu.set(3,y_dim,text) iter = iter + 1
- l,r = r,l
- if skip == skipFrames then os.sleep(0.001) end
- return true
- end
- function evo.main()
- while mode=='play' do
- evo.whatNews()
- evo.toUnicode()
- evo.showMustGoOne()
- evo.iteration()
- end
- return true
- end
- -----------------------------------------------------
- evo.border() evo.clr_snap() evo.tablesInit()
- evo.preset() evo.play()
- while mode ~= 'terminate' do os.sleep(0.11) end
- gpu.setForeground(fg) return true
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement