Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change---back to object based gb #47

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ src/tmp2.js
src/tmp3.js

# production
.vscode
/build
src/**/*.css

Expand Down
10 changes: 8 additions & 2 deletions src/components/GameEngine.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ import * as actions from "../actions";
class GameEngine extends Component {
componentWillUpdate(nextProps) {
//=== stop game if all cells are dead
const stillAlive = this.props.gameboard.some(row => row.some(cell => cell));
let stillAlive = false;

for (let cell in this.props.gameboard) {
if (this.props.gameboard[cell].isAlive) {
stillAlive = true;
}
}

if (!stillAlive) {
console.log("All dead --- stopping...");
Expand Down Expand Up @@ -44,7 +50,7 @@ class GameEngine extends Component {
}

GameEngine.propTypes = {
gameboard: PropTypes.array.isRequired,
gameboard: PropTypes.object.isRequired,
intervalId: PropTypes.number.isRequired,
speed: PropTypes.number.isRequired,
runGame: PropTypes.func.isRequired,
Expand Down
45 changes: 13 additions & 32 deletions src/components/Gameboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,37 +43,18 @@ class Gameboard extends Component {
}

createGameboard = gameboard => {
const size = gameboard.length;

return gameboard.map((row, rowNumber) => [
...row.map((cell, cellNumber) => {
return (
// <GameboardCell
// key={`${rowNumber}-${cellNumber}`}
// size={size}
// alive={cell}
// rowNumber={rowNumber}
// cellNumber={cellNumber}
// />
<div
key={`${rowNumber}-${cellNumber}`}
className={`${rowNumber}-${cellNumber}${cell ? " alive" : ""}${
rowNumber === 0 ? " top" : ""
}${cellNumber === 0 ? " left" : ""}${
rowNumber === size - 1 ? " bottom" : ""
}${cellNumber === size - 1 ? " right" : ""}`}
/>
// <div
// key={`${rowNumber}-${cellNumber}`}
// className={`${rowNumber}-${cellNumber}${
// rowNumber === 0 ? " top" : ""
// }${cellNumber === 0 ? " left" : ""}${
// rowNumber === size - 1 ? " bottom" : ""
// }${cellNumber === size - 1 ? " right" : ""}`}
// />
);
})
]);
return Object.entries(gameboard).map(cell => {
return (
<GameboardCell
key={cell[0]}
size={this.props.size - 1}
cellName={cell[0]}
isAlive={cell[1].isAlive}
rowNum={cell[1].rowNum}
colNum={cell[1].colNum}
/>
);
});
};

handleMouseDown = ({ target }) => {
Expand Down Expand Up @@ -135,7 +116,7 @@ class Gameboard extends Component {
}

Gameboard.propTypes = {
gameboard: PropTypes.array.isRequired,
gameboard: PropTypes.object.isRequired,
mouseDrag: PropTypes.bool.isRequired,
size: PropTypes.number.isRequired,
dragMouse: PropTypes.func.isRequired,
Expand Down
32 changes: 22 additions & 10 deletions src/components/GameboardCell.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,29 @@ import React from "react";

class GameboardCell extends React.PureComponent {
render() {
const { size, alive, rowNumber, cellNumber } = this.props;
const { size, cellName, isAlive, rowNum, colNum } = this.props;

return (
<div
className={`${rowNumber}-${cellNumber}${alive ? " alive" : ""}${
rowNumber === 0 ? " top" : ""
}${cellNumber === 0 ? " left" : ""}${
rowNumber === size - 1 ? " bottom" : ""
}${cellNumber === size - 1 ? " right" : ""}`}
/>
);
if (isAlive) {
return (
<div
className={`${cellName} alive ${rowNum === 0 ? " top" : ""}${
colNum === 0 ? " left" : ""
}${rowNum === size ? " bottom" : ""}${
colNum === size ? " right" : ""
}`}
/>
);
} else {
return (
<div
className={`${cellName}${rowNum === 0 ? " top" : ""}${
colNum === 0 ? " left" : ""
}${rowNum === size ? " bottom" : ""}${
colNum === size ? " right" : ""
}`}
/>
);
}
}
}

Expand Down
34 changes: 18 additions & 16 deletions src/reducers/gameboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,28 @@ export default function(state = createEmptyGameboard(20), action) {
}

export const toggleCellHelper = (gameboard, cell) => {
const coords = cell.split("-").map(parseFloat),
rowsBefore = gameboard.slice(0, coords[0]),
rowsAfter = gameboard.slice(coords[0] + 1),
cellsBefore = gameboard[coords[0]].slice(0, coords[1]),
cellsAfter = gameboard[coords[0]].slice(coords[1] + 1),
targetCellState = gameboard[coords[0]][coords[1]];

return [
...rowsBefore,
[...cellsBefore, !targetCellState, ...cellsAfter],
...rowsAfter
];
const oldCell = gameboard[cell];
const newCell = { ...oldCell, isAlive: !oldCell.isAlive };

return { ...gameboard, [cell]: newCell };
};

export const clearGameboardHelper = gameboard => {
return gameboard.map(row => row.map(cell => false));
const newGameboard = Object.assign({}, gameboard);

for (let cell in newGameboard) {
newGameboard[cell].isAlive = false;
}

return newGameboard;
};

export const randomizeGameboardHelper = gameboard => {
return gameboard.map(row =>
row.map(cell => (Math.random() > 0.35 ? false : true))
);
const newGameboard = Object.assign({}, gameboard);

for (let cell in newGameboard) {
newGameboard[cell].isAlive = Math.random() > 0.35 ? false : true;
}

return newGameboard;
};
138 changes: 80 additions & 58 deletions src/utils/updateGameboard.js
Original file line number Diff line number Diff line change
@@ -1,88 +1,110 @@
import gameboard from "../reducers/gameboard";
//======================================================
// Update array-based gameboard
//======================================================

const minus2 = (current, max) => {
if (current - 1 < 0) return max - 1;
return current - 1;
};

const plus2 = (current, max) => {
if (current + 1 === max) return 0;
return current + 1;
};

const findAliveNeighbours = (rowNum, cellNum, gameboard) => {
const max = gameboard.length,
neighbours = [
[minus2(rowNum, max), minus2(cellNum, max)],
[minus2(rowNum, max), cellNum],
[minus2(rowNum, max), plus2(cellNum, max)],
[rowNum, minus2(cellNum, max)],
[rowNum, plus2(cellNum, max)],
[plus2(rowNum, max), minus2(cellNum, max)],
[plus2(rowNum, max), cellNum],
[plus2(rowNum, max), plus2(cellNum, max)]
];

return neighbours.filter(neighbour => gameboard[neighbour[0]][neighbour[1]])
.length;
};

const checkCell = (cell, rowNum, cellNum, gameboard) => {
const aliveNeighbours = findAliveNeighbours(rowNum, cellNum, gameboard);

if (cell && (aliveNeighbours === 2 || aliveNeighbours === 3)) {
const checkCell = (isAlive, aliveNeighbours) => {
if (isAlive && (aliveNeighbours === 2 || aliveNeighbours === 3)) {
return true;
}
if (!cell && aliveNeighbours === 3) {
if (!isAlive && aliveNeighbours === 3) {
return true;
}

return false;
};

export const updateGameboard = gameboard => {
// use this function to stop the game when all cells are dead
// let deadCells = 0;
console.time("updating");
const updatedGameboard = gameboard.map((row, rowNum) => {
return row.map((cell, cellNum) => {
const isAlive = checkCell(cell, rowNum, cellNum, gameboard);
// const cellElement = document.querySelector(`.${rowNum}-${cellNum}`);

// if (cellElement.classList.contains("alive") && !isAlive) {
// cellElement.classList.remove("alive");
// } else if (!cellElement.classList.contains("alive") && isAlive) {
// cellElement.classList.add("alive");
// }
// if (isAlive) deadCells += 1;

return isAlive;
});
});
const newGameboard = Object.assign({}, gameboard);

for (let cell in newGameboard) {
const currentCell = newGameboard[cell];
// let aliveNeighbours = 0;
const aliveNeighbours = currentCell.neighbours.filter(
neighbour => newGameboard[neighbour].isAlive
);
//=== count alive neighbours & update them with current cell state
// for (let neighbour in currentCell.neighbours) {
//=== check neighbour if we don't know its state already
// if (currentCell.neighbours[neighbour] === null) {
// const neighbourCell = newGameboard[neighbour];

//=== update neighbour cell "neighbours" state
// neighbourCell.neighbours[cell] = currentCell.isAlive;
//=== increase aliveNeighbours count if neighbour is alive
// if (newGameboard[neighbour].isAlive) aliveNeighbours += 1;
// } else {
//=== increase aliveNeighbours count if neighbour is alive
// if (currentCell.neighbours[neighbour] === true) aliveNeighbours += 1;
// }
//=== set neighbour state to NULL for the next updateGameboard iteration
// currentCell.neighbours[neighbour] = null;
// }

//=== set dead/alive state for the current cell
currentCell.isAlive = checkCell(
currentCell.isAlive,
aliveNeighbours.length
);
}

// const allDead = deadCells === gameboard.length * 2;
console.timeEnd("updating");

return updatedGameboard;
return newGameboard;
};

//======================================
// Create empty array-based gameboard
// Create empty object-based gameboard
//======================================

export const createEmptyGameboard = maxCell => {
const minus = (current, max) => {
if (current - 1 < 0) return max - 1;
return current - 1;
};

const plus = (current, max) => {
if (current + 1 === max) return 0;
return current + 1;
};

// const findAllNeighbours = (rowNum, colNum, gameboardSize) => ({
// [`${minus(rowNum, gameboardSize)}-${minus(colNum, gameboardSize)}`]: null,
// [`${minus(rowNum, gameboardSize)}-${colNum}`]: null,
// [`${minus(rowNum, gameboardSize)}-${plus(colNum, gameboardSize)}`]: null,
// [`${rowNum}-${minus(colNum, gameboardSize)}`]: null,
// [`${rowNum}-${plus(colNum, gameboardSize)}`]: null,
// [`${plus(rowNum, gameboardSize)}-${minus(colNum, gameboardSize)}`]: null,
// [`${plus(rowNum, gameboardSize)}-${colNum}`]: null,
// [`${plus(rowNum, gameboardSize)}-${plus(colNum, gameboardSize)}`]: null
// });

const findAllNeighbours = (rowNum, colNum, gameboardSize) => [
`${minus(rowNum, gameboardSize)}-${minus(colNum, gameboardSize)}`,
`${minus(rowNum, gameboardSize)}-${colNum}`,
`${minus(rowNum, gameboardSize)}-${plus(colNum, gameboardSize)}`,
`${rowNum}-${minus(colNum, gameboardSize)}`,
`${rowNum}-${plus(colNum, gameboardSize)}`,
`${plus(rowNum, gameboardSize)}-${minus(colNum, gameboardSize)}`,
`${plus(rowNum, gameboardSize)}-${colNum}`,
`${plus(rowNum, gameboardSize)}-${plus(colNum, gameboardSize)}`
];

export const createEmptyGameboard = gameboardSize => {
//=== initialize gameboard
let gameboard = [];
let gameboard = {};

//=== populate gameboard with empty cells
for (let i = 0; i < maxCell; i++) {
let row = [];
for (let j = 0; j < maxCell; j++) {
row.push(false);
for (let i = 0; i < gameboardSize; i++) {
for (let j = 0; j < gameboardSize; j++) {
gameboard[`${i}-${j}`] = {
isAlive: false,
rowNum: i,
colNum: j,
neighbours: findAllNeighbours(i, j, gameboardSize)
};
}
gameboard.push(row);
}

return gameboard;
Expand Down