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_ROWS = boardSize;
|
||||||
const BOARD_COLS = boardSize + 1; // n + 1 extra square on top row
|
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 generateRandomTiling = useCallback(() => {
|
||||||
const newDominoes: Domino[] = [];
|
const newDominoes: Domino[] = [];
|
||||||
const occupied = new Set<string>();
|
const occupied = new Set<string>();
|
||||||
let dominoId = 0;
|
let dominoId = 0;
|
||||||
|
|
||||||
// Fill the n×n board with random dominoes
|
// Helper to find first uncovered cell
|
||||||
for (let row = 0; row < boardSize; row++) {
|
const findFirstUncovered = (): { row: number; col: number } | null => {
|
||||||
for (let col = 0; col < boardSize; col++) {
|
for (let row = 0; row < boardSize; row++) {
|
||||||
const key = `${row},${col}`;
|
for (let col = 0; col < boardSize; col++) {
|
||||||
if (occupied.has(key)) continue;
|
if (!occupied.has(`${row},${col}`)) {
|
||||||
|
return { row, col };
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
newDominoes.push({
|
// Greedy fill with backtracking if needed
|
||||||
id: dominoId++,
|
while (true) {
|
||||||
row,
|
const cell = findFirstUncovered();
|
||||||
col,
|
if (!cell) break; // All covered
|
||||||
isHorizontal
|
|
||||||
});
|
|
||||||
|
|
||||||
occupied.add(key);
|
const { row, col } = cell;
|
||||||
if (isHorizontal) {
|
|
||||||
occupied.add(`${row},${col + 1}`);
|
// Try to place a domino here
|
||||||
} else {
|
const canHorizontal = col + 1 < boardSize && !occupied.has(`${row},${col + 1}`);
|
||||||
occupied.add(`${row + 1},${col}`);
|
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 renderBoard = () => {
|
||||||
const cells: JSX.Element[] = [];
|
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
|
// Render cells
|
||||||
for (let row = 0; row < BOARD_ROWS; row++) {
|
for (let row = 0; row < BOARD_ROWS; row++) {
|
||||||
const maxCol = row === 0 ? BOARD_COLS : boardSize;
|
const maxCol = row === 0 ? BOARD_COLS : boardSize;
|
||||||
|
|
@ -193,15 +230,10 @@ const DominoRetilingPuzzle: React.FC<DominoRetilingPuzzleProps> = ({ showSocialS
|
||||||
key={`cell-${row}-${col}`}
|
key={`cell-${row}-${col}`}
|
||||||
className={`border border-border/50 ${
|
className={`border border-border/50 ${
|
||||||
isExtraSquare
|
isExtraSquare
|
||||||
? 'bg-blue-500/40'
|
? 'bg-blue-400/50'
|
||||||
: (row + col) % 2 === 0 ? 'bg-muted/30' : 'bg-muted/60'
|
: (row + col) % 2 === 0 ? 'bg-muted/30' : 'bg-muted/60'
|
||||||
} ${selectedDomino !== null ? 'cursor-pointer' : ''}`}
|
} ${selectedDomino !== null ? 'cursor-pointer' : ''}`}
|
||||||
style={{
|
style={cellStyle}
|
||||||
...cellStyle,
|
|
||||||
...(isExtraSquare ? {
|
|
||||||
backgroundImage: 'repeating-linear-gradient(45deg, transparent, transparent 4px, rgba(59, 130, 246, 0.3) 4px, rgba(59, 130, 246, 0.3) 8px)',
|
|
||||||
} : {})
|
|
||||||
}}
|
|
||||||
onMouseEnter={() => handleCellHover(row, col)}
|
onMouseEnter={() => handleCellHover(row, col)}
|
||||||
onMouseLeave={() => setHoverPlacement(null)}
|
onMouseLeave={() => setHoverPlacement(null)}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue