|
| 1 | +import sys |
| 2 | +import math |
| 3 | +import pygame |
| 4 | +import neat |
| 5 | +from pathlib import Path |
| 6 | +import os |
| 7 | +from random import randint |
| 8 | +import time |
| 9 | +import joblib |
| 10 | + |
| 11 | +resett = True |
| 12 | + |
| 13 | + |
| 14 | +ploss = False |
| 15 | +def translate_point(point, angle, distance): |
| 16 | + radians = math.radians(angle) |
| 17 | + return int(point[0] + distance * math.cos(radians)),\ |
| 18 | + int(point[1] + distance * math.sin(radians)) |
| 19 | + |
| 20 | +def rotate_image(win,image,top_left,angle): |
| 21 | + rotated_image = pygame.transform.rotate(image,angle) |
| 22 | + new_rect = rotated_image.get_rect(center =top_left) |
| 23 | + win.blit(rotated_image,new_rect.topleft) |
| 24 | + |
| 25 | +def changeploss(): |
| 26 | + global ploss |
| 27 | + ploss = True |
| 28 | +class PlayerCar: |
| 29 | + |
| 30 | + def __init__(self,max_vel): |
| 31 | + self.img = CARp |
| 32 | + self.max_vel = max_vel |
| 33 | + self.vel = 0 |
| 34 | + self.angle = 180 |
| 35 | + self.x,self.y = Spawn |
| 36 | + self.acc = 0.3 |
| 37 | + |
| 38 | + def draw(self,win): |
| 39 | + rotate_image(win,self.img,(self.x,self.y ),self.angle) |
| 40 | + if TRACK.get_at((int(self.x), int(self.y))) in Border: |
| 41 | + self.x,self.y = Spawn |
| 42 | + self.angle = 180 |
| 43 | + self.vel = 0 |
| 44 | + text =FONT.render("You Lost", 1, (255,255,255)) |
| 45 | + SCREEN.blit(text, (200, 400)) |
| 46 | + |
| 47 | + CARp = pygame.image.load(str(os.fspath(Path(__file__).resolve().parent / "car{}.png".format(randint(1,9))))) |
| 48 | + CARp = pygame.transform.rotate(CARp,180) |
| 49 | + CARp = pygame.transform.scale(CARp,(CAR_SIZE[0]-3,CAR_SIZE[1]-6)) |
| 50 | + self.img = CARp |
| 51 | + pygame.display.update() |
| 52 | + time.sleep(2) |
| 53 | + changeploss() |
| 54 | + |
| 55 | + |
| 56 | + def forward(self): |
| 57 | + self.vel = min(self.vel + self.acc,self.max_vel) |
| 58 | + |
| 59 | + self.move() |
| 60 | + |
| 61 | + |
| 62 | + |
| 63 | + def move(self): |
| 64 | + self.img = CARp |
| 65 | + radians = math.radians(self.angle) |
| 66 | + |
| 67 | + vert = math.cos(radians) * self.vel |
| 68 | + horz = math.sin(radians) * self.vel |
| 69 | + |
| 70 | + self.y -= vert |
| 71 | + self.x -= horz |
| 72 | + def momentum(self): |
| 73 | + self.vel = max(self.vel - self.acc / 2,0) |
| 74 | + |
| 75 | + self.move() |
| 76 | + |
| 77 | + |
| 78 | +class Car: |
| 79 | + def __init__(self): |
| 80 | + self.corners = [] |
| 81 | + self.edge_points = [] |
| 82 | + self.edge_distances = [] |
| 83 | + self.travelled_distance = 0 |
| 84 | + self.angle = 0 |
| 85 | + self.Spawn = Spawn |
| 86 | + self.last = Spawn |
| 87 | + self.car = pygame.image.load(str(os.fspath(Path(__file__).resolve().parent / 'car{}.png'.format(randint(1,9))))) |
| 88 | + self.car = pygame.transform.scale(self.car, CAR_SIZE) |
| 89 | + self.crashed = False |
| 90 | + self.update_sensor_data() |
| 91 | + |
| 92 | + def display_car(self): |
| 93 | + rotated_car = pygame.transform.rotate(self.car, self.angle) |
| 94 | + rect = rotated_car.get_rect(center=self.Spawn) |
| 95 | + SCREEN.blit(rotated_car, rect.topleft) |
| 96 | + |
| 97 | + def crash_check(self): |
| 98 | + for corner in self.corners: |
| 99 | + if TRACK.get_at(corner) in Border: |
| 100 | + return True |
| 101 | + return False |
| 102 | + |
| 103 | + def update_sensor_data(self): |
| 104 | + angles = [360 - self.angle, 90 - self.angle, 180 - self.angle,45 - self.angle, 135- self.angle,70 - self.angle, 110- self.angle] |
| 105 | + angles = [math.radians(i) for i in angles] |
| 106 | + |
| 107 | + edge_points = [] |
| 108 | + edge_distances = [] |
| 109 | + for angle in angles: |
| 110 | + distance = 0 |
| 111 | + edge_x, edge_y = self.Spawn |
| 112 | + try: |
| 113 | + while TRACK_COPY.get_at((edge_x, edge_y)) not in Border : |
| 114 | + distance += 1 |
| 115 | + edge_x = int(self.Spawn[0] + distance * math.cos(angle)) |
| 116 | + edge_y = int(self.Spawn[1] + distance * math.sin(angle)) |
| 117 | + except: |
| 118 | + f=0 |
| 119 | + edge_points.append((edge_x, edge_y)) |
| 120 | + edge_distances.append(distance) |
| 121 | + self.edge_points = edge_points |
| 122 | + self.edge_distances = edge_distances |
| 123 | + |
| 124 | + |
| 125 | + def display_edge_points(self): |
| 126 | + |
| 127 | + for point in self.edge_points: |
| 128 | + |
| 129 | + pygame.draw.line(SCREEN, (255,0,255), self.Spawn, point) |
| 130 | + pygame.draw.circle(SCREEN, (255,0,255), point, 5) |
| 131 | + |
| 132 | + def update_position(self): |
| 133 | + self.Spawn = translate_point( |
| 134 | + self.Spawn, 90 - self.angle, Speed) |
| 135 | + self.travelled_distance += Speed |
| 136 | + dist = math.sqrt(CAR_SIZE[0]**2 + CAR_SIZE[1]**2)/2 |
| 137 | + corners = [] |
| 138 | + corners.append(translate_point( |
| 139 | + self.Spawn, 60 - self.angle, dist)) |
| 140 | + corners.append(translate_point( |
| 141 | + self.Spawn, 120 - self.angle, dist)) |
| 142 | + corners.append(translate_point( |
| 143 | + self.Spawn, 240 - self.angle, dist)) |
| 144 | + corners.append(translate_point( |
| 145 | + self.Spawn, 300 - self.angle, dist)) |
| 146 | + self.corners = corners |
| 147 | + |
| 148 | + |
| 149 | +def run(genomes, config): |
| 150 | + global GENERATION,lines,fps,TRACK,TRACK_COPY,Spawn,resett,countdown |
| 151 | + GENERATION += 1 |
| 152 | + models = [] |
| 153 | + cars = [] |
| 154 | + |
| 155 | + for _, genome in genomes: |
| 156 | + net = neat.nn.FeedForwardNetwork.create(genome, config) |
| 157 | + models.append(net) |
| 158 | + genome.fitness = 0 |
| 159 | + cars.append(Car()) |
| 160 | + starttime = time.time() |
| 161 | + lasttime = starttime |
| 162 | + |
| 163 | + while True: |
| 164 | + for event in pygame.event.get(): |
| 165 | + if event.type == pygame.QUIT: |
| 166 | + pygame.quit() |
| 167 | + sys.exit() |
| 168 | + |
| 169 | + keys_pressed = pygame.key.get_pressed() |
| 170 | + |
| 171 | + if keys_pressed[pygame.K_1]: |
| 172 | + TRACK = pygame.image.load(str(os.fspath(Path(__file__).resolve().parent / 'track1.png'))).convert_alpha() |
| 173 | + TRACK = pygame.transform.scale(TRACK,(900,900)) |
| 174 | + TRACK_COPY = TRACK.copy() |
| 175 | + Spawn = 70, 800 |
| 176 | + resett = True |
| 177 | + if keys_pressed[pygame.K_2]: |
| 178 | + TRACK = pygame.image.load(str(os.fspath(Path(__file__).resolve().parent / 'track2.png'))).convert_alpha() |
| 179 | + TRACK = pygame.transform.scale(TRACK,(900,900)) |
| 180 | + TRACK_COPY = TRACK.copy() |
| 181 | + Spawn = 820, 300 |
| 182 | + resett = True |
| 183 | + if keys_pressed[pygame.K_3]: |
| 184 | + TRACK = pygame.image.load(str(os.fspath(Path(__file__).resolve().parent / 'track3.png'))).convert_alpha() |
| 185 | + TRACK = pygame.transform.scale(TRACK,(900,900)) |
| 186 | + TRACK_COPY = TRACK.copy() |
| 187 | + Spawn = 190, 600 |
| 188 | + resett = True |
| 189 | + if keys_pressed[pygame.K_4]: |
| 190 | + TRACK = pygame.image.load(str(os.fspath(Path(__file__).resolve().parent / 'track4.png'))).convert_alpha() |
| 191 | + TRACK = pygame.transform.scale(TRACK,(900,900)) |
| 192 | + TRACK_COPY = TRACK.copy() |
| 193 | + Spawn = 230, 350 |
| 194 | + resett = True |
| 195 | + moved = False |
| 196 | + if keys_pressed[pygame.K_w]: |
| 197 | + moved = True |
| 198 | + pcar.forward() |
| 199 | + if keys_pressed[pygame.K_a]: |
| 200 | + pcar.angle += 5 |
| 201 | + if keys_pressed[pygame.K_d]: |
| 202 | + pcar.angle -= 5 |
| 203 | + |
| 204 | + running_cars = 0 |
| 205 | + |
| 206 | + SCREEN.blit(TRACK,(0,0)) |
| 207 | + |
| 208 | + for i, car in enumerate(cars): |
| 209 | + if not car.crashed: |
| 210 | + running_cars += 1 |
| 211 | + output = models[i].activate(car.edge_distances) |
| 212 | + choice = output.index(max(output)) |
| 213 | + if choice == 0: |
| 214 | + car.angle += Turn |
| 215 | + elif choice == 1: |
| 216 | + car.angle -= Turn |
| 217 | + car.update_position() |
| 218 | + car.display_car() |
| 219 | + car.crashed = car.crash_check() |
| 220 | + car.update_sensor_data() |
| 221 | + genomes[i][1].fitness += car.travelled_distance |
| 222 | + if lines: |
| 223 | + car.display_edge_points() |
| 224 | + if ploss: |
| 225 | + car.Spawn = Spawn |
| 226 | + car.crashed = True |
| 227 | + |
| 228 | + pcar.draw(SCREEN) |
| 229 | + |
| 230 | + if running_cars == 0: |
| 231 | + G_Data.append(GENERATION) |
| 232 | + T_Data.append(laptime) |
| 233 | + |
| 234 | + return |
| 235 | + laptime = round((time.time() - lasttime)*(fps/24), 2) |
| 236 | + if resett == True: |
| 237 | + fps = 1 |
| 238 | + text = FONT.render(str(countdown), 1, (255,0,0)) |
| 239 | + SCREEN.blit(text, (400, 400)) |
| 240 | + countdown -=1 |
| 241 | + if countdown == 0: |
| 242 | + resett = False |
| 243 | + fps = 24 |
| 244 | + countdown = 3 |
| 245 | + if not moved: |
| 246 | + pcar.momentum() |
| 247 | + pygame.display.update() |
| 248 | + CLOCK.tick(fps) |
| 249 | + |
| 250 | + |
| 251 | + |
| 252 | +def load_ai(filename): |
| 253 | + return joblib.load((os.fspath(Path(__file__).resolve().parent / filename))) |
| 254 | + |
| 255 | + |
| 256 | +# if __name__ == "__main__": |
| 257 | +pygame.init() |
| 258 | +pygame.display.set_caption("YOU VS AI") |
| 259 | +WIN = 900, 900 |
| 260 | +SCREEN = pygame.display.set_mode(WIN) |
| 261 | +countdown = 3 |
| 262 | + |
| 263 | +Spawn = 190, 600 |
| 264 | +Speed = 10 |
| 265 | +Turn = 28 |
| 266 | + |
| 267 | +CAR_SIZE = 25,50 |
| 268 | +Border = [(67, 153, 162, 255),(66, 154, 162, 255),(37, 156, 163, 255),(120, 220, 82, 255),(76, 155, 162, 255),(136, 242, 255, 255),(65, 152, 162, 255),(154, 239, 254, 255),(136, 219, 91, 255),(137, 219, 92, 255),(67, 153, 162, 255),(23, 57, 170, 255)] |
| 269 | +TRACK = pygame.image.load(str(os.fspath(Path(__file__).resolve().parent / 'track3.png'))).convert_alpha() |
| 270 | +TRACK = pygame.transform.scale(TRACK,(900,900)) |
| 271 | +TRACK_COPY = TRACK.copy() |
| 272 | +FONT = pygame.font.SysFont("Grand9K Pixel", 100) |
| 273 | + |
| 274 | +CARp = pygame.image.load(str(os.fspath(Path(__file__).resolve().parent / "car{}.png".format(randint(1,9))))) |
| 275 | +CARp = pygame.transform.rotate(CARp,180) |
| 276 | +CARp = pygame.transform.scale(CARp,(CAR_SIZE[0]-3,CAR_SIZE[1]-6)) |
| 277 | + |
| 278 | +rot = 0 |
| 279 | +pcar = PlayerCar(Speed) |
| 280 | +CLOCK = pygame.time.Clock() |
| 281 | +GENERATION = 0 |
| 282 | + |
| 283 | +lines = False |
| 284 | +fps = 30 |
| 285 | + |
| 286 | +G_Data =[] |
| 287 | +T_Data = [] |
| 288 | + |
| 289 | + |
| 290 | +# population = load_ai(str(os.fspath(Path(__file__).resolve().parent / "best.pickle"))) |
| 291 | +population = load_ai("best.pkl") |
| 292 | +while True: |
| 293 | + ploss = False |
| 294 | + population.run(run, 1) |
| 295 | + if ploss == False: |
| 296 | + text = FONT.render("You Won", 1, (255,255,255)) |
| 297 | + SCREEN.blit(text, (200, 400)) |
| 298 | + CARp = pygame.image.load(str(os.fspath(Path(__file__).resolve().parent / "car{}.png".format(randint(1,9))))) |
| 299 | + CARp = pygame.transform.rotate(CARp,180) |
| 300 | + CARp = pygame.transform.scale(CARp,(CAR_SIZE[0]-3,CAR_SIZE[1]-6)) |
| 301 | + pygame.display.update() |
| 302 | + time.sleep(2) |
| 303 | + pcar.x = Spawn[0] |
| 304 | + pcar.y = Spawn[1] |
| 305 | + |
| 306 | + |
| 307 | + |
| 308 | + |
0 commit comments