purchased cards removed from available face up cards, replaced with new card from deck

This commit is contained in:
2022-08-06 11:52:18 -05:00
parent 9c067172bf
commit 381027eb82
6 changed files with 54 additions and 23 deletions

View File

@@ -19,7 +19,6 @@ export default function Gameboard({ state, setState }: StateProps) {
// callbacks for lifting state // callbacks for lifting state
const liftSelection = useCallback((value: keyof ResourceCost) => { const liftSelection = useCallback((value: keyof ResourceCost) => {
if (!state.actions.getChips.active) return; if (!state.actions.getChips.active) return;
setState((prev: AppState) => { setState((prev: AppState) => {
let newSelection = prev.actions.getChips.selection; let newSelection = prev.actions.getChips.selection;
newSelection?.push(value); newSelection?.push(value);
@@ -38,7 +37,6 @@ export default function Gameboard({ state, setState }: StateProps) {
const result = validateChips(newState); const result = validateChips(newState);
newState.actions.getChips.valid = result; newState.actions.getChips.valid = result;
return newState; return newState;
}) })
}, [state]); }, [state]);

View File

@@ -1,5 +1,5 @@
import { turnOrderUtil } from "../../../util/turnOrderUtil"; import { turnOrderUtil } from "../../../util/turnOrderUtil";
import { AppState, CardData, ResourceCost, setStateType } from "../../../util/types"; import { AppState, CardData, FullDeck, ResourceCost, setStateType } from "../../../util/types";
import { useCurrentPlayer } from "../../../util/useCurrentPlayer"; import { useCurrentPlayer } from "../../../util/useCurrentPlayer";
import getTotalBuyingPower from "../../../util/getTotalBuyingPower"; import getTotalBuyingPower from "../../../util/getTotalBuyingPower";
import { initialActions } from "../../../util/stateSetters"; import { initialActions } from "../../../util/stateSetters";
@@ -24,10 +24,12 @@ export const buyCard = (state: AppState, setState: setStateType, card: CardData)
if (!currentPlayer) return; if (!currentPlayer) return;
setState((prev) => { setState((prev) => {
// shift turn order and identify current player in new player state
const { newPlayers, roundIncrement } = turnOrderUtil(prev, currentPlayer); const { newPlayers, roundIncrement } = turnOrderUtil(prev, currentPlayer);
const idx = newPlayers.indexOf(currentPlayer); const idx = newPlayers.indexOf(currentPlayer);
const updatedPlayer = newPlayers[idx]; const updatedPlayer = newPlayers[idx];
// pointers for each value to be modified
const cardCost = card.resourceCost; const cardCost = card.resourceCost;
const playerBuyingPower = getTotalBuyingPower(currentPlayer); const playerBuyingPower = getTotalBuyingPower(currentPlayer);
const newPlayerInventory = updatedPlayer.inventory; const newPlayerInventory = updatedPlayer.inventory;
@@ -35,31 +37,45 @@ export const buyCard = (state: AppState, setState: setStateType, card: CardData)
for (let key of Object.keys(cardCost)) { for (let key of Object.keys(cardCost)) {
const typedKey = key as keyof ResourceCost; const typedKey = key as keyof ResourceCost;
let adjustedCost = cardCost[typedKey]; let adjustedCost = cardCost[typedKey];
let adjustedInventoryValue = newPlayerInventory[typedKey]; let adjustedInventoryValue = newPlayerInventory[typedKey];
let adjustedResourcePoolValue = newResourcePool[typedKey]; let adjustedResourcePoolValue = newResourcePool[typedKey];
if (!adjustedCost || !adjustedInventoryValue || !adjustedResourcePoolValue) continue; if (!adjustedCost || !adjustedInventoryValue || !adjustedResourcePoolValue) continue;
// before decrementing player inventory values, account for total buying power
const buyingPowerDifference = playerBuyingPower[typedKey] - adjustedInventoryValue; const buyingPowerDifference = playerBuyingPower[typedKey] - adjustedInventoryValue;
adjustedCost -= buyingPowerDifference; adjustedCost -= buyingPowerDifference;
while (adjustedCost > 0) { while (adjustedCost > 0) {
adjustedInventoryValue--; adjustedInventoryValue--;
adjustedResourcePoolValue++; adjustedResourcePoolValue++;
adjustedCost--; adjustedCost--;
} }
// assign modified values to player inventory and resource pool
newPlayerInventory[typedKey] = adjustedInventoryValue; newPlayerInventory[typedKey] = adjustedInventoryValue;
newResourcePool[typedKey] = adjustedResourcePoolValue; newResourcePool[typedKey] = adjustedResourcePoolValue;
} }
// connect modified player state to updated list of all players
updatedPlayer.inventory = newPlayerInventory; updatedPlayer.inventory = newPlayerInventory;
updatedPlayer.cards = [...updatedPlayer.cards, card]; updatedPlayer.cards = [...updatedPlayer.cards, card];
newPlayers[idx] = updatedPlayer; newPlayers[idx] = updatedPlayer;
// attempt to queue replacement card from full deck
const typedCardTier = ["tierThree", "tierTwo", "tierOne"][card.tier + 1] as keyof FullDeck;
let newFullDeckTargetTier = prev.gameboard.deck[typedCardTier];
const replacementCard = newFullDeckTargetTier.shift();
// isolate the affected row of face up cards, remove the purchased card
let newTargetCardRow = prev.gameboard.cardRows[typedCardTier];
newTargetCardRow = newTargetCardRow.filter((data: CardData) => data.resourceCost !== card.resourceCost);
// push replacement card to face up card, if exists
if (replacementCard) newTargetCardRow.push(replacementCard);
console.log(newTargetCardRow);
console.log(newFullDeckTargetTier);
return { return {
...prev, ...prev,
players: newPlayers, players: newPlayers,
@@ -67,7 +83,15 @@ export const buyCard = (state: AppState, setState: setStateType, card: CardData)
actions: initialActions, actions: initialActions,
gameboard: { gameboard: {
...prev.gameboard, ...prev.gameboard,
tradingResources: newResourcePool tradingResources: newResourcePool,
cardRows: {
...prev.gameboard.cardRows,
[typedCardTier]: newTargetCardRow
},
deck: {
...prev.gameboard.deck,
[typedCardTier]: newFullDeckTargetTier
}
} }
} }
}) })

View File

@@ -31,9 +31,7 @@ export const reserveCard = (state: AppState, setState: setStateType, card: CardD
const updatedPlayer = { const updatedPlayer = {
...currentPlayer, ...currentPlayer,
reservedCards: currentPlayer.reservedCards ? [ reservedCards: currentPlayer.reservedCards ? [...currentPlayer.reservedCards, card] : [card],
...currentPlayer.reservedCards, card
] : [card],
inventory: goldAllowable(currentPlayer) ? { inventory: goldAllowable(currentPlayer) ? {
...currentPlayer.inventory, ...currentPlayer.inventory,
gold: currentPlayer.inventory.gold && currentPlayer.inventory.gold + 1 gold: currentPlayer.inventory.gold && currentPlayer.inventory.gold + 1

View File

@@ -1,15 +1,13 @@
import { setStateAwaitAction, setStateBuyCard, setStateGetChips, setStateReserveCard } from "../../util/stateSetters";
import { useEffect, useState } from "react";
import { PlayerProps } from "../../util/propTypes"; import { PlayerProps } from "../../util/propTypes";
import { CardData, PlayerData } from "../../util/types" import { CardData, PlayerData } from "../../util/types"
import { useEffect, useState } from "react";
import { v4 } from "uuid";
import { hasMaxReserved } from "./ActionMethods/reserveCardActions"; import { hasMaxReserved } from "./ActionMethods/reserveCardActions";
import { hasMaxChips } from "./ActionMethods/getChipsActions"; import { hasMaxChips } from "./ActionMethods/getChipsActions";
import { setStateAwaitAction, setStateBuyCard, setStateGetChips, setStateReserveCard } from "../../util/stateSetters"; import { v4 } from "uuid";
export default function Player({ player, state, setState }: PlayerProps) { export default function Player({ player, state, setState }: PlayerProps) {
const [dynamic, setDynamic] = useState<PlayerData>(); const [dynamic, setDynamic] = useState<PlayerData>();
const [prompt, setPrompt] = useState("Your turn! Select an action type below.");
const [cardView, setCardView] = useState(<p>Cards:</p>); const [cardView, setCardView] = useState(<p>Cards:</p>);
const [reservedView, setReservedView] = useState(<p>Reserved cards:</p>); const [reservedView, setReservedView] = useState(<p>Reserved cards:</p>);
@@ -60,19 +58,15 @@ export default function Player({ player, state, setState }: PlayerProps) {
switch (actionSelection) { switch (actionSelection) {
case 0: case 0:
setState((prev) => setStateGetChips(prev)); setState((prev) => setStateGetChips(prev));
setPrompt('Make your selection of up to three chips.');
break; break;
case 1: case 1:
setState((prev) => setStateBuyCard(prev)); setState((prev) => setStateBuyCard(prev));
setPrompt('Choose a card above to purchase.');
break; break;
case 2: case 2:
setState((prev) => setStateReserveCard(prev)); setState((prev) => setStateReserveCard(prev));
setPrompt('Choose a card above to reserve.');
break; break;
default: default:
setState((prev) => setStateAwaitAction(prev)); setState((prev) => setStateAwaitAction(prev));
setPrompt("Your turn! Select an action type below.");
break; break;
} }
} }
@@ -88,7 +82,7 @@ export default function Player({ player, state, setState }: PlayerProps) {
{/* Dynamic data from state */} {/* Dynamic data from state */}
<section className="turn-and-action-based"> <section className="turn-and-action-based">
<p>Score: {dynamic?.points}</p> <p>Score: {dynamic?.points}</p>
<p>{dynamic?.turnActive ? prompt : '...'}</p> <p>{dynamic?.turnActive ? "It's your turn!" : "..."}</p>
<button disabled={dynamic && hasMaxChips(dynamic)} onClick={() => handleClick(0)}>Get Chips</button> <button disabled={dynamic && hasMaxChips(dynamic)} onClick={() => handleClick(0)}>Get Chips</button>
<button onClick={() => handleClick(1)}>Buy Card</button> <button onClick={() => handleClick(1)}>Buy Card</button>
<button disabled={dynamic && hasMaxReserved(dynamic)} onClick={() => handleClick(2)}>Reserve Card</button> <button disabled={dynamic && hasMaxReserved(dynamic)} onClick={() => handleClick(2)}>Reserve Card</button>

View File

@@ -1,8 +1,11 @@
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { StateProps } from "../../util/propTypes"; import { StateProps } from "../../util/propTypes";
import { useCurrentPlayer } from "../../util/useCurrentPlayer";
import { GetChipsHTML, ReserveCardHTML } from "./ViewHTML"; import { GetChipsHTML, ReserveCardHTML } from "./ViewHTML";
export default function SelectionView({ state, setState }: StateProps) { export default function SelectionView({ state, setState }: StateProps) {
const [currentPlayer, setCurrentPlayer] = useState(useCurrentPlayer(state));
const actionTypes = [ const actionTypes = [
state.actions.getChips, state.actions.getChips,
state.actions.buyCard, state.actions.buyCard,
@@ -16,14 +19,25 @@ export default function SelectionView({ state, setState }: StateProps) {
case (actionTypes[0].active): case (actionTypes[0].active):
return <GetChipsHTML state={state} setState={setState} /> return <GetChipsHTML state={state} setState={setState} />
case (actionTypes[1].active): case (actionTypes[1].active):
return <strong>Please make your selection above:</strong>; return (
<div className="selection-view">
<h2>{currentPlayer?.name} has elected to purchase a card!</h2>
<strong>Choose a card above to purchase.</strong>
</div>
)
case (actionTypes[2].active): case (actionTypes[2].active):
return <ReserveCardHTML state={state} setState={setState} />; return <ReserveCardHTML state={state} setState={setState} />;
default: default:
return <></>; return (
<div className="selection-view">
<h2>{currentPlayer ? `It is currently ${currentPlayer.name}'s turn!` : "Loading..."}</h2>
</div>
);
} }
}) })
}, [state])
setCurrentPlayer(useCurrentPlayer(state));
}, [state, state.actions, setState])
return view return view
} }

View File

@@ -10,6 +10,7 @@ const { getChips } = getChipsActions;
export const GetChipsHTML = ({ state, setState }: StateProps) => { export const GetChipsHTML = ({ state, setState }: StateProps) => {
const [prompt, setPrompt] = useState(""); const [prompt, setPrompt] = useState("");
const currentPlayer = useCurrentPlayer(state);
useEffect(() => { useEffect(() => {
if (!state.actions.getChips.active) setPrompt(""); if (!state.actions.getChips.active) setPrompt("");
@@ -22,6 +23,7 @@ export const GetChipsHTML = ({ state, setState }: StateProps) => {
return ( return (
<div className="selection-view"> <div className="selection-view">
<h2>{currentPlayer?.name} has elected to collect resources!</h2>
<strong>{prompt}</strong> <strong>{prompt}</strong>
<div className="current-selections"> <div className="current-selections">
{ {
@@ -49,6 +51,7 @@ export const ReserveCardHTML = ({ state, setState }: StateProps) => {
return ( return (
<div className="selection-view"> <div className="selection-view">
<h2>{currentPlayer?.name} has elected to reserve a card!</h2>
<strong>Please make your selection above.</strong> <strong>Please make your selection above.</strong>
{ !hasMaxChips(currentPlayer) && ( { !hasMaxChips(currentPlayer) && (
<div className="take-gold"> <div className="take-gold">