点数随时间减少

时间:2018-08-05 17:53:21

标签: python python-2.7 pygame genetic-programming

我正在尝试制作一个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()

0 个答案:

没有答案