Shade inaccessible region
Shade the inaccessible last-column region (except top tile) to reflect board limits and fix tiling holes at 12x12 by ensuring the shaded area covers missing cells and address incomplete tiling bugs. X-Lovable-Edit-ID: edt-11779aed-a2f6-4c13-92a0-0ccbd20e7020
This commit is contained in:
commit
c5d7901fa2
1 changed files with 69 additions and 37 deletions
|
|
@ -28,44 +28,62 @@ const DominoRetilingPuzzle: React.FC<DominoRetilingPuzzleProps> = ({ showSocialS
|
|||
const BOARD_ROWS = boardSize;
|
||||
const BOARD_COLS = boardSize + 1; // n + 1 extra square on top row
|
||||
|
||||
// Generate a random valid tiling of the n×n board
|
||||
// Generate a random valid tiling of the n×n board using backtracking
|
||||
const generateRandomTiling = useCallback(() => {
|
||||
const newDominoes: Domino[] = [];
|
||||
const occupied = new Set<string>();
|
||||
let dominoId = 0;
|
||||
|
||||
// Fill the n×n board with random dominoes
|
||||
for (let row = 0; row < boardSize; row++) {
|
||||
for (let col = 0; col < boardSize; col++) {
|
||||
const key = `${row},${col}`;
|
||||
if (occupied.has(key)) continue;
|
||||
|
||||
// Randomly choose horizontal or vertical
|
||||
const canHorizontal = col + 1 < boardSize && !occupied.has(`${row},${col + 1}`);
|
||||
const canVertical = row + 1 < boardSize && !occupied.has(`${row + 1},${col}`);
|
||||
|
||||
if (!canHorizontal && !canVertical) continue;
|
||||
|
||||
let isHorizontal: boolean;
|
||||
if (canHorizontal && canVertical) {
|
||||
isHorizontal = Math.random() > 0.5;
|
||||
} else {
|
||||
isHorizontal = canHorizontal;
|
||||
// Helper to find first uncovered cell
|
||||
const findFirstUncovered = (): { row: number; col: number } | null => {
|
||||
for (let row = 0; row < boardSize; row++) {
|
||||
for (let col = 0; col < boardSize; col++) {
|
||||
if (!occupied.has(`${row},${col}`)) {
|
||||
return { row, col };
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
newDominoes.push({
|
||||
id: dominoId++,
|
||||
row,
|
||||
col,
|
||||
isHorizontal
|
||||
});
|
||||
// Greedy fill with backtracking if needed
|
||||
while (true) {
|
||||
const cell = findFirstUncovered();
|
||||
if (!cell) break; // All covered
|
||||
|
||||
occupied.add(key);
|
||||
if (isHorizontal) {
|
||||
occupied.add(`${row},${col + 1}`);
|
||||
} else {
|
||||
occupied.add(`${row + 1},${col}`);
|
||||
}
|
||||
const { row, col } = cell;
|
||||
|
||||
// Try to place a domino here
|
||||
const canHorizontal = col + 1 < boardSize && !occupied.has(`${row},${col + 1}`);
|
||||
const canVertical = row + 1 < boardSize && !occupied.has(`${row + 1},${col}`);
|
||||
|
||||
if (!canHorizontal && !canVertical) {
|
||||
// Stuck - this shouldn't happen with even board sizes, but reset if it does
|
||||
newDominoes.length = 0;
|
||||
occupied.clear();
|
||||
dominoId = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
let isHorizontal: boolean;
|
||||
if (canHorizontal && canVertical) {
|
||||
isHorizontal = Math.random() > 0.5;
|
||||
} else {
|
||||
isHorizontal = canHorizontal;
|
||||
}
|
||||
|
||||
newDominoes.push({
|
||||
id: dominoId++,
|
||||
row,
|
||||
col,
|
||||
isHorizontal
|
||||
});
|
||||
|
||||
occupied.add(`${row},${col}`);
|
||||
if (isHorizontal) {
|
||||
occupied.add(`${row},${col + 1}`);
|
||||
} else {
|
||||
occupied.add(`${row + 1},${col}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -174,6 +192,25 @@ const DominoRetilingPuzzle: React.FC<DominoRetilingPuzzleProps> = ({ showSocialS
|
|||
const renderBoard = () => {
|
||||
const cells: JSX.Element[] = [];
|
||||
|
||||
// Render the inaccessible shaded region (last column except top cell)
|
||||
for (let row = 1; row < BOARD_ROWS; row++) {
|
||||
cells.push(
|
||||
<div
|
||||
key={`inaccessible-${row}`}
|
||||
className="border border-border/30"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
left: boardSize * cellSize,
|
||||
top: row * cellSize,
|
||||
width: cellSize,
|
||||
height: cellSize,
|
||||
backgroundColor: 'rgba(100, 100, 100, 0.3)',
|
||||
backgroundImage: 'repeating-linear-gradient(45deg, transparent, transparent 4px, rgba(80, 80, 80, 0.4) 4px, rgba(80, 80, 80, 0.4) 8px)',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// Render cells
|
||||
for (let row = 0; row < BOARD_ROWS; row++) {
|
||||
const maxCol = row === 0 ? BOARD_COLS : boardSize;
|
||||
|
|
@ -193,15 +230,10 @@ const DominoRetilingPuzzle: React.FC<DominoRetilingPuzzleProps> = ({ showSocialS
|
|||
key={`cell-${row}-${col}`}
|
||||
className={`border border-border/50 ${
|
||||
isExtraSquare
|
||||
? 'bg-blue-500/40'
|
||||
? 'bg-blue-400/50'
|
||||
: (row + col) % 2 === 0 ? 'bg-muted/30' : 'bg-muted/60'
|
||||
} ${selectedDomino !== null ? 'cursor-pointer' : ''}`}
|
||||
style={{
|
||||
...cellStyle,
|
||||
...(isExtraSquare ? {
|
||||
backgroundImage: 'repeating-linear-gradient(45deg, transparent, transparent 4px, rgba(59, 130, 246, 0.3) 4px, rgba(59, 130, 246, 0.3) 8px)',
|
||||
} : {})
|
||||
}}
|
||||
style={cellStyle}
|
||||
onMouseEnter={() => handleCellHover(row, col)}
|
||||
onMouseLeave={() => setHoverPlacement(null)}
|
||||
onClick={() => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue