Skip to content

Commit

Permalink
Merge pull request #10 from JollyGrin/feat/pool-actions
Browse files Browse the repository at this point in the history
Feat/pool actions
  • Loading branch information
JollyGrin authored Sep 9, 2024
2 parents b5d70e6 + 4b56769 commit 6bb8339
Show file tree
Hide file tree
Showing 10 changed files with 145 additions and 74 deletions.
2 changes: 1 addition & 1 deletion src/components/molecules/LoadDeck/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { GameStateActions } from "@/components/organisms/GameBoard";
import { GRIDS } from "@/components/organisms/GameBoard/constants";
import { GameCard } from "@/pages/game";
import { GameCard } from "@/types/card";
import { useCuriosaDeck } from "@/utils/api/curiosa/useCuriosa";
import { useState } from "react";
import { Box, Flex } from "styled-system/jsx";
Expand Down
2 changes: 1 addition & 1 deletion src/components/organisms/GameBoard/Auras/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Box } from "styled-system/jsx";
import { AuraDrop } from "./AuraDrop";
import { GameStateActions } from "..";
import { DragItem } from "@/components/molecules/DragItem";
import { GameCard } from "@/pages/game";
import { GameCard } from "@/types/card";
import { useState } from "react";
import { Modal } from "@/components/atoms/Modal";
import { FullCardAtlas } from "@/components/atoms/card-view/atlas";
Expand Down
23 changes: 4 additions & 19 deletions src/components/organisms/GameBoard/Footer/Decks.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,13 @@
import { Grid, VStack } from "styled-system/jsx";
import { GRIDS, LAYOUT_HEIGHTS } from "../constants";
import { GameStateActions } from "..";
import { actDrawAtlas, actDrawDeck } from "@/utils/actions";

