computer mouse problems

This commit is contained in:
2022-08-06 14:33:48 -05:00
parent 8fba7605b4
commit bde0b1f66d
7 changed files with 205 additions and 100 deletions

View File

@@ -5,6 +5,7 @@ import { useEffect, useState } from 'react'
import Gameboard from './components/Gameboard/Gameboard' import Gameboard from './components/Gameboard/Gameboard'
import GameConstructor from './components/GameConstructor'; import GameConstructor from './components/GameConstructor';
import './App.css' import './App.css'
import ResumeGame from './components/ResumeGame';
function App() { function App() {
const [state, setState] = useState(initialState); const [state, setState] = useState(initialState);
@@ -18,9 +19,11 @@ function App() {
<h1>SPLENDOR</h1> <h1>SPLENDOR</h1>
<BrowserRouter> <BrowserRouter>
<Routes> <Routes>
{/* @ts-ignore */}a {/* @ts-ignore */}
<Route path="/" element={<GameConstructor state={state} setState={setState} />} /> <Route path="/" element={<GameConstructor state={state} setState={setState} />} />
{/* @ts-ignore */} {/* @ts-ignore */}
<Route path="/resume-game" element={<ResumeGame state={state} setState={setState} /> } />
{/* @ts-ignore */}
<Route path="/game" element={<Gameboard state={state} setState={setState} />} /> <Route path="/game" element={<Gameboard state={state} setState={setState} />} />
</Routes> </Routes>
</BrowserRouter> </BrowserRouter>

View File

@@ -1,5 +1,5 @@
import { useEffect, useState } from "react" 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 { CardData, NobleData, PlayerData } from "../util/types";
import { StateProps } from '../util/propTypes'; import { StateProps } from '../util/propTypes';
@@ -103,7 +103,9 @@ export default function GameConstructor({ state, setState }: StateProps) {
return ( return (
<div className="game-constructor App"> <div className="game-constructor App">
<h1>Configure a new game:</h1> <strong>Start a new game</strong>
<h2>OR</h2>
<strong>Enter your previous game data <Link to={'/resume-game'}>here</Link> to pick up where you left off.</strong>
<div> <div>
<label htmlFor="P1-NAME">Player 1 Name:</label> <label htmlFor="P1-NAME">Player 1 Name:</label>
@@ -162,7 +164,7 @@ export default function GameConstructor({ state, setState }: StateProps) {
</input> </input>
<input <input
type="radio" type="radio"
id="P1-START" id="P4-START"
onChange={() => handleRadio(4)} onChange={() => handleRadio(4)}
checked={starter === 3 && input.playerFour.name.length > 0}> checked={starter === 3 && input.playerFour.name.length > 0}>
</input> </input>

View File

@@ -3,7 +3,7 @@ import { AppState, ResourceCost } from '../../util/types';
import { useCallback, useEffect, useState } from 'react'; import { useCallback, useEffect, useState } from 'react';
import { getChipsActions } from '../Player/ActionMethods'; import { getChipsActions } from '../Player/ActionMethods';
import { StateProps } from '../../util/propTypes'; import { StateProps } from '../../util/propTypes';
const { validateChips } = getChipsActions; import { Link } from 'react-router-dom';
// components // components
import Nobles from './Nobles'; import Nobles from './Nobles';
@@ -12,6 +12,7 @@ import AvailableChips from '../Resources/AvailableChips';
import AllPlayers from '../Player/AllPlayers'; import AllPlayers from '../Player/AllPlayers';
import CardRow from '../Card/CardRow'; import CardRow from '../Card/CardRow';
import SelectionView from '../Resources/SelectionView'; import SelectionView from '../Resources/SelectionView';
const { validateChips } = getChipsActions;
export default function Gameboard({ state, setState }: StateProps) { export default function Gameboard({ state, setState }: StateProps) {
const [view, setView] = useState(<p>Loading...</p>); const [view, setView] = useState(<p>Loading...</p>);
@@ -50,17 +51,13 @@ export default function Gameboard({ state, setState }: StateProps) {
setCardRows(state); setCardRows(state);
}, [state]) }, [state])
useEffect(() => { // displays state of board if data is populated, otherwise points to game constructor
console.log(state)
}, [state])
// displays state of board if data is populated
useEffect(() => { useEffect(() => {
if (!state.players.length) { if (!state.players.length) {
setView( setView(
<div className="error-page"> <div className="error-page">
<strong>Sorry! It appears we've lost track of your game data.</strong> <strong>Sorry! It appears we've lost track of your game data.</strong>
<p>Please head back to the <a href="/">home page</a> to start a fresh game.</p> <p>Please head back to the <Link to="/">home page</Link> to start a fresh game.</p>
</div> </div>
); );
} else { } else {

View File

@@ -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', () => {
})
})

View File

@@ -1,8 +1,10 @@
import { useEffect } from "react";
import { v4 } from "uuid"; import { v4 } from "uuid";
import { NobleData, ResourceCost } from "../../util/types"; import { NobleData, PlayerData, ResourceCost } from "../../util/types";
import { StateProps } from "../../util/propTypes"; import { StateProps } from "../../util/propTypes";
import "./Nobles.css" import "./Nobles.css"
import getTotalBuyingPower from "../../util/getTotalBuyingPower";
import { useCurrentPlayer } from "../../util/useCurrentPlayer";
import { useEffect } from "react";
export default function Nobles({ state, setState }: StateProps) { export default function Nobles({ state, setState }: StateProps) {
const removeNoble = (noble: NobleData) => { 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 ( return (
<div className="nobles-panel"> <div className="nobles-panel">
<strong>NOBLES</strong> <strong>NOBLES</strong>

View File

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

View File

@@ -0,0 +1,12 @@
import { Link } from "react-router-dom";
import { StateProps } from "../util/propTypes";
export default function ResumeGame({ state, setState }: StateProps) {
return (
<div className="resume-game App">
<h2>Congrats! You've found an in-progress feature.</h2>
<p>Check back in here later to enter a save game token to pick up a game from where you left off.</p>
<p>In the meantime, click <Link to="/">here</Link> to head back home.</p>
</div>
)
}