Ivanhoe9 commited on
Commit
d78fa94
·
verified ·
1 Parent(s): 0df63b9

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +760 -19
index.html CHANGED
@@ -1,19 +1,760 @@
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>Conway's Game of Life - Built with anycoder</title>
7
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
8
+ <style>
9
+ :root {
10
+ --primary: #4a6fa5;
11
+ --secondary: #166088;
12
+ --accent: #4fc3f7;
13
+ --dark: #1a2a3a;
14
+ --light: #f8f9fa;
15
+ --success: #4caf50;
16
+ --danger: #f44336;
17
+ --shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
18
+ --transition: all 0.3s ease;
19
+ }
20
+
21
+ * {
22
+ margin: 0;
23
+ padding: 0;
24
+ box-sizing: border-box;
25
+ }
26
+
27
+ body {
28
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
29
+ background-color: var(--light);
30
+ color: var(--dark);
31
+ line-height: 1.6;
32
+ padding: 20px;
33
+ min-height: 100vh;
34
+ display: flex;
35
+ flex-direction: column;
36
+ align-items: center;
37
+ }
38
+
39
+ header {
40
+ width: 100%;
41
+ max-width: 1200px;
42
+ margin-bottom: 20px;
43
+ display: flex;
44
+ justify-content: space-between;
45
+ align-items: center;
46
+ flex-wrap: wrap;
47
+ gap: 15px;
48
+ }
49
+
50
+ .logo {
51
+ font-size: 1.8rem;
52
+ font-weight: 700;
53
+ color: var(--primary);
54
+ text-decoration: none;
55
+ display: flex;
56
+ align-items: center;
57
+ gap: 10px;
58
+ }
59
+
60
+ .logo i {
61
+ color: var(--accent);
62
+ }
63
+
64
+ .anycoder-link {
65
+ color: var(--secondary);
66
+ text-decoration: none;
67
+ font-size: 0.9rem;
68
+ font-weight: 500;
69
+ transition: var(--transition);
70
+ }
71
+
72
+ .anycoder-link:hover {
73
+ color: var(--accent);
74
+ text-decoration: underline;
75
+ }
76
+
77
+ .controls {
78
+ width: 100%;
79
+ max-width: 1200px;
80
+ background-color: white;
81
+ border-radius: 12px;
82
+ padding: 20px;
83
+ box-shadow: var(--shadow);
84
+ margin-bottom: 20px;
85
+ display: flex;
86
+ flex-wrap: wrap;
87
+ gap: 15px;
88
+ justify-content: center;
89
+ align-items: center;
90
+ }
91
+
92
+ .control-group {
93
+ display: flex;
94
+ flex-direction: column;
95
+ gap: 8px;
96
+ }
97
+
98
+ .control-group label {
99
+ font-weight: 600;
100
+ font-size: 0.9rem;
101
+ color: var(--dark);
102
+ }
103
+
104
+ button, select, input {
105
+ padding: 10px 15px;
106
+ border-radius: 8px;
107
+ border: 1px solid #ddd;
108
+ background-color: white;
109
+ font-family: inherit;
110
+ font-size: 1rem;
111
+ cursor: pointer;
112
+ transition: var(--transition);
113
+ }
114
+
115
+ button {
116
+ background-color: var(--primary);
117
+ color: white;
118
+ border: none;
119
+ font-weight: 600;
120
+ display: flex;
121
+ align-items: center;
122
+ gap: 8px;
123
+ }
124
+
125
+ button:hover {
126
+ background-color: var(--secondary);
127
+ transform: translateY(-2px);
128
+ }
129
+
130
+ button:disabled {
131
+ background-color: #cccccc;
132
+ cursor: not-allowed;
133
+ transform: none;
134
+ }
135
+
136
+ select, input {
137
+ width: 100%;
138
+ max-width: 200px;
139
+ }
140
+
141
+ select:focus, input:focus {
142
+ outline: 2px solid var(--accent);
143
+ border-color: var(--accent);
144
+ }
145
+
146
+ .game-container {
147
+ width: 100%;
148
+ max-width: 1200px;
149
+ background-color: white;
150
+ border-radius: 12px;
151
+ padding: 20px;
152
+ box-shadow: var(--shadow);
153
+ display: flex;
154
+ flex-direction: column;
155
+ align-items: center;
156
+ }
157
+
158
+ .grid-container {
159
+ width: 100%;
160
+ aspect-ratio: 1 / 1;
161
+ max-width: 800px;
162
+ display: grid;
163
+ grid-template-columns: repeat(var(--cols), 1fr);
164
+ gap: 1px;
165
+ background-color: #e0e0e0;
166
+ border-radius: 8px;
167
+ overflow: hidden;
168
+ margin: 20px 0;
169
+ touch-action: none;
170
+ }
171
+
172
+ .cell {
173
+ background-color: white;
174
+ aspect-ratio: 1 / 1;
175
+ transition: background-color 0.1s ease;
176
+ }
177
+
178
+ .cell.alive {
179
+ background-color: var(--primary);
180
+ }
181
+
182
+ .stats {
183
+ width: 100%;
184
+ display: flex;
185
+ justify-content: space-around;
186
+ flex-wrap: wrap;
187
+ gap: 15px;
188
+ margin-top: 10px;
189
+ }
190
+
191
+ .stat {
192
+ background-color: rgba(74, 111, 165, 0.1);
193
+ padding: 10px 15px;
194
+ border-radius: 8px;
195
+ font-weight: 600;
196
+ color: var(--primary);
197
+ }
198
+
199
+ .stat span {
200
+ color: var(--secondary);
201
+ margin-left: 5px;
202
+ }
203
+
204
+ .presets {
205
+ display: flex;
206
+ flex-wrap: wrap;
207
+ gap: 10px;
208
+ justify-content: center;
209
+ margin-top: 15px;
210
+ }
211
+
212
+ .preset-btn {
213
+ background-color: var(--light);
214
+ color: var(--dark);
215
+ border: 1px solid #ddd;
216
+ }
217
+
218
+ .preset-btn:hover {
219
+ background-color: var(--accent);
220
+ color: white;
221
+ border-color: var(--accent);
222
+ }
223
+
224
+ footer {
225
+ margin-top: 20px;
226
+ text-align: center;
227
+ color: #666;
228
+ font-size: 0.9rem;
229
+ }
230
+
231
+ footer a {
232
+ color: var(--primary);
233
+ text-decoration: none;
234
+ font-weight: 600;
235
+ }
236
+
237
+ footer a:hover {
238
+ text-decoration: underline;
239
+ }
240
+
241
+ @media (max-width: 768px) {
242
+ .controls {
243
+ flex-direction: column;
244
+ align-items: stretch;
245
+ }
246
+
247
+ .control-group {
248
+ width: 100%;
249
+ }
250
+
251
+ .grid-container {
252
+ max-width: 100%;
253
+ }
254
+ }
255
+
256
+ @media (max-width: 480px) {
257
+ body {
258
+ padding: 10px;
259
+ }
260
+
261
+ header {
262
+ flex-direction: column;
263
+ align-items: flex-start;
264
+ }
265
+
266
+ .stats {
267
+ flex-direction: column;
268
+ align-items: center;
269
+ }
270
+ }
271
+ </style>
272
+ </head>
273
+ <body>
274
+ <header>
275
+ <a href="#" class="logo">
276
+ <i class="fas fa-gamepad"></i>
277
+ <span>Game of Life</span>
278
+ </a>
279
+ <a href="https://huggingface.co/spaces/akhaliq/anycoder" class="anycoder-link" target="_blank">Built with anycoder</a>
280
+ </header>
281
+
282
+ <div class="controls">
283
+ <div class="control-group">
284
+ <label for="grid-size">Grid Size</label>
285
+ <select id="grid-size">
286
+ <option value="20">20x20</option>
287
+ <option value="30" selected>30x30</option>
288
+ <option value="40">40x40</option>
289
+ <option value="50">50x50</option>
290
+ </select>
291
+ </div>
292
+
293
+ <div class="control-group">
294
+ <label for="speed">Speed (ms)</label>
295
+ <input type="range" id="speed" min="50" max="1000" value="200">
296
+ </div>
297
+
298
+ <button id="start-btn">
299
+ <i class="fas fa-play"></i>
300
+ <span>Start</span>
301
+ </button>
302
+
303
+ <button id="stop-btn" disabled>
304
+ <i class="fas fa-stop"></i>
305
+ <span>Stop</span>
306
+ </button>
307
+
308
+ <button id="clear-btn">
309
+ <i class="fas fa-trash"></i>
310
+ <span>Clear</span>
311
+ </button>
312
+
313
+ <button id="random-btn">
314
+ <i class="fas fa-random"></i>
315
+ <span>Random</span>
316
+ </button>
317
+ </div>
318
+
319
+ <div class="game-container">
320
+ <div class="grid-container" id="grid"></div>
321
+
322
+ <div class="stats">
323
+ <div class="stat">Generation: <span id="generation">0</span></div>
324
+ <div class="stat">Population: <span id="population">0</span></div>
325
+ <div class="stat">Status: <span id="status">Stopped</span></div>
326
+ </div>
327
+
328
+ <div class="presets">
329
+ <button class="preset-btn" data-preset="glider">Glider</button>
330
+ <button class="preset-btn" data-preset="pulsar">Pulsar</button>
331
+ <button class="preset-btn" data-preset="spaceship">Spaceship</button>
332
+ <button class="preset-btn" data-preset="beacon">Beacon</button>
333
+ </div>
334
+ </div>
335
+
336
+ <footer>
337
+ <p>Conway's Game of Life - A cellular automaton devised by mathematician John Conway.</p>
338
+ <p>Rules: 1. Any live cell with fewer than two live neighbors dies (underpopulation). 2. Any live cell with two or three live neighbors lives on. 3. Any live cell with more than three live neighbors dies (overpopulation). 4. Any dead cell with exactly three live neighbors becomes a live cell (reproduction).</p>
339
+ </footer>
340
+
341
+ <script>
342
+ document.addEventListener('DOMContentLoaded', () => {
343
+ // DOM Elements
344
+ const gridContainer = document.getElementById('grid');
345
+ const startBtn = document.getElementById('start-btn');
346
+ const stopBtn = document.getElementById('stop-btn');
347
+ const clearBtn = document.getElementById('clear-btn');
348
+ const randomBtn = document.getElementById('random-btn');
349
+ const gridSizeSelect = document.getElementById('grid-size');
350
+ const speedInput = document.getElementById('speed');
351
+ const generationSpan = document.getElementById('generation');
352
+ const populationSpan = document.getElementById('population');
353
+ const statusSpan = document.getElementById('status');
354
+ const presetButtons = document.querySelectorAll('.preset-btn');
355
+
356
+ // Game state
357
+ let grid = [];
358
+ let rows = 30;
359
+ let cols = 30;
360
+ let isRunning = false;
361
+ let generation = 0;
362
+ let animationId = null;
363
+ let speed = 200;
364
+ let isDrawing = false;
365
+ let isErasing = false;
366
+
367
+ // Initialize the game
368
+ initGame();
369
+
370
+ // Event Listeners
371
+ startBtn.addEventListener('click', startGame);
372
+ stopBtn.addEventListener('click', stopGame);
373
+ clearBtn.addEventListener('click', clearGrid);
374
+ randomBtn.addEventListener('click', randomizeGrid);
375
+ gridSizeSelect.addEventListener('change', changeGridSize);
376
+ speedInput.addEventListener('input', updateSpeed);
377
+
378
+ // Grid interaction
379
+ gridContainer.addEventListener('mousedown', startDrawing);
380
+ gridContainer.addEventListener('mouseup', stopDrawing);
381
+ gridContainer.addEventListener('mouseleave', stopDrawing);
382
+ gridContainer.addEventListener('mousemove', drawCell);
383
+
384
+ // Touch support
385
+ gridContainer.addEventListener('touchstart', handleTouchStart);
386
+ gridContainer.addEventListener('touchend', stopDrawing);
387
+ gridContainer.addEventListener('touchmove', handleTouchMove);
388
+
389
+ // Preset patterns
390
+ presetButtons.forEach(button => {
391
+ button.addEventListener('click', () => {
392
+ const preset = button.getAttribute('data-preset');
393
+ loadPreset(preset);
394
+ });
395
+ });
396
+
397
+ // Initialize the game grid
398
+ function initGame() {
399
+ createGrid();
400
+ updateStats();
401
+ }
402
+
403
+ // Create the grid
404
+ function createGrid() {
405
+ gridContainer.style.setProperty('--cols', cols);
406
+ gridContainer.innerHTML = '';
407
+
408
+ grid = Array(rows).fill().map(() => Array(cols).fill(false));
409
+
410
+ for (let row = 0; row < rows; row++) {
411
+ for (let col = 0; col < cols; col++) {
412
+ const cell = document.createElement('div');
413
+ cell.className = 'cell';
414
+ cell.dataset.row = row;
415
+ cell.dataset.col = col;
416
+ cell.addEventListener('click', toggleCell);
417
+ gridContainer.appendChild(cell);
418
+ }
419
+ }
420
+ }
421
+
422
+ // Change grid size
423
+ function changeGridSize() {
424
+ const size = parseInt(gridSizeSelect.value);
425
+ rows = size;
426
+ cols = size;
427
+ generation = 0;
428
+ stopGame();
429
+ createGrid();
430
+ updateStats();
431
+ }
432
+
433
+ // Update simulation speed
434
+ function updateSpeed() {
435
+ speed = parseInt(speedInput.value);
436
+ if (isRunning) {
437
+ stopGame();
438
+ startGame();
439
+ }
440
+ }
441
+
442
+ // Start the game
443
+ function startGame() {
444
+ if (isRunning) return;
445
+
446
+ isRunning = true;
447
+ startBtn.disabled = true;
448
+ stopBtn.disabled = false;
449
+ statusSpan.textContent = 'Running';
450
+ runSimulation();
451
+ }
452
+
453
+ // Stop the game
454
+ function stopGame() {
455
+ isRunning = false;
456
+ startBtn.disabled = false;
457
+ stopBtn.disabled = true;
458
+ statusSpan.textContent = 'Stopped';
459
+ if (animationId) {
460
+ cancelAnimationFrame(animationId);
461
+ animationId = null;
462
+ }
463
+ }
464
+
465
+ // Clear the grid
466
+ function clearGrid() {
467
+ stopGame();
468
+ grid.forEach(row => row.fill(false));
469
+ updateGridDisplay();
470
+ generation = 0;
471
+ updateStats();
472
+ }
473
+
474
+ // Randomize the grid
475
+ function randomizeGrid() {
476
+ stopGame();
477
+ grid = grid.map(row => row.map(() => Math.random() > 0.7));
478
+ updateGridDisplay();
479
+ generation = 0;
480
+ updateStats();
481
+ }
482
+
483
+ // Run the simulation
484
+ function runSimulation() {
485
+ if (!isRunning) return;
486
+
487
+ const newGrid = JSON.parse(JSON.stringify(grid));
488
+
489
+ for (let row = 0; row < rows; row++) {
490
+ for (let col = 0; col < cols; col++) {
491
+ const neighbors = countNeighbors(row, col);
492
+
493
+ // Apply Conway's rules
494
+ if (grid[row][col]) {
495
+ // Cell is alive
496
+ if (neighbors < 2 || neighbors > 3) {
497
+ newGrid[row][col] = false; // Dies
498
+ }
499
+ } else {
500
+ // Cell is dead
501
+ if (neighbors === 3) {
502
+ newGrid[row][col] = true; // Becomes alive
503
+ }
504
+ }
505
+ }
506
+ }
507
+
508
+ grid = newGrid;
509
+ generation++;
510
+ updateGridDisplay();
511
+ updateStats();
512
+
513
+ animationId = setTimeout(() => runSimulation(), speed);
514
+ }
515
+
516
+ // Count live neighbors
517
+ function countNeighbors(row, col) {
518
+ let count = 0;
519
+ for (let i = -1; i <= 1; i++) {
520
+ for (let j = -1; j <= 1; j++) {
521
+ if (i === 0 && j === 0) continue; // Skip self
522
+
523
+ const newRow = row + i;
524
+ const newCol = col + j;
525
+
526
+ if (newRow >= 0 && newRow < rows && newCol >= 0 && newCol < cols) {
527
+ if (grid[newRow][newCol]) {
528
+ count++;
529
+ }
530
+ }
531
+ }
532
+ }
533
+ return count;
534
+ }
535
+
536
+ // Update the grid display
537
+ function updateGridDisplay() {
538
+ const cells = gridContainer.querySelectorAll('.cell');
539
+ cells.forEach(cell => {
540
+ const row = parseInt(cell.dataset.row);
541
+ const col = parseInt(cell.dataset.col);
542
+ if (grid[row][col]) {
543
+ cell.classList.add('alive');
544
+ } else {
545
+ cell.classList.remove('alive');
546
+ }
547
+ });
548
+ }
549
+
550
+ // Update statistics
551
+ function updateStats() {
552
+ generationSpan.textContent = generation;
553
+
554
+ let population = 0;
555
+ grid.forEach(row => {
556
+ row.forEach(cell => {
557
+ if (cell) population++;
558
+ });
559
+ });
560
+ populationSpan.textContent = population;
561
+ }
562
+
563
+ // Toggle cell state
564
+ function toggleCell(e) {
565
+ if (e.target.classList.contains('cell')) {
566
+ const row = parseInt(e.target.dataset.row);
567
+ const col = parseInt(e.target.dataset.col);
568
+ grid[row][col] = !grid[row][col];
569
+ e.target.classList.toggle('alive');
570
+ updateStats();
571
+ }
572
+ }
573
+
574
+ // Start drawing
575
+ function startDrawing(e) {
576
+ if (e.target.classList.contains('cell')) {
577
+ isDrawing = true;
578
+ isErasing = e.target.classList.contains('alive');
579
+ toggleCell(e);
580
+ }
581
+ }
582
+
583
+ // Stop drawing
584
+ function stopDrawing() {
585
+ isDrawing = false;
586
+ }
587
+
588
+ // Draw cells
589
+ function drawCell(e) {
590
+ if (!isDrawing) return;
591
+ e.preventDefault();
592
+
593
+ if (e.target.classList.contains('cell')) {
594
+ const row = parseInt(e.target.dataset.row);
595
+ const col = parseInt(e.target.dataset.col);
596
+
597
+ if (isErasing) {
598
+ if (grid[row][col]) {
599
+ grid[row][col] = false;
600
+ e.target.classList.remove('alive');
601
+ updateStats();
602
+ }
603
+ } else {
604
+ if (!grid[row][col]) {
605
+ grid[row][col] = true;
606
+ e.target.classList.add('alive');
607
+ updateStats();
608
+ }
609
+ }
610
+ }
611
+ }
612
+
613
+ // Touch support
614
+ function handleTouchStart(e) {
615
+ e.preventDefault();
616
+ const touch = e.touches[0];
617
+ const element = document.elementFromPoint(touch.clientX, touch.clientY);
618
+ if (element && element.classList.contains('cell')) {
619
+ isDrawing = true;
620
+ isErasing = element.classList.contains('alive');
621
+ toggleCell({ target: element });
622
+ }
623
+ }
624
+
625
+ function handleTouchMove(e) {
626
+ e.preventDefault();
627
+ if (!isDrawing) return;
628
+
629
+ const touch = e.touches[0];
630
+ const element = document.elementFromPoint(touch.clientX, touch.clientY);
631
+ if (element && element.classList.contains('cell')) {
632
+ drawCell({ target: element, preventDefault: () => {} });
633
+ }
634
+ }
635
+
636
+ // Load preset patterns
637
+ function loadPreset(preset) {
638
+ stopGame();
639
+ clearGrid();
640
+
641
+ switch(preset) {
642
+ case 'glider':
643
+ // Glider pattern
644
+ if (rows >= 3 && cols >= 3) {
645
+ grid[1][2] = true;
646
+ grid[2][3] = true;
647
+ grid[3][1] = true;
648
+ grid[3][2] = true;
649
+ grid[3][3] = true;
650
+ }
651
+ break;
652
+
653
+ case 'pulsar':
654
+ // Pulsar pattern (simplified)
655
+ if (rows >= 15 && cols >= 15) {
656
+ const centerRow = Math.floor(rows / 2);
657
+ const centerCol = Math.floor(cols / 2);
658
+
659
+ // Top left block
660
+ grid[centerRow-2][centerCol-4] = true;
661
+ grid[centerRow-2][centerCol-3] = true;
662
+ grid[centerRow-2][centerCol-2] = true;
663
+ grid[centerRow-1][centerCol-6] = true;
664
+ grid[centerRow-1][centerCol-1] = true;
665
+ grid[centerRow][centerCol-6] = true;
666
+ grid[centerRow][centerCol-1] = true;
667
+ grid[centerRow+1][centerCol-6] = true;
668
+ grid[centerRow+1][centerCol-1] = true;
669
+ grid[centerRow+2][centerCol-4] = true;
670
+ grid[centerRow+2][centerCol-3] = true;
671
+ grid[centerRow+2][centerCol-2] = true;
672
+
673
+ // Top right block
674
+ grid[centerRow-2][centerCol+2] = true;
675
+ grid[centerRow-2][centerCol+3] = true;
676
+ grid[centerRow-2][centerCol+4] = true;
677
+ grid[centerRow-1][centerCol+1] = true;
678
+ grid[centerRow-1][centerCol+6] = true;
679
+ grid[centerRow][centerCol+1] = true;
680
+ grid[centerRow][centerCol+6] = true;
681
+ grid[centerRow+1][centerCol+1] = true;
682
+ grid[centerRow+1][centerCol+6] = true;
683
+ grid[centerRow+2][centerCol+2] = true;
684
+ grid[centerRow+2][centerCol+3] = true;
685
+ grid[centerRow+2][centerCol+4] = true;
686
+
687
+ // Bottom left block
688
+ grid[centerRow+4][centerCol-4] = true;
689
+ grid[centerRow+4][centerCol-3] = true;
690
+ grid[centerRow+4][centerCol-2] = true;
691
+ grid[centerRow+5][centerCol-6] = true;
692
+ grid[centerRow+5][centerCol-1] = true;
693
+ grid[centerRow+6][centerCol-6] = true;
694
+ grid[centerRow+6][centerCol-1] = true;
695
+ grid[centerRow+7][centerCol-6] = true;
696
+ grid[centerRow+7][centerCol-1] = true;
697
+ grid[centerRow+8][centerCol-4] = true;
698
+ grid[centerRow+8][centerCol-3] = true;
699
+ grid[centerRow+8][centerCol-2] = true;
700
+
701
+ // Bottom right block
702
+ grid[centerRow+4][centerCol+2] = true;
703
+ grid[centerRow+4][centerCol+3] = true;
704
+ grid[centerRow+4][centerCol+4] = true;
705
+ grid[centerRow+5][centerCol+1] = true;
706
+ grid[centerRow+5][centerCol+6] = true;
707
+ grid[centerRow+6][centerCol+1] = true;
708
+ grid[centerRow+6][centerCol+6] = true;
709
+ grid[centerRow+7][centerCol+1] = true;
710
+ grid[centerRow+7][centerCol+6] = true;
711
+ grid[centerRow+8][centerCol+2] = true;
712
+ grid[centerRow+8][centerCol+3] = true;
713
+ grid[centerRow+8][centerCol+4] = true;
714
+ }
715
+ break;
716
+
717
+ case 'spaceship':
718
+ // Lightweight spaceship
719
+ if (rows >= 5 && cols >= 5) {
720
+ const centerRow = Math.floor(rows / 2);
721
+ const centerCol = Math.floor(cols / 2);
722
+
723
+ grid[centerRow][centerCol+1] = true;
724
+ grid[centerRow][centerCol+4] = true;
725
+ grid[centerRow+1][centerCol+4] = true;
726
+ grid[centerRow+2][centerCol] = true;
727
+ grid[centerRow+2][centerCol+4] = true;
728
+ grid[centerRow+3][centerCol+1] = true;
729
+ grid[centerRow+3][centerCol+2] = true;
730
+ grid[centerRow+3][centerCol+3] = true;
731
+ grid[centerRow+3][centerCol+4] = true;
732
+ }
733
+ break;
734
+
735
+ case 'beacon':
736
+ // Beacon pattern
737
+ if (rows >= 4 && cols >= 4) {
738
+ const centerRow = Math.floor(rows / 2);
739
+ const centerCol = Math.floor(cols / 2);
740
+
741
+ grid[centerRow][centerCol] = true;
742
+ grid[centerRow][centerCol+1] = true;
743
+ grid[centerRow+1][centerCol] = true;
744
+ grid[centerRow+1][centerCol+1] = true;
745
+
746
+ grid[centerRow+2][centerCol+2] = true;
747
+ grid[centerRow+2][centerCol+3] = true;
748
+ grid[centerRow+3][centerCol+2] = true;
749
+ grid[centerRow+3][centerCol+3] = true;
750
+ }
751
+ break;
752
+ }
753
+
754
+ updateGridDisplay();
755
+ updateStats();
756
+ }
757
+ });
758
+ </script>
759
+ </body>
760
+ </html>