Phoenixoni commited on
Commit
d51d7c4
·
verified ·
1 Parent(s): 06acc6e

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +642 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Farm
3
- emoji: 🏆
4
- colorFrom: green
5
- colorTo: purple
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: farm
3
+ emoji: 🐳
4
+ colorFrom: red
5
+ colorTo: gray
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,642 @@
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="ru">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>3D Формикарий - Муравьиная ферма</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
9
+ <script src="https://cdn.jsdelivr.net/npm/vanta@0.5.21/dist/vanta.net.min.js"></script>
10
+ <style>
11
+ #ant-farm {
12
+ width: 100%;
13
+ height: 70vh;
14
+ position: relative;
15
+ border-radius: 12px;
16
+ overflow: hidden;
17
+ box-shadow: 0 10px 25px rgba(0,0,0,0.2);
18
+ }
19
+ .ant {
20
+ position: absolute;
21
+ width: 8px;
22
+ height: 4px;
23
+ background-color: #333;
24
+ border-radius: 4px;
25
+ transform-origin: center;
26
+ }
27
+ .food {
28
+ position: absolute;
29
+ width: 10px;
30
+ height: 10px;
31
+ border-radius: 50%;
32
+ background-color: #f59e0b;
33
+ }
34
+ .tunnel {
35
+ position: absolute;
36
+ background-color: #d1d5db;
37
+ border-radius: 4px;
38
+ }
39
+ .queen {
40
+ position: absolute;
41
+ width: 12px;
42
+ height: 6px;
43
+ background-color: #8b5cf6;
44
+ border-radius: 6px;
45
+ }
46
+ .control-panel {
47
+ backdrop-filter: blur(10px);
48
+ background-color: rgba(255,255,255,0.8);
49
+ }
50
+ .ant-leg {
51
+ position: absolute;
52
+ width: 3px;
53
+ height: 1px;
54
+ background-color: #333;
55
+ }
56
+ @keyframes ant-walk {
57
+ 0%, 100% { transform: rotate(0deg); }
58
+ 50% { transform: rotate(10deg); }
59
+ }
60
+ </style>
61
+ </head>
62
+ <body class="bg-gray-100 min-h-screen">
63
+ <div class="container mx-auto px-4 py-8">
64
+ <header class="text-center mb-8">
65
+ <h1 class="text-4xl font-bold text-gray-800 mb-2">3D Формикарий</h1>
66
+ <p class="text-lg text-gray-600">Интерактивный симулятор муравьиной колонии</p>
67
+ </header>
68
+
69
+ <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
70
+ <div class="lg:col-span-2">
71
+ <div id="ant-farm" class="bg-amber-50 relative">
72
+ <!-- 3D сцена будет здесь -->
73
+ </div>
74
+
75
+ <div class="mt-4 bg-white rounded-lg shadow-md p-4">
76
+ <h2 class="text-xl font-semibold mb-3">Статистика колонии</h2>
77
+ <div class="grid grid-cols-3 gap-4 text-center">
78
+ <div class="bg-blue-50 p-3 rounded-lg">
79
+ <p class="text-sm text-blue-600">Муравьёв</p>
80
+ <p id="ant-count" class="text-2xl font-bold">1</p>
81
+ </div>
82
+ <div class="bg-purple-50 p-3 rounded-lg">
83
+ <p class="text-sm text-purple-600">Еды собрано</p>
84
+ <p id="food-count" class="text-2xl font-bold">0</p>
85
+ </div>
86
+ <div class="bg-green-50 p-3 rounded-lg">
87
+ <p class="text-sm text-green-600">Время</p>
88
+ <p id="time-count" class="text-2xl font-bold">0:00</p>
89
+ </div>
90
+ </div>
91
+ </div>
92
+ </div>
93
+
94
+ <div class="control-panel p-6 rounded-lg shadow-md">
95
+ <h2 class="text-xl font-semibold mb-4">Управление фермой</h2>
96
+
97
+ <div class="mb-6">
98
+ <label class="block text-sm font-medium text-gray-700 mb-2">Скорость симуляции</label>
99
+ <input id="speed-slider" type="range" min="1" max="10" value="3" class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer">
100
+ <div class="flex justify-between text-xs text-gray-500 mt-1">
101
+ <span>Медленно</span>
102
+ <span>Быстро</span>
103
+ </div>
104
+ </div>
105
+
106
+ <div class="mb-6">
107
+ <label class="block text-sm font-medium text-gray-700 mb-2">Количество еды</label>
108
+ <input id="food-slider" type="range" min="1" max="20" value="5" class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer">
109
+ </div>
110
+
111
+ <div class="mb-6">
112
+ <label class="block text-sm font-medium text-gray-700 mb-2">Тип муравьёв</label>
113
+ <select id="ant-type" class="mt-1 block w-full pl-3 pr-10 py-2 text-base border-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md">
114
+ <option value="worker">Рабочие</option>
115
+ <option value="soldier">Солдаты</option>
116
+ <option value="harvester">Собиратели</option>
117
+ </select>
118
+ </div>
119
+
120
+ <div class="grid grid-cols-2 gap-3 mb-6">
121
+ <button id="add-ant" class="bg-indigo-600 text-white py-2 px-4 rounded-md hover:bg-indigo-700 transition">+ Муравей</button>
122
+ <button id="add-queen" class="bg-purple-600 text-white py-2 px-4 rounded-md hover:bg-purple-700 transition">+ Королева</button>
123
+ <button id="add-food" class="bg-amber-500 text-white py-2 px-4 rounded-md hover:bg-amber-600 transition">+ Еда</button>
124
+ <button id="reset" class="bg-gray-600 text-white py-2 px-4 rounded-md hover:bg-gray-700 transition">Сброс</button>
125
+ </div>
126
+
127
+ <div class="bg-yellow-50 border-l-4 border-yellow-400 p-4 mb-6">
128
+ <div class="flex">
129
+ <div class="ml-3">
130
+ <p class="text-sm text-yellow-700">
131
+ <strong>Совет:</strong> Кликните по ферме, чтобы добавить еду в указанное место.
132
+ </p>
133
+ </div>
134
+ </div>
135
+ </div>
136
+
137
+ <div class="border-t pt-4">
138
+ <h3 class="font-medium mb-2">Информация о колонии</h3>
139
+ <div id="colony-info" class="text-sm text-gray-600">
140
+ Колония только что основана. Добавьте больше муравьёв и еды для развития!
141
+ </div>
142
+ </div>
143
+ </div>
144
+ </div>
145
+
146
+ <div class="mt-8 bg-white rounded-lg shadow-md overflow-hidden">
147
+ <div class="px-6 py-4 border-b">
148
+ <h2 class="text-xl font-semibold">Журнал событий</h2>
149
+ </div>
150
+ <div id="event-log" class="px-6 py-4 h-40 overflow-y-auto text-sm space-y-2">
151
+ <p class="text-gray-500">[Система] Формикарий инициализирован. Добро пожаловать!</p>
152
+ </div>
153
+ </div>
154
+ </div>
155
+
156
+ <script>
157
+ document.addEventListener('DOMContentLoaded', function() {
158
+ // Инициализация 3D сцены
159
+ const container = document.getElementById('ant-farm');
160
+ const width = container.clientWidth;
161
+ const height = container.clientHeight;
162
+
163
+ // Создаем 2D симуляцию вместо 3D для упрощения
164
+ const farmWidth = width;
165
+ const farmHeight = height;
166
+
167
+ // Состояние симуляции
168
+ let ants = [];
169
+ let foods = [];
170
+ let tunnels = [];
171
+ let queens = [];
172
+ let antCount = 1;
173
+ let foodCollected = 0;
174
+ let simulationTime = 0;
175
+ let simulationSpeed = 3;
176
+ let animationId = null;
177
+
178
+ // Создаем первого муравья (королеву)
179
+ addQueen(farmWidth / 2, farmHeight / 2);
180
+
181
+ // Добавляем начальные туннели
182
+ createInitialTunnels();
183
+
184
+ // Добавляем начальную еду
185
+ addInitialFood();
186
+
187
+ // Обработчики кнопок
188
+ document.getElementById('add-ant').addEventListener('click', function() {
189
+ const x = Math.random() * (farmWidth - 40) + 20;
190
+ const y = Math.random() * (farmHeight - 40) + 20;
191
+ addAnt(x, y);
192
+ logEvent(`Добавлен новый муравей в позиции (${Math.round(x)}, ${Math.round(y)})`);
193
+ });
194
+
195
+ document.getElementById('add-queen').addEventListener('click', function() {
196
+ const x = Math.random() * (farmWidth - 40) + 20;
197
+ const y = Math.random() * (farmHeight - 40) + 20;
198
+ addQueen(x, y);
199
+ logEvent(`Добавлена новая королева в позиции (${Math.round(x)}, ${Math.round(y)})`);
200
+ });
201
+
202
+ document.getElementById('add-food').addEventListener('click', function() {
203
+ const x = Math.random() * (farmWidth - 40) + 20;
204
+ const y = Math.random() * (farmHeight - 40) + 20;
205
+ addFood(x, y);
206
+ logEvent(`Добавлена новая еда в позиции (${Math.round(x)}, ${Math.round(y)})`);
207
+ });
208
+
209
+ document.getElementById('reset').addEventListener('click', function() {
210
+ resetSimulation();
211
+ logEvent(`Симуляция сброшена к начальному состоянию`);
212
+ });
213
+
214
+ document.getElementById('speed-slider').addEventListener('input', function(e) {
215
+ simulationSpeed = parseInt(e.target.value);
216
+ });
217
+
218
+ document.getElementById('food-slider').addEventListener('input', function(e) {
219
+ // Применяется при следующем сбросе
220
+ });
221
+
222
+ // Обработчик клика по ферме для добавления еды
223
+ container.addEventListener('click', function(e) {
224
+ const rect = container.getBoundingClientRect();
225
+ const x = e.clientX - rect.left;
226
+ const y = e.clientY - rect.top;
227
+ addFood(x, y);
228
+ logEvent(`Игрок добавил еду в позиции (${Math.round(x)}, ${Math.round(y)})`);
229
+ });
230
+
231
+ // Функции симуляции
232
+ function addAnt(x, y) {
233
+ const ant = document.createElement('div');
234
+ ant.className = 'ant';
235
+ ant.style.left = `${x}px`;
236
+ ant.style.top = `${y}px`;
237
+
238
+ // Добавляем ножки для анимации
239
+ for (let i = 0; i < 6; i++) {
240
+ const leg = document.createElement('div');
241
+ leg.className = 'ant-leg';
242
+ leg.style.top = '2px';
243
+ leg.style.left = `${i % 2 === 0 ? -2 : 7}px`;
244
+ leg.style.transform = `rotate(${i % 2 === 0 ? -30 : 30}deg)`;
245
+ leg.style.animation = `ant-walk 0.3s infinite ${i * 0.1}s alternate`;
246
+ ant.appendChild(leg);
247
+ }
248
+
249
+ container.appendChild(ant);
250
+ ants.push({
251
+ element: ant,
252
+ x: x,
253
+ y: y,
254
+ vx: (Math.random() - 0.5) * 2,
255
+ vy: (Math.random() - 0.5) * 2,
256
+ targetX: null,
257
+ targetY: null,
258
+ carryingFood: false,
259
+ type: document.getElementById('ant-type').value
260
+ });
261
+
262
+ antCount++;
263
+ updateStats();
264
+ }
265
+
266
+ function addQueen(x, y) {
267
+ const queen = document.createElement('div');
268
+ queen.className = 'queen';
269
+ queen.style.left = `${x}px`;
270
+ queen.style.top = `${y}px`;
271
+ container.appendChild(queen);
272
+
273
+ queens.push({
274
+ element: queen,
275
+ x: x,
276
+ y: y,
277
+ health: 100,
278
+ eggTimer: 0
279
+ });
280
+
281
+ updateColonyInfo();
282
+ }
283
+
284
+ function addFood(x, y) {
285
+ const food = document.createElement('div');
286
+ food.className = 'food';
287
+ food.style.left = `${x}px`;
288
+ food.style.top = `${y}px`;
289
+ container.appendChild(food);
290
+
291
+ foods.push({
292
+ element: food,
293
+ x: x,
294
+ y: y,
295
+ amount: 10
296
+ });
297
+ }
298
+
299
+ function addInitialFood() {
300
+ const foodCount = parseInt(document.getElementById('food-slider').value);
301
+ for (let i = 0; i < foodCount; i++) {
302
+ const x = Math.random() * (farmWidth - 40) + 20;
303
+ const y = Math.random() * (farmHeight - 40) + 20;
304
+ addFood(x, y);
305
+ }
306
+ }
307
+
308
+ function createInitialTunnels() {
309
+ // Создаем центральную камеру
310
+ const chamber = document.createElement('div');
311
+ chamber.className = 'tunnel';
312
+ chamber.style.width = '80px';
313
+ chamber.style.height = '60px';
314
+ chamber.style.left = `${farmWidth/2 - 40}px`;
315
+ chamber.style.top = `${farmHeight/2 - 30}px`;
316
+ container.appendChild(chamber);
317
+
318
+ tunnels.push({
319
+ element: chamber,
320
+ x: farmWidth/2,
321
+ y: farmHeight/2,
322
+ width: 80,
323
+ height: 60,
324
+ type: 'chamber'
325
+ });
326
+
327
+ // Создаем несколько туннелей
328
+ for (let i = 0; i < 4; i++) {
329
+ const angle = (i / 4) * Math.PI * 2;
330
+ const length = 50 + Math.random() * 50;
331
+ const tunnelWidth = 10;
332
+
333
+ const tunnel = document.createElement('div');
334
+ tunnel.className = 'tunnel';
335
+ tunnel.style.width = `${length}px`;
336
+ tunnel.style.height = `${tunnelWidth}px`;
337
+ tunnel.style.left = `${farmWidth/2}px`;
338
+ tunnel.style.top = `${farmHeight/2 - tunnelWidth/2}px`;
339
+ tunnel.style.transform = `rotate(${angle}rad)`;
340
+ tunnel.style.transformOrigin = 'left center';
341
+ container.appendChild(tunnel);
342
+
343
+ tunnels.push({
344
+ element: tunnel,
345
+ x: farmWidth/2,
346
+ y: farmHeight/2,
347
+ length: length,
348
+ width: tunnelWidth,
349
+ angle: angle,
350
+ type: 'tunnel'
351
+ });
352
+ }
353
+ }
354
+
355
+ function updateAnt(ant, deltaTime) {
356
+ // Простое ИИ муравья
357
+ if (!ant.carryingFood) {
358
+ // Поиск еды
359
+ if (!ant.targetX || !ant.targetY || Math.random() < 0.01) {
360
+ findFood(ant);
361
+ }
362
+ } else {
363
+ // Возвращение в колонию
364
+ ant.targetX = farmWidth/2;
365
+ ant.targetY = farmHeight/2;
366
+ }
367
+
368
+ // Движение к цели
369
+ if (ant.targetX && ant.targetY) {
370
+ const dx = ant.targetX - ant.x;
371
+ const dy = ant.targetY - ant.y;
372
+ const dist = Math.sqrt(dx*dx + dy*dy);
373
+
374
+ if (dist < 5) {
375
+ // Достигли цели
376
+ if (ant.carryingFood) {
377
+ // Доставили еду в колонию
378
+ foodCollected++;
379
+ ant.carryingFood = false;
380
+ updateStats();
381
+ logEvent(`Муравей доставил еду в колонию! Всего собрано: ${foodCollected}`);
382
+ } else {
383
+ // Проверяем, есть ли здесь еда
384
+ for (let i = 0; i < foods.length; i++) {
385
+ const food = foods[i];
386
+ const fdx = food.x - ant.x;
387
+ const fdy = food.y - ant.y;
388
+ const fdist = Math.sqrt(fdx*fdx + fdy*fdy);
389
+
390
+ if (fdist < 15) {
391
+ // Собираем еду
392
+ food.amount--;
393
+ if (food.amount <= 0) {
394
+ container.removeChild(food.element);
395
+ foods.splice(i, 1);
396
+ }
397
+ ant.carryingFood = true;
398
+ logEvent(`Муравей нашёл еду и несёт её в колонию`);
399
+ break;
400
+ }
401
+ }
402
+ }
403
+
404
+ ant.targetX = null;
405
+ ant.targetY = null;
406
+ } else {
407
+ // Двигаемся к цели
408
+ const speed = 0.1 * simulationSpeed;
409
+ ant.vx = (dx / dist) * speed;
410
+ ant.vy = (dy / dist) * speed;
411
+ }
412
+ }
413
+
414
+ // Случайное блуждание, если нет цели
415
+ if (!ant.targetX || !ant.targetY) {
416
+ if (Math.random() < 0.05) {
417
+ ant.vx += (Math.random() - 0.5) * 0.2;
418
+ ant.vy += (Math.random() - 0.5) * 0.2;
419
+ }
420
+ }
421
+
422
+ // Ограничение скорости
423
+ const speed = Math.sqrt(ant.vx*ant.vx + ant.vy*ant.vy);
424
+ const maxSpeed = 0.15 * simulationSpeed;
425
+ if (speed > maxSpeed) {
426
+ ant.vx = (ant.vx / speed) * maxSpeed;
427
+ ant.vy = (ant.vy / speed) * maxSpeed;
428
+ }
429
+
430
+ // Обновление позиции
431
+ ant.x += ant.vx * deltaTime;
432
+ ant.y += ant.vy * deltaTime;
433
+
434
+ // Границы фермы
435
+ ant.x = Math.max(5, Math.min(farmWidth - 5, ant.x));
436
+ ant.y = Math.max(5, Math.min(farmHeight - 5, ant.y));
437
+
438
+ // Обновление DOM
439
+ ant.element.style.left = `${ant.x}px`;
440
+ ant.element.style.top = `${ant.y}px`;
441
+
442
+ // Направление движения
443
+ if (ant.vx !== 0 || ant.vy !== 0) {
444
+ const angle = Math.atan2(ant.vy, ant.vx);
445
+ ant.element.style.transform = `rotate(${angle}rad)`;
446
+ }
447
+
448
+ // Визуальное отличие для муравья с едой
449
+ if (ant.carryingFood) {
450
+ ant.element.style.backgroundColor = '#10b981';
451
+ } else {
452
+ ant.element.style.backgroundColor = '#333';
453
+ }
454
+ }
455
+
456
+ function findFood(ant) {
457
+ // Поиск ближайшей еды
458
+ let closestDist = Infinity;
459
+ let closestFood = null;
460
+
461
+ for (const food of foods) {
462
+ const dx = food.x - ant.x;
463
+ const dy = food.y - ant.y;
464
+ const dist = dx*dx + dy*dy;
465
+
466
+ if (dist < closestDist) {
467
+ closestDist = dist;
468
+ closestFood = food;
469
+ }
470
+ }
471
+
472
+ if (closestFood) {
473
+ ant.targetX = closestFood.x;
474
+ ant.targetY = closestFood.y;
475
+ } else {
476
+ // Случайное движение, если еды нет
477
+ ant.targetX = ant.x + (Math.random() - 0.5) * 100;
478
+ ant.targetY = ant.y + (Math.random() - 0.5) * 100;
479
+ }
480
+ }
481
+
482
+ function updateQueen(queen, deltaTime) {
483
+ // Королева откладывает яйца
484
+ queen.eggTimer += deltaTime * simulationSpeed / 1000;
485
+
486
+ if (queen.eggTimer > 10 && antCount < 100) {
487
+ queen.eggTimer = 0;
488
+
489
+ // Создаем нового муравья рядом с королевой
490
+ const angle = Math.random() * Math.PI * 2;
491
+ const dist = 20 + Math.random() * 10;
492
+ const x = queen.x + Math.cos(angle) * dist;
493
+ const y = queen.y + Math.sin(angle) * dist;
494
+
495
+ addAnt(x, y);
496
+ logEvent(`Королева произвела нового муравья! Всего муравьёв: ${antCount}`);
497
+ }
498
+
499
+ // Медленное движение королевы
500
+ if (Math.random() < 0.005) {
501
+ queen.x += (Math.random() - 0.5) * 5;
502
+ queen.y += (Math.random() - 0.5) * 5;
503
+
504
+ // Границы фермы
505
+ queen.x = Math.max(20, Math.min(farmWidth - 20, queen.x));
506
+ queen.y = Math.max(20, Math.min(farmHeight - 20, queen.y));
507
+
508
+ queen.element.style.left = `${queen.x}px`;
509
+ queen.element.style.top = `${queen.y}px`;
510
+ }
511
+ }
512
+
513
+ function updateStats() {
514
+ document.getElementById('ant-count').textContent = antCount;
515
+ document.getElementById('food-count').textContent = foodCollected;
516
+
517
+ // Обновляем информацию о колонии
518
+ updateColonyInfo();
519
+ }
520
+
521
+ function updateColonyInfo() {
522
+ let info = '';
523
+
524
+ if (queens.length === 0) {
525
+ info = 'Колония без королевы не может развиваться. Добавьте королеву!';
526
+ } else if (antCount < 5) {
527
+ info = 'Колония только что основана. Добавьте больше муравьёв и еды для развития!';
528
+ } else if (antCount < 20) {
529
+ info = 'Колония активно развивается. Муравьи собирают еду и расширяют туннели.';
530
+ } else {
531
+ info = 'Мощная колония! Муравьи ��ффективно работают и приносят много еды.';
532
+ }
533
+
534
+ if (foods.length < 3) {
535
+ info += ' Внимание: запасы еды заканчиваются!';
536
+ }
537
+
538
+ document.getElementById('colony-info').textContent = info;
539
+ }
540
+
541
+ function updateTime() {
542
+ simulationTime += 0.1 * simulationSpeed;
543
+ const minutes = Math.floor(simulationTime / 60);
544
+ const seconds = Math.floor(simulationTime % 60);
545
+ document.getElementById('time-count').textContent =
546
+ `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
547
+ }
548
+
549
+ function logEvent(message) {
550
+ const now = new Date();
551
+ const timeString = `[${now.getHours()}:${now.getMinutes()}:${now.getSeconds()}]`;
552
+ const eventElement = document.createElement('p');
553
+ eventElement.innerHTML = `<span class="text-gray-500">${timeString}</span> ${message}`;
554
+
555
+ const log = document.getElementById('event-log');
556
+ log.appendChild(eventElement);
557
+ log.scrollTop = log.scrollHeight;
558
+
559
+ // Ограничиваем количество сообщений
560
+ if (log.children.length > 50) {
561
+ log.removeChild(log.children[0]);
562
+ }
563
+ }
564
+
565
+ function resetSimulation() {
566
+ // Останавливаем анимацию
567
+ if (animationId) {
568
+ cancelAnimationFrame(animationId);
569
+ }
570
+
571
+ // Очищаем ферму
572
+ ants.forEach(ant => container.removeChild(ant.element));
573
+ foods.forEach(food => container.removeChild(food.element));
574
+ tunnels.forEach(tunnel => container.removeChild(tunnel.element));
575
+ queens.forEach(queen => container.removeChild(queen.element));
576
+
577
+ // Сбрасываем состояние
578
+ ants = [];
579
+ foods = [];
580
+ tunnels = [];
581
+ queens = [];
582
+ antCount = 0;
583
+ foodCollected = 0;
584
+ simulationTime = 0;
585
+
586
+ // Создаем новую колонию
587
+ addQueen(farmWidth / 2, farmHeight / 2);
588
+ createInitialTunnels();
589
+ addInitialFood();
590
+
591
+ // Обновляем статистику
592
+ updateStats();
593
+
594
+ // Запускаем симуляцию снова
595
+ startSimulation();
596
+ }
597
+
598
+ function startSimulation() {
599
+ let lastTime = performance.now();
600
+
601
+ function animate(currentTime) {
602
+ const deltaTime = currentTime - lastTime;
603
+ lastTime = currentTime;
604
+
605
+ // Обновляем всех муравьев
606
+ ants.forEach(ant => updateAnt(ant, deltaTime));
607
+
608
+ // Обновляем королев
609
+ queens.forEach(queen => updateQueen(queen, deltaTime));
610
+
611
+ // Обновляем время
612
+ updateTime();
613
+
614
+ animationId = requestAnimationFrame(animate);
615
+ }
616
+
617
+ animationId = requestAnimationFrame(animate);
618
+ }
619
+
620
+ // Запускаем симуляцию
621
+ startSimulation();
622
+
623
+ // Инициализация Vanta.js для фона
624
+ VANTA.NET({
625
+ el: "#ant-farm",
626
+ mouseControls: true,
627
+ touchControls: true,
628
+ gyroControls: false,
629
+ minHeight: 200.00,
630
+ minWidth: 200.00,
631
+ scale: 1.00,
632
+ scaleMobile: 1.00,
633
+ color: 0x7c3aed,
634
+ backgroundColor: 0xfff7ed,
635
+ points: 10.00,
636
+ maxDistance: 20.00,
637
+ spacing: 15.00
638
+ });
639
+ });
640
+ </script>
641
+ <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 <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Phoenixoni/farm" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
642
+ </html>