Skip to content

Instantly share code, notes, and snippets.

@jorpic
Last active August 29, 2015 14:01
Show Gist options
  • Save jorpic/c8dd686f5e68a41d4ab4 to your computer and use it in GitHub Desktop.
Save jorpic/c8dd686f5e68a41d4ab4 to your computer and use it in GitHub Desktop.
конформизм
<!DOCTYPE html>
<!-- По мотивам http://macroevolution.livejournal.com/168362.html -->
<meta charset="utf-8">
<style>
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://coffeescript.org/extras/coffee-script.js"></script>
<script src="http://underscorejs.org/underscore-min.js"></script>
<script type="text/coffeescript">
colors = d3.scale.category10().range()
xs = d3.scale.ordinal().domain([0..14]).rangePoints([0,innerWidth], 2).range()
ys = d3.scale.ordinal().domain([0..9]).rangePoints([0,innerHeight], 1).range()
rs = d3.scale.ordinal()
.domain(d3.range(colors.length))
.rangePoints([0,innerHeight/ys.length/2], 2)
.range().reverse()
nodes =
xs.map (x) ->
ys.map (y) ->
rs.map (r) ->
{x: x, y: y, r: r, c: _.sample colors}
grid = d3
.select('body').append('svg')
.attr('width', innerWidth)
.attr('height', innerHeight)
row = grid
.selectAll('.row')
.data(nodes)
.enter().append('svg:g')
.attr('class', 'row')
cell = row
.selectAll('.cell')
.data((d) -> d)
.enter().append('svg:g')
.attr('class', 'cell')
cell
.selectAll('circle')
.data((d) -> d)
.enter().append('circle')
.attr('cx', (d) -> d.x)
.attr('cy', (d) -> d.y)
.attr('r', (d) -> d.r)
.style('fill', (d) -> d.c)
.style('stroke', '#000')
.style('stroke-width', '1px')
nodeColors = (n) -> n.map (c) -> c.c
neighbors = (x, y) ->
res = []
for i in [x-1..x+1] when i >=0 and i < xs.length
for j in [y-1..y+1] when j >= 0 and j < ys.length
if not (i == 0 and j == 0)
res.push(nodes[i][j])
res
step = ->
for x in d3.range xs.length
for y in d3.range ys.length
current = nodes[x][y]
selected = _.sample (neighbors x, y), 3
selectedColors = _.zip.apply _, selected.map(nodeColors)
current.fit = 0
for [c,cs] in _.zip nodeColors(current), selectedColors
current.fit += _.filter(cs, (x) -> x == c).length
for x in d3.range xs.length
for y in d3.range ys.length
current = nodes[x][y]
selected = _.sample (neighbors x, y)
if selected.fit >= current.fit
i = _.sample(d3.range colors.length)
current[i].c = selected[i].c
cell
.selectAll('circle')
.data((d) -> d)
.style('fill', (d) -> d.c)
setInterval step, 100
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment