chriswingler commited on
Commit
e530823
·
verified ·
1 Parent(s): cc06bdb

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +537 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Deepsite
3
- emoji: 💻
4
- colorFrom: red
5
- colorTo: pink
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: deepsite
3
+ emoji: 🐳
4
+ colorFrom: blue
5
+ colorTo: blue
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,537 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>2D Wildfire Simulation</title>
7
+ <style>
8
+ body {
9
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
10
+ background: linear-gradient(135deg, #1a2a6c, #b21f1f, #fdbb2d);
11
+ margin: 0;
12
+ padding: 20px;
13
+ color: #fff;
14
+ }
15
+
16
+ .container {
17
+ max-width: 1200px;
18
+ margin: 0 auto;
19
+ display: flex;
20
+ flex-direction: column;
21
+ align-items: center;
22
+ gap: 20px;
23
+ }
24
+
25
+ h1 {
26
+ text-align: center;
27
+ text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
28
+ margin-bottom: 0;
29
+ }
30
+
31
+ .simulation-container {
32
+ display: flex;
33
+ gap: 30px;
34
+ flex-wrap: wrap;
35
+ justify-content: center;
36
+ }
37
+
38
+ .controls {
39
+ background-color: rgba(255, 255, 255, 0.1);
40
+ backdrop-filter: blur(10px);
41
+ padding: 20px;
42
+ border-radius: 10px;
43
+ box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
44
+ width: 300px;
45
+ }
46
+
47
+ .control-group {
48
+ margin-bottom: 15px;
49
+ }
50
+
51
+ label {
52
+ display: block;
53
+ margin-bottom: 5px;
54
+ font-weight: bold;
55
+ }
56
+
57
+ input, select {
58
+ width: 100%;
59
+ padding: 8px;
60
+ border-radius: 5px;
61
+ border: 1px solid #ccc;
62
+ background-color: rgba(255, 255, 255, 0.8);
63
+ }
64
+
65
+ button {
66
+ background: linear-gradient(45deg, #ff416c, #ff4b2b);
67
+ color: white;
68
+ border: none;
69
+ padding: 10px 15px;
70
+ border-radius: 5px;
71
+ cursor: pointer;
72
+ font-weight: bold;
73
+ width: 100%;
74
+ margin-top: 5px;
75
+ transition: all 0.3s;
76
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
77
+ }
78
+
79
+ button:hover {
80
+ transform: translateY(-2px);
81
+ box-shadow: 0 6px 10px rgba(0, 0, 0, 0.2);
82
+ }
83
+
84
+ .stats {
85
+ background-color: rgba(0, 0, 0, 0.3);
86
+ padding: 15px;
87
+ border-radius: 10px;
88
+ margin-top: 15px;
89
+ }
90
+
91
+ .simulation {
92
+ position: relative;
93
+ }
94
+
95
+ canvas {
96
+ background-color: #123524;
97
+ border-radius: 10px;
98
+ box-shadow: 0 10px 20px rgba(0, 0, 0, 0.3);
99
+ }
100
+
101
+ .legend {
102
+ display: flex;
103
+ gap: 15px;
104
+ justify-content: center;
105
+ margin-top: 10px;
106
+ }
107
+
108
+ .legend-item {
109
+ display: flex;
110
+ align-items: center;
111
+ gap: 5px;
112
+ }
113
+
114
+ .legend-color {
115
+ width: 20px;
116
+ height: 20px;
117
+ border-radius: 50%;
118
+ border: 1px solid #fff;
119
+ }
120
+
121
+ .wind-indicator {
122
+ text-align: center;
123
+ font-weight: bold;
124
+ margin-top: 10px;
125
+ }
126
+
127
+ .credits {
128
+ text-align: center;
129
+ font-size: 0.8em;
130
+ margin-top: 20px;
131
+ opacity: 0.7;
132
+ }
133
+ </style>
134
+ </head>
135
+ <body>
136
+ <div class="container">
137
+ <h1>🌲 Wildfire Simulation 🔥</h1>
138
+
139
+ <div class="simulation-container">
140
+ <div class="simulation">
141
+ <canvas id="simulationCanvas" width="600" height="600"></canvas>
142
+ <div class="legend">
143
+ <div class="legend-item">
144
+ <div class="legend-color" style="background-color: #228B22;"></div>
145
+ <span>Unburned</span>
146
+ </div>
147
+ <div class="legend-item">
148
+ <div class="legend-color" style="background-color: #FF4500;"></div>
149
+ <span>Burning</span>
150
+ </div>
151
+ <div class="legend-item">
152
+ <div class="legend-color" style="background-color: #8B4513;"></div>
153
+ <span>Burned</span>
154
+ </div>
155
+ <div class="legend-item">
156
+ <div class="legend-color" style="background-color: #696969;"></div>
157
+ <span>Empty</span>
158
+ </div>
159
+ </div>
160
+ </div>
161
+
162
+ <div class="controls">
163
+ <div class="control-group">
164
+ <label for="gridSize">Grid Size:</label>
165
+ <input type="range" id="gridSize" min="10" max="100" value="40">
166
+ </div>
167
+
168
+ <div class="control-group">
169
+ <label for="treeDensity">Tree Density:</label>
170
+ <input type="range" id="treeDensity" min="10" max="100" value="70">
171
+ </div>
172
+
173
+ <div class="control-group">
174
+ <label for="spreadProbability">Spread Probability:</label>
175
+ <input type="range" id="spreadProbability" min="1" max="100" value="40">
176
+ </div>
177
+
178
+ <div class="control-group">
179
+ <label for="windDirection">Wind Direction:</label>
180
+ <select id="windDirection">
181
+ <option value="0">None</option>
182
+ <option value="1">North</option>
183
+ <option value="2">East</option>
184
+ <option value="3">South</option>
185
+ <option value="4">West</option>
186
+ </select>
187
+ </div>
188
+
189
+ <div class="control-group">
190
+ <label for="windStrength">Wind Strength:</label>
191
+ <input type="range" id="windStrength" min="0" max="100" value="20">
192
+ </div>
193
+
194
+ <button id="resetBtn">Reset Simulation</button>
195
+ <button id="startFireBtn">Start Fire</button>
196
+ <button id="stepBtn">Step Simulation</button>
197
+ <button id="runBtn">Run Simulation</button>
198
+
199
+ <div class="stats" id="stats">
200
+ <div>Unburned: <span id="unburnedCount">0</span></div>
201
+ <div>Burning: <span id="burningCount">0</span></div>
202
+ <div>Burned: <span id="burnedCount">0</span></div>
203
+ <div>Empty: <span id="emptyCount">0</span></div>
204
+ <div>Iteration: <span id="iteration">0</span></div>
205
+ <div class="wind-indicator">Wind: <span id="windDisplay">None</span></div>
206
+ </div>
207
+ </div>
208
+ </div>
209
+
210
+ <div class="credits">
211
+ <p>A 2D wildfire simulation showing how fires spread through a forest based on various parameters.</p>
212
+ </div>
213
+ </div>
214
+
215
+ <script>
216
+ // Constants
217
+ const CELL_STATES = {
218
+ EMPTY: 0, // gray
219
+ UNBURNED: 1, // green
220
+ BURNING: 2, // orange/red
221
+ BURNED: 3 // brown
222
+ };
223
+
224
+ const CELL_COLORS = {
225
+ [CELL_STATES.EMPTY]: '#696969',
226
+ [CELL_STATES.UNBURNED]: '#228B22',
227
+ [CELL_STATES.BURNING]: '#FF4500',
228
+ [CELL_STATES.BURNED]: '#8B4513'
229
+ };
230
+
231
+ const WIND_DIRECTIONS = {
232
+ 0: 'None',
233
+ 1: 'North',
234
+ 2: 'East',
235
+ 3: 'South',
236
+ 4: 'West'
237
+ };
238
+
239
+ // Simulation variables
240
+ let grid = [];
241
+ let gridSize = 40;
242
+ let cellSize;
243
+ let treeDensity = 70;
244
+ let spreadProbability = 40;
245
+ let windDirection = 0;
246
+ let windStrength = 20;
247
+ let isRunning = false;
248
+ let iteration = 0;
249
+ let animationId;
250
+
251
+ // DOM elements
252
+ const canvas = document.getElementById('simulationCanvas');
253
+ const ctx = canvas.getContext('2d');
254
+ const gridSizeSlider = document.getElementById('gridSize');
255
+ const treeDensitySlider = document.getElementById('treeDensity');
256
+ const spreadProbabilitySlider = document.getElementById('spreadProbability');
257
+ const windDirectionSelect = document.getElementById('windDirection');
258
+ const windStrengthSlider = document.getElementById('windStrength');
259
+ const resetBtn = document.getElementById('resetBtn');
260
+ const startFireBtn = document.getElementById('startFireBtn');
261
+ const stepBtn = document.getElementById('stepBtn');
262
+ const runBtn = document.getElementById('runBtn');
263
+ const unburnedCountSpan = document.getElementById('unburnedCount');
264
+ const burningCountSpan = document.getElementById('burningCount');
265
+ const burnedCountSpan = document.getElementById('burnedCount');
266
+ const emptyCountSpan = document.getElementById('emptyCount');
267
+ const iterationSpan = document.getElementById('iteration');
268
+ const windDisplaySpan = document.getElementById('windDisplay');
269
+
270
+ // Initialize the simulation
271
+ function init() {
272
+ resetSimulation();
273
+ addEventListeners();
274
+ updateStats();
275
+ updateWindDisplay();
276
+ }
277
+
278
+ // Add event listeners
279
+ function addEventListeners() {
280
+ resetBtn.addEventListener('click', resetSimulation);
281
+ startFireBtn.addEventListener('click', startFire);
282
+ stepBtn.addEventListener('click', stepSimulation);
283
+ runBtn.addEventListener('click', toggleRunSimulation);
284
+
285
+ // Canvas click to manually set fires
286
+ canvas.addEventListener('click', (e) => {
287
+ if (isRunning) return;
288
+
289
+ const rect = canvas.getBoundingClientRect();
290
+ const x = e.clientX - rect.left;
291
+ const y = e.clientY - rect.top;
292
+
293
+ const col = Math.floor(x / cellSize);
294
+ const row = Math.floor(y / cellSize);
295
+
296
+ if (grid[row] && grid[row][col] && grid[row][col] === CELL_STATES.UNBURNED) {
297
+ grid[row][col] = CELL_STATES.BURNING;
298
+ drawGrid();
299
+ updateStats();
300
+ }
301
+ });
302
+
303
+ // Parameter change listeners
304
+ gridSizeSlider.addEventListener('input', () => {
305
+ gridSize = parseInt(gridSizeSlider.value);
306
+ resetSimulation();
307
+ });
308
+
309
+ treeDensitySlider.addEventListener('input', () => {
310
+ treeDensity = parseInt(treeDensitySlider.value);
311
+ resetSimulation();
312
+ });
313
+
314
+ spreadProbabilitySlider.addEventListener('input', () => {
315
+ spreadProbability = parseInt(spreadProbabilitySlider.value);
316
+ });
317
+
318
+ windDirectionSelect.addEventListener('change', () => {
319
+ windDirection = parseInt(windDirectionSelect.value);
320
+ updateWindDisplay();
321
+ });
322
+
323
+ windStrengthSlider.addEventListener('input', () => {
324
+ windStrength = parseInt(windStrengthSlider.value);
325
+ updateWindDisplay();
326
+ });
327
+ }
328
+
329
+ // Reset the simulation
330
+ function resetSimulation() {
331
+ // Stop any running simulation
332
+ if (isRunning) {
333
+ toggleRunSimulation();
334
+ }
335
+
336
+ iteration = 0;
337
+ grid = [];
338
+ cellSize = canvas.width / gridSize;
339
+
340
+ // Initialize grid with random trees
341
+ for (let i = 0; i < gridSize; i++) {
342
+ grid[i] = [];
343
+ for (let j = 0; j < gridSize; j++) {
344
+ // Randomly decide if this cell is a tree or empty
345
+ const isTree = Math.random() * 100 < treeDensity;
346
+ grid[i][j] = isTree ? CELL_STATES.UNBURNED : CELL_STATES.EMPTY;
347
+ }
348
+ }
349
+
350
+ drawGrid();
351
+ updateStats();
352
+ }
353
+
354
+ // Start a fire at a random location
355
+ function startFire() {
356
+ if (isRunning) return;
357
+
358
+ // Find all unburned trees
359
+ const unburnedCells = [];
360
+ for (let i = 0; i < gridSize; i++) {
361
+ for (let j = 0; j < gridSize; j++) {
362
+ if (grid[i][j] === CELL_STATES.UNBURNED) {
363
+ unburnedCells.push({row: i, col: j});
364
+ }
365
+ }
366
+ }
367
+
368
+ // If there are unburned trees, start a fire at a random one
369
+ if (unburnedCells.length > 0) {
370
+ const randomIndex = Math.floor(Math.random() * unburnedCells.length);
371
+ const {row, col} = unburnedCells[randomIndex];
372
+ grid[row][col] = CELL_STATES.BURNING;
373
+ drawGrid();
374
+ updateStats();
375
+ }
376
+ }
377
+
378
+ // Run one step of the simulation
379
+ function stepSimulation() {
380
+ if (isRunning) return;
381
+
382
+ const newGrid = JSON.parse(JSON.stringify(grid));
383
+ let burningCells = 0;
384
+
385
+ for (let i = 0; i < gridSize; i++) {
386
+ for (let j = 0; j < gridSize; j++) {
387
+ // If this cell is burning, it will turn to burned in the next step
388
+ if (grid[i][j] === CELL_STATES.BURNING) {
389
+ newGrid[i][j] = CELL_STATES.BURNED;
390
+ burningCells++;
391
+
392
+ // Try to spread the fire to adjacent cells
393
+ spreadFire(i, j, newGrid);
394
+ }
395
+ }
396
+ }
397
+
398
+ grid = newGrid;
399
+ iteration++;
400
+ drawGrid();
401
+ updateStats();
402
+
403
+ // If no burning cells left, fire has burned out
404
+ return burningCells > 0;
405
+ }
406
+
407
+ // Spread fire to adjacent cells
408
+ function spreadFire(row, col, newGrid) {
409
+ // Directions in row, col offsets: north, east, south, west
410
+ const directions = [[-1, 0], [0, 1], [1, 0], [0, -1]];
411
+
412
+ for (const [dr, dc] of directions) {
413
+ const newRow = row + dr;
414
+ const newCol = col + dc;
415
+
416
+ // Check if the new position is within bounds
417
+ if (newRow >= 0 && newRow < gridSize && newCol >= 0 && newCol < gridSize) {
418
+ // Only spread to unburned trees
419
+ if (grid[newRow][newCol] === CELL_STATES.UNBURNED) {
420
+ // Base probability
421
+ let prob = spreadProbability;
422
+
423
+ // Adjust probability based on wind direction
424
+ switch (windDirection) {
425
+ case 1: // North
426
+ if (dr === -1) prob += windStrength; // Favor north
427
+ if (dr === 1) prob -= windStrength; // Reduce south
428
+ break;
429
+ case 2: // East
430
+ if (dc === 1) prob += windStrength; // Favor east
431
+ if (dc === -1) prob -= windStrength; // Reduce west
432
+ break;
433
+ case 3: // South
434
+ if (dr === 1) prob += windStrength; // Favor south
435
+ if (dr === -1) prob -= windStrength; // Reduce north
436
+ break;
437
+ case 4: // West
438
+ if (dc === -1) prob += windStrength; // Favor west
439
+ if (dc === 1) prob -= windStrength; // Reduce east
440
+ break;
441
+ }
442
+
443
+ // Ensure probability is within bounds
444
+ prob = Math.max(1, Math.min(100, prob));
445
+
446
+ // Random chance to spread fire
447
+ if (Math.random() * 100 < prob) {
448
+ newGrid[newRow][newCol] = CELL_STATES.BURNING;
449
+ }
450
+ }
451
+ }
452
+ }
453
+ }
454
+
455
+ // Run the simulation continuously
456
+ function runSimulation() {
457
+ if (!isRunning) return;
458
+
459
+ const hasBurningCells = stepSimulation();
460
+
461
+ if (hasBurningCells) {
462
+ animationId = requestAnimationFrame(runSimulation);
463
+ } else {
464
+ toggleRunSimulation();
465
+ }
466
+ }
467
+
468
+ // Toggle between running and paused states
469
+ function toggleRunSimulation() {
470
+ isRunning = !isRunning;
471
+
472
+ if (isRunning) {
473
+ runBtn.textContent = 'Pause Simulation';
474
+ runSimulation();
475
+ } else {
476
+ runBtn.textContent = 'Run Simulation';
477
+ cancelAnimationFrame(animationId);
478
+ }
479
+ }
480
+
481
+ // Draw the grid on canvas
482
+ function drawGrid() {
483
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
484
+
485
+ for (let i = 0; i < gridSize; i++) {
486
+ for (let j = 0; j < gridSize; j++) {
487
+ const x = j * cellSize;
488
+ const y = i * cellSize;
489
+
490
+ // Draw cell background
491
+ ctx.fillStyle = CELL_COLORS[grid[i][j]];
492
+ ctx.fillRect(x, y, cellSize, cellSize);
493
+
494
+ // Draw grid lines
495
+ ctx.strokeStyle = 'rgba(0, 0, 0, 0.1)';
496
+ ctx.strokeRect(x, y, cellSize, cellSize);
497
+ }
498
+ }
499
+ }
500
+
501
+ // Update the statistics display
502
+ function updateStats() {
503
+ let unburned = 0;
504
+ let burning = 0;
505
+ let burned = 0;
506
+ let empty = 0;
507
+
508
+ for (let i = 0; i < gridSize; i++) {
509
+ for (let j = 0; j < gridSize; j++) {
510
+ switch (grid[i][j]) {
511
+ case CELL_STATES.UNBURNED: unburned++; break;
512
+ case CELL_STATES.BURNING: burning++; break;
513
+ case CELL_STATES.BURNED: burned++; break;
514
+ case CELL_STATES.EMPTY: empty++; break;
515
+ }
516
+ }
517
+ }
518
+
519
+ unburnedCountSpan.textContent = unburned;
520
+ burningCountSpan.textContent = burning;
521
+ burnedCountSpan.textContent = burned;
522
+ emptyCountSpan.textContent = empty;
523
+ iterationSpan.textContent = iteration;
524
+ }
525
+
526
+ // Update the wind direction display
527
+ function updateWindDisplay() {
528
+ const direction = WIND_DIRECTIONS[windDirection];
529
+ const strengthText = windDirection === 0 ? '' : ` (Strength: ${windStrength}%)`;
530
+ windDisplaySpan.textContent = direction + strengthText;
531
+ }
532
+
533
+ // Initialize when the page loads
534
+ window.onload = init;
535
+ </script>
536
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <a href="https://enzostvs-deepsite.hf.space" style="color: #fff;" target="_blank" >DeepSite</a> <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;"></p></body>
537
+ </html>