SimFactory / index.html
awacke1's picture
Create index.html
b01e3bc verified
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;