Пример #1
0
 def reset(self):
     """ Reset the spaceship """
     self.dead = False
     self.pos = Vector2(d.SCREEN_SIZE / 2, d.SCREEN_SIZE / 2)
     self.velocity = Vector2()
     self.angular_vel = 0
     self.rotation = 0
    def get_wall_collision(self):
        """ Find intersection point with the wall """
        self.inters = None

        # Check collision with inner wall
        for i in range(len(d.WALL_IN)):
            if self.inters == None:
                j = 0 if len(d.WALL_IN) - 1 == i else i + 1

                w_p1 = d.WALL_I_EXT[i]
                w_p2 = d.WALL_I_EXT[j]
                p1 = Vector2(w_p1[0], w_p1[1])
                p2 = Vector2(w_p2[0], w_p2[1])
                s = Algs.get_segment_inters(
                    p1, p2, self.pos, self.pos + self.dir * d.SENSOR_LENGTH)
                self.inters = s

        # Check collision with outer wall
        for i in range(len(d.WALL_O_EXT) - 1):
            if self.inters == None:
                if i == len(d.WALL_IN) - 1:
                    j = 0
                else:
                    j = i + 1

                w_p1 = d.WALL_O_EXT[i]
                w_p2 = d.WALL_O_EXT[j]
                p1 = Vector2(w_p1[0], w_p1[1])
                p2 = Vector2(w_p2[0], w_p2[1])
                s = Algs.get_segment_inters(
                    p1, p2, self.pos, self.pos + self.dir * d.SENSOR_LENGTH)
                self.inters = s
Пример #3
0
    def __init__(self, neural_net):
        self.pos = Vector2(d.SCREEN_SIZE / 2, d.SCREEN_SIZE / 2)
        self.points = [Vector2()] * 3  # Shape points of the player (triangle)
        self.dir = Vector2(0, -1)  # Direction in which the ship moves
        self.rotation = 0  # Rotation of the ship (radians)
        self.dead = False

        # Inputs fed to the neural network:
        # If sensor mode: the length of each sensor
        # Else: the distance vectors to the closest asteroids
        self.inputs = [] * d.INPUT_COUNT

        if d.sensor_mode:
            # Configure the ship's sensors
            self.sensors = []
            self.setup_sensors()
        else:
            # Indices of the asteroids closest to the player
            # of 'data.asteroids' list
            self.ast_idx = [0] * d.CLOSEST_AST_COUNT

        self.neural_net = neural_net
        self.start_time = pg.time.get_ticks()
        self.speed = d.SPEED
        self.color = d.NEON_BLUE
Пример #4
0
    def spawn(self, edge):
        """ Spawn the asteroid at the given edge """
        s = d.SCREEN_SIZE
        rd = random.uniform(0, s)

        # Get the position
        if edge == 1:
            self.pos.x = rd
            self.pos.y = 0
            self.dir = Vector2(0, 1)
        elif edge == 2:
            self.pos.x = s
            self.pos.y = rd
            self.dir = Vector2(-1, 0)
        elif edge == 3:
            self.pos.x = rd
            self.pos.y = s
            self.dir = Vector2(0, -1)
        else:
            self.pos.x = 0
            self.pos.y = rd
            self.dir = Vector2(1, 0)

        # Choose random direction (towards the center direction)
        self.dir.rotate(random.uniform(-math.pi/2, math.pi/2), Vector2())        
 def __init__(self, angle):
     self.angle = angle
     self.dir = Vector2()
     self.pos = Vector2()
     self.end_pos = Vector2()
     self.car_dir = Vector2()
     self.inters = None
     self.length = d.SENSOR_LENGTH
Пример #6
0
 def __init__(self, angle):
     self.angle = angle  # In degrees
     self.dir = Vector2()
     self.pos = Vector2()  # Start position (= Ship position)
     self.end_pos = Vector2()  # End of the sensor
     self.ship_dir = Vector2()
     self.inters = None  # Intersection point
     self.dist = d.SENSOR_LENGTH  # Length of the sensor
