From bde0b1f66db9c91fe8f28b24cfd4fbabb5a351cb Mon Sep 17 00:00:00 2001 From: Mikayla Dobson Date: Sat, 6 Aug 2022 14:33:48 -0500 Subject: [PATCH] computer mouse problems --- src/App.tsx | 5 +- src/components/GameConstructor.tsx | 8 +- src/components/Gameboard/Gameboard.tsx | 11 +- src/components/Gameboard/Nobles.test.ts | 144 ++++++++++++++++++ src/components/Gameboard/Nobles.tsx | 38 ++++- .../Player/ActionMethods/oldBuyCard.ts | 87 ----------- src/components/ResumeGame.tsx | 12 ++ 7 files changed, 205 insertions(+), 100 deletions(-) create mode 100644 src/components/Gameboard/Nobles.test.ts delete mode 100644 src/components/Player/ActionMethods/oldBuyCard.ts create mode 100644 src/components/ResumeGame.tsx diff --git a/src/App.tsx b/src/App.tsx index 9e78fa7..d72e35d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -5,6 +5,7 @@ import { useEffect, useState } from 'react' import Gameboard from './components/Gameboard/Gameboard' import GameConstructor from './components/GameConstructor'; import './App.css' +import ResumeGame from './components/ResumeGame'; function App() { const [state, setState] = useState(initialState); @@ -18,9 +19,11 @@ function App() {

SPLENDOR

- {/* @ts-ignore */}a + {/* @ts-ignore */} } /> {/* @ts-ignore */} + } /> + {/* @ts-ignore */} } /> diff --git a/src/components/GameConstructor.tsx b/src/components/GameConstructor.tsx index 8fe7f7f..1b020b4 100644 --- a/src/components/GameConstructor.tsx +++ b/src/components/GameConstructor.tsx @@ -1,5 +1,5 @@ import { useEffect, useState } from "react" -import { useNavigate } from "react-router-dom" +import { Link, useNavigate } from "react-router-dom" import { CardData, NobleData, PlayerData } from "../util/types"; import { StateProps } from '../util/propTypes'; @@ -103,7 +103,9 @@ export default function GameConstructor({ state, setState }: StateProps) { return (
-

Configure a new game:

+ Start a new game +

OR

+ Enter your previous game data here to pick up where you left off.
@@ -162,7 +164,7 @@ export default function GameConstructor({ state, setState }: StateProps) { handleRadio(4)} checked={starter === 3 && input.playerFour.name.length > 0}> diff --git a/src/components/Gameboard/Gameboard.tsx b/src/components/Gameboard/Gameboard.tsx index d30334a..8038a1b 100644 --- a/src/components/Gameboard/Gameboard.tsx +++ b/src/components/Gameboard/Gameboard.tsx @@ -3,7 +3,7 @@ import { AppState, ResourceCost } from '../../util/types'; import { useCallback, useEffect, useState } from 'react'; import { getChipsActions } from '../Player/ActionMethods'; import { StateProps } from '../../util/propTypes'; -const { validateChips } = getChipsActions; +import { Link } from 'react-router-dom'; // components import Nobles from './Nobles'; @@ -12,6 +12,7 @@ import AvailableChips from '../Resources/AvailableChips'; import AllPlayers from '../Player/AllPlayers'; import CardRow from '../Card/CardRow'; import SelectionView from '../Resources/SelectionView'; +const { validateChips } = getChipsActions; export default function Gameboard({ state, setState }: StateProps) { const [view, setView] = useState(

Loading...

); @@ -50,17 +51,13 @@ export default function Gameboard({ state, setState }: StateProps) { setCardRows(state); }, [state]) - useEffect(() => { - console.log(state) - }, [state]) - - // displays state of board if data is populated + // displays state of board if data is populated, otherwise points to game constructor useEffect(() => { if (!state.players.length) { setView(
Sorry! It appears we've lost track of your game data. -

Please head back to the home page to start a fresh game.

+

Please head back to the home page to start a fresh game.

); } else { diff --git a/src/components/Gameboard/Nobles.test.ts b/src/components/Gameboard/Nobles.test.ts new file mode 100644 index 0000000..fa5a676 --- /dev/null +++ b/src/components/Gameboard/Nobles.test.ts @@ -0,0 +1,144 @@ +import { describe, test } from "vitest"; +import { CardData, NobleData, PlayerData } from "../../util/types"; + +export const firstNoble: NobleData = { + points: 3, + resourceCost: { + ruby: 0, + sapphire: 0, + emerald: 0, + onyx: 0, + diamond: 3 + } + } + + export const secondNoble: NobleData = { + points: 3, + resourceCost: { + ruby: 3, + sapphire: 0, + emerald: 0, + onyx: 0, + diamond: 0 + } + } + + const exampleOneCards: CardData[] = [ + { + gemValue: "diamond", + tier: 3, + points: 0, + resourceCost: { + ruby: 0, + sapphire: 0, + emerald: 0, + onyx: 0, + diamond: 3 + } + }, + { + gemValue: "diamond", + tier: 3, + points: 1, + resourceCost: { + ruby: 0, + sapphire: 0, + emerald: 0, + onyx: 0, + diamond: 4 + } + }, + { + gemValue: "diamond", + tier: 2, + points: 2, + resourceCost: { + ruby: 0, + sapphire: 0, + emerald: 0, + onyx: 0, + diamond: 5 + } + } +] + +export const legalPlayer: PlayerData = { + name: "First example", + id: 1, + starter: true, + turnActive: true, + points: 5, + nobles: [], + cards: exampleOneCards, + reservedCards: [], + inventory: { + ruby: 0, + sapphire: 0, + emerald: 0, + onyx: 0, + diamond: 0 + } +} + +const exampleTwoCards: CardData[] = [ + { + gemValue: "ruby", + tier: 2, + points: 2, + resourceCost: { + ruby: 5, + sapphire: 0, + emerald: 0, + onyx: 0, + diamond: 0 + } + }, + { + gemValue: "ruby", + tier: 3, + points: 1, + resourceCost: { + ruby: 4, + sapphire: 0, + emerald: 0, + onyx: 0, + diamond: 0 + } + }, + { + gemValue: "ruby", + tier: 3, + points: 0, + resourceCost: { + ruby: 3, + sapphire: 0, + emerald: 0, + onyx: 0, + diamond: 0 + } + }, +] + +export const doesNotIncludeInventory: PlayerData = { + name: "second example", + id: 2, + starter: true, + turnActive: true, + points: 5, + nobles: [], + cards: exampleTwoCards, + reservedCards: [], + inventory: { + ruby: 3, + sapphire: 3, + emerald: 3, + onyx: 3, + diamond: 3, + } +} + +describe('canPickUpNoble', () => { + test('detects noble eligibility by card count', () => { + + }) +}) \ No newline at end of file diff --git a/src/components/Gameboard/Nobles.tsx b/src/components/Gameboard/Nobles.tsx index 02945df..589a855 100644 --- a/src/components/Gameboard/Nobles.tsx +++ b/src/components/Gameboard/Nobles.tsx @@ -1,8 +1,10 @@ -import { useEffect } from "react"; import { v4 } from "uuid"; -import { NobleData, ResourceCost } from "../../util/types"; +import { NobleData, PlayerData, ResourceCost } from "../../util/types"; import { StateProps } from "../../util/propTypes"; import "./Nobles.css" +import getTotalBuyingPower from "../../util/getTotalBuyingPower"; +import { useCurrentPlayer } from "../../util/useCurrentPlayer"; +import { useEffect } from "react"; export default function Nobles({ state, setState }: StateProps) { const removeNoble = (noble: NobleData) => { @@ -18,6 +20,38 @@ export default function Nobles({ state, setState }: StateProps) { }) } + const canPickUpNoble = (player: PlayerData, noble: NobleData): boolean => { + const nobleCost = noble.resourceCost; + + const totalBuyingPower = getTotalBuyingPower(player); + const playerInventory = player.inventory; + + + for (let key of Object.keys(totalBuyingPower)) { + const typedKey = key as keyof ResourceCost; + let coinValue = playerInventory[typedKey] || 0; + + if (!noble.resourceCost[typedKey]) continue; + // @ts-ignore + if ((totalBuyingPower[typedKey] - coinValue) >= noble.resourceCost[typedKey]) { + continue; + } else { + return false; + } + } + + return true; + } + + useEffect(() => { + const currentPlayer = useCurrentPlayer(state); + if (!currentPlayer) return; + + for (let each of state.gameboard.nobles) { + console.log(`${currentPlayer.name} can pick up noble ${state.gameboard.nobles.indexOf(each) + 1}? ${canPickUpNoble(currentPlayer, each) ? "yes" : "no"}`) + } + }, [state]) + return (
NOBLES diff --git a/src/components/Player/ActionMethods/oldBuyCard.ts b/src/components/Player/ActionMethods/oldBuyCard.ts deleted file mode 100644 index f9383ad..0000000 --- a/src/components/Player/ActionMethods/oldBuyCard.ts +++ /dev/null @@ -1,87 +0,0 @@ -import cardTierToKey from "../../../util/cardTierToKey"; -import { initialActions } from "../../../util/stateSetters"; -import { turnOrderUtil } from "../../../util/turnOrderUtil"; -import { AppState, CardData, PlayerData, ResourceCost, setStateType } from "../../../util/types"; -import { useCurrentPlayer } from "../../../util/useCurrentPlayer"; -import { getTotalBuyingPower } from "./buyCardActions"; - -export const buyCard = (card: CardData, state: AppState, setState: setStateType) => { - /** - * functionality: adds target card's data to current player's collection of cards, - * removes the card from the active state of the gameboard, replaces it with - * a new card in the correct tier, and runs turn order utility - * - * @param card -> the target card, @param state -> current app state - */ - - let currentPlayer = useCurrentPlayer(state); - - setState((prev: AppState) => { - if (!currentPlayer) return prev; - - const { newPlayers, roundIncrement } = turnOrderUtil(prev, currentPlayer); - let newPlayerInventory = currentPlayer.inventory; - let newResourcePool = prev.gameboard.tradingResources; - const totalBuyingPower = getTotalBuyingPower(state); - - // iterate through cost values of card to purchase - for (let [gem, cost] of Object.entries(card.resourceCost)) { - if (cost < 1) continue; - let inventoryValue = newPlayerInventory[gem as keyof ResourceCost]; - let globalResource = newResourcePool[gem as keyof ResourceCost]; - - if (!inventoryValue || !globalResource) { - continue; - } else { - let i = cost; - - // prevents duplication of resources when purchasing a card using permanent resources from cards - if (totalBuyingPower[gem as keyof ResourceCost] !== inventoryValue) { - console.log('caught'); - } - - while (i > 0) { - inventoryValue -= 1; - globalResource += 1; - i--; - } - - newResourcePool[gem as keyof ResourceCost] = globalResource; - newPlayerInventory[gem as keyof ResourceCost] = inventoryValue; - } - } - - let updatedPlayer: PlayerData = { - ...currentPlayer, - cards: [...currentPlayer.cards, card], - inventory: newPlayerInventory - } - - let newScore = 0; - for (let each of updatedPlayer.cards) { - newScore += each.points || 0; - } - - updatedPlayer.points = newScore; - const idx = newPlayers.findIndex((one: PlayerData) => one.id === currentPlayer?.id); - newPlayers[idx] = updatedPlayer; - let updatedRows = prev.gameboard.cardRows; - - if (card.tier) { - const tierKey = cardTierToKey(card.tier); - updatedRows[tierKey] = prev.gameboard.cardRows[tierKey].filter((found: CardData) => found.resourceCost !== card.resourceCost); - } - - return { - ...prev, - round: (roundIncrement ? prev.round + 1 : prev.round), - players: newPlayers, - gameboard: { - ...prev.gameboard, - tradingResources: prev.gameboard.tradingResources, - cardRows: updatedRows - }, - actions: initialActions - } - }) -} \ No newline at end of file diff --git a/src/components/ResumeGame.tsx b/src/components/ResumeGame.tsx new file mode 100644 index 0000000..b9ce53e --- /dev/null +++ b/src/components/ResumeGame.tsx @@ -0,0 +1,12 @@ +import { Link } from "react-router-dom"; +import { StateProps } from "../util/propTypes"; + +export default function ResumeGame({ state, setState }: StateProps) { + return ( +
+

Congrats! You've found an in-progress feature.

+

Check back in here later to enter a save game token to pick up a game from where you left off.

+

In the meantime, click here to head back home.

+
+ ) +} \ No newline at end of file