我正在尝试制作一个AI的点子范例游戏,使人们逐渐了解如何达到目标。我一直在每个新一代的问题,在屏幕上的点数减少。它应该保持不变,但是每次丢失3-4点,直到只有1点。
这是我的代码:
import pygame, random
import math
SCREENWIDTH=800
SCREENHEIGHT=800
size = (SCREENWIDTH, SCREENHEIGHT)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
sed = random.randint(0,100)
random.seed(sed)
GREEN = (20, 255, 140)
pygame.init()
all_sprites_list = pygame.sprite.Group()
screen = pygame.display.set_mode(size)
class Brain:
def __init__(self,size):
self.step = 0
self.directions = []
self.size = size
self.randomize()
def randomize(self):
for i in range(self.size):
rand = random.uniform(-5000.0,5000.0) / 100.0
self.directions.append([math.cos(rand)*math.pi,math.sin(rand)*math.pi])
def clone(self):
cl = Brain(self.size)
cl.directions = self.directions
cl.step = 0
return cl
def mutate(self):
mrate = 0.1
randn = random.uniform(0,1)
if mrate > randn:
rand = random.uniform(-5000.0,5000.0) / 100.0
self.directions.append([math.cos(rand)*math.pi,math.sin(rand)*math.pi])
def addv(v1,v2):
v1[0] += v2[0]
v1[1] += v2[1]
return v1
clamp = lambda n, minn, maxn: max(min(maxn, n), minn)
class Dot(pygame.sprite.Sprite):
def __init__(self):
self.goal = False
self.best = False
super(Dot,self).__init__()
self.sup = super(Dot,self)
self.brain = Brain(801)
self.acc = [0,0]
self.vel = [0,0]
self.dead = False
self.image = pygame.Surface([10, 10])
self.image.fill(WHITE)
self.image.set_colorkey(WHITE)
pygame.draw.ellipse(self.image, RED, [0, 0, 10, 10])
self.pos = [100,100]
self.fitness = 0
self.rect = self.image.get_rect()
def move(self):
brain = self.brain
if(len(brain.directions) > brain.step):
self.acc = brain.directions[brain.step]
brain.step += 1
self.vel = addv(self.vel,self.acc)
self.vel[0] = math.sin(self.vel[0]) * 10
self.vel[1] = math.sin(self.vel[1]) * 10
#print "%s, %s" % (self.vel[1],self.pos[1])
self.pos[0] += self.vel[0]
#self.pos[0] = clamp(self.pos[0],10,790)
self.pos[1] += self.vel[1]
#self.pos[1] = clamp(self.pos[1],10,790)
self.rect.x = self.pos[0]
self.rect.y = self.pos[1]
else:
self.dead = True
#print self.pos
def updat(self):
#print self.rect.x
if not self.dead and not self.goal:
self.move()
if self.rect.x > 790 or self.rect.x < 10 or self.rect.y > 790 or self.rect.y < 10:
self.dead = True
self.calculateFitness()
#print self.fitness
elif math.hypot(self.rect.x - 400, self.rect.y - 400) < 5:
self.goal = True
def baby(self):
baby = Dot()
baby.brain = self.brain.clone()
return baby
def calculateFitness(self):
if self.goal:
self.fitness = 1.0/16.0 + 10000.0/(self.brain.step * self.brain.step)
else:
distanceToGoal = math.hypot(self.rect.x - 400, self.rect.y - 400)
self.fitness = 1.0/(distanceToGoal * distanceToGoal)
class Population:
def __init__(self,size):
self.size = size
self.minStep = 800
self.bestDot = None
self.dots = []
self.gen = 1
self.fsum = 0
for i in range(size):
self.dots.append(Dot())
def show(self):
for i in range(self.size):
all_sprites_list.add(self.dots[i])
self.dots[i].rect.x = 200
self.dots[i].rect.y = 300
def update(self):
for i in range(self.size):
if self.dots[i].brain.step > self.minStep:
self.dots[i].dead = True
else:
#print "a"
#print self.dots[i].dead
self.dots[i].updat()
def fitness(self):
for i in range(self.size):
self.dots[i].calculateFitness()
def getBestDot(self):
maxx = 0
maxIndex = 0
for i in range(self.size):
if self.dots[i].fitness > maxx:
maxx = self.dots[i].fitness
maxIndex = i
self.bestDot = maxIndex
if self.dots[self.bestDot].goal:
self.minStep = self.dots[self.bestDot].brain.step
print "Step: %i" % self.minStep
def allDotsDead(self):
for i in range(self.size):
if not self.dots[i].dead and not self.dots[i].goal:
#print self.dots[i]
return False
return True
def getFitnessSum(self):
self.fsum = 0
for i in range(self.size):
self.fsum += self.dots[i].fitness
def selectp(self):
rand = random.uniform(0,self.fsum)
rsum = 0
for i in range(self.size):
rsum += self.dots[i].fitness
if (rsum > rand):
return self.dots[i]
def mutate(self):
for i in range(self.size-1):
self.dots[i].brain.mutate()
def select(self):
for i in range(self.size):
all_sprites_list.remove(self.dots[i])
newdots = []
self.getBestDot()
self.getFitnessSum()
newdots.append(self.dots[self.bestDot].baby())
all_sprites_list.add(newdots[0])
newdots[0].rect.x = 200
newdots[0].rect.y = 300
for i in range(self.size-1):
parent = self.selectp()
newdots.append(parent.baby())
all_sprites_list.add(newdots[i])
newdots[i].rect.x = 200
newdots[i].rect.y = 300
screen.fill((0,0,0))
self.dots = newdots
for i in range(self.size):
all_sprites_list.add(self.dots[i])
self.gen += 1
pop = Population(10)
GREY = (210, 210 ,210)
WHITE = (255, 255, 255)
PURPLE = (255, 0, 255)
pygame.display.set_caption("Some Blob Thing")
goalx = 400
goaly = 400
pop.show()
DotryOn = True
clock=pygame.time.Clock()
all_sprites_list.draw(screen)
while DotryOn:
for event in pygame.event.get():
if event.type==pygame.QUIT:
DotryOn=False
if pop.allDotsDead():
pop.fitness()
pop.select()
pop.mutate()
for i in pop.dots:
print i.dead
else:
pop.update()
all_sprites_list.update()
screen.fill((0,0,0))
pygame.draw.rect(screen,GREEN,[goalx,goaly,10,10])
all_sprites_list.draw(screen)
pygame.display.flip()
clock.tick(100)
pygame.quit()