示例#1
0
    def __client_logic(self, net):
        """
        The Client-logic according to the given network.
        Server messages are received. Based on the image the features are calculated.
        The features are used as network input.
        The output of the network is send to the server.
        Also statistics for the fitness-value are stored
        :param net: the network used to calculate the key-strokes
        :return:
        """
        status = -1
        while True:
            if self.socket.new_message:
                # receive new message
                client_id, status, lap_id, lap_total, damage, rank, image = self.socket.receive(
                )
                if self.fc is not None:
                    self.fc.update(img=image, print_features=False)

                if damage is not None:
                    self.damage = damage

            if status == S_WAIT:
                # wait for game to start
                pass

            elif status == S_COUNTDOWN:
                # extract track during countdown
                if self.fc is None:
                    self.fc = FeatureCalculator(client_id=client_id, img=image)

            elif status == S_RUNNING:
                if self.start_timestamp is None:
                    # set timestamp when race stated for fitness calculation
                    self.start_timestamp = time.time()

                inputs = np.asarray(list(self.fc.features), dtype=np.int64)

                # calculate key strokes
                output = net.activate(inputs=inputs)

                if ARGS.output_mode_2:
                    keys = np.zeros(4)
                    # vertical control
                    if output[0] <= .25:  # down
                        keys[1] = 1
                    elif output[0] >= .75:  # up
                        keys[0] = 1
                    # horizontal control
                    if output[1] <= .25:  # right
                        keys[3] = 1
                    elif output[1] >= .75:  # left
                        keys[2] = 1

                else:
                    keys = np.asarray(list(map(lambda x: x + .5, output)),
                                      dtype=np.int8)

                # send keys strokes to server
                self.socket.send_key_msg(keys[0], keys[1], keys[2], keys[3])

                speed = self.fc.speed_features
                if speed[0] == 0 and speed[1] == 0:
                    self.zero_speed_counter += 1

                if self.zero_speed_counter >= self.time_out_zero_speed_counter:
                    return

            elif status == S_FINISHED:
                # save time of racing
                self.race_time = time.time() - self.start_timestamp
                return

            elif status == S_CRASHED:
                # client broke
                self.race_time = self.time_out
                return

            elif status == S_CANCELED:
                self.race_time = self.time_out
                return

            if self.start_timestamp and time.time(
            ) > self.start_timestamp + self.time_out:
                self.race_time = self.time_out
                return

            time.sleep(.1)
示例#2
0
            up = (1 < angle < 179) and (speed_y >= -max_speed)
            down = (181 < angle < 359) and (speed_y <= max_speed)
            left = (91 < angle < 269) and (speed_x >= -max_speed)
            right = (angle < 89 or angle > 271) and (speed_x <= max_speed)

            s.send_key_msg(up, down, left, right)

            display.blit(pygame.surfarray.make_surface(image), (0, 0))
            fc.draw_features(display)
            pygame.display.update()

        elif status == S_COUNTDOWN:
            display.blit(pygame.surfarray.make_surface(image), (0, 0))
            pygame.display.update()
            if fc is None:
                fc = FeatureCalculator(img=image, client_id=ID)

            time.sleep(0.1)
        elif status == S_WAIT:
            display.blit(pygame.surfarray.make_surface(image), (0, 0))
            pygame.display.update()

        elif status == S_FINISHED:
            display.blit(pygame.surfarray.make_surface(image), (0, 0))
            pygame.display.update()
            print_debug('Finished!')
            break

        elif status == S_CRASHED:
            print_debug('Crashed')
            break
