Skip to content

Commit 40304c1

Browse files
committedMar 16, 2022
-- Implement Toroidal Wrapping.
1 parent 280544a commit 40304c1

File tree

3 files changed

+74
-42
lines changed

3 files changed

+74
-42
lines changed
 

‎.env

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
ESLINT_NO_DEV_ERRORS=true
2+
TSC_COMPILE_ON_ERROR=true

‎src/App.tsx

+64-39
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@ function App() {
77
const [gameBoard, setGameBoard] = useState<number[][]>(Array(MAX_WIDTH).fill(Array(MAX_HEIGHT).fill(0)));
88
const [simulationRunning, setSimulationRunning] = useState<boolean>(false);
99
const [gameSpeed, setGameSpeed] = useState<number>(200);
10+
const [toroidalBorders, setToroidalBorders] = useState<boolean>(false);
1011
const gameSpeedRef = useRef<number>(gameSpeed);
1112
const simulationRunningRef = useRef<boolean>(simulationRunning);
13+
const toroidalBordersRef = useRef<boolean>(toroidalBorders);
14+
toroidalBordersRef.current = toroidalBorders;
1215
gameSpeedRef.current = gameSpeed;
1316
simulationRunningRef.current = simulationRunning;
1417

@@ -27,7 +30,7 @@ function App() {
2730
return produce(g, (gameBoardCopy) => {
2831
for (let x = 0; x < gameBoardCopy.length; x++) {
2932
for (let y = 0; y < gameBoardCopy.length; y++) {
30-
gameBoardCopy[x][y] = resolvePosition(g, x, y);
33+
gameBoardCopy[x][y] = resolvePosition(g, x, y, toroidalBordersRef.current);
3134
}
3235
}
3336
});
@@ -41,48 +44,70 @@ function App() {
4144
}, []);
4245

4346
return (
44-
<div>
45-
<div style={{ display: 'grid', gridTemplateColumns: `repeat(${MAX_WIDTH},20px` }}>
46-
{gameBoard.map((row: number[], i) =>
47-
row.map((_column: number, j) => {
48-
const key = `el_${i}_${j}`;
49-
return (
50-
<div
51-
key={key}
52-
onClick={() => {
53-
handleTogglePosition(i, j);
47+
<div style={{ height: '100vh', display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
48+
<div>
49+
<div style={{ display: 'grid', gridTemplateColumns: `repeat(${MAX_WIDTH},20px` }}>
50+
{gameBoard.map((row: number[], i) =>
51+
row.map((_column: number, j) => {
52+
const key = `el_${i}_${j}`;
53+
return (
54+
<div
55+
key={key}
56+
onClick={() => {
57+
handleTogglePosition(i, j);
58+
}}
59+
style={{
60+
width: 20,
61+
height: 20,
62+
backgroundColor: gameBoard[i][j] ? 'skyblue' : undefined,
63+
border: '1px solid black',
64+
}}
65+
/>
66+
);
67+
}),
68+
)}
69+
</div>
70+
<span style={{ display: 'flex', flexDirection: 'row' }}>
71+
<button
72+
style={{ width: '200px', height: '50px', margin: '10px' }}
73+
onClick={() => {
74+
setSimulationRunning(!simulationRunning);
75+
if (!simulationRunning) {
76+
simulationRunningRef.current = true;
77+
startSimulation();
78+
}
79+
}}
80+
>
81+
{simulationRunning ? 'pause' : 'start'}
82+
</button>
83+
<div style={{ margin: '10px', padding: '5px' }}>
84+
<label>
85+
<input
86+
type={'numeric'}
87+
value={gameSpeed}
88+
onChange={(e) => {
89+
const { value: rawValue } = e.target;
90+
const num = parseInt(rawValue || '0');
91+
setGameSpeed(num);
5492
}}
55-
style={{
56-
width: 20,
57-
height: 20,
58-
backgroundColor: gameBoard[i][j] ? 'skyblue' : undefined,
59-
border: '1px solid black',
93+
/>
94+
<span>game speed</span>
95+
</label>
96+
</div>
97+
<div style={{ margin: '10px', padding: '5px' }}>
98+
<label className={'switch'}>
99+
<input
100+
type="checkbox"
101+
value={`${toroidalBorders}`}
102+
onChange={() => {
103+
setToroidalBorders(!toroidalBorders);
60104
}}
61105
/>
62-
);
63-
}),
64-
)}
106+
<span>Wrap Toroidal</span>
107+
</label>
108+
</div>
109+
</span>
65110
</div>
66-
<button
67-
style={{ width: '200px', height: '50px' }}
68-
onClick={() => {
69-
setSimulationRunning(!simulationRunning);
70-
if (!simulationRunning) {
71-
simulationRunningRef.current = true;
72-
startSimulation();
73-
}
74-
}}
75-
>
76-
{simulationRunning ? 'pause' : 'start'}
77-
</button>
78-
<input
79-
type={'numeric'}
80-
value={gameSpeed}
81-
onChange={(e) => {
82-
const num = parseInt(e.target.value);
83-
setGameSpeed(num);
84-
}}
85-
/>
86111
</div>
87112
);
88113
}

‎src/utils/ConwayUtils.ts

+8-3
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,20 @@ export const NeighborRelativePositions: number[][] = [
1212
[0, 1],
1313
[1, 0],
1414
];
15-
export const resolvePosition = (originalBoard: number[][], x: number, y: number): number => {
15+
export const resolvePosition = (originalBoard: number[][], x: number, y: number, toroidal = false): number => {
1616
let neighbors = 0;
1717
let isLiving: number = originalBoard[x][y];
1818
const maxDimensionX = originalBoard[0].length;
1919
const maxDimensionY = originalBoard.length;
2020
for (const position of NeighborRelativePositions) {
2121
const [xNeighbor, yNeighbor] = position;
22-
const relativeX = x + xNeighbor;
23-
const relativeY = y + yNeighbor;
22+
let relativeX = x + xNeighbor;
23+
let relativeY = y + yNeighbor;
24+
if (toroidal) {
25+
// If we are on a "toroidal" map, we wrap around to the opposite end.
26+
relativeX = relativeX < MIN_WIDTH ? MAX_WIDTH - 1 : relativeX >= MAX_WIDTH ? 0 : relativeX;
27+
relativeY = relativeY < MIN_HEIGHT ? MAX_HEIGHT - 1 : relativeY >= MAX_HEIGHT ? 0 : relativeY;
28+
}
2429
if (
2530
relativeX >= MIN_WIDTH &&
2631
relativeX < maxDimensionX &&

0 commit comments

Comments
 (0)
Please sign in to comment.