You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ai001/main.py

192 lines
5.8 KiB

# coding:utf-8
import pygame
import sys
from pygame.locals import *
import random
import math
import forAI
BACKGROUND = (255, 255, 255)
SCREEN_SIZE = (800, 600)
MAX = 0
Generation = 0
class Plane():
def __init__(self, plane_image):
self.plane_image = plane_image
self.rect = plane_image.get_rect()
self.width = self.rect[2]
self.height = self.rect[3]
self.x = SCREEN_SIZE[0] / 2 - self.width / 2
self.y = SCREEN_SIZE[1] - self.height
self.move_x = 0
self.speed = 2
self.alive = True
def update(self):
self.x += self.move_x * self.speed
if self.x+self.width > SCREEN_SIZE[0]:#飞出右边
self.x =0 # 如果超出屏幕则还原
elif self.x<0:#左边
self.x = SCREEN_SIZE[0]-self.width#如果超出屏幕则还原
def draw(self, screen):
screen.blit(self.plane_image, (self.x, self.y, self.width, self.height))
def is_dead(self, enemies):
# if self.x < -self.width or self.x + self.width > SCREEN_SIZE[0] + self.width:
# return True
for eneme in enemies:
if self.collision(eneme):
return True
return False
def collision(self, enemy):
if not (self.x > enemy.x + enemy.width or self.x + self.width < enemy.x or self.y > enemy.y + enemy.height or self.y + self.height < enemy.y):
return True
else:
return False
def get_Xs(self, enemies, Size=4):##计算x轴相对位置
Xs = []
for i in range(Size):
Xs.append(0.0)
Xs[0] = (self.x * 1.0 / SCREEN_SIZE[0])
index = 1
for eneme in enemies:
Xs[index] = eneme.x * 1.0 / SCREEN_SIZE[0]
index += 1
Xs[index] = eneme.y * 1.0 / SCREEN_SIZE[1]
index += 1
if len(enemies) > 0 and self.x < enemies[0].x:
Xs[index] = -1.0
#index += 1
else:
Xs[index] = 1.0
#print("---------" + str(index) + "---------")
return Xs
class Enemy():
def __init__(self, enemy_image):
self.enemy_image = enemy_image
self.rect = enemy_image.get_rect()
self.width = self.rect[2]
self.height = self.rect[3]
self.x = random.choice(range(0, int(SCREEN_SIZE[0] - self.width / 2), 71))
self.y = 0
def update(self):
self.y += 6
def draw(self, screen):
screen.blit(self.enemy_image, (self.x, self.y, self.width, self.height))
def is_out(self):
return True if self.y >= SCREEN_SIZE[1] else False
class Game():
def __init__(self):
pygame.init()
self.screen = pygame.display.set_mode(SCREEN_SIZE)
self.clock = pygame.time.Clock()
pygame.display.set_caption('AI躲核弹')
self.ai = forAI.NeuroEvolution()
self.generation = 0
self.max_enemes = 1
# 加载飞机、敌机图片
self.plane_image = pygame.image.load('plane.png')
self.enemy_image = pygame.image.load('enemy.png')
def start(self):
self.score = 0
self.planes = []
self.enemes = []
self.gen = self.ai.next_generation()#AI初始化
for i in range(len(self.gen)):
plane = Plane(self.plane_image)
self.planes.append(plane)
self.generation += 1
self.alives = len(self.planes)
def update(self, screen):
global MAX,Generation
self.gen_enemes()
for i in range(len(self.planes)):
if self.planes[i].alive:
Xs = self.planes[i].get_Xs(self.enemes)
res = self.gen[i].feed_forward(Xs)
if res[0] < 0.45:
self.planes[i].move_x = -1
elif res[0] > 0.55:
self.planes[i].move_x = 1
self.planes[i].update()
self.planes[i].draw(screen)
for eneme in self.enemes[:]:
if self.planes[i].collision(eneme):
self.alives -= 1
self.enemes.remove(eneme)
self.planes[i].alive = False
self.ai.network_score(self.score, self.gen[i])#评分
if self.is_ai_all_dead():
self.start()
break
for eneme in self.enemes[:]:
eneme.update()
eneme.draw(screen)
if eneme.is_out():
self.score += 1
self.enemes.remove(eneme)
end = '\r'
if(self.score!=0):
if(self.generation>Generation):#分数大于最大值或者子代更迭才显示
Generation=self.generation
print(" 迭代次数:{}, 存活飞机数:{},得分:{}".format(self.generation, self.alives, self.score), end)
if(self.score>MAX):
MAX=self.score
print(" 迭代次数:{}, 存活飞机数:{},得分:{}".format(self.generation, self.alives, self.score), end)
def run(self, FPS=100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000):
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
self.screen.fill(BACKGROUND) #背景色
self.update(self.screen)
pygame.display.update()
self.clock.tick(FPS)
def gen_enemes(self):
if len(self.enemes) < self.max_enemes:
enemy = Enemy(self.enemy_image)
self.enemes.append(enemy)
def is_ai_all_dead(self):
for plane in self.planes:
if plane.alive:
return False
return True
game = Game()
game.start()
game.run()