Skip to content

Commit d847cba

Browse files
committed
Implemented marquee border
1 parent 4257a0d commit d847cba

File tree

3 files changed

+91
-4
lines changed

3 files changed

+91
-4
lines changed

src/GameOfLife.js

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,44 @@ class GameOfLife extends Component {
1616
populatedCells: (props.startingPopulation || []).map((cell) => {
1717
return cell[0] + (cell[1] * props.width);
1818
}),
19+
border: this.props.border,
20+
};
21+
}
22+
23+
cellIsPopulated(populatedCells, x, y) {
24+
let cellIndex = x + (y * this.state.width);
25+
return populatedCells.includes(cellIndex);
26+
}
27+
28+
getAdjacentCellIndices(x, y) {
29+
let left = x - 1;
30+
let right = x + 1;
31+
if (this.state.border === 'marquee') {
32+
if (left < 0) {
33+
left = this.state.width - 1;
34+
}
35+
if (right >= this.state.width) {
36+
right = 0;
37+
}
38+
} else {
39+
right = Math.min(this.state.width - 1, x + 1);
40+
}
41+
42+
let top = y - 1;
43+
let bottom = y + 1;
44+
if (this.state.border === 'marquee') {
45+
if (bottom >= this.state.height) {
46+
bottom = 0;
47+
}
48+
if (top < 0) {
49+
top = this.state.height - 1;
50+
}
51+
} else {
52+
bottom = Math.min(this.state.height - 1, y + 1);
53+
}
54+
55+
return {
56+
top, right, bottom, left,
1957
};
2058
}
2159

@@ -25,8 +63,14 @@ class GameOfLife extends Component {
2563
for (let y = 0; y < this.state.height; y++) {
2664
const currentCellIndex = x + (y * this.state.width);
2765
let numberOfPopulatedNeighbours = 0;
28-
for (let nx = x - 1; nx <= Math.min(this.state.width - 1, x + 1); nx++) {
29-
for (let ny = y - 1; ny <= Math.min(this.state.height - 1, y + 1); ny++) {
66+
// let cellRight = x + 1 >= this.state.width ? 0 : x + 1;
67+
// let cellBelow = y + 1 >= this.state.height ? 0 : y + 1;
68+
const { top, right, bottom, left } = this.getAdjacentCellIndices(x, y);
69+
let xOptions = x === right ? [left, x] : [left, x, right];
70+
let yOptions = y === bottom ? [top, y] : [top, y, bottom];
71+
72+
for (let nx of xOptions) {
73+
for (let ny of yOptions) {
3074
let cellIndex = nx + (ny * this.state.width);
3175
let populated = populatedCells.includes(cellIndex);
3276
if ((nx !== x || ny !== y) && populated) {
@@ -132,11 +176,14 @@ GameOfLife.propTypes = {
132176
height: PropTypes.number,
133177
generation: PropTypes.number,
134178
start: PropTypes.bool,
179+
gridBehaviour: PropTypes.bool,
180+
border: PropTypes.oneOf(['hard', 'marquee']),
135181
}
136182

137183
GameOfLife.defaultProps = {
138184
generation: 0,
139185
start: false,
186+
border: 'hard',
140187
}
141188

142189
export default GameOfLife;

src/GameOfLife.test.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,37 @@ describe('when the population is specified in props and then stepped', () => {
125125
});
126126
});
127127

128+
describe('when grid behaviour is marquee', () => {
129+
let game, wrapper;
130+
131+
beforeAll(() => {
132+
const div = document.createElement('div');
133+
const population = [[0, 0], [0, 1], [0, 2],];
134+
game = <GameOfLife width={4} height={4} startingPopulation={population} border='marquee' />;
135+
wrapper = mount(game);
136+
});
137+
138+
it('should put a triomino line which is cut off to the other side on generation increment', () => {
139+
/*
140+
xooo oooo
141+
xooo --> xxox
142+
xooo oooo
143+
oooo oooo
144+
*/
145+
let allCells = wrapper.find(Cell);
146+
allCells.should.have.lengthOf(16);
147+
allCells.at(0).props().populated.should.equal(true);
148+
allCells.at(4).props().populated.should.equal(true);
149+
allCells.at(8).props().populated.should.equal(true);
150+
wrapper.setProps({ generation: 1 });
151+
wrapper.update();
152+
allCells = wrapper.find(Cell);
153+
allCells.should.have.lengthOf(16);
154+
allCells.at(4).props().populated.should.equal(true);
155+
allCells.at(5).props().populated.should.equal(true);
156+
allCells.at(7).props().populated.should.equal(true);
157+
158+
const deadCells = wrapper.findWhere(cell => cell.props().populated === false);
159+
deadCells.should.have.lengthOf(13);
160+
});
161+
});

src/index.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,14 @@ import './index.css';
44
import GameOfLife from './GameOfLife';
55
import * as serviceWorker from './serviceWorker';
66

7-
const gliderPopulation = [[1, 0],[2, 1],[0, 2],[1, 2],[2, 2],]
8-
ReactDOM.render(<GameOfLife width={25} height={25} startingPopulation={gliderPopulation} start={true} />, document.getElementById('root'));
7+
const gliderPopulation = [[1, 0], [2, 1], [0, 2], [1, 2], [2, 2],]
8+
ReactDOM.render(<GameOfLife
9+
width={10}
10+
height={10}
11+
startingPopulation={gliderPopulation}
12+
start={true}
13+
border='marquee'
14+
/>, document.getElementById('root'));
915

1016
// If you want your app to work offline and load faster, you can change
1117
// unregister() to register() below. Note this comes with some pitfalls.

0 commit comments

Comments
 (0)