Пример #7
0
    def __init__(self, spawn_edge):
        self.dir = Vector2(0, 1)
        self.pos = Vector2()
        self.rad = random.randint(d.AST_MIN_SIZE, d.AST_MAX_SIZE)
        self.speed = random.uniform(d.AST_MIN_SPD, d.AST_MAX_SPD)
        self.dead = False
        self.color = d.WHITE

        self.spawn(spawn_edge)
    def check_checkpoint_col(self):
        """ Check whether the car collects a checkpoint """

        # First point of the first active checkpoint
        p1 = Vector2(d.active_checkp[0][0][0], d.active_checkp[0][0][1])
        # Second point of the first active checkpoint
        p2 = Vector2(d.active_checkp[0][1][0], d.active_checkp[0][1][1])

        if self.check_col(p1, p2):
            # Check for collision with the checkpoint
            d.active_checkp.pop(0)
            d.best_car = self

            if len(d.active_checkp) == 0:
                self.restart_simulation()
 def __init__(self, net=None):
     self.position = Vector2(d.START_POSITION[0], d.START_POSITION[1])
     self.rotation = 0
     self.direction = Vector2(1, 0)
     self.direction_normal = Vector2(0, 1)
     self.frame = [Vector2()] * 4
     self.sensors = [
         Sensor((180 / (d.SENSOR_COUNT - 1)) * i - 90)
         for i in range(d.SENSOR_COUNT)
     ]
     self.dead = False
     self.turn = 0.5
     if net == None:
         self.neural_net = NeuralNetWork(d.SENSOR_COUNT, d.HIDDEN_LAYERS, 1)
     else:
         self.neural_net = net
Пример #10
0
    def forward_prop(self, inputs):
        """ Calculate output from given inputs through the neural network """
        layers = [inputs]
        for i in range(len(self.h_layers)+1):
            # Calculate the input * weights + bias
            z = np.dot(layers[i], self.weights[i]) + self.biases[i]

            # Apply activation function
            out = []
            if d.sensor_mode:
                # Outputs are numbers
                for j in range(len(z)):
                    o = sigmoid(clamp(-20, 20, z[j]))
                    out.append(o)
            else:
                # Output are vectors
                for j in range(len(z)):
                    sigm_x = sigmoid(clamp(-20, 20, z[j].x))
                    sigm_y = sigmoid(clamp(-20, 20, z[j].y))
                    out.append(Vector2(sigm_x, sigm_y))

            layers.append(out)

        # Return the output
        final_output = layers[len(layers)-1][0]     # Last layer only has 1 output neuron
        return final_output
        
    def check_wall_col(self):
        """ Check whether the car collides with a wall """

        # Check collision with inner wall
        for i in range(len(d.WALL_I_EXT) - 1):
            w_p1 = d.WALL_I_EXT[i]
            w_p2 = d.WALL_I_EXT[i + 1]
            p1 = Vector2(w_p1[0], w_p1[1])
            p2 = Vector2(w_p2[0], w_p2[1])

            if self.check_col(p1, p2):
                self.die()

        # Check collision with outer wall
        for i in range(len(d.WALL_O_EXT) - 1):
            w_p1 = d.WALL_O_EXT[i]
            w_p2 = d.WALL_O_EXT[i + 1]
            p1 = Vector2(w_p1[0], w_p1[1])
            p2 = Vector2(w_p2[0], w_p2[1])

            if self.check_col(p1, p2):
                self.die()
Пример #12
0
    def setup_biases(self):
        """ Set every bias to random value between -1 and 1 """
        # There is a bias for every hidden layer and for the input layer
        self.biases = []
        for _ in range(len(self.h_layers) + 1):
            rd = random.uniform(-1, 1)

            # Floats as inputs --> bias must be number as well
            if d.sensor_mode:
                self.biases.append(rd)
            # Vectors as inputs --> bias must be vector as well
            else:
                self.biases.append(Vector2(rd, rd))
Пример #13
0
    def turn(self, out):
        """ Control the spaceship's direction through neural network output or key input """
        if not d.solo:
            if d.sensor_mode:
                angle = out - 0.5
                angle *= d.TURN_SPEED
                self.rotation -= angle
                self.dir.rotate(-angle, Vector2())
            else:
                # x and y are between (0, 1) --> (-0.5, 0.5)
                out.x -= 0.5
                out.y -= 0.5

                out = out.normalized()

                # Turn the spaceship by changing its direction
                r = self.dir + out
                self.dir = (self.dir +
                            r.normalized() * d.TURN_SPEED).normalized()
        else:
            angle = out - 0.5
            angle *= 0.2
            self.rotation -= angle
            self.dir.rotate(-angle, Vector2())
