Spaces:
Running
Running
import React, { useState, useEffect } from 'react'; | |
import { AlertCircle, Axe, Box, Building, Cpu, Factory, Zap } from 'lucide-react'; | |
const Game = () => { | |
const [selectedTool, setSelectedTool] = useState(null); | |
const [grid, setGrid] = useState(() => | |
Array(8).fill().map(() => Array(8).fill({ type: null, color: 'white' })) | |
); | |
const [resources, setResources] = useState({ energy: 50, minerals: 50, circuits: 0 }); | |
const [tick, setTick] = useState(0); | |
const [researchProgress, setResearchProgress] = useState({ automation: 0, speed: 0 }); | |
const [message, setMessage] = useState(''); | |
const tools = { | |
solarPanel: { | |
cost: { minerals: 10 }, | |
color: 'bg-yellow-200', | |
produces: 'energy', | |
icon: <Zap className="w-6 h-6" /> | |
}, | |
mineralExtractor: { | |
cost: { energy: 10 }, | |
color: 'bg-gray-300', | |
produces: 'minerals', | |
icon: <Box className="w-6 h-6" /> | |
}, | |
circuitFactory: { | |
cost: { energy: 15, minerals: 15 }, | |
color: 'bg-green-200', | |
produces: 'circuits', | |
icon: <Cpu className="w-6 h-6" /> | |
} | |
}; | |
// Game tick for resource production | |
useEffect(() => { | |
const timer = setInterval(() => { | |
setTick(t => t + 1); | |
setResources(prev => { | |
const newResources = { ...prev }; | |
grid.forEach(row => { | |
row.forEach(cell => { | |
if (cell.type && tools[cell.type]) { | |
const produces = tools[cell.type].produces; | |
newResources[produces] = (newResources[produces] || 0) + 1; | |
} | |
}); | |
}); | |
return newResources; | |
}); | |
}, 1000); | |
return () => clearInterval(timer); | |
}, [grid]); | |
const handleCellClick = (rowIndex, colIndex) => { | |
if (!selectedTool) { | |
setMessage('Select a building first!'); | |
return; | |
} | |
const tool = tools[selectedTool]; | |
const canAfford = Object.entries(tool.cost).every( | |
([resource, cost]) => resources[resource] >= cost | |
); | |
if (!canAfford) { | |
setMessage('Not enough resources!'); | |
return; | |
} | |
// Deduct costs | |
setResources(prev => { | |
const newResources = { ...prev }; | |
Object.entries(tool.cost).forEach(([resource, cost]) => { | |
newResources[resource] -= cost; | |
}); | |
return newResources; | |
}); | |
// Place building | |
setGrid(prev => { | |
const newGrid = [...prev]; | |
newGrid[rowIndex] = [...prev[rowIndex]]; | |
newGrid[rowIndex][colIndex] = { | |
type: selectedTool, | |
color: tool.color | |
}; | |
return newGrid; | |
}); | |
// Show success message | |
setMessage(`Built ${selectedTool}!`); | |
setTimeout(() => setMessage(''), 2000); | |
}; | |
return ( | |
<div className="p-4 max-w-4xl mx-auto"> | |
{/* Resources */} | |
<div className="grid grid-cols-3 gap-4 mb-6"> | |
<div className="p-3 bg-yellow-100 rounded-lg flex items-center gap-2"> | |
<Zap className="w-4 h-4" /> | |
<span>Energy: {resources.energy}</span> | |
</div> | |
<div className="p-3 bg-gray-100 rounded-lg flex items-center gap-2"> | |
<Box className="w-4 h-4" /> | |
<span>Minerals: {resources.minerals}</span> | |
</div> | |
<div className="p-3 bg-green-100 rounded-lg flex items-center gap-2"> | |
<Cpu className="w-4 h-4" /> | |
<span>Circuits: {resources.circuits}</span> | |
</div> | |
</div> | |
{/* Tool Selection */} | |
<div className="mb-6"> | |
<div className="flex gap-4 mb-4"> | |
{Object.entries(tools).map(([name, data]) => ( | |
<button | |
key={name} | |
onClick={() => setSelectedTool(name)} | |
className={`p-4 rounded-lg flex flex-col items-center ${data.color} | |
${selectedTool === name ? 'ring-2 ring-blue-500' : ''}`} | |
> | |
{data.icon} | |
<span className="text-sm mt-2">{name.replace(/([A-Z])/g, ' $1').trim()}</span> | |
<span className="text-xs mt-1"> | |
Cost: {Object.entries(data.cost).map(([r, c]) => `${c} ${r}`).join(', ')} | |
</span> | |
</button> | |
))} | |
</div> | |
{message && ( | |
<div className="text-center text-sm font-medium text-blue-600 mb-2"> | |
{message} | |
</div> | |
)} | |
</div> | |
{/* Game Grid */} | |
<div className="grid grid-cols-8 gap-1 bg-gray-100 p-2 rounded-lg"> | |
{grid.map((row, rowIndex) => ( | |
row.map((cell, colIndex) => ( | |
<button | |
key={`${rowIndex}-${colIndex}`} | |
onClick={() => handleCellClick(rowIndex, colIndex)} | |
className={`w-16 h-16 rounded-lg ${cell.type ? tools[cell.type].color : 'bg-white'} | |
hover:bg-opacity-80 transition-colors flex items-center justify-center`} | |
> | |
{cell.type && tools[cell.type].icon} | |
</button> | |
)) | |
))} | |
</div> | |
</div> | |
); | |
}; | |
export default Game; |