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 |