Browse Source

Set up board, allow toggling cells

master
Dylan Baker 3 years ago
parent
commit
2cfbe3c89e
10 changed files with 106 additions and 86 deletions
  1. 2
    0
      .gitignore
  2. 1
    1
      public/index.html
  3. 0
    38
      src/App.css
  4. 0
    9
      src/App.test.tsx
  5. 0
    26
      src/App.tsx
  6. 37
    0
      src/Board.tsx
  7. 20
    0
      src/Cell.tsx
  8. 38
    0
      src/index.css
  9. 5
    3
      src/index.tsx
  10. 3
    9
      tsconfig.json

+ 2
- 0
.gitignore View File

@@ -21,3 +21,5 @@
21 21
 npm-debug.log*
22 22
 yarn-debug.log*
23 23
 yarn-error.log*
24
+
25
+.eslintcache

+ 1
- 1
public/index.html View File

@@ -24,7 +24,7 @@
24 24
       work correctly both with client-side routing and a non-root public URL.
25 25
       Learn how to configure a non-root public URL by running `npm run build`.
26 26
     -->
27
-    <title>React App</title>
27
+    <title>Conway's Game of Life</title>
28 28
   </head>
29 29
   <body>
30 30
     <noscript>You need to enable JavaScript to run this app.</noscript>

+ 0
- 38
src/App.css View File

@@ -1,38 +0,0 @@
1
-.App {
2
-  text-align: center;
3
-}
4
-
5
-.App-logo {
6
-  height: 40vmin;
7
-  pointer-events: none;
8
-}
9
-
10
-@media (prefers-reduced-motion: no-preference) {
11
-  .App-logo {
12
-    animation: App-logo-spin infinite 20s linear;
13
-  }
14
-}
15
-
16
-.App-header {
17
-  background-color: #282c34;
18
-  min-height: 100vh;
19
-  display: flex;
20
-  flex-direction: column;
21
-  align-items: center;
22
-  justify-content: center;
23
-  font-size: calc(10px + 2vmin);
24
-  color: white;
25
-}
26
-
27
-.App-link {
28
-  color: #61dafb;
29
-}
30
-
31
-@keyframes App-logo-spin {
32
-  from {
33
-    transform: rotate(0deg);
34
-  }
35
-  to {
36
-    transform: rotate(360deg);
37
-  }
38
-}

+ 0
- 9
src/App.test.tsx View File

@@ -1,9 +0,0 @@
1
-import React from 'react';
2
-import { render, screen } from '@testing-library/react';
3
-import App from './App';
4
-
5
-test('renders learn react link', () => {
6
-  render(<App />);
7
-  const linkElement = screen.getByText(/learn react/i);
8
-  expect(linkElement).toBeInTheDocument();
9
-});

+ 0
- 26
src/App.tsx View File

@@ -1,26 +0,0 @@
1
-import React from 'react';
2
-import logo from './logo.svg';
3
-import './App.css';
4
-
5
-function App() {
6
-  return (
7
-    <div className="App">
8
-      <header className="App-header">
9
-        <img src={logo} className="App-logo" alt="logo" />
10
-        <p>
11
-          Edit <code>src/App.tsx</code> and save to reload.
12
-        </p>
13
-        <a
14
-          className="App-link"
15
-          href="https://reactjs.org"
16
-          target="_blank"
17
-          rel="noopener noreferrer"
18
-        >
19
-          Learn React
20
-        </a>
21
-      </header>
22
-    </div>
23
-  );
24
-}
25
-
26
-export default App;

+ 37
- 0
src/Board.tsx View File

