-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path1dsim.js
More file actions
167 lines (112 loc) · 2.99 KB
/
1dsim.js
File metadata and controls
167 lines (112 loc) · 2.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
var _ = require('underscore');
function seed (n, rand) {
// bytes size
var size = Math.ceil(n / 8);
// generation buffer (only use n bits)
var buf = new ArrayBuffer(size);
// generation buffer view
var vw = new DataView(buf);
// center w/ respect to n (is this necessary?)
if (!rand) {
// center bit index
var i = Math.floor((n - 1) / 2);
// index relative to its byte
var r = i % 8;
// center byte offset
var o = Math.floor(i / 8);
// if even then double seed else single
var s = (n % 2 === 0) ? 192 : 128;
// shift in the seed
vw.setUint8(o, s >>> r);
// use random seed(s)
} else {
// for each byte
for (var o = 0; o < size; o++) {
// set random 8-bits
vw.setUint8(o, _.random(0, 255));
}
}
return buf;
}
function next_gen (sbuf, n, r) {
// bytes size
var size = Math.ceil(n / 8);
// next generation buffer
var buf = new ArrayBuffer(size);
// next generation buffer view
var vw = new DataView(buf);
// seed buffer view
var svw = new DataView(sbuf);
// next generation byte buffer
var byte_buf = 0;
// TODO stream generation to stdout here
for (var sbi = 0; sbi < n; sbi++) {
// relative "self bit" index
var rsbi = sbi % 8;
// byte offset
var sbo = Math.floor(sbi / 8);
var lbo = sbo; // case: left bit is in this byte
var rbo = sbo; // case: right bit is in this byte
// bit index
var lbi = sbi - 1;
var rbi = sbi + 1;
// case: left bit is in very last byte (at some index)
if (sbi === 0) {
lbo = size - 1;
lbi = n - 1;
}
// case: left bit is in previous byte (as lsb index 7)
else if (rsbi === 0) {
lbo = sbo - 1;
lbi = 7;
}
// case: right bit is in very first byte (at 0 index)
if (sbi === n - 1) {
rbo = 0;
rbi = 0;
}
// case: right bit is in the next byte (as msb index 0)
else if (rsbi === 7) {
rbo = sbo + 1;
rbi = 0;
}
// left, center, and right bits
var lb = svw.getUint8(lbo);
var sb = svw.getUint8(sbo);
var rb = svw.getUint8(rbo);
// shift bit to lsb of byte
lb >>>= 7 - lbi % 8;
sb >>>= 7 - rsbi;
rb >>>= 7 - rbi % 8;
// pull bit out
lb &= 1;
sb &= 1;
rb &= 1;
// interpret pattern as decimal
var d = 4 * lb + 2 * sb + 1 * rb;
// convert decimal rule to binary string
var bs = r.toString(2);
// pad high order bits of binary rule # w/ 0s if neccessary
while (bs.length < 8) bs = '0' + bs;
// shift on 0 lsb
byte_buf <<= 1
// flip lsb to 1
if (parseInt(bs[7 - d], 2) === 1) byte_buf |= 1;
// when byte read or end of bits
if (rsbi === 7 || sbi === n - 1) {
byte_buf <<= 7 - rsbi;
vw.setUint8(sbo, byte_buf);
byte_buf *= 0;
}
}
return buf;
}
module.exports = function (w, h, r, rand, callback) {
var buf = seed(w, rand);
var t = 0;
while (t < h) {
callback(buf);
buf = next_gen(buf, w, r);
t++;
}
}