-
Notifications
You must be signed in to change notification settings - Fork 2
/
player.py
111 lines (83 loc) · 3.08 KB
/
player.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
import brain
import random
import pygame
import config
class Player:
def __init__(self):
# Bird
self.x, self.y = 50, 200
self.rect = pygame.Rect(self.x, self.y, 20, 20)
self.color = random.randint(100, 255), random.randint(100, 255), random.randint(100, 255)
self.vel = 0
self.flap = False
self.alive = True
self.lifespan = 0
# AI
self.decision = None
self.vision = [0.5, 1, 0.5]
self.fitness = 0
self.inputs = 3
self.brain = brain.Brain(self.inputs)
self.brain.generate_net()
# Game related functions
def draw(self, window):
pygame.draw.rect(window, self.color, self.rect)
def ground_collision(self, ground):
return pygame.Rect.colliderect(self.rect, ground)
def sky_collision(self):
return bool(self.rect.y < 30)
def pipe_collision(self):
for p in config.pipes:
return pygame.Rect.colliderect(self.rect, p.top_rect) or \
pygame.Rect.colliderect(self.rect, p.bottom_rect)
def update(self, ground):
if not (self.ground_collision(ground) or self.pipe_collision()):
# Gravity
self.vel += 0.25
self.rect.y += self.vel
if self.vel > 5:
self.vel = 5
# Increment lifespan
self.lifespan += 1
else:
self.alive = False
self.flap = False
self.vel = 0
def bird_flap(self):
if not self.flap and not self.sky_collision():
self.flap = True
self.vel = -5
if self.vel >= 3:
self.flap = False
@staticmethod
def closest_pipe():
for p in config.pipes:
if not p.passed:
return p
# AI related functions
def look(self):
if config.pipes:
# Line to top pipe
self.vision[0] = max(0, self.rect.center[1] - self.closest_pipe().top_rect.bottom) / 500
pygame.draw.line(config.window, self.color, self.rect.center,
(self.rect.center[0], config.pipes[0].top_rect.bottom))
# Line to mid pipe
self.vision[1] = max(0, self.closest_pipe().x - self.rect.center[0]) / 500
pygame.draw.line(config.window, self.color, self.rect.center,
(config.pipes[0].x, self.rect.center[1]))
# Line to bottom pipe
self.vision[2] = max(0, self.closest_pipe().bottom_rect.top - self.rect.center[1]) / 500
pygame.draw.line(config.window, self.color, self.rect.center,
(self.rect.center[0], config.pipes[0].bottom_rect.top))
def think(self):
self.decision = self.brain.feed_forward(self.vision)
if self.decision > 0.73:
self.bird_flap()
def calculate_fitness(self):
self.fitness = self.lifespan
def clone(self):
clone = Player()
clone.fitness = self.fitness
clone.brain = self.brain.clone()
clone.brain.generate_net()
return clone