flvvsc's picture
When the die are cast they each must land on one of 6 faces so let's exemplify this by adding a random number between 1-6 for each die when it lands.
cd06770 verified
class DiceGrid extends HTMLElement {
constructor() {
super();
this.grid = Array(4).fill().map(() => Array(4).fill().map(() => []));
this.colors = [
'bg-red-500', 'bg-blue-500', 'bg-green-500', 'bg-yellow-500',
'bg-purple-500', 'bg-pink-500', 'bg-indigo-500', 'bg-teal-500'
];
}
connectedCallback() {
this.attachShadow({ mode: 'open' });
this.render();
}
render() {
this.shadowRoot.innerHTML = `
<style>
.grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(4, 1fr);
gap: 8px;
aspect-ratio: 1/1;
}
.dice {
display: flex;
justify-content: center;
align-items: center;
width: 40px;
height: 40px;
border-radius: 6px;
font-weight: bold;
color: white;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}
.grid-slot {
position: relative;
min-height: 80px;
border: 1px solid #e2e8f0;
transition: all 0.2s ease;
}
.grid-slot.highlight {
background-color: #e0e7ff;
}
.dice-stack {
position: absolute;
display: flex;
flex-direction: column;
gap: 4px;
}
.dice-enter {
animation: diceRoll 0.5s ease-out forwards;
}
@keyframes diceRoll {
0% { transform: translateY(-10px) rotate(0deg); opacity: 0; }
100% { transform: translateY(0) rotate(360deg); opacity: 1; }
}
</style>
<div class="grid">
${Array(4).fill().map((_, row) =>
Array(4).fill().map((_, col) => `
<div class="grid-slot" data-row="${row}" data-col="${col}">
${this.grid[row][col].length > 0 ? `
<div class="dice-stack">
${this.grid[row][col].map((die, index) => `
<div class="dice ${this.colors[die.charCodeAt(0) - 65 % this.colors.length]} dice-enter" style="animation-delay: ${index * 0.1}s">
${Math.floor(Math.random() * 6) + 1}
</div>
`).join('')}
</div>
` : ''}
</div>
`).join('')
).join('')}
</div>
`;
}
placeDice(diceLabels) {
// Reset the grid
this.grid = Array(4).fill().map(() => Array(4).fill().map(() => []));
// Place each die randomly with a random face value
diceLabels.forEach((die, index) => {
const faceValue = Math.floor(Math.random() * 6) + 1;
let row, col;
// Try to find a random position (max 5 attempts to avoid infinite loops)
let attempts = 0;
do {
row = Math.floor(Math.random() * 4);
col = Math.floor(Math.random() * 4);
attempts++;
} while (attempts < 5 && this.grid[row][col].length >= 2);
// If slot has 2 dice already, find adjacent slot
if (this.grid[row][col].length >= 2) {
const adjacent = this.findAvailableAdjacentSlot(row, col);
if (adjacent) {
row = adjacent.row;
col = adjacent.col;
}
}
this.grid[row][col].push({label: die, value: faceValue});
});
this.render();
}
findAvailableAdjacentSlot(row, col) {
// Check all adjacent slots (up, down, left, right)
const directions = [
{ dr: -1, dc: 0 }, // up
{ dr: 1, dc: 0 }, // down
{ dr: 0, dc: -1 }, // left
{ dr: 0, dc: 1 } // right
];
// Shuffle directions to randomize selection
directions.sort(() => Math.random() - 0.5);
for (const dir of directions) {
const newRow = row + dir.dr;
const newCol = col + dir.dc;
// Check if new position is within bounds
if (newRow >= 0 && newRow < 4 && newCol >= 0 && newCol < 4) {
// Check if slot has less than 2 dice
if (this.grid[newRow][newCol].length < 2) {
return { row: newRow, col: newCol };
}
}
}
// If no adjacent slots available, find first available slot
for (let r = 0; r < 4; r++) {
for (let c = 0; c < 4; c++) {
if (this.grid[r][c].length < 2) {
return { row: r, col: c };
}
}
}
return null; // No available slots (shouldn't happen with only 5 dice)
}
}
customElements.define('dice-grid', DiceGrid);