Skip to content

Instantly share code, notes, and snippets.

@creikey
Created December 8, 2023 22:30
Show Gist options
  • Save creikey/2e388de813617fd5b6f81006bfc54765 to your computer and use it in GitHub Desktop.
Save creikey/2e388de813617fd5b6f81006bfc54765 to your computer and use it in GitHub Desktop.
This is a nice lights out mini game, just throw this into a default vite project the npm run dev
.game-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
padding: 20px;
}
.controls {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
.grid {
display: grid;
grid-template-columns: repeat(5, 60px);
gap: 5px;
}
.row {
display: contents;
}
.cell {
width: 60px;
height: 60px;
border: 2px solid #444;
background-color: #000;
transition: background-color 0.3s, background-image 0.3s;
background-size: contain;
background-repeat: no-repeat;
background-position: center;
}
.cell.on {
background-color: #ff0;
}
button {
cursor: pointer;
outline: none;
}
.button-showing-clicks {
background-color: #4caf50; /* Or any color that indicates active state */
color: white; /* Adjust text color for better visibility if needed */
}
import { useState, useEffect } from 'react'
import './App.css'
import blueDiamond from './blue-diamond.png'
const generateInitialGrid = () => Array.from({ length: 5 }, () => Array.from({ length: 5 }, () => false));
function App() {
const [grid, setGrid] = useState(generateInitialGrid());
const [clicks, setClicks] = useState([]);
const [totalClicks, setTotalClicks] = useState(0);
const [showClicks, setShowClicks] = useState(false);
// Moved toggleLights function inside App to use setGrid directly
const toggleLights = (x, y, simulate = false) => {
setGrid(currentGrid => {
return currentGrid.map((row, i) =>
row.map((cell, j) => {
if (
i === x && j === y ||
i === x - 1 && j === y ||
i === x + 1 && j === y ||
i === x && j === y - 1 ||
i === x && j === y + 1
) {
return !cell;
}
return cell;
})
);
});
// Only update totalClicks if it's not a simulated click
if (!simulate) {
setTotalClicks(totalClicks + 1);
setClicks(prevClicks => {
const clickIndex = prevClicks.findIndex(click => click.x === x && click.y === y);
if (clickIndex > -1) {
return [...prevClicks.slice(0, clickIndex), ...prevClicks.slice(clickIndex + 1)];
}
return [...prevClicks, { x, y }];
});
}
};
const randomizeBoard = () => {
for (let i = 0; i < 5; i++) {
for (let j = 0; j < 5; j++) {
if (Math.random() < 0.3) { // Adjust the probability as needed
toggleLights(i, j, true); // Pass true to simulate the click without affecting the click count
}
}
}
// Reset the total clicks and click history when the board is randomized
setTotalClicks(0);
setClicks([]);
};
useEffect(randomizeBoard, []); // Randomize board on startup
useEffect(() => {
if (totalClicks > 0 && grid.every(row => row.every(cell => !cell))) {
alert('You won!');
}
}, [grid, totalClicks]);
return (
<div className="game-container">
<div className="controls">
<button onClick={randomizeBoard}>Randomize Board</button>
<button
onClick={() => setShowClicks(!showClicks)}
className={showClicks ? 'button-showing-clicks' : ''}
>
Toggle Clicks View
</button>
<p>Total Clicks: {totalClicks}</p>
</div>
<div className="grid">
{grid.map((row, i) => (
<div key={i} className="row">
{row.map((cell, j) => {
// Check if the current cell has been clicked
const isClicked = clicks.some(click => click.x === i && click.y === j);
return (
<button
key={j}
className={`cell ${cell ? 'on' : ''}`}
onClick={() => toggleLights(i, j)}
// Apply background image only if showClicks is true and the cell has been clicked
style={showClicks && isClicked ? { backgroundImage: `url(${blueDiamond})` } : {}}
/>
);
})}
</div>
))}
</div>
</div>
);
}
export default App
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment