implemented usePreviousPlayer, preparing to implement gold chip funcitonality
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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';
|
||||||
|
|||||||
@@ -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', () => {
|
||||||
|
|||||||
@@ -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) {
|
||||||
@@ -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);
|
||||||
@@ -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";
|
||||||
|
|||||||
@@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
@@ -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>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
@@ -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 => {
|
||||||
/**
|
/**
|
||||||
12
src/hooks/usePreviousPlayer.tsx
Normal file
12
src/hooks/usePreviousPlayer.tsx
Normal 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];
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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', () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user