X commited on
Commit
3902bd5
·
verified ·
1 Parent(s): a3a494a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +55 -34
app.py CHANGED
@@ -5,7 +5,7 @@ import random
5
  import numpy as np
6
  from PIL import Image, ImageDraw
7
  import io
8
- import base64
9
  from urllib.parse import parse_qs, urlparse
10
  import threading
11
  import time
@@ -15,12 +15,13 @@ WORLD_SIZE = 40
15
  CELL_SIZE = 10
16
  MAX_CREATURES = 50
17
  PORT = 7890
18
- UPDATE_INTERVAL = 0.3 # секунд между обновлениями
19
 
20
- # ============== ПРОСТАЯ НЕЙРОСЕТЬ ==============
21
  class SimpleBrain:
22
  def __init__(self):
23
- self.weights = np.random.randn(8, 5) * 0.5
 
24
  self.bias = np.random.randn(5) * 0.5
25
 
26
  def forward(self, inputs):
@@ -36,9 +37,9 @@ class SimpleBrain:
36
 
37
  def mutate(self):
38
  if random.random() < 0.2:
39
- self.weights += np.random.randn(*self.weights.shape) * 0.3
40
  if random.random() < 0.2:
41
- self.bias += np.random.randn(*self.bias.shape) * 0.3
42
 
43
  # ============== СУЩЕСТВО ==============
44
  class Creature:
@@ -58,30 +59,30 @@ class Creature:
58
  self.brain = SimpleBrain()
59
 
60
  def think(self, world, creatures):
 
61
  hunger = 1.0 - self.food / 100.0
62
  thirst = 1.0 - self.water / 100.0
63
  health = self.health / 100.0
64
  energy = self.energy / 100.0
65
 
 
66
  nearby = []
67
- for dx in [-1, 0, 1]:
68
- for dy in [-1, 0, 1]:
69
- if dx == 0 and dy == 0:
70
- continue
71
- nx, ny = self.x + dx, self.y + dy
72
- if 0 <= nx < WORLD_SIZE and 0 <= ny < WORLD_SIZE:
73
- cell = world[nx, ny]
74
- if cell[0] == 34 and cell[1] == 139 and cell[2] == 34:
75
- nearby.append(1.0)
76
- elif cell[0] == 0 and cell[1] == 150 and cell[2] == 0:
77
- nearby.append(2.0)
78
- elif cell[0] == 128 and cell[1] == 128 and cell[2] == 128:
79
- nearby.append(0.5)
80
- else:
81
- nearby.append(0.0)
82
  else:
83
  nearby.append(0.0)
 
 
84
 
 
85
  partners = 0
86
  enemies = 0
87
  for other in creatures:
@@ -94,11 +95,24 @@ class Creature:
94
  else:
95
  enemies = max(enemies, 1.0 - dist/3.0)
96
 
97
- inputs = [hunger, thirst, health, energy, partners, enemies]
98
- inputs.extend(nearby[:4])
 
 
 
 
 
 
 
 
 
 
 
99
 
 
100
  output = self.brain.forward(inputs)
101
 
 
102
  dx = int(round(output[0] * 2))
103
  dy = int(round(output[1] * 2))
104
  build = output[2] > 0.3
@@ -237,6 +251,7 @@ def create_world():
237
  world = np.zeros((WORLD_SIZE, WORLD_SIZE, 3), dtype=np.uint8)
238
  world[:, :] = [100, 200, 100]
239
 
 
240
  for _ in range(20):
241
  for _ in range(30):
242
  x, y = random.randint(0, WORLD_SIZE-1), random.randint(0, WORLD_SIZE-1)
@@ -244,6 +259,7 @@ def create_world():
244
  world[x, y] = [34, 139, 34]
245
  break
246
 
 
247
  for _ in range(15):
248
  for _ in range(30):
249
  x, y = random.randint(0, WORLD_SIZE-1), random.randint(0, WORLD_SIZE-1)
@@ -251,6 +267,7 @@ def create_world():
251
  world[x, y] = [0, 150, 0]
252
  break
253
 
 
254
  for _ in range(10):
255
  for _ in range(30):
256
  x, y = random.randint(0, WORLD_SIZE-1), random.randint(0, WORLD_SIZE-1)
@@ -258,6 +275,7 @@ def create_world():
258
  world[x, y] = [128, 128, 128]
259
  break
260
 
 
261
  for _ in range(5):
262
  for _ in range(30):
263
  x, y = random.randint(0, WORLD_SIZE-1), random.randint(0, WORLD_SIZE-1)
@@ -266,13 +284,13 @@ def create_world():
266
  break
267
 
268
  creatures = []
269
- # Красные (верхний левый угол)
270
  for i in range(3):
271
  creatures.append(Creature(5 + i*2, 5 + i*2, [255, 50, 50], "red"))
272
- # Синие (нижний правый угол)
273
  for i in range(3):
274
  creatures.append(Creature(WORLD_SIZE-5 - i*2, WORLD_SIZE-5 - i*2, [50, 50, 255], "blue"))
275
- # Золотые (центр)
276
  for i in range(2):