Пример #14
0
    def update_inputs(self):
        """ Update the ship's inputs used for the neural network """
        self.inputs = []
        if d.sensor_mode:
            # Inputs are the distances of the sensors
            for sensor in self.sensors:
                input = sensor.dist / d.SENSOR_LENGTH  # Scale the inputs between 0 and 1
                self.inputs.append(input)
        else:
            # Inputs are the distance vectors of the closest asteroids
            for index in self.ast_idx:
                a_p = d.asteroids[index].pos - self.pos
                n = a_p.normalized()

                dist = []
                d1 = a_p

                # Find all the possible distances to the spaceship for the current asteroid
                # For example when the player is far right and the asteroid far left,
                # the player is still close to the asteroid (through the screen)
                dist.append(d1 - n * (d.asteroids[index].rad + d.PLAYER_H))
                dist.append((d1 - Vector2(d.SCREEN_SIZE, 0)) - n *
                            (d.asteroids[index].rad + d.PLAYER_H))
                dist.append((d1 + Vector2(d.SCREEN_SIZE, 0)) - n *
                            (d.asteroids[index].rad + d.PLAYER_H))
                dist.append((d1 - Vector2(0, d.SCREEN_SIZE)) - n *
                            (d.asteroids[index].rad + d.PLAYER_H))
                dist.append((d1 + Vector2(0, d.SCREEN_SIZE)) - n *
                            (d.asteroids[index].rad + d.PLAYER_H))
                dist.append((d1 - Vector2(d.SCREEN_SIZE, d.SCREEN_SIZE)) - n *
                            (d.asteroids[index].rad + d.PLAYER_H))
                dist.append((d1 + Vector2(d.SCREEN_SIZE, d.SCREEN_SIZE)) - n *
                            (d.asteroids[index].rad + d.PLAYER_H))
                dist.append((d1 - Vector2(-d.SCREEN_SIZE, d.SCREEN_SIZE)) - n *
                            (d.asteroids[index].rad + d.PLAYER_H))
                dist.append((d1 + Vector2(-d.SCREEN_SIZE, d.SCREEN_SIZE)) - n *
                            (d.asteroids[index].rad + d.PLAYER_H))

                # Take the smallest distance
                m = Algs.v2_min(dist)
                m.x = m.x
                m.y = m.y
                self.inputs.append(m)
Пример #15
0
def mutate(net, strong):
    """ Mutate a neural network\n
        Parameters: \n
        \tnet = the neural net to mutate
        \tstrong = whether or not the mutation should be strong"""
    b = net.biases
    w = net.weights
    """ weights """
    w_new = net.weights
    for _ in range(d.MUTATED_WEIGHTS_COUNT):
        # Find a random weight
        layer_i = random.randint(0, len(w) - 1)
        input_i = random.randint(0, len(w[layer_i]) - 1)
        weigth_i = random.randint(0, len(w[layer_i][input_i]) - 1)
        _w = w[layer_i][input_i][weigth_i]

        # How strong should the weight be mutated
        if (strong):
            mut_strength = d.MUTATION_STRENGTH_HIGH
        else:
            mut_strength = d.MUTATION_STRENGTH_LOW

        # Mutate the weight (weights are always clamped between -1 and 1)
        rd = random.uniform(-mut_strength, mut_strength)
        w_new[layer_i][input_i][weigth_i] = clamp(-1, 1, _w + rd * _w)

    net.weights = w_new
    """ biases """
    # Find a random bias
    index = random.randint(0, len(b) - 1)

    # How strong should the bias be mutated
    rd = random.uniform(-mut_strength, mut_strength)

    # Mutate the bias
    if d.sensor_mode:
        # Bias is a number
        b[index] += rd
    else:
        # Bias is a vector
        b[index] += Vector2(rd, rd)

    net.biases = b

    return net