Skip to content

Commit 2b41f74

Browse files
committed
Added more grid options
1 parent 71b7341 commit 2b41f74

File tree

8 files changed

+127
-105
lines changed

8 files changed

+127
-105
lines changed

index.html

+57-13
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,69 @@
22
<head>
33
<!-- <link rel="stylesheet" href="https://necolas.github.io/normalize.css/4.1.1/normalize.css"> -->
44
<link rel="stylesheet" href="style.css">
5-
<script type="text/javascript" src="js/conway.js"></script>
6-
<script type="text/javascript" src="js/grid.js"></script>
7-
<script type="text/javascript" src="js/vector.js"></script>
8-
<script type="text/javascript" src="js/views.js"></script>
9-
<script type="text/javascript" src="js/board.js"></script>
10-
<script type="text/javascript" src="js/main.js"></script>
5+
<script src="js/conway.js"></script>
6+
<script src="js/grid.js"></script>
7+
<script src="js/vector.js"></script>
8+
<script src="js/views.js"></script>
9+
<script src="js/board.js"></script>
10+
<script src="js/main.js"></script>
11+
12+
<style type="text/css">
13+
#controls {
14+
}
15+
16+
#display {
17+
margin-top: 10px;
18+
}
19+
20+
.dimensions {
21+
width: 40px;
22+
}
23+
24+
.control-group {
25+
height: 75px;
26+
vertical-align: top;
27+
display: inline-block;
28+
}
29+
.group-label {
30+
text-align: center;
31+
}
32+
.group-controls {
33+
padding: 10px;
34+
text-align: center;
35+
border: 1px solid black;
36+
}
37+
</style>
1138
</head>
1239
<body>
1340
<div id="container">
1441
<h1>Conway</h1>
1542
<div id="controls">
16-
<button id="start">start</button>
17-
<button id="stop">stop</button>
18-
<button id="next">next</button>
19-
<button id="reset">reset</button>
20-
<select id="viewSelection"></select>
21-
<input id="fpsSlider" type="range" min="1" max="30" value="20"><span id="fpsData">2</span>
43+
<div class="control-group">
44+
<div class="group-label">Gameboard</div>
45+
<div class="group-controls">
46+
<button id="start">start</button>
47+
<button id="stop">stop</button>
48+
<button id="next">next</button>
49+
<button id="reset">reset</button>
50+
</div>
51+
</div>
52+
53+
<div class="control-group">
54+
<div class="group-label">Renderer</div>
55+
<div class="group-controls">
56+
<select id="viewSelection"></select>
57+
</div>
58+
</div>
59+
60+
<div class="control-group">
61+
<div class="group-label">Size & Rate</div>
62+
<div class="group-controls">
63+
<input id="gridWidth" class="dimensions" value=60> x <input id="gridHeight" class="dimensions" value=30> <input id="fpsSlider" type="range" min="1" max="30" value="20"><span id="fpsData">20</span> fps
64+
</div>
65+
</div>
2266
</div>
23-
<br>
67+
2468
<div id="display"></div>
2569
</div>
2670

js/board.js

