Gameboard 041622 #3

Merged
innocuous-symmetry merged 4 commits from gameboard-041622 into main 2022-04-16 19:23:08 +00:00
17 changed files with 260 additions and 56 deletions

View File

@@ -15,6 +15,7 @@
"react-dom": "^18.0.0",
"react-router-dom": "^6.2.2",
"react-scripts": "5.0.0",
"uuid": "^8.3.2",
"web-vitals": "^2.1.4"
}
},

View File

@@ -10,6 +10,7 @@
"react-dom": "^18.0.0",
"react-router-dom": "^6.2.2",
"react-scripts": "5.0.0",
"uuid": "^8.3.2",
"web-vitals": "^2.1.4"
},
"scripts": {

View File

@@ -1,38 +1,14 @@
.App {
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;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.gameboard {
display: flex;
flex-direction: column;
width: 95vw;
height: 75vh;
}

View File

@@ -2,18 +2,21 @@ import './App.css';
import { Routes, Route, BrowserRouter } from 'react-router-dom';
import Welcome from './components/Welcome';
import GameBoard from './components/Game/GameBoard';
import FulLGameView from './components/Game/FullGameView';
import Store from './store/Store';
function App() {
return (
<div className="App">
<BrowserRouter>
<Routes>
<Route path="/" element={<Welcome />}/>
<Route path="/gameboard" element={<GameBoard />}/>
</Routes>
</BrowserRouter>
</div>
<Store>
<div className="App">
<BrowserRouter>
<Routes>
<Route path="/" element={<Welcome />}/>
<Route path="/gameboard" element={<FulLGameView />}/>
</Routes>
</BrowserRouter>
</div>
</Store>
);
}

View File

@@ -0,0 +1,9 @@
import GameBoard from "./GameBoard";
export default function FulLGameView() {
return (
<>
<GameBoard />
</>
)
}

View File

@@ -1,22 +1,24 @@
import { useContext, useEffect, useState } from 'react';
import { Context } from '../../store/Store';
import '../../styles/GameBoard.css';
import { useEffect, useState } from 'react';
import Card from '../Cards/Card';
import { TierOneDeck } from '../../store/TierOneDeck';
import { TierTwoDeck } from '../../store/TierTwoDeck';
import { TierThreeDeck } from '../../store/TierThreeDeck';
import {v4} from 'uuid';
export default function GameBoard() {
const [state, dispatch] = useContext(Context);
const [trigger, setTrigger] = useState(true);
const [tierThree, setTierThree] = useState(null);
const [tierTwo, setTierTwo] = useState(null);
const [tierOne, setTierOne] = useState(null);
const [content, setContent] = useState(null);
const AllDecks = [TierOneDeck, TierTwoDeck, TierThreeDeck];
useEffect(() => {
const AllDecks = [TierOneDeck, TierTwoDeck, TierThreeDeck];
// param limit sets limit on number of cards rendered
// param tier filters by card tier
const buildGameBoardRow = (limit, tier) => {
@@ -26,7 +28,7 @@ export default function GameBoard() {
iter++;
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) {
@@ -57,7 +59,19 @@ export default function GameBoard() {
return (
<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">
{tierThree || 'Loading'}

View File

@@ -1,4 +1,4 @@
import Card from "./Card";
import Card from "../Cards/Card";
export default class Inventory {
constructor(state) {

View File

@@ -0,0 +1,11 @@
import { useState } from "react"
export default function PlayerInventory({ name }) {
const [materials, setMaterials] = useState(null);
return (
<>
</>
)
}

View 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
}
},
]

View File

@@ -2,6 +2,7 @@ export default function CpuMultiForm() {
return (
<form className="local-multi-form">
<h1>AI and stuff?</h1>
<h2>Coming soon!</h2>
</form>
)
}

View File

@@ -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() {
const [state, dispatch] = useContext(Context);
const navigate = useNavigate();
const [players, setPlayers] = useState(null);
const [formVariant, setFormVariant] = useState(null);
const [playerOne, setPlayerOne] = useState('');
@@ -8,6 +13,8 @@ export default function LocalMultiForm() {
const [playerThree, setPlayerThree] = useState('');
const [playerFour, setPlayerFour] = useState('');
const allPlayerNames = [playerOne, playerTwo, playerThree, playerFour];
const formVariants = [
<> { /* Fragment, expects to be concatenated as necessary within a <form> element */ }
{ /* Player one and two base; index 0 */ }
@@ -46,6 +53,43 @@ export default function LocalMultiForm() {
break;
}
}, [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 (
<>
@@ -69,6 +113,8 @@ export default function LocalMultiForm() {
<form className="player-input" style={{paddingBottom: '1rem'}}>
{formVariant}
</form>
<button onClick={handleStartGame}>Start game</button>
<button onClick={() => dispatch({type: "PRINT PLAYERS"})}>Get Players</button>
</>
)
}

View File

@@ -1,8 +1,11 @@
import { useState, useRef } from "react"
import { useState, useRef, useContext } from "react"
import LocalMultiForm from "./GameConfigForms/LocalMultiForm";
import CpuMultiForm from "./GameConfigForms/CpuMultiForm";
import { Context } from "../store/Store";
export default function Welcome() {
const [state, dispatch] = useContext(Context);
const [localMulti, setLocalMulti] = useState(false);
const [cpuMulti, setCpuMulti] = useState(false);
@@ -50,7 +53,7 @@ export default function Welcome() {
</form>
{localMulti ? <LocalMultiForm /> : null}
{cpuMulti ? <CpuMultiForm /> : null}
{cpuMulti ? <CpuMultiForm /> : null}
<button onClick={handleClear}>Clear form input</button>
</>

View File

@@ -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);

View File

@@ -1,9 +1,6 @@
.gameboard {
display: flex;
flex-direction: column;
}
.gameboard-title {
text-decoration: none;
font-size: 2rem;
font-weight: bold;
}

27
package-lock.json generated Normal file
View 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
View File

@@ -0,0 +1,5 @@
{
"dependencies": {
"uuid": "^8.3.2"
}
}