% КА: однопоточная версия functor import Application(exit) QTk at 'x-oz://system/wp/QTk.ozf' Browser(browse:Browse) Panel define % Переменные: FieldSize = 40 Data1 = {Array.new 0 FieldSize*FieldSize-1 false} Data2 = {Array.new 0 FieldSize*FieldSize-1 false} ArrSel = {NewCell true} WgText WgN % ГИП (Графический Интерфейс Пользователя): proc {ExitProg} {Application.exit 0} end Window = {QTk.build td( text(tdscrollbar:false lrscrollbar:false handle:WgText font:'Courier 8 bold' width:40 height:40 bg:'white' foreground:'DarkBlue') numberentry(min:1 max:1000 init:1 handle:WgN) button(text:'Next' glue:we action:NextCadrs) button(text:'Init' glue:we action:InitProg) button(text:'Exit' glue:we action:ExitProg) action:proc{$} {Application.exit 0} end )} {Window show} {Window set(title:"Life")} % Функции и процедуры: proc {DrawField} local S in S = {NewCell ""} {WgText delete('1.0' 'end')} for X in 0..FieldSize-1 do for Y in 0..FieldSize-1 do if {Get X Y} == true then S := @S#"O" else S := @S#" " end end S := @S#"\n" end {WgText insert('end' @S)} end end fun {Get X Y} if {Or {Or X<0 X>=FieldSize} {Or Y<0 Y>=FieldSize}} then false elseif @ArrSel then {Array.get Data1 X+Y*FieldSize} else {Array.get Data2 X+Y*FieldSize} end end proc {Clear} for X in 0..FieldSize-1 do for Y in 0..FieldSize-1 do {Set X Y false} end end end proc {Set X Y V} if {Or {Or X<0 X>=FieldSize} {Or Y<0 Y>=FieldSize}} then skip elseif {Not @ArrSel} then {Array.put Data1 X+Y*FieldSize V} else {Array.put Data2 X+Y*FieldSize V} end end proc {Sw} ArrSel := {Not @ArrSel} end proc {NextCadrs} local T1 T2 T3 N in N = {WgN get($)} {Time.time T1} for I in 1..N do {NextCadr} end {Time.time T2} T3 = T2 - T1 {Browse 'N: '#N#' total: '#T3#' one: '#{Int.toFloat T3}/{Int.toFloat N}} {DrawField} end end proc {NextCadr} % Расчет - собственно алгоритм {Clear} for X in 0..FieldSize-1 do for Y in 0..FieldSize-1 do local C in C = {NewCell 0} for DX in X-1..X+1 do for DY in Y-1..Y+1 do if {And {Not {And DX== X DY == Y}} {Get DX DY}} then C := @C + 1 end end end if {Get X Y} then if {And @C >= 2 @C =< 3} then {Set X Y true} end else if @C == 3 then {Set X Y true} end end end end end {Sw} end proc {InitProg} {Clear} {Sw} {Clear} ArrSel := true for I in 0..8 do {Array.put Data1 497+I true} end for I in 0..4 do {Array.put Data1 507+I true} end {DrawField} end % Программа: {InitProg} {Panel.object open} end