export const DecksTray = (props: GameStateActions) => {
function draw(deck: GRIDS.DECK | GRIDS.ATLAS_DECK) {
props.setGridItems((prev) => {
// Create a shallow copy of the previous grid items array
const newGridItems = [...prev];

// Make a copy of the deck and hand arrays, preserving their positions
const newDeck = [...newGridItems[deck]];
const newHand = [...newGridItems[GRIDS.HAND]];

// Pop a card from the deck and push it to the hand
const card = newDeck.pop();
if (card) newHand.push(card);

// Update the newGridItems array with the updated deck and hand arrays
newGridItems[deck] = newDeck;
newGridItems[GRIDS.HAND] = newHand;

// Return the updated newGridItems array to trigger a re-render
return newGridItems;
});
deck === GRIDS.DECK
? props.setGridItems(actDrawDeck(props.gridItems))
: props.setGridItems(actDrawAtlas(props.gridItems));
}

function drawDeck() {
Expand Down
7 changes: 3 additions & 4 deletions src/components/organisms/GameBoard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,11 @@ import { Modal } from "@/components/atoms/Modal";

import { Dispatch, SetStateAction, useState } from "react";
import { FullCardAtlas } from "@/components/atoms/card-view/atlas";
import { GameCard } from "@/pages/game";
import { GameCard, GameState } from "@/types/card";

type Cards = GameCard[][];
export type GameStateActions = {
gridItems: Cards;
setGridItems: Dispatch<SetStateAction<Cards>>;
gridItems: GameState;
setGridItems: Dispatch<SetStateAction<GameState>>;
};
export const GameBoard = ({ gridItems, setGridItems }: GameStateActions) => {
const { sensors, handleDragEnd, handleDragStart, activeId, activeCard } =
Expand Down
41 changes: 2 additions & 39 deletions src/components/organisms/GameBoard/useHandleDrag.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { SorceryCard } from "@/types/card";
import { actMoveCard } from "@/utils/actions/grid";
import {
DragEndEvent,
KeyboardSensor,
Expand Down Expand Up @@ -44,45 +45,7 @@ export const useHandleDrag = ({

function handleDragEnd(event: DragEndEvent) {
setActive(null);
const { active, over } = event;

if (over?.id === active.id) return; // if self, do nothing

if (over) {
const originIndex = parseInt(active.data.current?.gridIndex, 10);
const destinationIndex = over?.data?.current?.gridIndex;

if (originIndex === destinationIndex) {
const updatedGrid = [...gridItems];
const cardsInCell = [...updatedGrid[originIndex]]; // Copy the cards in the original cell

const activeCardIndex = active?.data?.current?.index; // Index of the card being dragged
const destinationCardIndex = over?.data?.current?.index; // Index where the card will be dropped

// Remove the active card from its original position
const [activeCard] = cardsInCell.splice(activeCardIndex, 1);

// Insert the active card into the new position (destination)
cardsInCell.splice(destinationCardIndex, 0, activeCard);

// Update the original grid with the modified cards in the cell
updatedGrid[originIndex] = cardsInCell;

setGridItems(updatedGrid);
return;
}

// Remove card from the origin area
const updatedGrid = [...gridItems];
const [movedCard] = updatedGrid[originIndex].splice(
active?.data?.current?.index,
1,
);
// Place card in the destination area
updatedGrid[destinationIndex]?.push(movedCard);

setGridItems(updatedGrid);
}
setGridItems(actMoveCard(gridItems, event));
}

return {
Expand Down
9 changes: 2 additions & 7 deletions src/pages/game.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
import { LoadDeck } from "@/components/molecules/LoadDeck";
import { GameBoard } from "@/components/organisms/GameBoard";
import { GRIDS } from "@/components/organisms/GameBoard/constants";
import { SorceryCard } from "@/types/card";
import { GameCard, GameState } from "@/types/card";
import { useState } from "react";

const initCards: GameCard[][] = Array.from({ length: 36 }, () => []);
// initCards[GRIDS.HAND] = handCards as GameCard[];
// initCards[GRIDS.DECK] = [...deckCards, ...mockDeck] as GameCard[];

type GameProps = {
id: string;
isTapped?: boolean;
};
export type GameCard = SorceryCard & GameProps; // for game position
export default function GamePage() {
const [gridItems, setGridItems] = useState<GameCard[][]>(initCards);
const [gridItems, setGridItems] = useState<GameState>(initCards);

if (
gridItems[GRIDS.DECK].length === 0 &&
Expand Down
22 changes: 19 additions & 3 deletions src/types/card.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,28 @@
type SorceryCardType =
| "site"
| "site" // in reality, only this one is relevant variation
| "aura"
| "avatar"
| "artifact"
| "minion"
| "magic";

export type SorceryCard = {
img: string;
type: SorceryCardType;
img: string; // used with CDN
type: SorceryCardType; // site card is rotated sideways
};

/**
* Card props used for playtesting
* */
type GameProps = {
id: string;
isTapped?: boolean;
};
/**
* Card type used for game playtesting
* */
export type GameCard = SorceryCard & GameProps;

export type GridItem = GameCard[];

export type GameState = GridItem[];
42 changes: 42 additions & 0 deletions src/utils/actions/deck.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { GRIDS } from "@/components/organisms/GameBoard/constants";
import { GameState } from "@/types/card";

export function actDrawDeck(state: GameState) {
// Create a shallow copy of the previous grid items array
const newState = [...state];

// Make a copy of the deck and hand arrays, preserving their positions
const newDeck = [...newState[GRIDS.DECK]];
const newHand = [...newState[GRIDS.HAND]];

// Pop a card from the deck and push it to the hand
const card = newDeck.pop();
if (card) newHand.push(card);

// Update the newState array with the updated deck and hand arrays
newState[GRIDS.DECK] = newDeck;
newState[GRIDS.HAND] = newHand;

// Return the updated newState array to trigger a re-render
return newState;
}

export function actDrawAtlas(state: GameState) {
// Create a shallow copy of the previous grid items array
const newState = [...state];

// Make a copy of the deck and hand arrays, preserving their positions
const newDeck = [...newState[GRIDS.ATLAS_DECK]];
const newHand = [...newState[GRIDS.HAND]];

// Pop a card from the deck and push it to the hand
const card = newDeck.pop();
if (card) newHand.push(card);

// Update the newState array with the updated deck and hand arrays
newState[GRIDS.ATLAS_DECK] = newDeck;
newState[GRIDS.HAND] = newHand;

// Return the updated newState array to trigger a re-render
return newState;
}
70 changes: 70 additions & 0 deletions src/utils/actions/grid.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { GameState } from "@/types/card";
import { DragEndEvent } from "@dnd-kit/core";

/**
* Repositions a card within it's existing grid cell
* Returns an updated game state
* */
export function actMoveCardInCell(state: GameState, event: DragEndEvent) {
const originIndex = parseInt(event.active.data.current?.gridIndex, 10);
const updatedGrid = [...state];
const cardsInCell = [...updatedGrid[originIndex]]; // Copy the cards in the original cell

const activeCardIndex = event.active?.data?.current?.index; // Index of the card being dragged
const destinationCardIndex = event.over?.data?.current?.index; // Index where the card will be dropped

// Remove the active card from its original position
const [activeCard] = cardsInCell.splice(activeCardIndex, 1);

// Insert the active card into the new position (destination)
cardsInCell.splice(destinationCardIndex, 0, activeCard);

// Update the original grid with the modified cards in the cell
updatedGrid[originIndex] = cardsInCell;

return updatedGrid;
}

/**
* Repositions a card to another grid cell
* Returns an updated game state
* */
export function actMoveCardOutsideCell(state: GameState, event: DragEndEvent) {
const originIndex = parseInt(event.active.data.current?.gridIndex, 10);
const destinationIndex = event.over?.data?.current?.gridIndex;

// Remove the active card from its original position
const updatedGrid = [...state];
const [movedCard] = updatedGrid[originIndex].splice(
event.active?.data?.current?.index,
1,
);
// Place card in the destination area
updatedGrid[destinationIndex]?.push(movedCard);

return updatedGrid;
}

/**
* Moves a card within a cell or to another grid cell
* Returns an updated game state
* If no action possible, will return the original state
* * */
export function actMoveCard(state: GameState, event: DragEndEvent) {
const { active, over } = event;

if (over?.id === active.id) return state; // if self, do nothing

if (over) {
const originIndex = parseInt(active.data.current?.gridIndex, 10);
const destinationIndex = over?.data?.current?.gridIndex;

if (originIndex === destinationIndex) {
return actMoveCardInCell(state, event);
}

return actMoveCardOutsideCell(state, event);
}

return state;
}
1 change: 1 addition & 0 deletions src/utils/actions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./deck";

0 comments on commit 6bb8339

Please sign in to comment.