Fix pyramid layout calculation and card ranking logic

This commit is contained in:
chris 2026-05-25 00:50:26 -04:00
parent 84d444c0ae
commit cd408efc0e

View File

@ -27,6 +27,7 @@
if (v === 'K') return 13; if (v === 'K') return 13;
if (v === 'Q') return 12; if (v === 'Q') return 12;
if (v === 'J') return 11; if (v === 'J') return 11;
if (v === '10') return 10;
return parseInt(v, 10); return parseInt(v, 10);
} }
@ -119,11 +120,10 @@
const el = createCardElement(cardData); const el = createCardElement(cardData);
cardElements[cardData.id] = el; cardElements[cardData.id] = el;
gameBoard.appendChild(el); gameBoard.appendChild(el);
// Start all cards at stock position
const sRect = stockEl.getBoundingClientRect(); // Set initial position (will be updated by renderBoard)
const bRect = gameBoard.getBoundingClientRect(); el.style.top = '0px';
el.style.top = `${sRect.top - bRect.top + PILE_BORDER_WIDTH}px`; el.style.left = '0px';
el.style.left = `${sRect.left - bRect.left + PILE_BORDER_WIDTH}px`;
}); });
// Fill Pyramid // Fill Pyramid
@ -134,21 +134,41 @@
stock = deck; stock = deck;
updateScoreDisplay(); updateScoreDisplay();
renderBoard(); requestAnimationFrame(renderBoard);
saveGame(); saveGame();
} }
function renderBoard() { function renderBoard() {
if (!isActive) return;
const boardRect = gameBoard.getBoundingClientRect(); const boardRect = gameBoard.getBoundingClientRect();
const layoutRect = pyramidLayout.getBoundingClientRect(); const layoutRect = pyramidLayout.getBoundingClientRect();
const cardWidth = parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--card-width'));
// If the board isn't visible yet, wait for the next frame
if (boardRect.width === 0) {
requestAnimationFrame(renderBoard);
return;
}
const rootStyle = getComputedStyle(document.documentElement);
let cardWidth = parseFloat(rootStyle.getPropertyValue('--card-width'));
// Fallback for cardWidth if parsing fails
if (isNaN(cardWidth) || cardWidth === 0) {
cardWidth = 90;
}
const cardHeight = cardWidth * 1.4; const cardHeight = cardWidth * 1.4;
const rowOverlap = 0.45; const rowOverlap = 0.45;
const horizontalGap = 10;
// Position Pyramid Cards // Position Pyramid Cards
let index = 0; let index = 0;
const boardTop = boardRect.top;
const boardLeft = boardRect.left;
for (let row = 0; row < 7; row++) { for (let row = 0; row < 7; row++) {
const rowWidth = (row + 1) * cardWidth + row * 10; const rowWidth = (row + 1) * cardWidth + row * horizontalGap;
const startX = (layoutRect.width - rowWidth) / 2; const startX = (layoutRect.width - rowWidth) / 2;
const y = row * (cardHeight * rowOverlap); const y = row * (cardHeight * rowOverlap);
@ -156,11 +176,15 @@
const card = pyramid[index]; const card = pyramid[index];
if (card) { if (card) {
const el = cardElements[card.id]; const el = cardElements[card.id];
el.style.top = `${y + layoutRect.top - boardRect.top}px`; // Calculate final positions relative to the board
el.style.left = `${startX + i * (cardWidth + 10) + layoutRect.left - boardRect.left}px`; const finalTop = y + (layoutRect.top - boardTop);
const finalLeft = startX + i * (cardWidth + horizontalGap) + (layoutRect.left - boardLeft);
el.style.top = `${finalTop}px`;
el.style.left = `${finalLeft}px`;
el.style.zIndex = 100 + row; el.style.zIndex = 100 + row;
el.classList.add('is-flipped'); el.classList.add('is-flipped');
el.draggable = false; // Pyramid uses clicks el.draggable = false;
} }
index++; index++;
} }
@ -174,6 +198,7 @@
el.style.left = `${sRect.left - boardRect.left + PILE_BORDER_WIDTH}px`; el.style.left = `${sRect.left - boardRect.left + PILE_BORDER_WIDTH}px`;
el.style.zIndex = 10 + i; el.style.zIndex = 10 + i;
el.classList.remove('is-flipped'); el.classList.remove('is-flipped');
el.classList.remove('is-selected'); // Selection only on top of waste/pyramid
}); });
// Position Waste // Position Waste
@ -194,6 +219,7 @@
el.style.left = `${dRect.left - boardRect.left + PILE_BORDER_WIDTH}px`; el.style.left = `${dRect.left - boardRect.left + PILE_BORDER_WIDTH}px`;
el.style.zIndex = 10 + i; el.style.zIndex = 10 + i;
el.classList.add('is-flipped'); el.classList.add('is-flipped');
el.classList.remove('is-selected');
}); });
checkWin(); checkWin();
@ -355,7 +381,7 @@
if (!loadGame()) initPyramid(); if (!loadGame()) initPyramid();
} else { } else {
updateScoreDisplay(); updateScoreDisplay();
renderBoard(); requestAnimationFrame(renderBoard);
} }
} }
}); });
@ -365,6 +391,10 @@
if (isActive) initPyramid(); if (isActive) initPyramid();
}); });
window.addEventListener('resize', () => {
if (isActive) renderBoard();
});
// Initial check // Initial check
if (localStorage.getItem('solitaire-mode') === 'pyramid') { if (localStorage.getItem('solitaire-mode') === 'pyramid') {
isActive = true; isActive = true;