Fix pyramid layout calculation and card ranking logic
This commit is contained in:
parent
84d444c0ae
commit
cd408efc0e
54
pyramid.js
54
pyramid.js
@ -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;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user