示例#3
0
class TournamentClient(object):
    time_out_zero_speed_counter = 100  # due time.sleep(.1) the run is over after 20 sec of zero speed
    zero_speed_counter = 0

    start_timestamp = None

    race_time = None

    damage = None

    thread = None

    fc = None

    track = None

    track_line = None

    def __init__(self, cp_ids, output_mode_2):
        self.socket = RaicerSocket.RaicerSocket()
        self.cp_ids = cp_ids
        self.output_mode_2 = output_mode_2

    def __connect_to_server(self):
        """
        Tries to connect to the server for 100s.
        :return: True if connection was successful, else False
        """
        t = time.time() + 100
        while time.time() <= t:
            try:
                self.socket.connect()
                return True
            except ConnectionRefusedError:
                time.sleep(.5)
        return False

    def run(self, genome_id, net, out_q, max_id, track_id):
        """
        Starts the connection to the server. Then runs the genome of this evaluator as a Client.
        When the game is over the connection is closed and the fitness-value saved in the given output-queue
        :param genome_id: the id of the corresponding genome in the current generation
        :param genome: the corresponding genome
        :param config: the current configuration
        :param out_q: Queue where the fitness-value of the genome is stored
        :param max_id: the largest id in the current race
        :param track_id: the id of the track for the current race. The numbering starts with 1
        :param num_laps: the number of laps in the current race
        :return:
        """
        if not self.__connect_to_server():
            return

        # receive client_id to check if all current clients are connected
        client_id = None
        while client_id in [None, -1]:
            client_id, *_ = self.socket.receive()
            time.sleep(.1)
        if client_id == max_id:
            # if current id is the largest possible, this client is the last one and should start the game
            self.socket.send_setting_msg(track_id=track_id, num_laps=5)

        # start client behavior
        self.__client_logic(net=net)

        # transfer fitness-value to main process
        # TODO send time and damage
        if self.damage is None:
            self.damage = 255
        if self.race_time is None:
            self.race_time = time.time() - self.start_timestamp
        out_q.put({genome_id: (self.race_time, self.damage)})

    def __client_logic(self, net):
        """
        The Client-logic according to the given network.
        Server messages are received. Based on the image the features are calculated.
        The features are used as network input.
        The output of the network is send to the server.
        Also statistics for the fitness-value are stored
        :param net: the network used to calculate the key-strokes
        :return:
        """
        status = -1
        power_up_used = False
        while True:

            if not self.socket.is_active:
                return

            if self.socket.new_message:
                # receive new message
                client_id, status, lap_id, lap_total, damage, rank, image = self.socket.receive(
                )
                if self.fc is not None:
                    self.fc.update(img=image, print_features=False)

                if damage is not None:
                    self.damage = damage

            if status == S_WAIT:
                # wait for game to start
                pass

            elif status == S_COUNTDOWN:
                # extract track during countdown
                if self.fc is None:
                    self.fc = FeatureCalculator(client_id=client_id, img=image)

            elif status == S_RUNNING:
                if self.start_timestamp is None:
                    # set timestamp when race stated for fitness calculation
                    self.start_timestamp = time.time()

                inputs = np.asarray(list(
                    self.fc.feature_m(speed=True,
                                      cp_ids=self.cp_ids,
                                      direc_dist=True)),
                                    dtype=np.int64)

                # calculate key strokes
                output = net.activate(inputs=inputs)

                if self.output_mode_2:
                    keys = np.zeros(4)
                    # vertical control
                    if output[0] <= .25:  # down
                        keys[0] = 0
                        keys[1] = 1
                    elif output[0] >= .75:  # up
                        keys[0] = 1
                        keys[1] = 0
                    # horizontal control
                    if output[1] <= .25:  # right
                        keys[2] = 0
                        keys[3] = 1
                    elif output[1] >= .75:  # left
                        keys[2] = 1
                        keys[3] = 0

                else:
                    keys = np.asarray(list(map(lambda x: x + .5, output)),
                                      dtype=np.int8)

                if not power_up_used:
                    power_up_used = True
                    if keys[0] == 0 and keys[1] == 0 and keys[2] == 0 and keys[
                            3] == 0:
                        keys[3] = 1

                # send keys strokes to server
                self.socket.send_key_msg(keys[0], keys[1], keys[2], keys[3])

                speed = self.fc.speed_features
                if speed[0] == 0 and speed[1] == 0:
                    self.zero_speed_counter += 1

                if self.zero_speed_counter >= self.time_out_zero_speed_counter:
                    return

            elif status == S_FINISHED:
                # save time of racing
                self.race_time = time.time() - self.start_timestamp
                return

            elif status == S_CRASHED:
                # client broke
                return

            elif status == S_CANCELED:
                return

            time.sleep(.1)