+16-15
Original file line numberDiff line numberDiff line change
@@ -7,36 +7,37 @@ function Board(rootEl, grid, view) {
77

88

99
Board.prototype.setView = function(view) {
10-
1110
this.view = view;
1211
};
1312

13+
Board.prototype.setGrid = function(grid) {
14+
this.grid = grid;
15+
}
1416

1517
Board.prototype.init = function() {
16-
1718
this.view.init(this.rootEl, this.grid);
1819
};
1920

21+
Board.prototype.randomize = function(values) {
22+
this.grid.fill(chooseRandom.bind(null, values));
2023

21-
Board.prototype.randomize = function() {
22-
23-
this.grid.fill(randomGenerator([false, true]));
24-
25-
function randomGenerator(values) {
26-
return function generate() {
27-
return values[Math.floor(Math.random() * values.length)];
28-
};
29-
}
24+
function chooseRandom(array) {
25+
return array[Math.floor(Math.random() * array.length)];
26+
};
3027
};
3128

3229
Board.prototype.clear = function() {
33-
3430
while (this.rootEl.firstChild)
3531
this.rootEl.removeChild(this.rootEl.firstChild);
3632
};
3733

38-
3934
Board.prototype.update = function() {
40-
4135
this.view.update(this.rootEl, this.grid);
42-
};
36+
};
37+
38+
Board.prototype.reset = function() {
39+
this.clear();
40+
this.init();
41+
this.randomize([false, true]);
42+
this.update();
43+
}

js/conway.js

-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ var Conway = {
1515
* @return {Grid} Same gameboard with updated grid
1616
*/
1717
nextGeneration: function nextGeneration(curGrid) {
18-
1918
var newGrid = new Grid(curGrid.width, curGrid.height);
2019

2120
curGrid.forEach( function(state, vector) {
@@ -49,7 +48,6 @@ var Conway = {
4948
* @return {int} Number of alive neighbors
5049
*/
5150
function countNeighbors(grid, vector, radius) {
52-
5351
return grid.getNeighbors(vector, radius).reduce(countAlive, 0);
5452

5553
function countAlive(total, state) {

js/grid.js

+5-10
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55
* @param {int} height Number of rows
66
*/
77
function Grid(width, height) {
8-
98
this.width = width;
109
this.height = height;
11-
this.space = new Array(height).fill(new Array(width));
10+
this.space = new Array(height);
11+
for (var i = 0; i < this.height; i++)
12+
this.space[i] = new Array(width);
1213
}
1314

1415

@@ -18,7 +19,6 @@ function Grid(width, height) {
1819
* @param {value} value New value for cell
1920
*/
2021
Grid.prototype.set = function set(vector, value) {
21-
2222
if (! this.isInside(vector))
2323
return null;
2424

@@ -32,7 +32,6 @@ Grid.prototype.set = function set(vector, value) {
3232
* @return {boolean} Value of cell
3333
*/
3434
Grid.prototype.get = function get(vector) {
35-
3635
if (! this.isInside(vector))
3736
return null;
3837

@@ -47,7 +46,6 @@ Grid.prototype.get = function get(vector) {
4746
* @return {Array} List of neighboring values
4847
*/
4948
Grid.prototype.getNeighbors = function getNeighbors(vector, radius) {
50-
5149
var neighbors = [];
5250

5351
for (var yOffset = -radius; yOffset <= radius; yOffset++) {
@@ -74,7 +72,6 @@ Grid.prototype.getNeighbors = function getNeighbors(vector, radius) {
7472
* @param {Object} ctx Context for 'this'
7573
*/
7674
Grid.prototype.fill = function fill(fn, ctx) {
77-
7875
for (var y = 0; y < this.height; y++)
7976
for (var x = 0; x < this.width; x++)
8077
this.space[y][x] = fn.call(ctx);
@@ -89,7 +86,6 @@ Grid.prototype.fill = function fill(fn, ctx) {
8986
* @param {Object} ctx Context for 'this'
9087
*/
9188
Grid.prototype.forEach = function forEach(fn, ctx) {
92-
9389
for (var y = 0; y < this.height; y++)
9490
for (var x = 0; x < this.width; x++)
9591
fn.call(ctx, this.space[y][x], new Vector(x, y));
@@ -102,7 +98,6 @@ Grid.prototype.forEach = function forEach(fn, ctx) {
10298
* @return {boolean} true or false
10399
*/
104100
Grid.prototype.isInside = function(vector) {
105-
106-
return vector.x >= 0 && vector.x < this.width &&
107-
vector.y >= 0 && vector.y < this.height;
101+
return (vector.x >= 0 && vector.x < this.width &&
102+
vector.y >= 0 && vector.y < this.height);
108103
};

js/main.js

+49-30
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
1-
var board, timer, prevTime, refreshInterval, fps = 20;
2-
1+
var board, timer, prevTime, fps, areaLimit = 10000;
32

43
function init() {
5-
64
// Board
75
var el = document.querySelector('#display');
8-
var grid = new Grid(60, 60);
6+
var grid = new Grid(60, 30);
97

108
board = new Board(el, grid, Views.circle);
11-
board.randomize();
12-
13-
board.init();
14-
board.update();
9+
board.reset();
1510

1611

1712
// UI
@@ -27,7 +22,10 @@ function init() {
2722
for (var view in Views)
2823
viewSelect.insertAdjacentHTML('beforeend', `<option value=${view}>${view}</option>`);
2924

30-
updateFps(fps);
25+
document.querySelector('#gridWidth').addEventListener('blur', onGridWidth);
26+
document.querySelector('#gridHeight').addEventListener('blur', onGridHeight);
27+
28+
updateFps(20);
3129
}
3230

3331

@@ -37,58 +35,82 @@ function init() {
3735
*/
3836

3937
function onFpsSlider(e) {
40-
4138
updateFps(e.target.value);
4239
}
4340

4441
function onViewSelection(e) {
45-
4642
board.clear();
4743
board.setView(Views[e.target.value]);
4844
board.init();
4945
board.update();
5046
}
5147

52-
5348
function onReset(e) {
54-
55-
board.randomize();
49+
board.randomize([false, true]);
5650
board.update();
5751
}
5852

53+
function onGridWidth(e) {
54+
const newWidth = e.target.value;
55+
const area = newWidth * board.grid.height;
56+
57+
if (newWidth != board.grid.width) {
58+
if ((area > 0) && (area <= areaLimit)) {
59+
board.setGrid(new Grid(newWidth, board.grid.height));
60+
board.reset();
61+
} else {
62+
e.target.value = board.grid.width;
63+
console.log(`Area limited to 1 - ${areaLimit}, ${area} is outside range.`);
64+
}
65+
}
66+
}
67+
68+
function onGridHeight(e) {
69+
const newHeight = e.target.value;
70+
const area = board.grid.width * newHeight;
71+
72+
if (newHeight != board.grid.height) {
73+
if ((area > 0) && (area <= areaLimit)) {
74+
board.setGrid(new Grid(board.grid.width, newHeight));
75+
board.reset();
76+
} else {
77+
e.target.value = board.grid.height;
78+
console.log(`Area limited to 1 - ${areaLimit}, ${area} is outside range.`);
79+
}
80+
}
81+
}
82+
5983

6084

6185
/*
6286
* Timing
6387
*/
6488

6589
function start() {
66-
67-
if (! timer)
90+
if (!timer)
6891
stepLoop();
6992
}
7093

71-
7294
function stop() {
73-
74-
cancelAnimationFrame(timer);
75-
timer = null;
95+
if (timer) {
96+
cancelAnimationFrame(timer);
97+
timer = null;
98+
}
7699
}
77100

78-
79101
function step() {
80-
81-
Conway.nextGeneration(board.grid);
102+
stop();
103+
Conway.nextGeneration(board.grid);
82104
board.update();
83105
}
84106

85-
86107
function stepLoop(timeStamp) {
87-
88108
if (!prevTime)
89109
prevTime = timeStamp;
90110

91-
if (timeStamp - prevTime > refreshInterval) {
111+
var delta = timeStamp - prevTime;
112+
var spf = 1000 / fps;
113+
if (delta > spf) {
92114

93115
step();
94116
prevTime = timeStamp;
@@ -97,10 +119,7 @@ function stepLoop(timeStamp) {
97119
timer = requestAnimationFrame(stepLoop);
98120
}
99121

100-
101122
function updateFps(newFps) {
102-
103123
fps = newFps;
104-
refreshInterval = 1000 / fps;
105124
document.querySelector('#fpsData').textContent = newFps;
106-
}
125+
}

js/vector.js

-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
function Vector(x, y) {
2-
32
this.x = x;
43
this.y = y;
54
}

0 commit comments

Comments
 (0)