SHOW:
|
|
- or go back to the newest paste.
1 | --One Dimensional Cellular Automaton | |
2 | --Adapted from "dominic"'s Lua CA written to use LOVE. | |
3 | --Original version can be found here: http://blog.signalsondisplay.com/?p=60 | |
4 | --The only thing I borrowed from his version is the algorithm computer. | |
5 | ----------------------------------------------------------------------------- | |
6 | --Tangent Automaton V. 1.2.2 | |
7 | --Notes: | |
8 | --Added the ability to define a custom seed to start with. | |
9 | ||
10 | width = 64 --Set your desired width here! | |
11 | debug = false --Do you want debugging messages? | |
12 | random = false --Start with a randomly generated seed? | |
13 | seed = true --Start with a pre-defined seed? | |
14 | center = false --Start with one center cell? | |
15 | ||
16 | seeddata={} --Put your seed information here! | |
17 | ||
18 | height = width / 2 | |
19 | ||
20 | t=true | |
21 | f=false | |
22 | ||
23 | states = {} | |
24 | rulegiven={} | |
25 | mt={} | |
26 | for i = 1, width do states[i] = 0 end | |
27 | states[width / 2] = 1 | |
28 | output={} | |
29 | ||
30 | ruletable= --The rule lookup table. | |
31 | { | |
32 | {t,t,t}, | |
33 | {t,t,f}, | |
34 | {t,f,t}, | |
35 | {t,f,f}, | |
36 | {f,t,t}, | |
37 | {f,t,f}, | |
38 | {f,f,t}, | |
39 | {f,f,f} | |
40 | } | |
41 | ||
42 | function dectobin(input) | |
43 | conversion={1,2,4,8,16,32,64,128} --I'll make this into 2^n eventually. | |
44 | output={0,0,0,0,0,0,0,0} --The output table, keeping it like this for now. | |
45 | i=8 --Starting number to decrement from | |
46 | for h=1,8 do --It's 8 bit! | |
47 | input=input-conversion[i] --Grabs the number to convert, and subtracts it from the lookup table. | |
48 | if debug then print(input) end | |
49 | if input <0 then --If it's less than 0 (negative)... | |
50 | input=input+conversion[i] --...undo that subtraction. | |
51 | else --If it isn't less than 0 (greater than or equal to)... | |
52 | output[h]=1 --...set the output bit high (change "h" to "i" to swap endianess). | |
53 | end | |
54 | i=i-1 --The simple decrementer | |
55 | end | |
56 | end | |
57 | ||
58 | ruletable= --My second rule lookup table. I have no idea why I have two. | |
59 | { | |
60 | {true,true,true}, | |
61 | {true,true,false}, | |
62 | {true,false,true}, | |
63 | {true,false,false}, | |
64 | {false,true,true}, | |
65 | {false,true,false}, | |
66 | {false,false,true}, | |
67 | {false,false,false} | |
68 | } | |
69 | ||
70 | rule={} --Sets up the actual table the algorithm looks at. | |
71 | ||
72 | function grabrule() --This function decodes the given rule. | |
73 | userinput=io.read() --Gets the user's input. | |
74 | dectobin(userinput) --Sends the input to get decoded into binary. | |
75 | rulegiven=output --Takes that binary number and sticks it into "rulegiven". | |
76 | if debug then print(#rulegiven) end | |
77 | --print(string.len(userinput)) --I might re-implement this later. For now, You'll have to use the decimal system. | |
78 | --for i=1,string.len(userinput) do | |
79 | -- rulegiven[i]=string.sub(userinput,i,i) | |
80 | --end | |
81 | ||
82 | if #rulegiven~=8 then --Rather pointless warning since an 8-bit number is ALWAYS created... | |
83 | print("You must enter an 8-bit number!") | |
84 | end | |
85 | ||
86 | if debug then --more debugging | |
87 | for j=1,#rulegiven do | |
88 | io.write(rulegiven[j].." ") | |
89 | end | |
90 | io.write("\n") | |
91 | end | |
92 | ||
93 | for k=1,#rulegiven do --This will turn the binary into bollean logic. | |
94 | if rulegiven[k]==1 then --If the bit is 1... | |
95 | rulegiven[k]=true --...set it to true (rather pointless, since I could combine this with the next part of the program). | |
96 | else | |
97 | rulegiven[k]=false --This is rather pointless, since it's set to "false" by default. | |
98 | end | |
99 | end | |
100 | ||
101 | rulecounter=1 --A temporary number that helps with keeping the rule table from skipping ahead. | |
102 | ||
103 | for i=1,#rulegiven do --For as many rules as there are given... | |
104 | if rulegiven[i]then --...if the state of the rule is true... | |
105 | rule[rulecounter]=ruletable[i] --...look at the lookup table, and stick that value into "rule". | |
106 | rulecounter=rulecounter+1 --Decrements the counter for the "rule" table. | |
107 | end | |
108 | end | |
109 | end | |
110 | ||
111 | function grabseed() --This function asks for an input, and stores it to "state" | |
112 | seedgiven={} --I always store "binary" data in a table. | |
113 | print("Please enter a starting seed in binary!") | |
114 | print("Note: This seed will be placed in the center of the algorithm.") | |
115 | inputseed=io.read() --Asks for the seed. | |
116 | for i=1,string.len(inputseed) do --This loop chops the user input up, and stuffs it into my table. | |
117 | seedgiven[i]=string.sub(inputseed,i,i) | |
118 | end | |
119 | for i=1,#seedgiven do --Appearently, it's a string, and I need numbers. | |
120 | if seedgiven[i]=="1" then --If the string is a "1"... | |
121 | seedgiven[i]=1 --...make it into a number 1... | |
122 | else | |
123 | seedgiven[i]=0 --...else it's a 0. | |
124 | end | |
125 | end | |
126 | bitshift=((width-#seedgiven)/2) --To find how much the data should be shifted, the lenght of the given seed is subtracted from the width, then divided by 2. | |
127 | bitshift=math.floor(bitshift) --If it's an odd number, it gets rounded down. | |
128 | j=bitshift --To keep the two numbers synced. | |
129 | for i=1,#seedgiven do --This stores the given string into the "states" table. | |
130 | states[j]=seedgiven[i] | |
131 | j=j+1 --To keep j and i in sync. | |
132 | end | |
133 | ||
134 | end | |
135 | ||
136 | ||
137 | function compute_next_gen(index) --Here's where all the computation happens. | |
138 | --mt[1][(#states / 2)+1]="#" | |
139 | current_gen = {} --This table stores the current information to get computed. | |
140 | for i = 1, #states do --This just stores the data from the current bit into the p, c, and n registers. | |
141 | p = states[i - 1] == 1 | |
142 | c = states[i] == 1 | |
143 | n = states[i + 1] == 1 | |
144 | current_gen[i] = 0 --Once that's done, it sets the gen back to 0 to do the actual computation. | |
145 | for j = 1, #rule do --It computes for as many rules it is given. | |
146 | if (p == rule[j][1] and c == rule[j][2] and n == rule[j][3]) then --If it complies with the rules... | |
147 | current_gen[i] = 1 --...set the current cell to an "on" state. | |
148 | mt[index+1][i + 1]="#" --Stores it in my matrix. | |
149 | end | |
150 | end | |
151 | end | |
152 | states = current_gen | |
153 | end | |
154 | ||
155 | print("Please take a look at the top of this script to configure it!") | |
156 | ||
157 | if seed then | |
158 | grabseed() | |
159 | grabrule() | |
160 | elseif center then | |
161 | grabrule() | |
162 | elseif random then | |
163 | grabrule() | |
164 | end | |
165 | ||
166 | ||
167 | for i=1,height+1 do --This loop sets up my matrix with a spacing character. | |
168 | mt[i] = {} | |
169 | for j=1,width+1 do | |
170 | mt[i][j] = " " | |
171 | end | |
172 | end | |
173 | ||
174 | --for i=1,width do | |
175 | -- states[i]=math.random(0,1) | |
176 | --end | |
177 | ||
178 | for i=1,width do | |
179 | if states[i]==1 then | |
180 | mt[1][i+1]="#" | |
181 | else | |
182 | mt[1][i+1]=" " | |
183 | end | |
184 | end | |
185 | ||
186 | if debug then print("This automaton uses "..#rule.." rules.") end --Disregard this, it's for debugging. | |
187 | if debug then | |
188 | for a=1,#rule do | |
189 | for b=1,3 do | |
190 | if rule[a][b] then | |
191 | io.write("true") | |
192 | else | |
193 | io.write("false") | |
194 | end | |
195 | end | |
196 | io.write("\n") | |
197 | end | |
198 | end | |
199 | ||
200 | for i = 1, height do --This runs the computation function for the desired height. | |
201 | compute_next_gen(i) | |
202 | end | |
203 | ||
204 | for a=1,height do --This loop actually prints out my matrix, displaying the pretty pattern! | |
205 | for b=1,width do | |
206 | io.write(mt[a][b]) | |
207 | end | |
208 | io.write("\n") | |
209 | end |