diff options
author | elioat <elioat@tilde.institute> | 2025-01-11 15:55:36 -0500 |
---|---|---|
committer | elioat <elioat@tilde.institute> | 2025-01-11 15:55:36 -0500 |
commit | bf9458eaed789d5f8c4487a16edd2295dbcbbe61 (patch) | |
tree | 032d74eb1f23b355e8e80c580b24ed98c53ee494 /html | |
parent | 0f764dbcc4873755b0d4355dbf3f03a9a39d27d4 (diff) | |
download | tour-bf9458eaed789d5f8c4487a16edd2295dbcbbe61.tar.gz |
*
Diffstat (limited to 'html')
-rw-r--r-- | html/cards/script.js | 70 |
1 files changed, 57 insertions, 13 deletions
diff --git a/html/cards/script.js b/html/cards/script.js index 36897c2..34f9296 100644 --- a/html/cards/script.js +++ b/html/cards/script.js @@ -51,7 +51,12 @@ const ctx = canvas.getContext('2d'); canvas.width = window.innerWidth; canvas.height = window.innerHeight; -// Pure functions + +/** + * Shuffles an array in place and returns a new shuffled array. + * @param {Array} array - The array to shuffle. + * @returns {Array} A new array containing the shuffled elements. + */ const shuffle = array => { const result = [...array]; for (let i = result.length - 1; i > 0; i--) { @@ -61,6 +66,12 @@ const shuffle = array => { return result; }; + +/** + * Creates a deck of cards for a given deck index. + * @param {number} deckIndex - The index of the deck being created. + * @returns {Array} An array of card objects, each containing suit, value, and deckId. + */ const createDeck = (deckIndex) => SUITS.flatMap(suit => VALUES.map(value => ({ suit, @@ -69,7 +80,14 @@ const createDeck = (deckIndex) => SUITS.flatMap(suit => })) ); -// Create multiple decks +/** + * Creates multiple decks of cards based on the specified count. + * If the count exceeds the number of unique deck colors defined, + * some decks will repeat colors. + * + * @param {number} count - The number of decks to create. + * @returns {Array} An array of card objects, each containing suit, value, and deckId. + */ const createDecks = (count) => { if (count > BASE_COLORS.length) { console.warn(`Only ${BASE_COLORS.length} unique deck colors are defined. Some decks will repeat colors.`); @@ -77,7 +95,6 @@ const createDecks = (count) => { return Array.from({ length: count }, (_, i) => createDeck(i)).flat(); }; -// Create a more functional card factory const createCard = (x, y, cardData) => Object.freeze({ x: x + PADDING, y: y + PADDING, @@ -85,11 +102,17 @@ const createCard = (x, y, cardData) => Object.freeze({ isFaceUp: false }); -// Function to check if a point is within a card +/** + * Determines if a point is within a card. + * Used to determine where to hold a card when dragging. + * @param {any} x + * @param {any} y + * @param {any} card + * @returns {any} + */ const isPointInCard = (x, y, card) => x >= card.x && x <= card.x + CARD_WIDTH && y >= card.y && y <= card.y + CARD_HEIGHT; -// Rendering functions const clearCanvas = () => { ctx.fillStyle = 'beige'; ctx.fillRect(0, 0, canvas.width, canvas.height); @@ -140,6 +163,10 @@ const drawCardSuit = (suit, x, y) => { ctx.fillText(suit, x, y); }; +/** + * Renders a card, determining which side to draw based on its face-up state. + * @param {Card} card - The card to render. + */ const renderCard = card => { card.isFaceUp ? drawCardFront(card) : drawCardBack(card); }; @@ -149,7 +176,6 @@ const renderAllCards = cards => { cards.forEach(renderCard); }; -// State management let gameState; const initializeGameState = () => ({ @@ -206,7 +232,6 @@ const setupEventListeners = () => { }); }; -// Event handlers const handleMouseMove = e => { if (!gameState.draggingCard) return; @@ -247,9 +272,22 @@ const handleMouseUp = e => { let dragOffset = { x: 0, y: 0 }; // To store the offset of the click position +/** + * Finds the card that was clicked. + * @param {number} x - The x-coordinate of the click. + * @param {number} y - The y-coordinate of the click. + * @param {Card[]} cards - The list of cards to search through. + * @returns {Card|null} The card that was clicked, or null if no card was clicked. + */ const findClickedCard = (x, y, cards) => cards.slice().reverse().find(card => isPointInCard(x, y, card)); +/** + * Moves a card to the top of the stack. + * @param {Card} targetCard - The card to move to the top. + * @param {Card[]} cards - The list of cards to search through. + * @returns {Card[]} A new array with the target card moved to the top. + */ const moveCardToTop = (targetCard, cards) => [ ...cards.filter(card => card !== targetCard), targetCard @@ -287,13 +325,19 @@ const handleMouseDown = e => { } }; -// Add this function to handle the reset confirmation const handleResetGame = () => { if (confirm("Would you like to reset the cards?")) { resetCardsToOriginalPiles(); } }; +/** + * Moves a card to a new position. + * @param {Card} card - The card to move. + * @param {number} newX - The new x-coordinate for the card. + * @param {number} newY - The new y-coordinate for the card. + * @returns {Card} A new card object with updated position. + */ const moveCard = (card, newX, newY) => ({ ...card, x: newX, @@ -305,7 +349,10 @@ const toggleCardFace = card => ({ isFaceUp: !card.isFaceUp }); -// Add a function to get deck statistics +/** + * Calculates some stats for each deck, including total and face-up counts. + * @returns {Map} A map containing the total and face-up counts for each deck. + */ const getDeckStats = () => { const stats = new Map(); gameState.cards.forEach(card => { @@ -319,7 +366,6 @@ const getDeckStats = () => { return stats; }; -// Optional: Add a display for deck statistics const renderDeckStats = () => { const stats = getDeckStats(); ctx.font = '16px "pokemon-font", monospace'; @@ -342,7 +388,7 @@ const renderDeckStats = () => { }); }; -// Optional: Add a function to reset cards to their original piles +// FIXME: this is too complicated, and would probably work better if I had a better way of handling state. const resetCardsToOriginalPiles = () => { const totalWidth = PILE_SPACING * DECK_COUNT; const startX = (canvas.width - totalWidth) / 2; @@ -369,10 +415,8 @@ const resetCardsToOriginalPiles = () => { renderAllCards(gameState.cards); }; -// Start the game initializeGame(); -// Clean up on window unload window.addEventListener('unload', () => { canvas.removeEventListener('mousedown', handleMouseDown); canvas.removeEventListener('contextmenu', e => e.preventDefault()); |