Created
December 8, 2023 22:30
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.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 */ | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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