-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsnake.py
112 lines (101 loc) · 3.9 KB
/
snake.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
from p5 import *
import numpy as np
from food import Food
from settings import Settings
class Snake:
def __init__(self, settings, foodObj):
self.x = settings.windowSize / 2
self.y = settings.windowSize / 2
self.xSpeed = settings.scale
self.ySpeed = 0
self.scale = settings.scale
self.settings: Settings = settings
self.food: Food = foodObj
self.total = 2
self.tail = [(self.x-self.settings.scale, self.y),(self.x-(self.settings.scale*2), self.y)]
self.alive = True
self.fitness = 0
self.lifetime = 0
self.hasBestBrain = False
self.movesRemaining = 100
def update(self):
if(self.alive):
#update tail
for i in range(len(self.tail)-1):
self.tail[i] = self.tail[i+1]
if(self.total - 1 == len(self.tail)):
self.tail.append((self.x, self.y))
else:
self.tail[self.total - 1] = (self.x, self.y)
#update self
self.x += self.xSpeed
self.y += self.ySpeed
self.x = constrain(self.x, 0, self.settings.windowSize-self.settings.scale)
self.y = constrain(self.y, 0, self.settings.windowSize-self.settings.scale)
self.lifetime += 1
#class methods
self.movesRemaining -= 1
self.checkForDeath()
self.tryEatFood()
self.show()
def show(self):
# if(self.hasBestBrain):
fill(255)
square((self.x, self.y), self.settings.scale)
for i in range(len(self.tail)):
square(self.tail[i], self.settings.scale)
def dir(self, x, y):
x *= self.scale
y *= self.scale
if abs(self.xSpeed) == abs(x):
self.xSpeed = self.xSpeed
elif abs(self.ySpeed) == abs(y):
self.ySpeed = self.ySpeed
else:
self.xSpeed = x
self.ySpeed = y
def tryEatFood(self):
d = dist((self.x, self.y), (self.food.x, self.food.y))
if(d == 0):
self.total+=1
self.movesRemaining += 100
self.food.eaten = True
if(self.total > self.settings.globalBestTotal):
print("updating total!! : {} {}".format(self.settings.globalBestTotal, self.total ))
self.settings.globalBestTotal = self.total
def checkForDeath(self):
self.calcFitness()
if(self.movesRemaining < 0):
self.alive = False
self.settings.numberOfSnakesAlive -= 1
self.settings.totalFitness += self.fitness
if(self.fitness > 0):
print("Fitness:", self.fitness, "out of moves", self.movesRemaining)
else:
for i in range(len(self.tail)):
d = dist((self.x, self.y), (self.tail[i]))
if d == 0:
self.alive = False
self.settings.numberOfSnakesAlive -= 1
self.settings.totalFitness += self.fitness
if(self.fitness > 0):
print("Fitness:", self.fitness, "snake crashed it's face")
def calcFitness(self):
if(self.total < 10):
self.fitness = (self.lifetime * self.lifetime) * np.power(2, self.total)
else:
self.fitness = ((self.lifetime * self.lifetime) * np.power(2, 10)) * (self.total-9)
if(self.fitness < 600):
self.fitness = 0
def resetSnake(self):
self.xSpeed = self.settings.scale
self.ySpeed = 0
self.x = self.settings.windowSize/2
self.y = self.settings.windowSize/2
self.total = 2
self.tail = [(self.x-self.settings.scale, self.y),(self.x-(2*self.settings.scale), self.y)]
self.alive = True
self.fitness = 0
self.lifetime = 0
self.movesRemaining = 100
self.food.spawnAtInitialLocation()