@@ -0,0 +1,37 @@
1
+import React, { useState } from 'react';
2
+import Cell from './Cell';
3
+
4
+interface Props {
5
+  width?: number;
6
+  height?: number;
7
+}
8
+
9
+const Board = (props: Props) => {
10
+  const width = props.width ?? 5;
11
+  const height = props.height ?? 5;
12
+
13
+  const initialGrid: boolean[][] = Array(height).fill(Array(width).fill(false));
14
+  const [grid, setGrid] = useState<boolean[][]>(initialGrid);
15
+
16
+  const toggle = (x: number, y: number) => {
17
+    const newGrid = [...grid];
18
+    const newRow = [...newGrid[y]];
19
+    newRow[x] = !newGrid[y][x];
20
+    newGrid[y] = newRow;
21
+    setGrid(newGrid);
22
+  };
23
+
24
+  return (
25
+    <div className="board">
26
+      {grid.map((row, y) => (
27
+        <div className="row" key={y}>
28
+          {row.map((cell, x) => (
29
+            <Cell x={x} y={y} alive={cell} toggle={toggle} key={x} />
30
+          ))}
31
+        </div>
32
+      ))}
33
+    </div>
34
+  );
35
+};
36
+
37
+export default Board;

+ 20
- 0
src/Cell.tsx View File

@@ -0,0 +1,20 @@
1
+import React from 'react';
2
+
3
+interface Props {
4
+  x: number;
5
+  y: number;
6
+  alive?: boolean;
7
+  toggle: (x: number, y: number) => void;
8
+}
9
+
10
+const Cell = (props: Props) => {
11
+  const { alive, toggle, x, y } = props;
12
+  return (
13
+    <span
14
+      onClick={() => toggle(x, y)}
15
+      className={`cell ${alive ? 'alive' : 'dead'}`}
16
+    ></span>
17
+  );
18
+};
19
+
20
+export default Cell;

+ 38
- 0
src/index.css View File

@@ -1,3 +1,8 @@
1
+* {
2
+  box-sizing: border-box;
3
+  margin: 0;
4
+  padding: 0;
5
+}
1 6
 body {
2 7
   margin: 0;
3 8
   font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
@@ -11,3 +16,36 @@ code {
11 16
   font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 17
     monospace;
13 18
 }
19
+
20
+.container {
21
+  align-items: center;
22
+  display: flex;
23
+  height: 100vh;
24
+  justify-content: center;
25
+  width: 100vw;
26
+}
27
+
28
+.row {
29
+  height: 30px;
30
+}
31
+
32
+.cell {
33
+  border: 1px solid black;
34
+  border-right: none;
35
+  border-bottom: none;
36
+  display: inline-block;
37
+  height: 30px;
38
+  width: 30px;
39
+}
40
+
41
+.row:last-child .cell {
42
+  border-bottom: 1px solid black;
43
+}
44
+
45
+.cell:last-child {
46
+  border-right: 1px solid black;
47
+}
48
+
49
+.cell.alive {
50
+  background: black;
51
+}

+ 5
- 3
src/index.tsx View File

@@ -1,14 +1,16 @@
1 1
 import React from 'react';
2 2
 import ReactDOM from 'react-dom';
3 3
 import './index.css';
4
-import App from './App';
4
+import Board from './Board';
5 5
 import reportWebVitals from './reportWebVitals';
6 6
 
7 7
 ReactDOM.render(
8 8
   <React.StrictMode>
9
-    <App />
9
+    <div className="container">
10
+      <Board />
11
+    </div>
10 12
   </React.StrictMode>,
11
-  document.getElementById('root')
13
+  document.getElementById('root'),
12 14
 );
13 15
 
14 16
 // If you want to start measuring performance in your app, pass a function

+ 3
- 9
tsconfig.json View File

@@ -1,11 +1,7 @@
1 1
 {
2 2
   "compilerOptions": {
3 3
     "target": "es5",
4
-    "lib": [
5
-      "dom",
6
-      "dom.iterable",
7
-      "esnext"
8
-    ],
4
+    "lib": ["dom", "dom.iterable", "esnext"],
9 5
     "allowJs": true,
10 6
     "skipLibCheck": true,
11 7
     "esModuleInterop": true,
@@ -18,9 +14,7 @@
18 14
     "resolveJsonModule": true,
19 15
     "isolatedModules": true,
20 16
     "noEmit": true,
21
-    "jsx": "react-jsx"
17
+    "jsx": "react"
22 18
   },
23
-  "include": [
24
-    "src"
25
-  ]
19
+  "include": ["src"]
26 20
 }

Loading…
Cancel
Save