277
  creatures.append(Creature(WORLD_SIZE//2 + i*2, WORLD_SIZE//2 + i*2, [255, 215, 0], "gold"))
278
 
@@ -282,7 +300,7 @@ def create_world():
282
  world, creatures = create_world()
283
  step_counter = 0
284
 
285
- # ============== ФУНКЦИИ СИМУЛЯЦИИ ==============
286
  def simulate_step():
287
  global world, creatures, step_counter
288
 
@@ -307,6 +325,7 @@ def simulate_step():
307
  creatures.extend(new_creatures)
308
  creatures = [c for c in creatures if c.alive]
309
 
 
310
  if step_counter % 5 == 0:
311
  for _ in range(2):
312
  for _ in range(20):
@@ -315,6 +334,7 @@ def simulate_step():
315
  world[x, y] = [0, 150, 0]
316
  break
317
 
 
318
  if len(creatures) > MAX_CREATURES:
319
  creatures.sort(key=lambda c: c.fitness, reverse=True)
320
  for c in creatures[MAX_CREATURES:]:
@@ -324,7 +344,6 @@ def simulate_step():
324
  step_counter += 1
325
 
326
  def render_world():
327
- # Размер изображения подстраивается под окно
328
  img = Image.new('RGB', (WORLD_SIZE * 12, WORLD_SIZE * 12 + 60), (30, 30, 30))
329
  draw = ImageDraw.Draw(img)
330
 
@@ -371,8 +390,12 @@ def render_world():
371
  # ============== ПОТОК СИМУЛЯЦИИ ==============
372
  def simulation_loop():
373
  while True:
374
- simulate_step()
375
- time.sleep(UPDATE_INTERVAL)
 
 
 
 
376
 
377
  # ============== HTTP СЕРВЕР ==============
378
  HTML_TEMPLATE = """
@@ -543,16 +566,14 @@ HTML_TEMPLATE = """
543
  updateStats();
544
  }
545
 
546
- // Обновляем каждые 300ms
547
  setInterval(update, 300);
548
-
549
- // Первое обновление
550
  update();
551
  </script>
552
  </body>
553
  </html>
554
  """
555
 
 
556
  class SimulationHandler(http.server.BaseHTTPRequestHandler):
557
  def do_GET(self):
558
  parsed = urlparse(self.path)
@@ -616,7 +637,7 @@ class SimulationHandler(http.server.BaseHTTPRequestHandler):
616
 
617
  # ============== ЗАПУСК ==============
618
  if __name__ == '__main__':
619
- # Запускаем симуляцию в отдельном потоке
620
  sim_thread = threading.Thread(target=simulation_loop, daemon=True)
621
  sim_thread.start()
622
 
 
5
  import numpy as np
6
  from PIL import Image, ImageDraw
7
  import io
8
+ import json
9
  from urllib.parse import parse_qs, urlparse
10
  import threading
11
  import time
 
15
  CELL_SIZE = 10
16
  MAX_CREATURES = 50
17
  PORT = 7890
18
+ UPDATE_INTERVAL = 0.3
19
 
20
+ # ============== НЕЙРОСЕТЬ (10 входов -> 5 выходов) ==============
21
  class SimpleBrain:
22
  def __init__(self):
23
+ # 10 входов (исправлено!), 5 выходов
24
+ self.weights = np.random.randn(10, 5) * 0.5
25
  self.bias = np.random.randn(5) * 0.5
26
 
27
  def forward(self, inputs):
 
37
 
38
  def mutate(self):
39
  if random.random() < 0.2:
40
+ self.weights += np.random.randn(10, 5) * 0.3
41
  if random.random() < 0.2:
42
+ self.bias += np.random.randn(5) * 0.3
43
 
44
  # ============== СУЩЕСТВО ==============
45
  class Creature:
 
59
  self.brain = SimpleBrain()
60
 
61
  def think(self, world, creatures):
62
+ # ---- ВХОДНЫЕ ДАННЫЕ (10 штук) ----
63
  hunger = 1.0 - self.food / 100.0
64
  thirst = 1.0 - self.water / 100.0
65
  health = self.health / 100.0
66
  energy = self.energy / 100.0
67
 
68
+ # Смотрим вокруг (4 направления: вверх, вниз, влево, вправо)
69
  nearby = []
70
+ for dx, dy in [(0, -1), (0, 1), (-1, 0), (1, 0)]:
71
+ nx, ny = self.x + dx, self.y + dy
72
+ if 0 <= nx < WORLD_SIZE and 0 <= ny < WORLD_SIZE:
73
+ cell = world[nx, ny]
74
+ if cell[0] == 34 and cell[1] == 139 and cell[2] == 34: # дерево
75
+ nearby.append(1.0)
76
+ elif cell[0] == 0 and cell[1] == 150 and cell[2] == 0: # ягоды
77
+ nearby.append(2.0)
78
+ elif cell[0] == 128 and cell[1] == 128 and cell[2] == 128: # камень
79
+ nearby.append(0.5)
 
 
 
 
 
80
  else:
81
  nearby.append(0.0)
82
+ else:
83
+ nearby.append(0.0)
84
 
85
+ # Свои и враги
86
  partners = 0
87
  enemies = 0
88
  for other in creatures:
 
95
  else:
96
  enemies = max(enemies, 1.0 - dist/3.0)
97
 
98
+ # Собираем 10 входов
99
+ inputs = [
100
+ hunger, # 1
101
+ thirst, # 2
102
+ health, # 3
103
+ energy, # 4
104
+ partners, # 5
105
+ enemies, # 6
106
+ nearby[0] if len(nearby) > 0 else 0.0, # 7 - вверх
107
+ nearby[1] if len(nearby) > 1 else 0.0, # 8 - вниз
108
+ nearby[2] if len(nearby) > 2 else 0.0, # 9 - влево
109
+ nearby[3] if len(nearby) > 3 else 0.0 # 10 - вправо
110
+ ]
111
 
112
+ # ---- ПРЯМОЙ ПРОХОД ----
113
  output = self.brain.forward(inputs)
114
 
115
+ # ---- ДЕЙСТВИЯ ----
116
  dx = int(round(output[0] * 2))
117
  dy = int(round(output[1] * 2))
118
  build = output[2] > 0.3
 
251
  world = np.zeros((WORLD_SIZE, WORLD_SIZE, 3), dtype=np.uint8)
252
  world[:, :] = [100, 200, 100]
253
 
254
+ # Деревья
255
  for _ in range(20):
256
  for _ in range(30):
257
  x, y = random.randint(0, WORLD_SIZE-1), random.randint(0, WORLD_SIZE-1)
 
259
  world[x, y] = [34, 139, 34]
260
  break
261
 
262
+ # Ягоды (еда)
263
  for _ in range(15):
264
  for _ in range(30):
265
  x, y = random.randint(0, WORLD_SIZE-1), random.randint(0, WORLD_SIZE-1)
 
267
  world[x, y] = [0, 150, 0]
268
  break
269
 
270
+ # Камни
271
  for _ in range(10):
272
  for _ in range(30):
273
  x, y = random.randint(0, WORLD_SIZE-1), random.randint(0, WORLD_SIZE-1)
 
275
  world[x, y] = [128, 128, 128]
276
  break
277
 
278
+ # Вода
279
  for _ in range(5):
280
  for _ in range(30):
281
  x, y = random.randint(0, WORLD_SIZE-1), random.randint(0, WORLD_SIZE-1)
 
284
  break
285
 
286
  creatures = []
287
+ # Красные
288
  for i in range(3):
289
  creatures.append(Creature(5 + i*2, 5 + i*2, [255, 50, 50], "red"))
290
+ # Синие
291
  for i in range(3):
292
  creatures.append(Creature(WORLD_SIZE-5 - i*2, WORLD_SIZE-5 - i*2, [50, 50, 255], "blue"))
293
+ # Золотые
294
  for i in range(2):
295
  creatures.append(Creature(WORLD_SIZE//2 + i*2, WORLD_SIZE//2 + i*2, [255, 215, 0], "gold"))
296
 
 
300
  world, creatures = create_world()
301
  step_counter = 0
302
 
303
+ # ============== СИМУЛЯЦИЯ ==============
304
  def simulate_step():
305
  global world, creatures, step_counter
306
 
 
325
  creatures.extend(new_creatures)
326
  creatures = [c for c in creatures if c.alive]
327
 
328
+ # Восстановление ягод
329
  if step_counter % 5 == 0:
330
  for _ in range(2):
331
  for _ in range(20):
 
334
  world[x, y] = [0, 150, 0]
335
  break
336
 
337
+ # Отбор
338
  if len(creatures) > MAX_CREATURES:
339
  creatures.sort(key=lambda c: c.fitness, reverse=True)
340
  for c in creatures[MAX_CREATURES:]:
 
344
  step_counter += 1
345
 
346
  def render_world():
 
347
  img = Image.new('RGB', (WORLD_SIZE * 12, WORLD_SIZE * 12 + 60), (30, 30, 30))
348
  draw = ImageDraw.Draw(img)
349
 
 
390
  # ============== ПОТОК СИМУЛЯЦИИ ==============
391
  def simulation_loop():
392
  while True:
393
+ try:
394
+ simulate_step()
395
+ time.sleep(UPDATE_INTERVAL)
396
+ except Exception as e:
397
+ print(f"Ошибка в симуляции: {e}")
398
+ time.sleep(1)
399
 
400
  # ============== HTTP СЕРВЕР ==============
401
  HTML_TEMPLATE = """
 
566
  updateStats();
567
  }
568
 
 
569
  setInterval(update, 300);
 
 
570
  update();
571
  </script>
572
  </body>
573
  </html>
574
  """
575
 
576
+ # ============== HTTP ОБРАБОТЧИК ==============
577
  class SimulationHandler(http.server.BaseHTTPRequestHandler):
578
  def do_GET(self):
579
  parsed = urlparse(self.path)
 
637
 
638
  # ============== ЗАПУСК ==============
639
  if __name__ == '__main__':
640
+ # Запускаем симуляцию в потоке
641
  sim_thread = threading.Thread(target=simulation_loop, daemon=True)
642
  sim_thread.start()
643