<s> import random <EOL> import math <EOL> import numpy as np <EOL> import pygame <EOL> from pygame . color import THECOLORS <EOL> import pymunk <EOL> from pymunk . vec2d import Vec2d <EOL> from pymunk . pygame_util import draw <EOL> width = <NUM_LIT:1000> <EOL> height = <NUM_LIT> <EOL> pygame . init ( ) <EOL> screen = pygame . display . set_mode ( ( width , height ) ) <EOL> clock = pygame . time . Clock ( ) <EOL> screen . set_alpha ( None ) <EOL> show_sensors = True <EOL> draw_screen = True <EOL> class GameState : <EOL> def __init__ ( self ) : <EOL> self . crashed = False <EOL> self . space = pymunk . Space ( ) <EOL> self . space . gravity = pymunk . Vec2d ( <NUM_LIT:0.> , <NUM_LIT:0.> ) <EOL> self . create_car ( <NUM_LIT:100> , <NUM_LIT:100> , <NUM_LIT:0.5> ) <EOL> self . num_steps = <NUM_LIT:0> <EOL> static = [ <EOL> pymunk . Segment ( <EOL> self . space . static_body , <EOL> ( <NUM_LIT:0> , <NUM_LIT:1> ) , ( <NUM_LIT:0> , height ) , <NUM_LIT:1> ) , <EOL> pymunk . Segment ( <EOL> self . space . static_body , <EOL> ( <NUM_LIT:1> , height ) , ( width , height ) , <NUM_LIT:1> ) , <EOL> pymunk . Segment ( <EOL> self . space . static_body , <EOL> ( width - <NUM_LIT:1> , height ) , ( width - <NUM_LIT:1> , <NUM_LIT:1> ) , <NUM_LIT:1> ) , <EOL> pymunk . Segment ( <EOL> self . space . static_body , <EOL> ( <NUM_LIT:1> , <NUM_LIT:1> ) , ( width , <NUM_LIT:1> ) , <NUM_LIT:1> ) <EOL> ] <EOL> for s in static : <EOL> s . friction = <NUM_LIT:1.> <EOL> s . group = <NUM_LIT:1> <EOL> s . collision_type = <NUM_LIT:1> <EOL> s . color = THECOLORS [ '<STR_LIT>' ] <EOL> self . space . add ( static ) <EOL> self . obstacles = [ ] <EOL> self . obstacles . append ( self . create_obstacle ( <NUM_LIT:200> , <NUM_LIT> , <NUM_LIT:100> ) ) <EOL> self . obstacles . append ( self . create_obstacle ( <NUM_LIT> , <NUM_LIT:200> , <NUM_LIT> ) ) <EOL> self . obstacles . append ( self . create_obstacle ( <NUM_LIT> , <NUM_LIT> , <NUM_LIT> ) ) <EOL> self . create_cat ( ) <EOL> def create_obstacle ( self , x , y , r ) : <EOL> c_body = pymunk . Body ( pymunk . inf , pymunk . inf ) <EOL> c_shape = pymunk . Circle ( c_body , r ) <EOL> c_shape . elasticity = <NUM_LIT:1.0> <EOL> c_body . position = x , y <EOL> c_shape . color = THECOLORS [ "<STR_LIT>" ] <EOL> self . space . add ( c_body , c_shape ) <EOL> return c_body <EOL> def create_cat ( self ) : <EOL> inertia = pymunk . moment_for_circle ( <NUM_LIT:1> , <NUM_LIT:0> , <NUM_LIT> , ( <NUM_LIT:0> , <NUM_LIT:0> ) ) <EOL> self . cat_body = pymunk . Body ( <NUM_LIT:1> , inertia ) <EOL> self . cat_body . position = <NUM_LIT:50> , height - <NUM_LIT:100> <EOL> self . cat_shape = pymunk . Circle ( self . cat_body , <NUM_LIT:30> ) <EOL> self . cat_shape . color = THECOLORS [ "<STR_LIT>" ] <EOL> self . cat_shape . elasticity = <NUM_LIT:1.0> <EOL> self . cat_shape . angle = <NUM_LIT:0.5> <EOL> direction = Vec2d ( <NUM_LIT:1> , <NUM_LIT:0> ) . rotated ( self . cat_body . angle ) <EOL> self . space . add ( self . cat_body , self . cat_shape ) <EOL> def create_car ( self , x , y , r ) : <EOL> inertia = pymunk . moment_for_circle ( <NUM_LIT:1> , <NUM_LIT:0> , <NUM_LIT> , ( <NUM_LIT:0> , <NUM_LIT:0> ) ) <EOL> self . car_body = pymunk . Body ( <NUM_LIT:1> , inertia ) <EOL> self . car_body . position = x , y <EOL> self . car_shape = pymunk . Circle ( self . car_body , <NUM_LIT> ) <EOL> self . car_shape . color = THECOLORS [ "<STR_LIT>" ] <EOL> self . car_shape . elasticity = <NUM_LIT:1.0> <EOL> self . car_body . angle = r <EOL> driving_direction = Vec2d ( <NUM_LIT:1> , <NUM_LIT:0> ) . rotated ( self . car_body . angle ) <EOL> self . car_body . apply_impulse ( driving_direction ) <EOL> self . space . add ( self . car_body , self . car_shape ) <EOL> def frame_step ( self , action ) : <EOL> if action == <NUM_LIT:0> : <EOL> self . car_body . angle -= <NUM_LIT> <EOL> elif action == <NUM_LIT:1> : <EOL> self . car_body . angle += <NUM_LIT> <EOL> if self . num_steps % <NUM_LIT:100> == <NUM_LIT:0> : <EOL> self . move_obstacles ( ) <EOL> if self . num_steps % <NUM_LIT:5> == <NUM_LIT:0> : <EOL> self . move_cat ( ) <EOL> driving_direction = Vec2d ( <NUM_LIT:1> , <NUM_LIT:0> ) . rotated ( self . car_body . angle ) <EOL> self . car_body . velocity = <NUM_LIT:100> * driving_direction <EOL> screen . fill ( THECOLORS [ "<STR_LIT>" ] ) <EOL> draw ( screen , self . space ) <EOL> self . space . step ( <NUM_LIT:1.> / <NUM_LIT:10> ) <EOL> if draw_screen : <EOL> pygame . display . flip ( ) <EOL> clock . tick ( ) <EOL> x , y = self . car_body . position <EOL> readings = self . get_sonar_readings ( x , y , self . car_body . angle ) <EOL> state = np . array ( [ readings ] ) <EOL> if self . car_is_crashed ( readings ) : <EOL> self . crashed = True <EOL> reward = - <NUM_LIT> <EOL> self . recover_from_crash ( driving_direction ) <EOL> else : <EOL> reward = - <NUM_LIT:5> + int ( self . sum_readings ( readings ) / <NUM_LIT:10> ) <EOL> self . num_steps += <NUM_LIT:1> <EOL> return reward , state <EOL> def move_obstacles ( self ) : <EOL> for obstacle in self . obstacles : <EOL> speed = random . randint ( <NUM_LIT:1> , <NUM_LIT:5> ) <EOL> direction = Vec2d ( <NUM_LIT:1> , <NUM_LIT:0> ) . rotated ( self . car_body . angle + random . randint ( - <NUM_LIT:2> , <NUM_LIT:2> ) ) <EOL> obstacle . velocity = speed * direction <EOL> def move_cat ( self ) : <EOL> speed = random . randint ( <NUM_LIT:20> , <NUM_LIT:200> ) <EOL> self . cat_body . angle -= random . randint ( - <NUM_LIT:1> , <NUM_LIT:1> ) <EOL> direction = Vec2d ( <NUM_LIT:1> , <NUM_LIT:0> ) . rotated ( self . cat_body . angle ) <EOL> self . cat_body . velocity = speed * direction <EOL> def car_is_crashed ( self , readings ) : <EOL> if readings [ <NUM_LIT:0> ] == <NUM_LIT:1> or readings [ <NUM_LIT:1> ] == <NUM_LIT:1> or readings [ <NUM_LIT:2> ] == <NUM_LIT:1> : <EOL> return True <EOL> else : <EOL> return False <EOL> def recover_from_crash ( self , driving_direction ) : <EOL> """<STR_LIT>""" <EOL> while self . crashed : <EOL> self . car_body . velocity = - <NUM_LIT:100> * driving_direction <EOL> self . crashed = False <EOL> for i in range ( <NUM_LIT:10> ) : <EOL> self . car_body . angle += <NUM_LIT> <EOL> screen . fill ( THECOLORS [ "<STR_LIT>" ] ) <EOL> draw ( screen , self . space ) <EOL> self . space . step ( <NUM_LIT:1.> / <NUM_LIT:10> ) <EOL> if draw_screen : <EOL> pygame . display . flip ( ) <EOL> clock . tick ( ) <EOL> def sum_readings ( self , readings ) : <EOL> """<STR_LIT>""" <EOL> tot = <NUM_LIT:0> <EOL> for i in readings : <EOL> tot += i <EOL> return tot <EOL> def get_sonar_readings ( self , x , y , angle ) : <EOL> readings = [ ] <EOL> """<STR_LIT>""" <EOL> arm_left = self . make_sonar_arm ( x , y ) <EOL> arm_middle = arm_left <EOL> arm_right = arm_left <EOL> readings . append ( self . get_arm_distance ( arm_left , x , y , angle , <NUM_LIT> ) ) <EOL> readings . append ( self . get_arm_distance ( arm_middle , x , y , angle , <NUM_LIT:0> ) ) <EOL> readings . append ( self . get_arm_distance ( arm_right , x , y , angle , - <NUM_LIT> ) ) <EOL> if show_sensors : <EOL> pygame . display . update ( ) <EOL> return readings <EOL> def get_arm_distance ( self , arm , x , y , angle , offset ) : <EOL> i = <NUM_LIT:0> <EOL> for point in arm : <EOL> i += <NUM_LIT:1> <EOL> rotated_p = self . get_rotated_point ( <EOL> x , y , point [ <NUM_LIT:0> ] , point [ <NUM_LIT:1> ] , angle + offset <EOL> ) <EOL> if rotated_p [ <NUM_LIT:0> ] <= <NUM_LIT:0> or rotated_p [ <NUM_LIT:1> ] <= <NUM_LIT:0> or rotated_p [ <NUM_LIT:0> ] >= width or rotated_p [ <NUM_LIT:1> ] >= height : <EOL> return i <EOL> else : <EOL> obs = screen . get_at ( rotated_p ) <EOL> if self . get_track_or_not ( obs ) != <NUM_LIT:0> : <EOL> return i <EOL> if show_sensors : <EOL> pygame . draw . circle ( screen , ( <NUM_LIT:255> , <NUM_LIT:255> , <NUM_LIT:255> ) , ( rotated_p ) , <NUM_LIT:2> ) <EOL> return i <EOL> def make_sonar_arm ( self , x , y ) : <EOL> spread = <NUM_LIT:10> <EOL> distance = <NUM_LIT:20> <EOL> arm_points = [ ] <EOL> for i in range ( <NUM_LIT:1> , <NUM_LIT> ) : <EOL> arm_points . append ( ( distance + x + ( spread * i ) , y ) ) <EOL> return arm_points <EOL> def get_rotated_point ( self , x_1 , y_1 , x_2 , y_2 , radians ) : <EOL> x_change = ( x_2 - x_1 ) * math . cos ( radians ) + ( y_2 - y_1 ) * math . sin ( radians ) <EOL> y_change = ( y_1 - y_2 ) * math . cos ( radians ) - ( x_1 - x_2 ) * math . sin ( radians ) <EOL> new_x = x_change + x_1 <EOL> new_y = height - ( y_change + y_1 ) <EOL> return int ( new_x ) , int ( new_y ) <EOL> def get_track_or_not ( self , reading ) : <EOL> if reading == THECOLORS [ '<STR_LIT>' ] : <EOL> return <NUM_LIT:0> <EOL> else : <EOL> return <NUM_LIT:1> <EOL> if __name__ == "<STR_LIT:__main__>" : <EOL> game_state = GameState ( ) <EOL> while True : <EOL> game_state . frame_step ( ( random . randint ( <NUM_LIT:0> , <NUM_LIT:2> ) ) ) </s>
