implemented usePreviousPlayer, preparing to implement gold chip funcitonality

This commit is contained in:
2022-08-09 14:27:59 -05:00
parent fd6d96737a
commit 35931eb8e5
22 changed files with 78 additions and 51 deletions

View File

@@ -1,11 +1,11 @@
import { BrowserRouter, Routes, Route } from 'react-router-dom' import { BrowserRouter, Routes, Route } from 'react-router-dom'
import { initialState } from './util/stateSetters'; import { initialState } from './hooks/stateSetters';
import { useEffect, useState } from 'react' import { 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 ResumeGame from './components/ResumeGame'; import ResumeGame from './components/ResumeGame';
import './App.css'
function App() { function App() {
const [state, setState] = useState(initialState); const [state, setState] = useState(initialState);

View File

@@ -1,7 +1,7 @@
import { v4 } from 'uuid'; import { v4 } from 'uuid';
import { CardProps } from '../../util/propTypes'; import { CardProps } from '../../util/propTypes';
import { ResourceCost } from '../../util/types'; import { ResourceCost } from '../../util/types';
import { useCurrentPlayer } from '../../util/useCurrentPlayer'; import { useCurrentPlayer } from '../../hooks/useCurrentPlayer';
import { buyCardActions } from '../Player/ActionMethods'; import { buyCardActions } from '../Player/ActionMethods';
import { hasMaxReserved, reserveCard } from '../Player/ActionMethods/reserveCardActions'; import { hasMaxReserved, reserveCard } from '../Player/ActionMethods/reserveCardActions';
const { buyCard, tooExpensive } = buyCardActions; const { buyCard, tooExpensive } = buyCardActions;

View File

@@ -6,7 +6,7 @@ import { StateProps } from '../../util/propTypes';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
// components // components
import Nobles from './Nobles'; import Nobles from '../Nobles/Nobles';
import initializeBoard, { setCardRows } from '../../util/initializeBoard'; import initializeBoard, { setCardRows } from '../../util/initializeBoard';
import AvailableChips from '../Resources/AvailableChips'; import AvailableChips from '../Resources/AvailableChips';
import AllPlayers from '../Player/AllPlayers'; import AllPlayers from '../Player/AllPlayers';

View File

@@ -1,6 +1,6 @@
import { expect, it, describe, vi } from 'vitest'; import { expect, it, describe, vi } from 'vitest';
import initializeBoard from '../../util/initializeBoard'; import initializeBoard from '../../util/initializeBoard';
import { initialState } from '../../util/stateSetters'; import { initialState } from '../../hooks/stateSetters';
import { AppState, setStateType } from '../../util/types'; import { AppState, setStateType } from '../../util/types';
describe('game config', () => { describe('game config', () => {

View File

@@ -1,7 +1,7 @@
import { v4 } from "uuid"; import { v4 } from "uuid";
import { NobleData, ResourceCost } from "../../util/types"; import { NobleData, ResourceCost } from "../../util/types";
import { StateProps } from "../../util/propTypes"; import { StateProps } from "../../util/propTypes";
import "./Nobles.css" import "../Nobles/Nobles.css"
export default function Nobles({ state }: StateProps) { export default function Nobles({ state }: StateProps) {
if (!state.gameboard.nobles.length) { if (!state.gameboard.nobles.length) {

View File

@@ -1,5 +1,5 @@
import getTotalBuyingPower from "./getTotalBuyingPower"; import getTotalBuyingPower from "../../util/getTotalBuyingPower";
import { NobleData, PlayerData, ResourceCost } from "./types"; import { NobleData, PlayerData, ResourceCost } from "../../util/types";
export const canPickUpNoble = (player: PlayerData, noble: NobleData) => { export const canPickUpNoble = (player: PlayerData, noble: NobleData) => {
const totalBuyingPower = getTotalBuyingPower(player); const totalBuyingPower = getTotalBuyingPower(player);

View File

@@ -1,7 +1,7 @@
import { expensiveCard, midGameCardOne, midGameCardTwo, midGameState, mockPlayerOne, mockPlayerTwo, mockState } from '../../../util/testUtils'; import { expensiveCard, midGameCardOne, midGameCardTwo, midGameState, mockPlayerOne, mockPlayerTwo, mockState } from '../../../util/testUtils';
import { buyCard, tooExpensive } from './buyCardActions'; import { buyCard, tooExpensive } from './buyCardActions';
import getTotalBuyingPower from '../../../util/getTotalBuyingPower'; import getTotalBuyingPower from '../../../util/getTotalBuyingPower';
import { useCurrentPlayer } from '../../../util/useCurrentPlayer'; import { useCurrentPlayer } from '../../../hooks/useCurrentPlayer';
import { AppState, CardData, PlayerData, ResourceCost } from '../../../util/types'; import { AppState, CardData, PlayerData, ResourceCost } from '../../../util/types';
import { test, expect, describe, vi, afterEach } from 'vitest'; import { test, expect, describe, vi, afterEach } from 'vitest';
import { renderHook } from "@testing-library/react"; import { renderHook } from "@testing-library/react";

View File

@@ -1,9 +1,10 @@
import { turnOrderUtil } from "../../../util/turnOrderUtil"; import { turnOrderUtil } from "../../../util/turnOrderUtil";
import { AppState, CardData, FullDeck, ResourceCost, setStateType } from "../../../util/types"; import { AppState, CardData, FullDeck, ResourceCost, setStateType } from "../../../util/types";
import { useCurrentPlayer } from "../../../util/useCurrentPlayer"; import { useCurrentPlayer } from "../../../hooks/useCurrentPlayer";
import getTotalBuyingPower from "../../../util/getTotalBuyingPower"; import getTotalBuyingPower from "../../../util/getTotalBuyingPower";
import { initialActions, setStateGetNoble } from "../../../util/stateSetters"; import { initialActions, setStateGetNoble } from "../../../hooks/stateSetters";
import { canPickUpNoble } from "../../../util/canPickUpNoble"; import { canPickUpNoble } from "../../Nobles/canPickUpNoble";
import usePreviousPlayer from "../../../hooks/usePreviousPlayer";
export const tooExpensive = (card: CardData, state: AppState): boolean => { export const tooExpensive = (card: CardData, state: AppState): boolean => {
const currentPlayer = useCurrentPlayer(state); const currentPlayer = useCurrentPlayer(state);
@@ -95,10 +96,13 @@ export const buyCard = (state: AppState, setState: setStateType, card: CardData)
} }
}); });
for (let each of state.gameboard.nobles) { // iterates through gameboard nobles to determine if any can be acquired
if (canPickUpNoble(currentPlayer, each)) { for (let noble of state.gameboard.nobles) {
console.log(`${currentPlayer.name} can pick up noble ${state.gameboard.nobles.indexOf(each)}`); const previousPlayer = usePreviousPlayer(state);
setState((prev) => setStateGetNoble(prev, each)); if (!previousPlayer) return;
if (canPickUpNoble(previousPlayer, noble)) {
setState((prev) => setStateGetNoble(prev, noble, previousPlayer));
} }
} }
} }

View File

@@ -1,5 +1,5 @@
import { describe, expect, it, test } from "vitest"; import { describe, expect, it, test } from "vitest";
import { initialActions } from "../../../util/stateSetters"; import { initialActions } from "../../../hooks/stateSetters";
import { mockPlayerOne, mockState } from "../../../util/testUtils"; import { mockPlayerOne, mockState } from "../../../util/testUtils";
import { AppState, PlayerData } from "../../../util/types"; import { AppState, PlayerData } from "../../../util/types";
import { hasMaxChips, validateChips } from "./getChipsActions"; import { hasMaxChips, validateChips } from "./getChipsActions";

View File

@@ -1,8 +1,8 @@
import { AppState, PlayerData, setStateType } from '../../../util/types'; import { AppState, PlayerData, setStateType } from '../../../util/types';
import { useCurrentPlayer } from '../../../util/useCurrentPlayer'; import { useCurrentPlayer } from '../../../hooks/useCurrentPlayer';
// @ts-ignore // @ts-ignore
import { turnOrderUtil } from '../../../util/turnOrderUtil'; import { turnOrderUtil } from '../../../util/turnOrderUtil';
import { initialActions } from "../../../util/stateSetters"; import { initialActions } from "../../../hooks/stateSetters";
export const hasMaxChips = (player: PlayerData | null): boolean => { export const hasMaxChips = (player: PlayerData | null): boolean => {
if (!player) return true; if (!player) return true;

View File

@@ -1,8 +1,8 @@
import cardTierToKey from "../../../util/cardTierToKey"; import cardTierToKey from "../../../util/cardTierToKey";
import { initialActions } from "../../../util/stateSetters"; import { initialActions } from "../../../hooks/stateSetters";
import { turnOrderUtil } from "../../../util/turnOrderUtil"; import { turnOrderUtil } from "../../../util/turnOrderUtil";
import { AppState, CardData, FullDeck, PlayerData, setStateType } from "../../../util/types"; import { AppState, CardData, FullDeck, PlayerData, setStateType } from "../../../util/types";
import { useCurrentPlayer } from "../../../util/useCurrentPlayer"; import { useCurrentPlayer } from "../../../hooks/useCurrentPlayer";
export const goldAllowable = (player: PlayerData | null): boolean => { export const goldAllowable = (player: PlayerData | null): boolean => {
if (!player) return false; if (!player) return false;

View File

@@ -1,4 +1,4 @@
import { setStateAwaitAction, setStateBuyCard, setStateGetChips, setStateReserveCard } from "../../util/stateSetters"; import { setStateAwaitAction, setStateBuyCard, setStateGetChips, setStateReserveCard } from "../../hooks/stateSetters";
import { useEffect, useState } from "react"; 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"
@@ -88,9 +88,26 @@ export default function Player({ player, state, setState }: PlayerProps) {
<section className="turn-and-action-based"> <section className="turn-and-action-based">
<p>Score: {dynamic && dynamic.points}</p> <p>Score: {dynamic && dynamic.points}</p>
<p>{dynamic?.turnActive ? "It's your turn!" : "..."}</p> <p>{dynamic?.turnActive ? "It's your turn!" : "..."}</p>
<button disabled={dynamic && hasMaxChips(dynamic)} onClick={() => handleClick(0)}>Get Chips</button>
<button onClick={() => handleClick(1)}>Buy Card</button> {/* Player actions */}
<button disabled={dynamic && hasMaxReserved(dynamic)} onClick={() => handleClick(2)}>Reserve Card</button> <button
disabled={(dynamic && hasMaxChips(dynamic)) || (!dynamic?.turnActive)}
onClick={() => handleClick(0)}>
Get Chips
</button>
<button
disabled={!dynamic?.turnActive}
onClick={() => handleClick(1)}>
Buy Card
</button>
<button
disabled={(dynamic && hasMaxReserved(dynamic)) || (!dynamic?.turnActive)}
onClick={() => handleClick(2)}>
Reserve Card
</button>
</section> </section>
<section className="resources"> <section className="resources">

View File

@@ -1,26 +1,24 @@
import { ResourceProps } from "../../util/propTypes"; import { ResourceProps } from "../../util/propTypes";
import { ResourceCost } from "../../util/types"; import { ResourceCost } from "../../util/types";
import { useEffect } from "react";
import { v4 } from "uuid"; import { v4 } from "uuid";
import "./AvailableChips.css" import "./AvailableChips.css"
export default function AvailableChips({ state, setState, liftSelection }: ResourceProps) { export default function AvailableChips({ state, liftSelection }: ResourceProps) {
useEffect(() => {
return;
}, [state])
return ( return (
<div className="available-chips"> <div className="available-chips">
{ {
Object.keys(state.gameboard.tradingResources).map((key: string | keyof ResourceCost) => { Object.keys(state.gameboard.tradingResources).map((key: string) => {
const typedKey = key as keyof ResourceCost;
return ( return (
<div key={v4()} className={`chips-${key}`}> <div key={v4()} className={`chips-${key}`}>
<button <button
key={v4()} key={v4()}
value={key} value={key}
onClick={() => liftSelection(key as keyof ResourceCost)} // @ts-ignore
disabled={state.gameboard.tradingResources[typedKey] <= 0}
onClick={() => liftSelection(typedKey)}
> >
{key}: {state.gameboard.tradingResources[key as keyof ResourceCost]} {key}: {state.gameboard.tradingResources[typedKey]}
</button> </button>
</div> </div>
) )

View File

@@ -1,6 +1,6 @@
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 { useCurrentPlayer } from "../../hooks/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) {

View File

@@ -1,10 +1,10 @@
import { v4 } from "uuid"; import { v4 } from "uuid";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { setStateGetChips } from "../../util/stateSetters"; import { setStateGetChips } from "../../hooks/stateSetters";
import { StateProps } from "../../util/propTypes"; import { StateProps } from "../../util/propTypes";
import { ResourceCost } from "../../util/types"; import { ResourceCost } from "../../util/types";
import { getChipsActions } from "../Player/ActionMethods"; import { getChipsActions } from "../Player/ActionMethods";
import { useCurrentPlayer } from "../../util/useCurrentPlayer"; import { useCurrentPlayer } from "../../hooks/useCurrentPlayer";
import { hasMaxChips } from "../Player/ActionMethods/getChipsActions"; import { hasMaxChips } from "../Player/ActionMethods/getChipsActions";
const { getChips } = getChipsActions; const { getChips } = getChipsActions;

View File

@@ -1,6 +1,5 @@
import { AppState, CardData, NobleData, PlayerData, ResourceCost } from "./types"; import { AppState, CardData, NobleData, PlayerData, ResourceCost } from "../util/types";
import CardDeck from '../data/cards.json'; import CardDeck from '../data/cards.json';
import { useCurrentPlayer } from "./useCurrentPlayer";
export const initialActions = { export const initialActions = {
buyCard: { active: false }, buyCard: { active: false },
@@ -79,17 +78,14 @@ export const setStateReserveCard = (prev: AppState) => {
} }
} }
export const setStateGetNoble = (prev: AppState, noble: NobleData) => { export const setStateGetNoble = (prev: AppState, noble: NobleData, prevPlayer: PlayerData) => {
const currentPlayer = useCurrentPlayer(prev);
if (!currentPlayer) return prev;
const updatedPlayer = { const updatedPlayer = {
...currentPlayer, ...prevPlayer,
nobles: [...currentPlayer.nobles, noble], nobles: [...prevPlayer.nobles, noble],
points: currentPlayer.points + 3 points: prevPlayer.points + 3
} }
const idx = prev.players.indexOf(currentPlayer); const idx = prev.players.indexOf(prevPlayer);
const newPlayers = prev.players; const newPlayers = prev.players;
newPlayers[idx] = updatedPlayer; newPlayers[idx] = updatedPlayer;

View File

@@ -1,4 +1,4 @@
import { AppState, PlayerData } from "./types"; import { AppState, PlayerData } from "../util/types";
export const useCurrentPlayer = (state: AppState): PlayerData | null => { export const useCurrentPlayer = (state: AppState): PlayerData | null => {
/** /**

View File

@@ -0,0 +1,12 @@
import { AppState } from "../util/types";
import { useCurrentPlayer } from "./useCurrentPlayer";
export default function usePreviousPlayer(state: AppState) {
const currentPlayer = useCurrentPlayer(state);
if (!currentPlayer) return;
const numPlayers = state.players.length;
const targetID = currentPlayer.id;
const idx = ((targetID - 2) < 0) ? (numPlayers - 1) : (targetID - 2);
return state.players[idx];
}

View File

@@ -1,4 +1,4 @@
import { initialState } from "./stateSetters" import { initialState } from "../hooks/stateSetters"
import { AppState, CardData, NobleData, PlayerData } from "./types" import { AppState, CardData, NobleData, PlayerData } from "./types"
// mock data for early game // mock data for early game

View File

@@ -2,7 +2,7 @@ import { describe, expect, test } from "vitest"
import cardTierToKey from "./cardTierToKey"; import cardTierToKey from "./cardTierToKey";
import { mockPlayerOne, mockState } from "./testUtils"; import { mockPlayerOne, mockState } from "./testUtils";
import { turnOrderUtil } from "./turnOrderUtil"; import { turnOrderUtil } from "./turnOrderUtil";
import { useCurrentPlayer } from "./useCurrentPlayer"; import { useCurrentPlayer } from "../hooks/useCurrentPlayer";
describe('app utilities', () => { describe('app utilities', () => {
test('useCurrentPlayer', () => { test('useCurrentPlayer', () => {