Merge pull request #3 from innocuous-symmetry/gameboard-041622
Gameboard 041622
This commit is contained in:
1
client/package-lock.json
generated
1
client/package-lock.json
generated
@@ -15,6 +15,7 @@
|
|||||||
"react-dom": "^18.0.0",
|
"react-dom": "^18.0.0",
|
||||||
"react-router-dom": "^6.2.2",
|
"react-router-dom": "^6.2.2",
|
||||||
"react-scripts": "5.0.0",
|
"react-scripts": "5.0.0",
|
||||||
|
"uuid": "^8.3.2",
|
||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^2.1.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
"react-dom": "^18.0.0",
|
"react-dom": "^18.0.0",
|
||||||
"react-router-dom": "^6.2.2",
|
"react-router-dom": "^6.2.2",
|
||||||
"react-scripts": "5.0.0",
|
"react-scripts": "5.0.0",
|
||||||
|
"uuid": "^8.3.2",
|
||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^2.1.4"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -1,38 +1,14 @@
|
|||||||
.App {
|
.App {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
|
||||||
|
|
||||||
.App-logo {
|
|
||||||
height: 40vmin;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-reduced-motion: no-preference) {
|
|
||||||
.App-logo {
|
|
||||||
animation: App-logo-spin infinite 20s linear;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.App-header {
|
|
||||||
background-color: #282c34;
|
|
||||||
min-height: 100vh;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: calc(10px + 2vmin);
|
|
||||||
color: white;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.App-link {
|
.gameboard {
|
||||||
color: #61dafb;
|
display: flex;
|
||||||
}
|
flex-direction: column;
|
||||||
|
width: 95vw;
|
||||||
@keyframes App-logo-spin {
|
height: 75vh;
|
||||||
from {
|
}
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,18 +2,21 @@ import './App.css';
|
|||||||
import { Routes, Route, BrowserRouter } from 'react-router-dom';
|
import { Routes, Route, BrowserRouter } from 'react-router-dom';
|
||||||
|
|
||||||
import Welcome from './components/Welcome';
|
import Welcome from './components/Welcome';
|
||||||
import GameBoard from './components/Game/GameBoard';
|
import FulLGameView from './components/Game/FullGameView';
|
||||||
|
import Store from './store/Store';
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
<div className="App">
|
<Store>
|
||||||
<BrowserRouter>
|
<div className="App">
|
||||||
<Routes>
|
<BrowserRouter>
|
||||||
<Route path="/" element={<Welcome />}/>
|
<Routes>
|
||||||
<Route path="/gameboard" element={<GameBoard />}/>
|
<Route path="/" element={<Welcome />}/>
|
||||||
</Routes>
|
<Route path="/gameboard" element={<FulLGameView />}/>
|
||||||
</BrowserRouter>
|
</Routes>
|
||||||
</div>
|
</BrowserRouter>
|
||||||
|
</div>
|
||||||
|
</Store>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
9
client/src/components/Game/FullGameView.js
Normal file
9
client/src/components/Game/FullGameView.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import GameBoard from "./GameBoard";
|
||||||
|
|
||||||
|
export default function FulLGameView() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<GameBoard />
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,22 +1,24 @@
|
|||||||
|
import { useContext, useEffect, useState } from 'react';
|
||||||
|
import { Context } from '../../store/Store';
|
||||||
import '../../styles/GameBoard.css';
|
import '../../styles/GameBoard.css';
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
|
|
||||||
import Card from '../Cards/Card';
|
import Card from '../Cards/Card';
|
||||||
import { TierOneDeck } from '../../store/TierOneDeck';
|
import { TierOneDeck } from '../../store/TierOneDeck';
|
||||||
import { TierTwoDeck } from '../../store/TierTwoDeck';
|
import { TierTwoDeck } from '../../store/TierTwoDeck';
|
||||||
import { TierThreeDeck } from '../../store/TierThreeDeck';
|
import { TierThreeDeck } from '../../store/TierThreeDeck';
|
||||||
|
|
||||||
|
import {v4} from 'uuid';
|
||||||
|
|
||||||
export default function GameBoard() {
|
export default function GameBoard() {
|
||||||
|
const [state, dispatch] = useContext(Context);
|
||||||
|
|
||||||
const [trigger, setTrigger] = useState(true);
|
const [trigger, setTrigger] = useState(true);
|
||||||
const [tierThree, setTierThree] = useState(null);
|
const [tierThree, setTierThree] = useState(null);
|
||||||
const [tierTwo, setTierTwo] = useState(null);
|
const [tierTwo, setTierTwo] = useState(null);
|
||||||
const [tierOne, setTierOne] = useState(null);
|
const [tierOne, setTierOne] = useState(null);
|
||||||
|
|
||||||
const [content, setContent] = useState(null);
|
|
||||||
|
|
||||||
const AllDecks = [TierOneDeck, TierTwoDeck, TierThreeDeck];
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
const AllDecks = [TierOneDeck, TierTwoDeck, TierThreeDeck];
|
||||||
|
|
||||||
// param limit sets limit on number of cards rendered
|
// param limit sets limit on number of cards rendered
|
||||||
// param tier filters by card tier
|
// param tier filters by card tier
|
||||||
const buildGameBoardRow = (limit, tier) => {
|
const buildGameBoardRow = (limit, tier) => {
|
||||||
@@ -26,7 +28,7 @@ export default function GameBoard() {
|
|||||||
iter++;
|
iter++;
|
||||||
|
|
||||||
if (!AllDecks[tier-1][iter-1]) continue;
|
if (!AllDecks[tier-1][iter-1]) continue;
|
||||||
newBoard.push(<Card state={AllDecks[tier-1][iter-1]} />);
|
newBoard.push(<Card key={`card-${v4()}`}state={AllDecks[tier-1][iter-1]} />);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (tier) {
|
switch (tier) {
|
||||||
@@ -57,7 +59,19 @@ export default function GameBoard() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="gameboard">
|
<div className="gameboard">
|
||||||
<h1 className="gameboard-title">SPLINTER</h1>
|
<a href='/' className="gameboard-title">SPLINTER</a>
|
||||||
|
<div>
|
||||||
|
<h2>Players:</h2>
|
||||||
|
{state.players.map(player => {
|
||||||
|
return (
|
||||||
|
<div className="player-info">
|
||||||
|
<p>{player.name}</p>
|
||||||
|
<p>{player.points && `Score: ${player.points}`}</p>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="gameboard-row">
|
<div className="gameboard-row">
|
||||||
{tierThree || 'Loading'}
|
{tierThree || 'Loading'}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import Card from "./Card";
|
import Card from "../Cards/Card";
|
||||||
|
|
||||||
export default class Inventory {
|
export default class Inventory {
|
||||||
constructor(state) {
|
constructor(state) {
|
||||||
11
client/src/components/Game/PlayerInventory.js
Normal file
11
client/src/components/Game/PlayerInventory.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { useState } from "react"
|
||||||
|
|
||||||
|
export default function PlayerInventory({ name }) {
|
||||||
|
const [materials, setMaterials] = useState(null);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
52
client/src/components/Game/Spirits.js
Normal file
52
client/src/components/Game/Spirits.js
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
export const Spirits = [
|
||||||
|
{
|
||||||
|
img: 'img src',
|
||||||
|
cost: {
|
||||||
|
cedar: 7,
|
||||||
|
birch: 0,
|
||||||
|
walnut: 0,
|
||||||
|
mahogany: 0,
|
||||||
|
cherry: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
img: 'img src',
|
||||||
|
cost: {
|
||||||
|
cedar: 7,
|
||||||
|
birch: 0,
|
||||||
|
walnut: 0,
|
||||||
|
mahogany: 0,
|
||||||
|
cherry: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
img: 'img src',
|
||||||
|
cost: {
|
||||||
|
cedar: 7,
|
||||||
|
birch: 0,
|
||||||
|
walnut: 0,
|
||||||
|
mahogany: 0,
|
||||||
|
cherry: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
img: 'img src',
|
||||||
|
cost: {
|
||||||
|
cedar: 7,
|
||||||
|
birch: 0,
|
||||||
|
walnut: 0,
|
||||||
|
mahogany: 0,
|
||||||
|
cherry: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
img: 'img src',
|
||||||
|
cost: {
|
||||||
|
cedar: 7,
|
||||||
|
birch: 0,
|
||||||
|
walnut: 0,
|
||||||
|
mahogany: 0,
|
||||||
|
cherry: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
]
|
||||||
@@ -2,6 +2,7 @@ export default function CpuMultiForm() {
|
|||||||
return (
|
return (
|
||||||
<form className="local-multi-form">
|
<form className="local-multi-form">
|
||||||
<h1>AI and stuff?</h1>
|
<h1>AI and stuff?</h1>
|
||||||
|
<h2>Coming soon!</h2>
|
||||||
</form>
|
</form>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,11 @@
|
|||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect, useContext } from "react";
|
||||||
|
import { Context } from "../../store/Store";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
export default function LocalMultiForm() {
|
export default function LocalMultiForm() {
|
||||||
|
const [state, dispatch] = useContext(Context);
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const [players, setPlayers] = useState(null);
|
const [players, setPlayers] = useState(null);
|
||||||
const [formVariant, setFormVariant] = useState(null);
|
const [formVariant, setFormVariant] = useState(null);
|
||||||
const [playerOne, setPlayerOne] = useState('');
|
const [playerOne, setPlayerOne] = useState('');
|
||||||
@@ -8,6 +13,8 @@ export default function LocalMultiForm() {
|
|||||||
const [playerThree, setPlayerThree] = useState('');
|
const [playerThree, setPlayerThree] = useState('');
|
||||||
const [playerFour, setPlayerFour] = useState('');
|
const [playerFour, setPlayerFour] = useState('');
|
||||||
|
|
||||||
|
const allPlayerNames = [playerOne, playerTwo, playerThree, playerFour];
|
||||||
|
|
||||||
const formVariants = [
|
const formVariants = [
|
||||||
<> { /* Fragment, expects to be concatenated as necessary within a <form> element */ }
|
<> { /* Fragment, expects to be concatenated as necessary within a <form> element */ }
|
||||||
{ /* Player one and two base; index 0 */ }
|
{ /* Player one and two base; index 0 */ }
|
||||||
@@ -46,6 +53,43 @@ export default function LocalMultiForm() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}, [players]);
|
}, [players]);
|
||||||
|
|
||||||
|
const handleStartGame = () => {
|
||||||
|
let toSubmit = [];
|
||||||
|
let iter = 0;
|
||||||
|
while (iter < players) {
|
||||||
|
toSubmit.push({
|
||||||
|
name: allPlayerNames[iter],
|
||||||
|
tokens: {
|
||||||
|
cedar: 0,
|
||||||
|
birch: 0,
|
||||||
|
walnut: 0,
|
||||||
|
mahogany: 0,
|
||||||
|
cherry: 0,
|
||||||
|
resin: 0,
|
||||||
|
},
|
||||||
|
cards: {
|
||||||
|
cedar: 0,
|
||||||
|
birch: 0,
|
||||||
|
walnut: 0,
|
||||||
|
mahogany: 0,
|
||||||
|
cherry: 0,
|
||||||
|
},
|
||||||
|
points: 0,
|
||||||
|
spirits: 0,
|
||||||
|
});
|
||||||
|
iter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toSubmit.length < players) return;
|
||||||
|
|
||||||
|
for (let item of toSubmit) {
|
||||||
|
if (!item) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch({ type: "ADD PLAYERS", payload: toSubmit });
|
||||||
|
navigate('/gameboard');
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -69,6 +113,8 @@ export default function LocalMultiForm() {
|
|||||||
<form className="player-input" style={{paddingBottom: '1rem'}}>
|
<form className="player-input" style={{paddingBottom: '1rem'}}>
|
||||||
{formVariant}
|
{formVariant}
|
||||||
</form>
|
</form>
|
||||||
|
<button onClick={handleStartGame}>Start game</button>
|
||||||
|
<button onClick={() => dispatch({type: "PRINT PLAYERS"})}>Get Players</button>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
import { useState, useRef } from "react"
|
import { useState, useRef, useContext } from "react"
|
||||||
import LocalMultiForm from "./GameConfigForms/LocalMultiForm";
|
import LocalMultiForm from "./GameConfigForms/LocalMultiForm";
|
||||||
import CpuMultiForm from "./GameConfigForms/CpuMultiForm";
|
import CpuMultiForm from "./GameConfigForms/CpuMultiForm";
|
||||||
|
import { Context } from "../store/Store";
|
||||||
|
|
||||||
export default function Welcome() {
|
export default function Welcome() {
|
||||||
|
const [state, dispatch] = useContext(Context);
|
||||||
|
|
||||||
const [localMulti, setLocalMulti] = useState(false);
|
const [localMulti, setLocalMulti] = useState(false);
|
||||||
const [cpuMulti, setCpuMulti] = useState(false);
|
const [cpuMulti, setCpuMulti] = useState(false);
|
||||||
|
|
||||||
@@ -50,7 +53,7 @@ export default function Welcome() {
|
|||||||
</form>
|
</form>
|
||||||
|
|
||||||
{localMulti ? <LocalMultiForm /> : null}
|
{localMulti ? <LocalMultiForm /> : null}
|
||||||
{cpuMulti ? <CpuMultiForm /> : null}
|
{cpuMulti ? <CpuMultiForm /> : null}
|
||||||
|
|
||||||
<button onClick={handleClear}>Clear form input</button>
|
<button onClick={handleClear}>Clear form input</button>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
import { useReducer, createContext } from "react"
|
||||||
|
|
||||||
|
import { TierOneDeck } from './TierOneDeck';
|
||||||
|
import { TierTwoDeck } from './TierTwoDeck';
|
||||||
|
import { TierThreeDeck } from './TierThreeDeck';
|
||||||
|
import { Spirits } from '../components/Game/Spirits';
|
||||||
|
|
||||||
|
const initialGameState = {
|
||||||
|
players: [{name: 'no players', inventory: null, cards: null}],
|
||||||
|
materials: {
|
||||||
|
cards: {
|
||||||
|
tierOneRemaining: TierOneDeck,
|
||||||
|
tierTwoRemaining: TierTwoDeck,
|
||||||
|
tierThreeRemaining: TierThreeDeck,
|
||||||
|
},
|
||||||
|
tokens: {
|
||||||
|
cedar: 7,
|
||||||
|
birch: 7,
|
||||||
|
walnut: 7,
|
||||||
|
mahogany: 7,
|
||||||
|
cherry: 7,
|
||||||
|
resin: 5,
|
||||||
|
},
|
||||||
|
spirits: [...Spirits]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const reducer = (state, action) => {
|
||||||
|
switch (action.type) {
|
||||||
|
case "GET PLAYERS":
|
||||||
|
return state;
|
||||||
|
case "ADD PLAYERS":
|
||||||
|
state.players = action.payload;
|
||||||
|
return state;
|
||||||
|
case "UPDATE PLAYER MATERIALS":
|
||||||
|
// find player in array of players and update their resources
|
||||||
|
// update list of available materials in state
|
||||||
|
break;
|
||||||
|
case "PRINT PLAYERS":
|
||||||
|
console.log(state.players);
|
||||||
|
return state;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default function Store({ children }) {
|
||||||
|
const [state, dispatch] = useReducer(reducer, initialGameState);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Context.Provider value={[state, dispatch]}>
|
||||||
|
{ children }
|
||||||
|
</Context.Provider>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Context = createContext(initialGameState);
|
||||||
@@ -1,9 +1,6 @@
|
|||||||
.gameboard {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gameboard-title {
|
.gameboard-title {
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 2rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
27
package-lock.json
generated
Normal file
27
package-lock.json
generated
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"name": "splinter",
|
||||||
|
"lockfileVersion": 2,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"dependencies": {
|
||||||
|
"uuid": "^8.3.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/uuid": {
|
||||||
|
"version": "8.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||||
|
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
||||||
|
"bin": {
|
||||||
|
"uuid": "dist/bin/uuid"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"uuid": {
|
||||||
|
"version": "8.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||||
|
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
5
package.json
Normal file
5
package.json
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"uuid": "^8.3.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user