D3.js 生命游戏 ( Conway's Game of Life Simulation )

介绍

Game of Life 是英国数学家 John Horton Conway 在 1970 年发明的细胞自动机。
建立一个 LxW 的格子,每个格子代表一个细胞。
规则如下:

如果一个活细胞周围有 2 或 3 个细胞为活,则该细胞为活如果一个死细胞周围有 3 个细胞为生,则该细胞的变成活在其它情况下,该细胞状态不变

练习写了一个生命游戏,用的是 Javascript 和 D3.js,演算方法并没有用最快的,所以速度无法加速到很快,改天再来换个演算法写一次。也写了几个简单的功能,分别是可以new、start/stop、加速和减速,以及点击改变细胞状态。

程式码

有个小地方 Debug 好久,是我对 JS 不够熟悉:

 var a = []; a[0] = 5; console.log(a[0]); //5 var b = a; b[0] = 6; console.log(a[0]); //6 var AA = [0,1]; var BB = [0,1]; console.log(AA == BB); //false

因为阵列算物件,所以 b 等于是和 a 是相通的。
AABB虽然看起来一样,js 却会判断为 false
所以要比较 AABB 只能用:AA[0] == BB[0] && AA[1] == BB[1]

程式码:

<!DOCTYPE html><html><head>    <title>Game of Life</title>    <script src="https://d3js.org/d3.v3.min.js"></script>    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script></head><body><style>    button {      padding: 6px 12px;      font-size: 14px;      background-color: #fff;      border: 1px solid #ccc;      border-radius: 4px;      margin: 5px;    }    .start {      color: white;      background-color: red;      border: 1px solid transparent;    }    .new {      color: white;      background-color: #5cb85c;      border: 1px solid transparent;    }    .speedUp {      color: white;      background-color: steelblue;      border: 1px solid transparent;    }    .speedDown {      color: white;      background-color: steelblue;      border: 1px solid transparent;    }</style><p>Game of Life</p><div id="Control"></div><div id="Grids"></div><script>var rectW = 30, rectL = 50, cc = 10, delayTime = 100, timerID = 0,xs = d3.scale.linear().domain([0,rectL]).range([0,rectL * cc]),ys = d3.scale.linear().domain([0,rectW]).range([0,rectW * cc]),grids = [];var stopped = false ;var Neighbour = {CLT: [[ 1, 0], [ 0, 1], [ 1, 1]],CT:  [[-1, 0], [ 1, 0], [-1, 1], [ 0, 1], [ 1, 1]],CRT: [[-1, 0], [-1, 1], [ 0, 1]],CL:  [[ 0,-1], [ 1,-1], [ 1, 0], [ 0, 1], [ 1, 1]],CR:  [[-1,-1], [ 0,-1], [-1, 0], [-1, 1], [ 0, 1]],CLB: [[ 0,-1], [ 1,-1], [ 1, 0]],CB:  [[-1,-1], [ 0,-1], [ 1,-1], [-1, 0], [ 1, 0]],CRB: [[-1,-1], [ 0,-1], [-1, 0]],C: [[-1,-1], [ 0,-1], [ 1,-1], [-1, 0], [ 1, 0], [-1, 1], [ 0, 1], [ 1, 1]]};var ctrl = d3.select("#Control")ctrl.append('button').attr('class', 'new').text('New').on('click', function(){ return setNewGrid() });ctrl.append('button').attr('class', 'start').text('Stop').on('click', startStop);ctrl.append('button').attr('class', 'speedDown').text('◄◄').on('click', speedDown);ctrl.append('button').attr('class', 'speedUp').text('►►').on('click', speedUp);function speedUp(){delayTime = delayTime / 2 ;run();}function speedDown(){delayTime = delayTime * 2;run();}var rects = d3.select("#Grids").append("svg:svg")    .attr("stroke", "rgba(204, 204,204,0.2)").attr("shape-rendering", "crispEdges").attr("width",rectL*cc).attr("height", rectW*cc);var initialize = function(){grids = [];d3.range(rectL).forEach(function(x){grids[x] = new Array();d3.range(rectW).forEach(function(y){grids[x][y] = 0;});});var GliderGun =  [[24, 0],                  [22, 1], [24, 1],                  [12, 2], [13, 2], [20, 2], [21, 2], [34, 2], [35, 2],                  [11, 3], [15, 3], [20, 3], [21, 3], [34, 3], [35, 3],                  [0, 4], [1, 4], [10, 4], [16, 4], [20, 4], [21, 4],                  [0, 5], [1, 5], [10, 5], [14, 5], [16, 5], [17, 5], [22, 5], [24, 5],                  [10, 6], [16, 6], [24, 6],                  [11, 7], [15, 7],                  [12, 8], [13, 8]];for(var i in GliderGun){var _x = GliderGun[i][0]+5;var _y = GliderGun[i][1]+10;grids[_x][_y] = 1;}rects.selectAll("rect").data(function(){ return setGrid()}).enter().append("rect").attr("x", function(d){ return xs(d.x)}).attr("y", function(d){ return ys(d.y)}).attr("width",cc).attr("height",cc).attr("fill", function(d){ return d.state? "black":"white";}).on('click', function(){ return toggleGrid(d3.mouse(this)) });};var toggleGrid = function(xy){var pos = [scaleDown(xy[0]), scaleDown(xy[1])];grids[pos[0]][pos[1]] = grids[pos[0]][pos[1]]? 0: 1;function scaleDown(n){return Math.floor(n / cc);};displayGrid();}var setGrid = function (){var bits = [];for(var i= 0; i< rectL; i++){for(var j= 0; j< rectW; j++){bits.push({ "x": i, "y": j, "state": grids[i][j] });}}return bits;};var setNewGrid = function (){delayTime = 100;initialize();displayGrid();}var nextGen = function(){var getNeighbours = function(x,y){var nei = "C";if (x == 0) nei += "L";if (x == rectL-1) nei += "R";if (y == 0) nei += "T";if (y == rectW-1) nei += "B";return Neighbour[nei];};var _grids = [];for(var i= 0; i< rectL; i++){_grids[i] = [];for(var j= 0; j< rectW; j++){var liveNei = 0, thisGrid = grids[i][j], newGrid;var Nei = getNeighbours(i,j);for(var k in Nei){liveNei += (grids[i+Nei[k][0]][j+Nei[k][1]]? 1: 0);}if(thisGrid){//alivenewGrid = liveNei==2 || liveNei==3 ? 1: 0;}else{newGrid = liveNei ==3 ? 1: 0;} _grids[i][j] = newGrid;}}grids = _grids;};var displayGrid = function(){rects.selectAll("rect").data(function(){ return setGrid()}).transition().attr("fill", function(d) { return d.state ? "black" : "white" }).duration(0);}function startStop() {stopped = !stopped;d3.select('button.start').text(function () { return stopped ? 'Start' : 'Stop';});}var run = function(){var aRound = function(){if (!stopped) {nextGen();displayGrid();}}clearInterval(timerID);timerID = setInterval(function(){return aRound();},delayTime);}function firstRun(){initialize();run();};firstRun();</script></body></html>

关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章