From dc603c891a53851205bdc2a609bac499d28d8129 Mon Sep 17 00:00:00 2001 From: Mikayla Dobson <93477693+innocuous-symmetry@users.noreply.github.com> Date: Sun, 24 Jul 2022 10:10:40 -0500 Subject: [PATCH 1/7] incorporating actions and chip selection into state --- src/App.tsx | 5 ++ .../{Gameboard => Card}/CardRow.css | 0 .../{Gameboard => Card}/CardRow.tsx | 0 src/components/Gameboard/Gameboard.tsx | 86 ++++++++----------- src/components/Resources/AvailableChips.tsx | 10 ++- src/util/GameConstructor.tsx | 1 - src/util/initializeBoard.ts | 48 +++++++++++ src/util/types.d.ts | 24 +++++- 8 files changed, 117 insertions(+), 57 deletions(-) rename src/components/{Gameboard => Card}/CardRow.css (100%) rename src/components/{Gameboard => Card}/CardRow.tsx (100%) create mode 100644 src/util/initializeBoard.ts diff --git a/src/App.tsx b/src/App.tsx index f586ed3..f5af205 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -27,6 +27,11 @@ function App() { }, round: 1, players: new Array, + actions: { + buyCard: { active: false }, + getChips: { active: false }, + reserveCard: { active: false } + } }) return ( diff --git a/src/components/Gameboard/CardRow.css b/src/components/Card/CardRow.css similarity index 100% rename from src/components/Gameboard/CardRow.css rename to src/components/Card/CardRow.css diff --git a/src/components/Gameboard/CardRow.tsx b/src/components/Card/CardRow.tsx similarity index 100% rename from src/components/Gameboard/CardRow.tsx rename to src/components/Card/CardRow.tsx diff --git a/src/components/Gameboard/Gameboard.tsx b/src/components/Gameboard/Gameboard.tsx index 88078f2..e755057 100644 --- a/src/components/Gameboard/Gameboard.tsx +++ b/src/components/Gameboard/Gameboard.tsx @@ -1,18 +1,44 @@ -import { Dispatch, SetStateAction, useEffect, useState } from 'react'; -import { CardData, FullDeck, NobleData, StateProps } from '../../util/types'; -import AllPlayers from '../Player/AllPlayers'; +import { useCallback, useEffect, useState } from 'react'; +import { AppState, ResourceCost, StateProps } from '../../util/types'; +import initializeBoard from '../../util/initializeBoard'; import AvailableChips from '../Resources/AvailableChips'; -import CardRow from './CardRow'; +import AllPlayers from '../Player/AllPlayers'; +import CardRow from '../Card/CardRow'; import Nobles from './Nobles'; -import NobleStore from '../../data/nobles.json'; export default function Gameboard({ state, setState }: StateProps) { - const [view, setView] = useState(

Loading...

) + const [view, setView] = useState(

Loading...

); + const [selection, setSelection] = useState(); + // callback for lifting state + const liftSelection = useCallback((value: keyof ResourceCost) => { + if (!state.actions.getChips.active) return; + + setState((prev: AppState) => { + let newSelection = prev.actions.getChips.selection; + newSelection?.push(value); + + return { + ...prev, + actions: { + ...state.actions, + getChips: { + active: true, + selection: newSelection + } + } + } + }) + + console.log(state); + }, []); + + // util functions to set up initial board useEffect(() => { - initializeBoard(); + initializeBoard(state, setState); }, []) + // displays state of board if data is populated useEffect(() => { if (!state.players.length) { setView( @@ -36,50 +62,6 @@ export default function Gameboard({ state, setState }: StateProps) { } }, [state]); - const shuffleDeck = () => { - if (!state.gameboard.deck) return; - let newDeck: FullDeck = state.gameboard.deck; - - for (const [key, value] of Object.entries(newDeck)) { - for (let i = value.length - 1; i > 0; i--) { - const j = Math.floor(Math.random() * (i + 1)) - const temp = value[i]; - value[i] = value[j]; - value[j] = temp; - } - } - - setState({ ...state, gameboard: { ...state.gameboard, deck: newDeck }}) - } - - const setNobles = () => { - let newNobles = NobleStore.nobles; - let shuffledNobles = new Array; - - while (shuffledNobles.length < 4) { - const rand = Math.floor(Math.random() * newNobles.length); - const randNoble = newNobles.splice(rand,1)[0]; - shuffledNobles.push(randNoble); - } - - setState({ ...state, gameboard: { ...state.gameboard, nobles: shuffledNobles }}) - } - - const initializeBoard = () => { - shuffleDeck(); - - let newDeck = state.gameboard.cardRows; - for (const [key, value] of Object.entries(state.gameboard.deck)) { - while (newDeck[key as keyof FullDeck].length < 4) { - // @ts-ignore - const nextCard = value.shift(); - newDeck[key as keyof FullDeck].push(nextCard); - } - } - - setState({ ...state, gameboard: { ...state.gameboard, cardRows: newDeck } }) - setNobles(); - } - + // render return view } \ No newline at end of file diff --git a/src/components/Resources/AvailableChips.tsx b/src/components/Resources/AvailableChips.tsx index baaad0a..2bb97de 100644 --- a/src/components/Resources/AvailableChips.tsx +++ b/src/components/Resources/AvailableChips.tsx @@ -1,9 +1,11 @@ import { ResourceCost, StateProps } from "../../util/types"; import { v4 } from "uuid"; import "./AvailableChips.css" -import { useEffect } from "react"; +import { useEffect, useState } from "react"; + +export default function AvailableChips({ state, setState }: StateProps) { + const [selection, setSelection] = useState([]); -export default function AvailableChips({ state }: StateProps) { useEffect(() => { return; }, [state]) @@ -14,7 +16,9 @@ export default function AvailableChips({ state }: StateProps) { Object.keys(state.gameboard.tradingResources).map((key: string) => { return (
-

{key}: {state.gameboard.tradingResources[key as keyof ResourceCost]}

+
) }) diff --git a/src/util/GameConstructor.tsx b/src/util/GameConstructor.tsx index 2946eb3..d110c7b 100644 --- a/src/util/GameConstructor.tsx +++ b/src/util/GameConstructor.tsx @@ -1,6 +1,5 @@ import { useEffect, useState } from "react" import { useNavigate } from "react-router-dom" -import { v4 } from "uuid"; import { CardData, NobleData, PlayerData, StateProps } from "./types"; interface InputState { diff --git a/src/util/initializeBoard.ts b/src/util/initializeBoard.ts new file mode 100644 index 0000000..718e8f4 --- /dev/null +++ b/src/util/initializeBoard.ts @@ -0,0 +1,48 @@ +import { Dispatch, SetStateAction } from "react"; +import { AppState, FullDeck, NobleData } from "./types"; +import NobleStore from '../data/nobles.json'; + +const shuffleDeck = (state: AppState, setState: Dispatch>) => { + if (!state.gameboard.deck) return; + let newDeck: FullDeck = state.gameboard.deck; + + for (const [key, value] of Object.entries(newDeck)) { + for (let i = value.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)) + const temp = value[i]; + value[i] = value[j]; + value[j] = temp; + } + } + + setState({ ...state, gameboard: { ...state.gameboard, deck: newDeck }}) +} + +const setNobles = (state: AppState, setState: Dispatch>) => { + let newNobles = NobleStore.nobles; + let shuffledNobles = new Array; + + while (shuffledNobles.length < 4) { + const rand = Math.floor(Math.random() * newNobles.length); + const randNoble = newNobles.splice(rand,1)[0]; + shuffledNobles.push(randNoble); + } + + setState({ ...state, gameboard: { ...state.gameboard, nobles: shuffledNobles }}) +} + +export default function initializeBoard(state: AppState, setState: Dispatch>) { + shuffleDeck(state, setState); + + let newDeck = state.gameboard.cardRows; + for (const [key, value] of Object.entries(state.gameboard.deck)) { + while (newDeck[key as keyof FullDeck].length < 4) { + // @ts-ignore + const nextCard = value.shift(); + newDeck[key as keyof FullDeck].push(nextCard); + } + } + + setState({ ...state, gameboard: { ...state.gameboard, cardRows: newDeck } }) + setNobles(state, setState); +} \ No newline at end of file diff --git a/src/util/types.d.ts b/src/util/types.d.ts index bd11f8e..1df47f8 100644 --- a/src/util/types.d.ts +++ b/src/util/types.d.ts @@ -13,7 +13,29 @@ export interface AppState { deck: FullDeck, }, round: number, - players: Array + players: Array, + actions: StateActions +} + +interface StateActions { + getChips: { + active: boolean + selection?: Array + valid?: boolean + confirm: () => void + } + buyCard: { + active: boolean + selection?: CardData + valid?: boolean + confirm: () => void + } + reserveCard: { + active: boolean + selection?: CardData + includeGold?: boolean + confirm: () => void + } } export interface StateProps { From 30425cde9106c9c293189c61a4fc36b408045fe2 Mon Sep 17 00:00:00 2001 From: Mikayla Dobson <93477693+innocuous-symmetry@users.noreply.github.com> Date: Sun, 24 Jul 2022 10:15:06 -0500 Subject: [PATCH 2/7] resource selection lifted to gameboard state --- src/components/Gameboard/Gameboard.tsx | 4 +++- src/components/Resources/AvailableChips.tsx | 14 ++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/components/Gameboard/Gameboard.tsx b/src/components/Gameboard/Gameboard.tsx index e755057..44eca43 100644 --- a/src/components/Gameboard/Gameboard.tsx +++ b/src/components/Gameboard/Gameboard.tsx @@ -12,6 +12,8 @@ export default function Gameboard({ state, setState }: StateProps) { // callback for lifting state const liftSelection = useCallback((value: keyof ResourceCost) => { + console.log(value) + if (!state.actions.getChips.active) return; setState((prev: AppState) => { @@ -55,7 +57,7 @@ export default function Gameboard({ state, setState }: StateProps) { - + ) diff --git a/src/components/Resources/AvailableChips.tsx b/src/components/Resources/AvailableChips.tsx index 2bb97de..394c915 100644 --- a/src/components/Resources/AvailableChips.tsx +++ b/src/components/Resources/AvailableChips.tsx @@ -1,11 +1,13 @@ import { ResourceCost, StateProps } from "../../util/types"; import { v4 } from "uuid"; import "./AvailableChips.css" -import { useEffect, useState } from "react"; +import { useEffect } from "react"; -export default function AvailableChips({ state, setState }: StateProps) { - const [selection, setSelection] = useState([]); +interface ResourceProps extends StateProps { + liftSelection: (value: keyof ResourceCost) => void +} +export default function AvailableChips({ state, setState, liftSelection }: ResourceProps) { useEffect(() => { return; }, [state]) @@ -13,11 +15,11 @@ export default function AvailableChips({ state, setState }: StateProps) { return (
{ - Object.keys(state.gameboard.tradingResources).map((key: string) => { + Object.keys(state.gameboard.tradingResources).map((key: string | keyof ResourceCost) => { return (
-
) From 00b2442598baa8d1722daf0384b5de90df674d83 Mon Sep 17 00:00:00 2001 From: Mikayla Dobson <93477693+innocuous-symmetry@users.noreply.github.com> Date: Sun, 24 Jul 2022 11:09:31 -0500 Subject: [PATCH 3/7] action types being passed between components --- src/App.tsx | 34 ++------------ src/components/Gameboard/Gameboard.tsx | 13 ++++-- src/components/Player/ActionMethods.ts | 31 +++++++++++++ src/components/Player/AllPlayers.tsx | 10 ++-- src/components/Player/Player.tsx | 51 ++++++++++----------- src/components/Resources/AvailableChips.tsx | 4 +- src/util/initialState.ts | 29 ++++++++++++ src/util/initializeBoard.ts | 9 ++-- src/util/{types.d.ts => types.ts} | 21 ++++++--- 9 files changed, 125 insertions(+), 77 deletions(-) create mode 100644 src/components/Player/ActionMethods.ts create mode 100644 src/util/initialState.ts rename src/util/{types.d.ts => types.ts} (85%) diff --git a/src/App.tsx b/src/App.tsx index f5af205..9784a1e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,45 +1,21 @@ -import { BrowserRouter, Routes, Route } from 'react-router-dom' import { useState } from 'react' +import { BrowserRouter, Routes, Route } from 'react-router-dom' import Gameboard from './components/Gameboard/Gameboard' import GameConstructor from './util/GameConstructor'; -import { PlayerData, NobleData, CardData } from './util/types'; -import CardDeck from './data/cards.json'; +import { initialState } from './util/initialState'; import './App.css' function App() { - const [state, setState] = useState({ - gameboard: { - nobles: new Array, - cardRows: { - tierOne: new Array, - tierTwo: new Array, - tierThree: new Array, - }, - tradingResources: { - ruby: 7, - sapphire: 7, - emerald: 7, - diamond: 7, - onyx: 7, - gold: 5 - }, - deck: CardDeck, - }, - round: 1, - players: new Array, - actions: { - buyCard: { active: false }, - getChips: { active: false }, - reserveCard: { active: false } - } - }) + const [state, setState] = useState(initialState); return (

SPLENDOR

+ {/* @ts-ignore */} } /> + {/* @ts-ignore */} } /> diff --git a/src/components/Gameboard/Gameboard.tsx b/src/components/Gameboard/Gameboard.tsx index 44eca43..0450325 100644 --- a/src/components/Gameboard/Gameboard.tsx +++ b/src/components/Gameboard/Gameboard.tsx @@ -1,5 +1,5 @@ import { useCallback, useEffect, useState } from 'react'; -import { AppState, ResourceCost, StateProps } from '../../util/types'; +import { AppState, PlayerData, ResourceCost, SetActionType, StateProps } from '../../util/types'; import initializeBoard from '../../util/initializeBoard'; import AvailableChips from '../Resources/AvailableChips'; import AllPlayers from '../Player/AllPlayers'; @@ -8,9 +8,8 @@ import Nobles from './Nobles'; export default function Gameboard({ state, setState }: StateProps) { const [view, setView] = useState(

Loading...

); - const [selection, setSelection] = useState(); - // callback for lifting state + // callbacks for lifting state const liftSelection = useCallback((value: keyof ResourceCost) => { console.log(value) @@ -35,6 +34,11 @@ export default function Gameboard({ state, setState }: StateProps) { console.log(state); }, []); + const setActionState = useCallback((value: SetActionType, player: PlayerData) => { + if (!player?.turnActive) return; + console.log(player.name + SetActionType[value]); + }, []); + // util functions to set up initial board useEffect(() => { initializeBoard(state, setState); @@ -58,7 +62,8 @@ export default function Gameboard({ state, setState }: StateProps) { - + {/* @ts-ignore */} +
) } diff --git a/src/components/Player/ActionMethods.ts b/src/components/Player/ActionMethods.ts new file mode 100644 index 0000000..97268a0 --- /dev/null +++ b/src/components/Player/ActionMethods.ts @@ -0,0 +1,31 @@ +import { AppState, PlayerData, ResourceCost, setStateType } from "../../util/types"; +import { TurnOrderUtil } from "../../util/TurnOrderUtil"; + +export const getChips = (resource: string, dynamic: PlayerData | undefined, setState: setStateType) => { + if (!dynamic || !dynamic?.turnActive) return; + + setState((prev: AppState) => { + const { newPlayers, roundIncrement } = TurnOrderUtil(prev, dynamic); + + return { + ...prev, + round: (roundIncrement ? prev.round + 1 : prev.round), + gameboard: { + ...prev.gameboard, + tradingResources: { + ...prev.gameboard.tradingResources, + [resource as keyof ResourceCost]: prev.gameboard.tradingResources[resource as keyof ResourceCost] -= 1 + } + }, + players: newPlayers + } + }) +} + +export const buyCard = () => { + return; +} + +export const reserveCard = () => { + return; +} \ No newline at end of file diff --git a/src/components/Player/AllPlayers.tsx b/src/components/Player/AllPlayers.tsx index 1378695..4e90b62 100644 --- a/src/components/Player/AllPlayers.tsx +++ b/src/components/Player/AllPlayers.tsx @@ -1,13 +1,17 @@ import Player from "./Player"; import { v4 } from "uuid"; import "./AllPlayers.css" -import { PlayerData, StateProps } from "../../util/types"; +import { PlayerData, SetActionType, StateProps } from "../../util/types"; -export default function AllPlayers({ state, setState }: StateProps) { +interface AllPlayersProps extends StateProps { + setActionState: (value: SetActionType, player?: PlayerData) => void +} + +export default function AllPlayers({ state, setState, setActionState }: AllPlayersProps) { return (
{ - state.players?.map((player: PlayerData) => ) + state.players?.map((player: PlayerData) => ) }
) diff --git a/src/components/Player/Player.tsx b/src/components/Player/Player.tsx index 26e168e..6dab0c0 100644 --- a/src/components/Player/Player.tsx +++ b/src/components/Player/Player.tsx @@ -1,38 +1,31 @@ -import { AppState, PlayerData, ResourceCost, StateProps } from "../../util/types" -import { v4 } from "uuid"; +import { PlayerData, SetActionType, StateProps } from "../../util/types" import { useEffect, useState } from "react"; -import { TurnOrderUtil } from "../../util/TurnOrderUtil"; +import { getChips } from "./ActionMethods"; +import { v4 } from "uuid"; interface PlayerProps extends StateProps { - player: PlayerData + player: PlayerData, + setActionState: (value: SetActionType, player?: PlayerData) => void } -export default function Player({ player, state, setState }: PlayerProps) { +export default function Player({ player, state, setState, setActionState }: PlayerProps) { const [dynamic, setDynamic] = useState(); - useEffect(() => { - setDynamic(state.players.find((element: PlayerData) => element.id === player.id)); - }, [state]); + useEffect(() => setDynamic(state.players.find((element: PlayerData) => element.id === player.id)), [state]); - const getChips = (resource: string) => { - if (!dynamic?.turnActive) return; - - setState((prev: AppState) => { - const { newPlayers, roundIncrement } = TurnOrderUtil(prev, dynamic); - - return { - ...prev, - round: (roundIncrement ? prev.round + 1 : prev.round), - gameboard: { - ...prev.gameboard, - tradingResources: { - ...prev.gameboard.tradingResources, - [resource as keyof ResourceCost]: prev.gameboard.tradingResources[resource as keyof ResourceCost] -= 1 - } - }, - players: newPlayers - } - }) + const handleSelection = (input: number) => { + switch (input) { + case 0: + setActionState(SetActionType.GETCHIPS, player); + getChips('ruby', dynamic, setState); + break; + case 1: + setActionState(SetActionType.BUYCARD, player); + break; + default: + setActionState(SetActionType.AWAIT, player); + break; + } } return ( @@ -44,7 +37,9 @@ export default function Player({ player, state, setState }: PlayerProps) { {/* Dynamic data from state */}

{dynamic?.turnActive ? "My turn!" : "..."}

- + + +
diff --git a/src/components/Resources/AvailableChips.tsx b/src/components/Resources/AvailableChips.tsx index 394c915..32c0a79 100644 --- a/src/components/Resources/AvailableChips.tsx +++ b/src/components/Resources/AvailableChips.tsx @@ -1,7 +1,7 @@ import { ResourceCost, StateProps } from "../../util/types"; +import { useEffect } from "react"; import { v4 } from "uuid"; import "./AvailableChips.css" -import { useEffect } from "react"; interface ResourceProps extends StateProps { liftSelection: (value: keyof ResourceCost) => void @@ -19,7 +19,7 @@ export default function AvailableChips({ state, setState, liftSelection }: Resou return (
) diff --git a/src/util/initialState.ts b/src/util/initialState.ts new file mode 100644 index 0000000..d718873 --- /dev/null +++ b/src/util/initialState.ts @@ -0,0 +1,29 @@ +import { CardData, NobleData, PlayerData } from "./types"; +import CardDeck from '../data/cards.json'; + +export const initialState = { + gameboard: { + nobles: new Array, + cardRows: { + tierOne: new Array, + tierTwo: new Array, + tierThree: new Array, + }, + tradingResources: { + ruby: 7, + sapphire: 7, + emerald: 7, + diamond: 7, + onyx: 7, + gold: 5 + }, + deck: CardDeck, + }, + round: 1, + players: new Array, + actions: { + buyCard: { active: false }, + getChips: { active: false }, + reserveCard: { active: false } + } +} \ No newline at end of file diff --git a/src/util/initializeBoard.ts b/src/util/initializeBoard.ts index 718e8f4..21699c9 100644 --- a/src/util/initializeBoard.ts +++ b/src/util/initializeBoard.ts @@ -1,8 +1,7 @@ -import { Dispatch, SetStateAction } from "react"; -import { AppState, FullDeck, NobleData } from "./types"; +import { AppState, FullDeck, NobleData, setStateType } from "./types"; import NobleStore from '../data/nobles.json'; -const shuffleDeck = (state: AppState, setState: Dispatch>) => { +const shuffleDeck = (state: AppState, setState: setStateType) => { if (!state.gameboard.deck) return; let newDeck: FullDeck = state.gameboard.deck; @@ -18,7 +17,7 @@ const shuffleDeck = (state: AppState, setState: Dispatch>) => { +const setNobles = (state: AppState, setState: setStateType) => { let newNobles = NobleStore.nobles; let shuffledNobles = new Array; @@ -31,7 +30,7 @@ const setNobles = (state: AppState, setState: Dispatch> setState({ ...state, gameboard: { ...state.gameboard, nobles: shuffledNobles }}) } -export default function initializeBoard(state: AppState, setState: Dispatch>) { +export default function initializeBoard(state: AppState, setState: setStateType) { shuffleDeck(state, setState); let newDeck = state.gameboard.cardRows; diff --git a/src/util/types.d.ts b/src/util/types.ts similarity index 85% rename from src/util/types.d.ts rename to src/util/types.ts index 1df47f8..d2dbd71 100644 --- a/src/util/types.d.ts +++ b/src/util/types.ts @@ -1,5 +1,4 @@ import { Dispatch, SetStateAction } from "react" -import { AppState } from "../context/types" export interface AppState { gameboard: { @@ -18,29 +17,39 @@ export interface AppState { } interface StateActions { + setAction?: (arg: SetActionType) => void getChips: { active: boolean selection?: Array valid?: boolean - confirm: () => void + confirm?: () => void } buyCard: { active: boolean selection?: CardData valid?: boolean - confirm: () => void + confirm?: () => void } reserveCard: { active: boolean selection?: CardData includeGold?: boolean - confirm: () => void + confirm?: () => void } } +export enum SetActionType { + GETCHIPS, + BUYCARD, + RESERVECARD, + AWAIT +} + +export type setStateType = Dispatch> + export interface StateProps { state: AppState, - setState: Dispatch> + setState: setStateType } export interface GameInformation { @@ -98,4 +107,4 @@ export enum GemValue { diamond, onyx, gold, -} +} \ No newline at end of file From 33736c6659c1c25735143aa9538067e3bd3ade6f Mon Sep 17 00:00:00 2001 From: Mikayla Dobson <93477693+innocuous-symmetry@users.noreply.github.com> Date: Sun, 24 Jul 2022 11:36:37 -0500 Subject: [PATCH 4/7] in progress: ui prompt on player component --- src/App.tsx | 2 +- src/components/Gameboard/Gameboard.tsx | 32 +++++++++--- src/components/Player/ActionMethods.ts | 2 +- src/components/Player/Player.tsx | 43 +++++++++------- src/util/initialState.ts | 29 ----------- src/util/stateSetters.ts | 70 ++++++++++++++++++++++++++ src/util/types.ts | 1 + 7 files changed, 123 insertions(+), 56 deletions(-) delete mode 100644 src/util/initialState.ts create mode 100644 src/util/stateSetters.ts diff --git a/src/App.tsx b/src/App.tsx index 9784a1e..b8a5d75 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,7 +2,7 @@ import { useState } from 'react' import { BrowserRouter, Routes, Route } from 'react-router-dom' import Gameboard from './components/Gameboard/Gameboard' import GameConstructor from './util/GameConstructor'; -import { initialState } from './util/initialState'; +import { initialState } from './util/stateSetters'; import './App.css' function App() { diff --git a/src/components/Gameboard/Gameboard.tsx b/src/components/Gameboard/Gameboard.tsx index 0450325..16a338a 100644 --- a/src/components/Gameboard/Gameboard.tsx +++ b/src/components/Gameboard/Gameboard.tsx @@ -1,10 +1,14 @@ -import { useCallback, useEffect, useState } from 'react'; +// types, data, utils import { AppState, PlayerData, ResourceCost, SetActionType, StateProps } from '../../util/types'; +import { setStateBuyCard, setStateGetChips, setStateReserveCard } from '../../util/stateSetters'; +import { useCallback, useEffect, useState } from 'react'; +import Nobles from './Nobles'; + +// components import initializeBoard from '../../util/initializeBoard'; import AvailableChips from '../Resources/AvailableChips'; import AllPlayers from '../Player/AllPlayers'; import CardRow from '../Card/CardRow'; -import Nobles from './Nobles'; export default function Gameboard({ state, setState }: StateProps) { const [view, setView] = useState(

Loading...

); @@ -30,16 +34,27 @@ export default function Gameboard({ state, setState }: StateProps) { } } }) - - console.log(state); }, []); const setActionState = useCallback((value: SetActionType, player: PlayerData) => { if (!player?.turnActive) return; - console.log(player.name + SetActionType[value]); + + switch (value) { + case 0: + if (!state.actions.getChips.active) setState((prev) => setStateGetChips(prev)); + break; + case 1: + if (!state.actions.buyCard.active) setState((prev) => setStateBuyCard(prev)); + break; + case 2: + if (!state.actions.reserveCard.active) setState((prev) => setStateReserveCard(prev)); + break; + default: + break; + } }, []); - // util functions to set up initial board + // util functions, setup on mount useEffect(() => { initializeBoard(state, setState); }, []) @@ -69,6 +84,11 @@ export default function Gameboard({ state, setState }: StateProps) { } }, [state]); + // DEBUG + useEffect(() => { + console.log(state); + }, [state]) + // render return view } \ No newline at end of file diff --git a/src/components/Player/ActionMethods.ts b/src/components/Player/ActionMethods.ts index 97268a0..31c03df 100644 --- a/src/components/Player/ActionMethods.ts +++ b/src/components/Player/ActionMethods.ts @@ -1,7 +1,7 @@ import { AppState, PlayerData, ResourceCost, setStateType } from "../../util/types"; import { TurnOrderUtil } from "../../util/TurnOrderUtil"; -export const getChips = (resource: string, dynamic: PlayerData | undefined, setState: setStateType) => { +export const getChips = (resource: string | Array, dynamic: PlayerData | undefined, setState: setStateType) => { if (!dynamic || !dynamic?.turnActive) return; setState((prev: AppState) => { diff --git a/src/components/Player/Player.tsx b/src/components/Player/Player.tsx index 6dab0c0..34af27d 100644 --- a/src/components/Player/Player.tsx +++ b/src/components/Player/Player.tsx @@ -1,6 +1,5 @@ import { PlayerData, SetActionType, StateProps } from "../../util/types" import { useEffect, useState } from "react"; -import { getChips } from "./ActionMethods"; import { v4 } from "uuid"; interface PlayerProps extends StateProps { @@ -10,23 +9,29 @@ interface PlayerProps extends StateProps { export default function Player({ player, state, setState, setActionState }: PlayerProps) { const [dynamic, setDynamic] = useState(); + const [prompt, setPrompt] = useState("My turn!"); + const [actionSelection, setActionSelection] = useState(-1); useEffect(() => setDynamic(state.players.find((element: PlayerData) => element.id === player.id)), [state]); - const handleSelection = (input: number) => { - switch (input) { - case 0: - setActionState(SetActionType.GETCHIPS, player); - getChips('ruby', dynamic, setState); - break; - case 1: - setActionState(SetActionType.BUYCARD, player); - break; - default: - setActionState(SetActionType.AWAIT, player); - break; - } - } + useEffect(() => { + setActionState(actionSelection, dynamic); + setPrompt(() => { + switch (actionSelection) { + case -1: + return "My turn!" + case 0: + return "Select up to three different chips, or two of the same color." + case 1: + return "Buy a card from the ones above using your available resources." + case 2: + return "Choose a card from the ones above to reserve for later purchase. \ + If you have less than ten chips, you may also pick up a gold chip." + default: + return "" + } + }) + }, [actionSelection, prompt]) return (
@@ -36,10 +41,10 @@ export default function Player({ player, state, setState, setActionState }: Play

Is {player.starter || "not"} round starter

{/* Dynamic data from state */} -

{dynamic?.turnActive ? "My turn!" : "..."}

- - - + {dynamic?.turnActive ?

{prompt}

:

...

} + + +
diff --git a/src/util/initialState.ts b/src/util/initialState.ts deleted file mode 100644 index d718873..0000000 --- a/src/util/initialState.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { CardData, NobleData, PlayerData } from "./types"; -import CardDeck from '../data/cards.json'; - -export const initialState = { - gameboard: { - nobles: new Array, - cardRows: { - tierOne: new Array, - tierTwo: new Array, - tierThree: new Array, - }, - tradingResources: { - ruby: 7, - sapphire: 7, - emerald: 7, - diamond: 7, - onyx: 7, - gold: 5 - }, - deck: CardDeck, - }, - round: 1, - players: new Array, - actions: { - buyCard: { active: false }, - getChips: { active: false }, - reserveCard: { active: false } - } -} \ No newline at end of file diff --git a/src/util/stateSetters.ts b/src/util/stateSetters.ts new file mode 100644 index 0000000..6fe152f --- /dev/null +++ b/src/util/stateSetters.ts @@ -0,0 +1,70 @@ +import { AppState, CardData, NobleData, PlayerData, ResourceCost } from "./types"; +import CardDeck from '../data/cards.json'; + +export const initialState = { + gameboard: { + nobles: new Array, + cardRows: { + tierOne: new Array, + tierTwo: new Array, + tierThree: new Array, + }, + tradingResources: { + ruby: 7, + sapphire: 7, + emerald: 7, + diamond: 7, + onyx: 7, + gold: 5 + }, + deck: CardDeck, + }, + round: 1, + players: new Array, + actions: { + buyCard: { active: false }, + getChips: { active: false }, + reserveCard: { active: false } + } +} + +export const setStateGetChips = (prev: AppState) => { + return { + ...prev, + actions: { + ...initialState.actions, + getChips: { + active: true, + selection: new Array, + valid: false + } + } + } +} + +export const setStateBuyCard = (prev: AppState) => { + return { + ...prev, + actions: { + ...initialState.actions, + buyCard: { + active: true, + valid: false + } + } + } +} + +export const setStateReserveCard = (prev: AppState) => { + return { + ...prev, + actions: { + ...initialState.actions, + reserveCard: { + active: true, + includeGold: false, + valid: false + } + } + } +} \ No newline at end of file diff --git a/src/util/types.ts b/src/util/types.ts index d2dbd71..96a8a1e 100644 --- a/src/util/types.ts +++ b/src/util/types.ts @@ -34,6 +34,7 @@ interface StateActions { active: boolean selection?: CardData includeGold?: boolean + valid?: boolean confirm?: () => void } } From f6ce03a8dcb58009e68c32cee1e46b09813482be Mon Sep 17 00:00:00 2001 From: Mikayla Dobson <93477693+innocuous-symmetry@users.noreply.github.com> Date: Sun, 24 Jul 2022 12:56:11 -0500 Subject: [PATCH 5/7] chip selection validator works as expected --- src/App.tsx | 2 +- src/{util => components}/GameConstructor.tsx | 2 +- src/components/Gameboard/Gameboard.tsx | 18 ++++++----- src/components/Player/ActionMethods.ts | 34 ++++++++++++++++++-- src/components/Player/Player.tsx | 31 ++++++++---------- src/components/Resources/AvailableChips.tsx | 7 ++++ src/util/TurnOrderUtil.ts | 2 +- 7 files changed, 64 insertions(+), 32 deletions(-) rename src/{util => components}/GameConstructor.tsx (98%) diff --git a/src/App.tsx b/src/App.tsx index b8a5d75..6534161 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,7 +1,7 @@ import { useState } from 'react' import { BrowserRouter, Routes, Route } from 'react-router-dom' import Gameboard from './components/Gameboard/Gameboard' -import GameConstructor from './util/GameConstructor'; +import GameConstructor from './components/GameConstructor'; import { initialState } from './util/stateSetters'; import './App.css' diff --git a/src/util/GameConstructor.tsx b/src/components/GameConstructor.tsx similarity index 98% rename from src/util/GameConstructor.tsx rename to src/components/GameConstructor.tsx index d110c7b..1b4a3eb 100644 --- a/src/util/GameConstructor.tsx +++ b/src/components/GameConstructor.tsx @@ -1,6 +1,6 @@ import { useEffect, useState } from "react" import { useNavigate } from "react-router-dom" -import { CardData, NobleData, PlayerData, StateProps } from "./types"; +import { CardData, NobleData, PlayerData, StateProps } from "../util/types"; interface InputState { playerOne: PlayerInput diff --git a/src/components/Gameboard/Gameboard.tsx b/src/components/Gameboard/Gameboard.tsx index 16a338a..3cefb8e 100644 --- a/src/components/Gameboard/Gameboard.tsx +++ b/src/components/Gameboard/Gameboard.tsx @@ -9,6 +9,7 @@ import initializeBoard from '../../util/initializeBoard'; import AvailableChips from '../Resources/AvailableChips'; import AllPlayers from '../Player/AllPlayers'; import CardRow from '../Card/CardRow'; +import { validateChips } from '../Player/ActionMethods'; export default function Gameboard({ state, setState }: StateProps) { const [view, setView] = useState(

Loading...

); @@ -23,18 +24,24 @@ export default function Gameboard({ state, setState }: StateProps) { let newSelection = prev.actions.getChips.selection; newSelection?.push(value); - return { + let newState = { ...prev, actions: { ...state.actions, getChips: { active: true, - selection: newSelection + selection: newSelection, + valid: false } } } + + const result = validateChips(newState); + newState.actions.getChips.valid = result; + + return newState; }) - }, []); + }, [state]); const setActionState = useCallback((value: SetActionType, player: PlayerData) => { if (!player?.turnActive) return; @@ -84,11 +91,6 @@ export default function Gameboard({ state, setState }: StateProps) { } }, [state]); - // DEBUG - useEffect(() => { - console.log(state); - }, [state]) - // render return view } \ No newline at end of file diff --git a/src/components/Player/ActionMethods.ts b/src/components/Player/ActionMethods.ts index 31c03df..ebe1b8d 100644 --- a/src/components/Player/ActionMethods.ts +++ b/src/components/Player/ActionMethods.ts @@ -1,11 +1,11 @@ import { AppState, PlayerData, ResourceCost, setStateType } from "../../util/types"; -import { TurnOrderUtil } from "../../util/TurnOrderUtil"; +import { turnOrderUtil } from "../../util/TurnOrderUtil"; -export const getChips = (resource: string | Array, dynamic: PlayerData | undefined, setState: setStateType) => { +export const _getChips = (resource: string | Array, dynamic: PlayerData | undefined, setState: setStateType) => { if (!dynamic || !dynamic?.turnActive) return; setState((prev: AppState) => { - const { newPlayers, roundIncrement } = TurnOrderUtil(prev, dynamic); + const { newPlayers, roundIncrement } = turnOrderUtil(prev, dynamic); return { ...prev, @@ -22,6 +22,34 @@ export const getChips = (resource: string | Array, dynamic: }) } +export const validateChips = (state: AppState): boolean => { + if (!state.actions.getChips.active || !state.actions.getChips.selection) return false; + + const selection = state.actions.getChips.selection; + + if (selection.length < 2 || selection.length > 3) return false; + const unique = new Set(selection); + + if (selection.length === 3 && selection.length > unique.size) return false; + return true; +} + +export const getChips = (state: AppState, setState: setStateType): boolean => { + /** + * features: + * identify player to receive currently selected chips + * update their inventory state + * update the total available resources + * change turn order + */ + + setState((prev: AppState) => { + return prev; + }) + + return true; +} + export const buyCard = () => { return; } diff --git a/src/components/Player/Player.tsx b/src/components/Player/Player.tsx index 34af27d..56f2aad 100644 --- a/src/components/Player/Player.tsx +++ b/src/components/Player/Player.tsx @@ -9,29 +9,24 @@ interface PlayerProps extends StateProps { export default function Player({ player, state, setState, setActionState }: PlayerProps) { const [dynamic, setDynamic] = useState(); - const [prompt, setPrompt] = useState("My turn!"); + const [prompt, setPrompt] = useState("Your turn! Select an action type below."); const [actionSelection, setActionSelection] = useState(-1); useEffect(() => setDynamic(state.players.find((element: PlayerData) => element.id === player.id)), [state]); useEffect(() => { setActionState(actionSelection, dynamic); - setPrompt(() => { - switch (actionSelection) { - case -1: - return "My turn!" - case 0: - return "Select up to three different chips, or two of the same color." - case 1: - return "Buy a card from the ones above using your available resources." - case 2: - return "Choose a card from the ones above to reserve for later purchase. \ - If you have less than ten chips, you may also pick up a gold chip." - default: - return "" - } - }) - }, [actionSelection, prompt]) + + if (state.actions.getChips.active) { + setPrompt('Make your selection of up to three chips.'); + } else if (state.actions.buyCard.active) { + setPrompt('Choose a card above to purchase.'); + } else if (state.actions.reserveCard.active) { + setPrompt('Choose a card above to reserve.'); + } else { + setPrompt("Your turn! Select an action type below."); + } + }, [actionSelection]) return (
@@ -41,7 +36,7 @@ export default function Player({ player, state, setState, setActionState }: Play

Is {player.starter || "not"} round starter

{/* Dynamic data from state */} - {dynamic?.turnActive ?

{prompt}

:

...

} +

{dynamic?.turnActive ? prompt : '...'}

diff --git a/src/components/Resources/AvailableChips.tsx b/src/components/Resources/AvailableChips.tsx index 32c0a79..fd8c441 100644 --- a/src/components/Resources/AvailableChips.tsx +++ b/src/components/Resources/AvailableChips.tsx @@ -2,6 +2,7 @@ import { ResourceCost, StateProps } from "../../util/types"; import { useEffect } from "react"; import { v4 } from "uuid"; import "./AvailableChips.css" +import { setStateGetChips } from "../../util/stateSetters"; interface ResourceProps extends StateProps { liftSelection: (value: keyof ResourceCost) => void @@ -14,6 +15,11 @@ export default function AvailableChips({ state, setState, liftSelection }: Resou return (
+ {state.actions.getChips.active &&

Your selection is {state.actions.getChips.valid || "not"} valid

} + { + state.actions.getChips.active && + state.actions.getChips.selection?.map((each) =>

{each}

) + } { Object.keys(state.gameboard.tradingResources).map((key: string | keyof ResourceCost) => { return ( @@ -25,6 +31,7 @@ export default function AvailableChips({ state, setState, liftSelection }: Resou ) }) } +
) } \ No newline at end of file diff --git a/src/util/TurnOrderUtil.ts b/src/util/TurnOrderUtil.ts index d28439f..f895ec8 100644 --- a/src/util/TurnOrderUtil.ts +++ b/src/util/TurnOrderUtil.ts @@ -1,6 +1,6 @@ import { AppState, PlayerData } from "./types"; -export const TurnOrderUtil = (prev: AppState, dynamic: PlayerData) => { +export const turnOrderUtil = (prev: AppState, dynamic: PlayerData) => { let roundIncrement = false; const newPlayers = prev.players; From a073304659941fac661721e3ea3947a2d6251d7d Mon Sep 17 00:00:00 2001 From: Mikayla Dobson <93477693+innocuous-symmetry@users.noreply.github.com> Date: Sun, 24 Jul 2022 13:44:46 -0500 Subject: [PATCH 6/7] state setter formats --- src/components/Gameboard/Gameboard.tsx | 4 +-- src/components/Player/ActionMethods.ts | 27 +++++++++++++-- src/components/Resources/AvailableChips.tsx | 6 ---- src/components/Resources/SelectionView.tsx | 38 +++++++++++++++++++++ src/components/Resources/ViewHTML.tsx | 36 +++++++++++++++++++ src/util/TurnOrderUtil.ts | 1 + src/util/stateSetters.ts | 17 ++++++--- 7 files changed, 114 insertions(+), 15 deletions(-) create mode 100644 src/components/Resources/SelectionView.tsx create mode 100644 src/components/Resources/ViewHTML.tsx diff --git a/src/components/Gameboard/Gameboard.tsx b/src/components/Gameboard/Gameboard.tsx index 3cefb8e..c942fe8 100644 --- a/src/components/Gameboard/Gameboard.tsx +++ b/src/components/Gameboard/Gameboard.tsx @@ -10,14 +10,13 @@ import AvailableChips from '../Resources/AvailableChips'; import AllPlayers from '../Player/AllPlayers'; import CardRow from '../Card/CardRow'; import { validateChips } from '../Player/ActionMethods'; +import SelectionView from '../Resources/SelectionView'; export default function Gameboard({ state, setState }: StateProps) { const [view, setView] = useState(

Loading...

); // callbacks for lifting state const liftSelection = useCallback((value: keyof ResourceCost) => { - console.log(value) - if (!state.actions.getChips.active) return; setState((prev: AppState) => { @@ -83,6 +82,7 @@ export default function Gameboard({ state, setState }: StateProps) { + {/* @ts-ignore */} diff --git a/src/components/Player/ActionMethods.ts b/src/components/Player/ActionMethods.ts index ebe1b8d..65d6477 100644 --- a/src/components/Player/ActionMethods.ts +++ b/src/components/Player/ActionMethods.ts @@ -1,5 +1,6 @@ import { AppState, PlayerData, ResourceCost, setStateType } from "../../util/types"; import { turnOrderUtil } from "../../util/TurnOrderUtil"; +import { initialActions } from "../../util/stateSetters"; export const _getChips = (resource: string | Array, dynamic: PlayerData | undefined, setState: setStateType) => { if (!dynamic || !dynamic?.turnActive) return; @@ -27,7 +28,7 @@ export const validateChips = (state: AppState): boolean => { const selection = state.actions.getChips.selection; - if (selection.length < 2 || selection.length > 3) return false; + if (selection.length === 0 || selection.length > 3) return false; const unique = new Set(selection); if (selection.length === 3 && selection.length > unique.size) return false; @@ -43,8 +44,28 @@ export const getChips = (state: AppState, setState: setStateType): boolean => { * change turn order */ - setState((prev: AppState) => { - return prev; + let targetPlayer: PlayerData; + + for (let each in state.players) { + if (state.players[each].turnActive) { + targetPlayer = state.players[each]; + } + } + + setState((prev) => { + const { newPlayers, roundIncrement } = turnOrderUtil(state, targetPlayer); + + console.log(newPlayers[newPlayers.indexOf(targetPlayer)]); + + return { + ...prev, + round: (roundIncrement ? prev.round + 1 : prev.round), + gameboard: { + ...prev.gameboard + }, + players: newPlayers, + actions: initialActions + } }) return true; diff --git a/src/components/Resources/AvailableChips.tsx b/src/components/Resources/AvailableChips.tsx index fd8c441..98639c9 100644 --- a/src/components/Resources/AvailableChips.tsx +++ b/src/components/Resources/AvailableChips.tsx @@ -15,11 +15,6 @@ export default function AvailableChips({ state, setState, liftSelection }: Resou return (
- {state.actions.getChips.active &&

Your selection is {state.actions.getChips.valid || "not"} valid

} - { - state.actions.getChips.active && - state.actions.getChips.selection?.map((each) =>

{each}

) - } { Object.keys(state.gameboard.tradingResources).map((key: string | keyof ResourceCost) => { return ( @@ -31,7 +26,6 @@ export default function AvailableChips({ state, setState, liftSelection }: Resou ) }) } -
) } \ No newline at end of file diff --git a/src/components/Resources/SelectionView.tsx b/src/components/Resources/SelectionView.tsx new file mode 100644 index 0000000..c359a35 --- /dev/null +++ b/src/components/Resources/SelectionView.tsx @@ -0,0 +1,38 @@ +import { v4 } from "uuid"; +import { useEffect, useState } from "react"; +import { ResourceCost, StateProps } from "../../util/types"; +import { setStateGetChips } from "../../util/stateSetters"; +import { GetChipsHTML } from "./ViewHTML"; + +export default function SelectionView({ state, setState }: StateProps) { + const actionTypes = [ + state.actions.getChips, + state.actions.buyCard, + state.actions.reserveCard + ] + const [view, setView] = useState(<>); + + useEffect(() => { + setView(() => { + switch (true) { + case (actionTypes[0].active): + return + case (actionTypes[1].active): + return ( + <> + {actionTypes[1].active && Your selection is {actionTypes[1].valid || "not"} valid} +

Card will display here

+ + ) + default: + return <>; + } + }) + }, [state]) + + return ( +
+ { view } +
+ ) +} \ No newline at end of file diff --git a/src/components/Resources/ViewHTML.tsx b/src/components/Resources/ViewHTML.tsx new file mode 100644 index 0000000..d42a3f4 --- /dev/null +++ b/src/components/Resources/ViewHTML.tsx @@ -0,0 +1,36 @@ +import { v4 } from "uuid"; +import { useEffect, useState } from "react"; +import { setStateGetChips } from "../../util/stateSetters"; +import { ResourceCost, StateProps } from "../../util/types"; +import { getChips } from "../Player/ActionMethods"; + +export const GetChipsHTML = ({ state, setState }: StateProps) => { + const [prompt, setPrompt] = useState(""); + + useEffect(() => { + if (!state.actions.getChips.active) setPrompt(""); + if (state.actions.getChips.selection?.length === 0) { + setPrompt("Please make a selection."); + } else { + setPrompt(`Your selection is ${state.actions.getChips.valid ? '' : "not"} valid`); + } + }, [state]) + + return ( +
+ {prompt} +
+ { + state.actions.getChips.active && + state.actions.getChips.selection?.map((each: keyof ResourceCost) =>

{each}

) + } +
+ { + state.actions.getChips.valid ? + + : + + } +
+ ) +} \ No newline at end of file diff --git a/src/util/TurnOrderUtil.ts b/src/util/TurnOrderUtil.ts index f895ec8..64af43f 100644 --- a/src/util/TurnOrderUtil.ts +++ b/src/util/TurnOrderUtil.ts @@ -5,6 +5,7 @@ export const turnOrderUtil = (prev: AppState, dynamic: PlayerData) => { const newPlayers = prev.players; for (let each of newPlayers) { + console.log(each); if (each.id === dynamic.id) { each.turnActive = false; } else if (each.id === dynamic.id + 1) { diff --git a/src/util/stateSetters.ts b/src/util/stateSetters.ts index 6fe152f..c3f8852 100644 --- a/src/util/stateSetters.ts +++ b/src/util/stateSetters.ts @@ -1,6 +1,12 @@ import { AppState, CardData, NobleData, PlayerData, ResourceCost } from "./types"; import CardDeck from '../data/cards.json'; +export const initialActions = { + buyCard: { active: false }, + getChips: { active: false }, + reserveCard: { active: false } +} + export const initialState = { gameboard: { nobles: new Array, @@ -21,10 +27,13 @@ export const initialState = { }, round: 1, players: new Array, - actions: { - buyCard: { active: false }, - getChips: { active: false }, - reserveCard: { active: false } + actions: initialActions +} + +export const setStateAwaitAction = (prev: AppState) => { + return { + ...prev, + actions: initialActions } } From efc99555878f96e80c98924af576ba0dc06ed306 Mon Sep 17 00:00:00 2001 From: Mikayla Dobson <93477693+innocuous-symmetry@users.noreply.github.com> Date: Sun, 24 Jul 2022 13:58:43 -0500 Subject: [PATCH 7/7] global resource stockpile updates as well --- src/components/Player/ActionMethods.ts | 31 ++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/components/Player/ActionMethods.ts b/src/components/Player/ActionMethods.ts index 65d6477..f6e46d2 100644 --- a/src/components/Player/ActionMethods.ts +++ b/src/components/Player/ActionMethods.ts @@ -38,10 +38,8 @@ export const validateChips = (state: AppState): boolean => { export const getChips = (state: AppState, setState: setStateType): boolean => { /** * features: - * identify player to receive currently selected chips * update their inventory state * update the total available resources - * change turn order */ let targetPlayer: PlayerData; @@ -54,20 +52,45 @@ export const getChips = (state: AppState, setState: setStateType): boolean => { setState((prev) => { const { newPlayers, roundIncrement } = turnOrderUtil(state, targetPlayer); + const idx = newPlayers.indexOf(targetPlayer); + const resources = state.actions.getChips.selection; + let newResources = prev.gameboard.tradingResources; + + if (resources) { + for (let value of resources) { + + // update player inventory + for (let each in newPlayers[idx].inventory) { + if (value === each) { + newPlayers[idx].inventory[value] += 1; + } + } + + // update globally available resources + for (let each in newResources) { + if (value === each) { + newResources[value] -= 1; + } + } + } + + } - console.log(newPlayers[newPlayers.indexOf(targetPlayer)]); return { ...prev, round: (roundIncrement ? prev.round + 1 : prev.round), gameboard: { - ...prev.gameboard + ...prev.gameboard, + tradingResources: newResources }, players: newPlayers, actions: initialActions } }) + console.log(state.players); + return true; }