Пример #1
0
    def __init__(self):
        """Creates all game objects needed, loads resources, initializes
        pygame library and sound mixer, sets display mode, etc."""
        self.state = STATE_TITLE
        pygame.mixer.pre_init(buffer=SOUND_BUFFER)
        pygame.init()
        self.clock = Clock()
        self.scr = pygame.display.set_mode(SCREEN_SIZE, VID_MODE_FLAGS)
        pygame.display.set_caption(WINDOW_CAPTION)
        pygame.mouse.set_visible(False)
        LoadingScreen(self.scr).draw()
        sound_box.init()

        self.level = GameLevel()
        self.stats = GameStats(self.scr)
        self.view_pt = ViewPoint(self.scr)
        self.stars = Stars(self.scr, self.view_pt)
        self.track = Track(self.scr, self.view_pt)
        self.explosions = Explosions(self.scr, self.view_pt)
        self.ship = Ship(self.scr, self.view_pt, self.explosions)
        self.asteroids = Asteroids(self.scr, self.view_pt, self.explosions,
                                   self.track)
        self.title_screen = TitleScreen(self.scr, self.view_pt, self.stars)
        self.level_start_screen = LevelStartScreen(self.scr)
        self.level_complete_effect = LevelCompleteEffect(self.scr)
        self.game_over_effect = GameOverEffect(self.scr)
        self.pause_screen = PauseScreen(self.scr)
        self.ending_screen = EndingScreen(self.scr)

        self._init_title()
Пример #2
0
    def init_physicals(self):
        #        self._entities = {}
        self.robot_names = ["dalek", "drWho", "k9", "kachna"]
        self.num_of_robots = len(self.robot_names)

        self.setup_collision_callbacks()

        self.entities = Entities(self.app)

        self.map = Map2D(self)

        self.asteroids = Asteroids(self)
        self.init_robots()
Пример #3
0
class SpaceRacer():
    """Represents the game itself"""
    def __init__(self):
        """Creates all game objects needed, loads resources, initializes
        pygame library and sound mixer, sets display mode, etc."""
        self.state = STATE_TITLE
        pygame.mixer.pre_init(buffer=SOUND_BUFFER)
        pygame.init()
        self.clock = Clock()
        self.scr = pygame.display.set_mode(SCREEN_SIZE, VID_MODE_FLAGS)
        pygame.display.set_caption(WINDOW_CAPTION)
        pygame.mouse.set_visible(False)
        LoadingScreen(self.scr).draw()
        sound_box.init()

        self.level = GameLevel()
        self.stats = GameStats(self.scr)
        self.view_pt = ViewPoint(self.scr)
        self.stars = Stars(self.scr, self.view_pt)
        self.track = Track(self.scr, self.view_pt)
        self.explosions = Explosions(self.scr, self.view_pt)
        self.ship = Ship(self.scr, self.view_pt, self.explosions)
        self.asteroids = Asteroids(self.scr, self.view_pt, self.explosions,
                                   self.track)
        self.title_screen = TitleScreen(self.scr, self.view_pt, self.stars)
        self.level_start_screen = LevelStartScreen(self.scr)
        self.level_complete_effect = LevelCompleteEffect(self.scr)
        self.game_over_effect = GameOverEffect(self.scr)
        self.pause_screen = PauseScreen(self.scr)
        self.ending_screen = EndingScreen(self.scr)

        self._init_title()

    def run(self):
        """The only public method just runs the game. It starts infinite
        loop where game objects are updated, drawn and interacts with
        each other. Also system events are processed."""
        while True:
            self.clock.tick(FRAMERATE)
            # print(f"FPS: {round(self.clock.get_fps(), 2)}")
            self._process_events()
            self._update_objects()
            self._interact_objects()
            self._draw_objects()

    def _init_title(self):
        self.state = STATE_TITLE
        self.stats.reset()
        self.level.restart()
        self.title_screen.restart()
        self.title_screen.play_music()

    def _init_level_starting(self):
        self.state = STATE_LEVEL_STARTING
        self.level_start_screen.set_level_number(self.level.get_level())
        self.level_start_screen.set_subtitle_text(self.level.get_description())
        self.level_start_screen.restart()

    def _init_level_playing(self):
        self.state = STATE_LEVEL_PLAYING
        self.level.play_music()
        self.view_pt.reset()
        self.stars.respawn()
        self.track.set_tile_map(self.level.get_map())

        top_limit = (self.track.get_track_height() -
                     self.scr.get_rect().height / 2)
        bottom_limit = self.scr.get_rect().height / 2
        self.view_pt.set_limits(top=top_limit, bottom=bottom_limit)

        self.explosions.items.empty()
        self.asteroids.set_spawn_density(self.level.get_asteroids_density())
        self.asteroids.respawn(self.level.get_asteroid_spawns())

        self.ship.set_speed(self.level.get_ship_speed())
        self.ship.set_acceleration(self.level.get_ship_acceleration())
        self.ship.restore((0, 0), reset_control=True)

    def _init_level_finishing(self):
        self.state = STATE_LEVEL_FINISHING
        self.stats.increase_score(LEVEL_COMPLETE_PTS)
        self.level_complete_effect.restart()
        self.ship.set_autopilot()
        pygame.mixer.music.fadeout(MUSIC_FADEOUT)

    def _init_game_over(self):
        self.state = STATE_GAME_OVER
        self.game_over_effect.restart()
        pygame.mixer.music.fadeout(MUSIC_FADEOUT)

    def _init_ending(self):
        self.state = STATE_ENDING
        self.ending_screen.set_score(self.stats.score)
        self.ending_screen.restart()
        self.ending_screen.play_music()

    def _init_pause(self):
        self.state = STATE_PAUSE
        self.pause_screen.refresh_background()
        pygame.mixer.music.pause()

    def _ship_control(self, key, control_status):
        """Returns True if the key was a ship direction control key."""
        key_processed = True

        if key == pygame.K_UP:
            self.ship.moving_up = control_status
        elif key == pygame.K_DOWN:
            self.ship.moving_down = control_status
        elif key == pygame.K_LEFT:
            self.ship.moving_left = control_status
        elif key == pygame.K_RIGHT:
            self.ship.moving_right = control_status
        elif key == pygame.K_SPACE:
            self.ship.shooting = control_status
        else:
            key_processed = False

        return key_processed

    def _process_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()

            if self.state == STATE_TITLE:
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        sys.exit()
                    elif event.key == pygame.K_RETURN:
                        pygame.mixer.music.fadeout(MUSIC_FADEOUT)
                        self._init_level_starting()

            elif self.state == STATE_PAUSE:
                if event.type == pygame.KEYDOWN:
                    if event.key in (pygame.K_ESCAPE, pygame.K_PAUSE):
                        self.state = STATE_LEVEL_PLAYING
                        pygame.mixer.music.unpause()
                    elif event.key == pygame.K_RETURN:
                        sys.exit()

            elif self.state == STATE_LEVEL_PLAYING:
                if event.type == pygame.KEYDOWN:
                    if event.key in (pygame.K_ESCAPE, pygame.K_PAUSE):
                        self._init_pause()
                    else:
                        self._ship_control(event.key, control_status=True)
                elif event.type == pygame.KEYUP:
                    self._ship_control(event.key, control_status=False)

            if self.state == STATE_ENDING:
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        sys.exit()
                    elif event.key == pygame.K_RETURN:
                        self._init_title()

    def _update_objects(self):
        if self.state == STATE_TITLE:
            self.title_screen.update()

        if self.state == STATE_LEVEL_STARTING:
            self.level_start_screen.update()

        if self.state in (STATE_LEVEL_PLAYING, STATE_LEVEL_FINISHING,
                          STATE_GAME_OVER):
            self.view_pt.update()
            self.stars.update()
            self.track.update()
            self.asteroids.update()
            self.ship.update()
            self.explosions.update()

        if self.state == STATE_LEVEL_FINISHING:
            self.level_complete_effect.update()

        if self.state == STATE_GAME_OVER:
            self.game_over_effect.update()

        if self.state == STATE_ENDING:
            self.ending_screen.update()

    def _crossed_finish_line(self):
        finish_line_y = (self.track.get_track_height() -
                         self.scr.get_rect().height / 2)
        return self.ship.y > finish_line_y

    def _interact_objects(self):
        if self.state == STATE_LEVEL_STARTING:
            if self.level_start_screen.finished():
                self._init_level_playing()

        elif self.state == STATE_LEVEL_PLAYING:
            if self.stats.game_over():
                self._init_game_over()
            elif self._crossed_finish_line():
                self._init_level_finishing()
            elif self.ship.status == SHIP_STATUS_NORMAL:
                self._check_collisions()
            elif self.ship.status == SHIP_STATUS_INACTIVE:
                self._ship_restore()

        elif self.state == STATE_LEVEL_FINISHING:
            if self.level_complete_effect.finished():
                if self.level.last_level():
                    self._init_ending()
                else:
                    self.level.next_level()
                    self._init_level_starting()

        elif self.state == STATE_GAME_OVER:
            if self.game_over_effect.finished():
                self._init_title()

    def _draw_objects(self):
        if self.state == STATE_TITLE:
            self.title_screen.draw()

        if self.state == STATE_PAUSE:
            self.pause_screen.draw()

        if self.state == STATE_LEVEL_STARTING:
            self.level_start_screen.draw()

        if self.state in (STATE_LEVEL_PLAYING, STATE_LEVEL_FINISHING,
                          STATE_GAME_OVER):

            self.scr.blit(self.level.get_background(), (0, 0))
            self.stars.draw()
            self.track.draw()
            self.asteroids.draw()
            self.ship.draw()
            self.explosions.draw()
            self.stats.draw()

        if self.state == STATE_LEVEL_FINISHING:
            self.level_complete_effect.draw()

        if self.state == STATE_GAME_OVER:
            self.game_over_effect.draw()

        if self.state == STATE_ENDING:
            self.ending_screen.draw()

        pygame.display.flip()

    def _ship_explode(self, collide_point=None):
        """collide_point is a tuple of absolute coordinates: (x, y)"""
        self.stats.lost_life()
        self.ship.explode(collide_point)

    def _ship_restore(self):
        restore_x, restore_y = self.ship.get_center()
        borders = self.track.get_track_borders(restore_y)
        if borders:
            restore_x = mean(borders)
        if self.ship.restore((restore_x, restore_y)):
            self.asteroids.explode_nearest(self.ship.get_center())

    def _check_ship_penalty(self):
        borders = self.track.get_track_borders(self.ship.get_center()[1])
        if borders:
            left = self.ship.x
            right = left + self.ship.rect.width
            if right < borders[0] or left > borders[1]:
                self._ship_explode()
                return True
        return False

    def _check_collisions(self):
        collide_point = self.track.collidemask(self.ship.mask, self.ship.rect)
        if collide_point:
            self._ship_explode(collide_point)
            return True

        collide_point = self.asteroids.collidemask(self.ship.mask,
                                                   self.ship.rect,
                                                   explode=True)
        if collide_point:
            self._ship_explode(collide_point)
            return True

        if self.ship.laser.shooting():
            if self.asteroids.collidemask(self.ship.laser.mask,
                                          self.ship.laser.rect,
                                          explode=True):
                self.stats.increase_score(ASTEROID_HIT_PTS)

        return self._check_ship_penalty()
Пример #4
0
import pygame

from asteroids import Asteroids
pygame.init()
# Create an object for managing the game
game = Asteroids("Asteroids", 640, 480)
# Start the main game loop
game.runGame()
Пример #5
0
from asteroids import Asteroids

# Create an object for managing the game
game = Asteroids("Asteroids", 1280, 720)
# Start the main game loop
game.runGame()








Пример #6
0
class TestGame(Widget):
    def init_collision_ids(self):
        self.ultrasound_count = 10

        # self.collide_control = CollideControl(self.ultrasound_count)
        # self.collision_ids = self.collide_control.collision_ids
        self.collision_ids = {
            "wall": 1,
            "obstacle_rect": 2,
            "obstacle": 3,
            "asteroid": 5,
            "ultrasound_detectable": 0,
            "ultrasound": [50 + i for i in range(self.ultrasound_count)],
            "robot": 100,  # let it be free after robot for num of robot create
            "candy": 42,
        }

        detected_names = ["wall", "obstacle", "obstacle_rect", "robot"]

        self.collision_ids["ultrasound_detectable"] = list(
            {self.collision_ids[name]
             for name in detected_names})
        print("ultrasound_detectable")
        print(self.collision_ids["ultrasound_detectable"])

        # ignore touch of user
        self.ignore_groups = []
        self.ignore_groups.extend(self.collision_ids["ultrasound"])
        # [ self.ignore_groups.append(self.collision_ids[key]) for key in ['robot']]

    def __init__(self, **kwargs):
        self.init_collision_ids()
        super(TestGame, self).__init__(**kwargs)

        self.gameworld.init_gameworld(
            [
                "cymunk_physics",
                "poly_renderer",
                "rotate_poly_renderer",
                "rotate_renderer",
                #'steering_system'
                "rotate",
                "position",
                "cymunk_touch",
            ],
            callback=self.init_game,
        )

    def info(self, text):
        self.app.info_text += "\n" + str(text)

    def init_game(self):
        # called automatically? probably
        self.pp = pprint.PrettyPrinter(indent=4)
        self.pprint = self.pp.pprint

        self.field_size = 800, 600
        self.to_draw_obstacles = 0

        self.robot = None
        self.robots = None

        self.setup_states()
        self.set_state()
        self.init_loaders()
        print("init_physicals")
        self.init_physicals()
        # self.init_space_constraints()

        self.init_properties_updater()

        self.init_control_logic()

    def init_control_logic(self):
        self.init_chase_candy_updater()

    def init_loaders(self):
        self.fl = FileLoader(self)

    def init_physicals(self):
        #        self._entities = {}
        self.robot_names = ["dalek", "drWho", "k9", "kachna"]
        self.num_of_robots = len(self.robot_names)

        self.setup_collision_callbacks()

        self.entities = Entities(self.app)

        self.map = Map2D(self)

        self.asteroids = Asteroids(self)
        self.init_robots()

    def init_robots(self):
        self.robots = [
            self.get_robot(name, i) for i, name in enumerate(self.robot_names)
        ]

        self.candy = Candy(self)

    def unused_load_robot_svg(self, robot):
        self.fl.load_svg(robot.path, self.gameworld)

    def add_robot(self):
        i = len(self.robots)
        name = f"robot_{i}"
        robot = self.get_robot(name, i)
        self.robots.append(robot)

    def get_robot(self, name, i):
        drive = "mecanum"
        us_count = 3
        return Robot(
            root=self,
            drive=drive,
            robot_name=name,
            us_id_offset=i * us_count,
            robot_number=i,
        )

    def toggle_robot_control(self, state):
        self.robot_controlled = state

        if not state:
            return

        for r in self.robots:
            r.add_state("INIT")
            r.reset_ultrasounds()

    def init_chase_candy_updater(self):
        for r in self.robots:
            r.chase_candy(self.candy)
        self.robot_controlled = False
        Clock.schedule_once(self.chase_candy_update)

    def chase_candy_update(self, dt):
        if self.robot_controlled:
            for r in self.robots:
                r.goto_target()
        Clock.schedule_once(self.chase_candy_update, 0.05)

    def draw_asteroids(self):
        self.asteroids.draw_asteroids()

    def setup_collision_callbacks(self):
        """Setup the correct collisions for the cymunk physics system manager.

        use the physics_system.add_collision_handler
        to define between which collision_ids the collision should happen and between which not

        Following handler functions are passed
        - begin_func - called once on collision begin
        - separate_func - called once on collision end
        """

        physics_system = self.gameworld.system_manager["cymunk_physics"]

        def ignore_collision(na, nb):
            """Returns false to indicate ignoring the collision."""
            return False

        # collide_remove_first

        # add robots
        us_detectable = self.collision_ids["ultrasound_detectable"]
        rob_collision_ids = [
            self.collision_ids["robot"] + ct
            for ct in range(self.num_of_robots)
        ]
        us_detectable.extend(rob_collision_ids)

        self.begin_ultrasound_callback = {}

        # ignore_collision of ultrasound triangle with 0-1024 collision_ids
        # to enable the triangles to clip through other objects
        # ! this should be done on robot / on ultrasound creation
        for us_id in self.collision_ids["ultrasound"]:
            for index_id in range(1024):
                physics_system.add_collision_handler(
                    index_id,
                    us_id,
                    begin_func=ignore_collision,
                    separate_func=ignore_collision,
                )

        # add ultrasound triangles object detection via collision
        # ! this should be done on robot / on ultrasound creation
        for us_id in self.collision_ids["ultrasound"]:
            for detectable in us_detectable:
                print("us_id", us_id)
                physics_system.add_collision_handler(
                    detectable,
                    us_id,
                    begin_func=self.return_begin_ultrasound_callback(
                        us_id, True),
                    separate_func=self.return_begin_ultrasound_callback(
                        us_id, False),
                )

        for r_ct in rob_collision_ids:
            from pudb.remote import set_trace

            set_trace(term_size=(238, 54), host="0.0.0.0", port=6900)  # noqa
            physics_system.add_collision_handler(
                self.collision_ids["candy"],
                r_ct,
                begin_func=self.begin_candy_callback,
                separate_func=self.begin_candy_callback,
            )

    def candy_caught(self, robot_ent_id):
        print("candy eaten! by robot:", robot_ent_id)
        self.candy.reset_position()
        self.to_draw_obstacles = 2

    def begin_candy_callback(self, space, arbiter):
        # self.r
        robot_ent_id = arbiter.shapes[1].body.data
        # us[us_id] = rob
        self.candy_caught(robot_ent_id)
        return False

    def get_robot_from_us_id(self, us_id):
        for r in self.robots:
            if r.is_this_us_mine(us_id):
                return r
        return None

    def get_robot_from_ent_id(self, robot_id):
        for r in self.robots:
            if r.ent == robot_id:
                return r
        return None

    def return_begin_ultrasound_callback(self, us_id, state):
        # this adds the segmentation fault on exit - but currently I am not able to simulate ultrasounds any other way than
        # returning
        def begin_ultrasound_callback(self, space, arbiter):
            # ent0_id = arbiter.shapes[0].body.data #detectable_object
            # ent1_id = arbiter.shapes[1].body.data #robot
            space.enable_contact_graph = True
            # print(space.bodies)

            ent0 = arbiter.shapes[0]
            e_id = ent0.body.data
            # a = ent0.body
            # print(len(arbiter.shapes))
            con = arbiter.contacts
            # print(a)
            # print(dir(a))
            # print(a.contact)
            rob_ent = arbiter.shapes[1].body.data

            if con is not None:
                r = self.get_robot_from_ent_id(rob_ent)

                # r = self.get_robot_from_us_id(us_id)
                r.ultrasound_detection(us_id, ent0, state)
                ent = self.gameworld.entities[e_id]
                cat = [
                    cat for cat, id_list in self.entities.items()
                    if e_id in id_list
                ]
                # print('detect', cat, e_id)
            return False

        ind = 2 * us_id + int(state)
        self.begin_ultrasound_callback[ind] = types.MethodType(
            begin_ultrasound_callback, self)
        return self.begin_ultrasound_callback[ind]
        # return begin_ultrasound_callback

    def add_entity(self, ent, category):
        # add to entity counter
        print("added entity", category)
        if category not in self.entities.keys():
            self.entities[category] = []
        self.entities.add_item(category, ent)

    def set_robots_rand(self):
        for r in self.robots:
            r.set_random_position()

    def kick_robots(self):
        for r in self.robots:
            self.kick_robot(r)

    def kick_robot(self, r):
        rob_ent = r.ent
        print(rob_ent)

        rob_body = self.gameworld.entities[rob_ent].cymunk_physics.body

        im = (10000, 10000)
        seq = [-1, 1]
        imp = (choice(seq) * randint(*im), choice(seq) * randint(*im))
        rob_body.apply_impulse(imp)
        print("impulse", imp)

    def init_entity(
        self,
        component_dict,
        component_order,
        category="default_category",
        object_info=None,
    ):
        if object_info is not None:
            category = object_info.get("category", category)
        else:
            object_info = {}

        ent = self.gameworld.init_entity(component_dict, component_order)

        # add to counter
        self.add_entity(ent, category)

        object_info.update({"ent": ent})
        entity_info = object_info

        # print('@'*42)
        # self.pprint(entity_info)
        # print(Robot.cats, category in Robot.cats)

        # add to specific subobjects
        # if self.robot is not None:
        #   self.robot.add_entity(entity_info)
        #      if category == 'robot':
        #         print('added robot')

        return ent

    def destroy_all_entities(self):
        self.destroy_entities()

    def destroy_entities(self, cat_list=None, skip_cat_list=None):
        for ent_cat, ent_list in self.entities.items():
            delete = False
            if cat_list is None and skip_cat_list is None:
                delete = True
            else:
                if cat_list is None:
                    if ent_cat not in skip_cat_list:
                        delete = True
                else:
                    if ent_cat in cat_list:
                        delete = True

            if delete:
                prinf("Clearing entities of " + ent_cat)
                for ent in ent_list:
                    self.destroy_created_entity(ent, 0)
                self.entities[ent_cat].clear()
        for r in self.robots:
            r.reset_ultrasounds()

    def destroy_created_entity(self, ent_id, dt):
        self.gameworld.remove_entity(ent_id)

    # def draw_some_stuff(self):
    #   self.load_svg('objects.svg', self.gameworld)
    # self.load_svg('map.svg', self.gameworld)
    #    self.map.draw_stuff()
    #       self.load_svg('map.svg', self.gameworld)

    def draw_obstacles(self):
        self.map.draw_obstacles(5)

    def draw_rect_obstacles(self):
        self.map.draw_rect_obstacles(5)

    def update(self, dt):
        self.gameworld.update(dt)

    def setup_states(self):
        self.gameworld.add_state(
            state_name="main",
            systems_added=["poly_renderer"],
            systems_removed=[],
            systems_paused=[],
            systems_unpaused=["poly_renderer"],
            screenmanager_screen="main",
        )

    def set_state(self):
        self.gameworld.state = "main"

    def init_properties_updater(self):
        Clock.schedule_once(self.update_properties)

    def update_properties(self, dt):
        self.app.ultrasound_status = "\n".join(
            [r.ultrasound_status() for r in self.robots])
        self.app.robot_states = "\n\n".join(
            [str(r.states) for r in self.robots])
        #       self.app.robot_score =
        #   self.r.reset_ultrasounds()
        if self.to_draw_obstacles > 0:
            self.map.draw_obstacles(self.to_draw_obstacles)
            self.to_draw_obstacles = 0
        Clock.schedule_once(self.update_properties, 0.05)
                                   v_dim=5,
                                   r_dim=256,
                                   h_dim=128,
                                   z_dim=64,
                                   L=8).to(device)

    optimizer = torch.optim.Adam(model.parameters(), lr=5 * 10**(-5))

    # Rate annealing schemes
    sigma_scheme = Annealer(2.0, 0.7, 2 * 10**5)
    mu_scheme = Annealer(5 * 10**(-4), 5 * 10**(-6), 1.6 * 10**5)

    # Load the dataset
    #train_dataset = ShepardMetzler(root_dir=args.data_dir, fraction=args.fraction)
    #valid_dataset = ShepardMetzler(root_dir=args.data_dir, fraction=args.fraction, train=False)
    train_dataset = Asteroids(rootDir, True, 20)
    valid_dataset = Asteroids(rootDir, False, 2)

    kwargs = {'num_workers': args.workers, 'pin_memory': True}
    train_loader = DataLoader(train_dataset,
                              batch_size=args.batch_size,
                              shuffle=True,
                              **kwargs)
    valid_loader = DataLoader(valid_dataset,
                              batch_size=args.batch_size,
                              shuffle=True,
                              **kwargs)

    def step(engine, batch):
        model.train()
Пример #8
0
#!/usr/bin/env python
# -*- coding: UTF-8 -*-#

#TODO
#Add asteroids
#Show life
#Show score
#Check screen limits
#Clear arrays with bullets/asteroids
#del asteroid when hit asteroid
#del you when asteroid hits you
#Decrement life when asteroid hits you
#Increment score when you hit asteroid

from asteroids import Asteroids

if __name__ == '__main__':
    gm = Asteroids()
    gm.run()
Пример #9
0
import tkinter

from player import Player
from game import Game
from asteroids import Asteroids

root = tkinter.Tk()
player = Player(root)
asteroids = Asteroids(root)
game = Game(root)

game.create_player(player)
game.create_asteroids(asteroids)

game.update()

root.mainloop()
Пример #10
0
from asteroids import Asteroids

# Create an object for managing the game
game = Asteroids( "Asteroids", 800, 600 )
# Start the main game loop
game.runGame()








Пример #11
0
def run_rounds(opts, args):
    def get_cmd_wd(cmd, exec_rel_cwd=False):
        ''' get the proper working directory from a command line '''
        new_cmd = []
        wd = None
        for i, part in reversed(list(enumerate(cmd.split()))):
            if wd == None and os.path.exists(part):
                wd = os.path.dirname(os.path.realpath(part))
                basename = os.path.basename(part)
                if i == 0:
                    if exec_rel_cwd:
                        new_cmd.insert(0, os.path.join(".", basename))
                    else:
                        new_cmd.insert(0, part)
                else:
                    new_cmd.insert(0, basename)
            else:
                new_cmd.insert(0, part)
        return wd, ' '.join(new_cmd)

    def get_cmd_name(cmd):
        ''' get the name of a bot from the command line '''
        for i, part in enumerate(reversed(cmd.split())):
            if os.path.exists(part):
                return os.path.basename(part)


# this split of options is not needed, but left for documentation

    game_options = {
        "map": opts.map,
        "kill_points": opts.kill_points,
        "loadtime": opts.loadtime,
        "turntime": opts.turntime,
        "turns": opts.turns,
        "cutoff_turn": opts.cutoff_turn,
        "cutoff_percent": opts.cutoff_percent,
        "scenario": opts.scenario
    }
    if opts.player_seed != None:
        game_options['player_seed'] = opts.player_seed
    if opts.engine_seed != None:
        game_options['engine_seed'] = opts.engine_seed
    engine_options = {
        "loadtime": opts.loadtime,
        "turntime": opts.turntime,
        "map_file": opts.map,
        "turns": opts.turns,
        "log_replay": opts.log_replay,
        "log_stream": opts.log_stream,
        "log_input": opts.log_input,
        "log_output": opts.log_output,
        "log_error": opts.log_error,
        "serial": opts.serial,
        "strict": opts.strict,
        "capture_errors": opts.capture_errors,
        "secure_jail": opts.secure_jail,
        "end_wait": opts.end_wait
    }
    for round in range(opts.rounds):
        # initialize game
        game_id = round + opts.game_id
        with open(opts.map, 'r') as map_file:
            game_options['map'] = map_file.read()
        if opts.engine_seed:
            game_options['engine_seed'] = opts.engine_seed + round
        game = Asteroids(game_options)
        # initialize bots
        bots = [get_cmd_wd(arg, exec_rel_cwd=opts.secure_jail) for arg in args]
        bot_count = len(bots)
        # insure correct number of bots, or fill in remaining positions
        if game.num_players != len(bots):
            if game.num_players > len(bots) and opts.fill:
                extra = game.num_players - len(bots)
                for _ in range(extra):
                    bots.append(bots[-1])
            else:
                print("Incorrect number of bots for map.  Need {0}, got {1}".
                      format(game.num_players, len(bots)),
                      file=stderr)
                for arg in args:
                    print("Bot Cmd: {0}".format(arg), file=stderr)
                break
        bot_count = len(bots)
        # move position of first bot specified
        if opts.position > 0 and opts.position <= len(bots):
            first_bot = bots[0]
            bots = bots[1:]
            bots.insert(opts.position, first_bot)

        # initialize file descriptors
        if opts.log_dir and not os.path.exists(opts.log_dir):
            os.mkdir(opts.log_dir)
        if not opts.log_replay and not opts.log_stream and (opts.log_dir or
                                                            opts.log_stdout):
            opts.log_replay = True
        replay_path = None  # used for visualizer launch

        if opts.log_replay:
            if opts.log_dir:
                replay_path = os.path.join(opts.log_dir,
                                           '{0}.replay'.format(game_id))
                engine_options['replay_log'] = open(replay_path, 'w')
            if opts.log_stdout:
                if 'replay_log' in engine_options and engine_options[
                        'replay_log']:
                    engine_options['replay_log'] = Tee(
                        sys.stdout, engine_options['replay_log'])
                else:
                    engine_options['replay_log'] = sys.stdout
        else:
            engine_options['replay_log'] = None

        if opts.log_stream:
            if opts.log_dir:
                engine_options['stream_log'] = open(
                    os.path.join(opts.log_dir, '{0}.stream'.format(game_id)),
                    'w')
            if opts.log_stdout:
                if engine_options['stream_log']:
                    engine_options['stream_log'] = Tee(
                        sys.stdout, engine_options['stream_log'])
                else:
                    engine_options['stream_log'] = sys.stdout
        else:
            engine_options['stream_log'] = None

        if opts.log_input and opts.log_dir:
            engine_options['input_logs'] = [
                open(
                    os.path.join(opts.log_dir,
                                 '{0}.bot{1}.input'.format(game_id, i)), 'w')
                for i in range(bot_count)
            ]
        else:
            engine_options['input_logs'] = None
        if opts.log_output and opts.log_dir:
            engine_options['output_logs'] = [
                open(
                    os.path.join(opts.log_dir,
                                 '{0}.bot{1}.output'.format(game_id, i)), 'w')
                for i in range(bot_count)
            ]
        else:
            engine_options['output_logs'] = None
        if opts.log_error and opts.log_dir:
            if opts.log_stderr:
                if opts.log_stdout:
                    engine_options['error_logs'] = [
                        Tee(
                            Comment(stderr),
                            open(
                                os.path.join(
                                    opts.log_dir,
                                    '{0}.bot{1}.error'.format(game_id, i)),
                                'w')) for i in range(bot_count)
                    ]
                else:
                    engine_options['error_logs'] = [
                        Tee(
                            stderr,
                            open(
                                os.path.join(
                                    opts.log_dir,
                                    '{0}.bot{1}.error'.format(game_id, i)),
                                'w')) for i in range(bot_count)
                    ]
            else:
                engine_options['error_logs'] = [
                    open(
                        os.path.join(opts.log_dir,
                                     '{0}.bot{1}.error'.format(game_id, i)),
                        'w') for i in range(bot_count)
                ]
        elif opts.log_stderr:
            if opts.log_stdout:
                engine_options['error_logs'] = [Comment(stderr)] * bot_count
            else:
                engine_options['error_logs'] = [stderr] * bot_count
        else:
            engine_options['error_logs'] = None

        if opts.verbose:
            if opts.log_stdout:
                engine_options['verbose_log'] = Comment(sys.stdout)
            else:
                engine_options['verbose_log'] = sys.stdout

        engine_options['game_id'] = game_id
        if opts.rounds > 1:
            print('# playgame round {0}, game id {1}'.format(round, game_id))

        # intercept replay log so we can add player names
        if opts.log_replay:
            intcpt_replay_io = StringIO()
            real_replay_io = engine_options['replay_log']
            engine_options['replay_log'] = intcpt_replay_io

        result = run_game(game, bots, engine_options)

        # add player names, write to proper io, reset back to normal
        if opts.log_replay:
            replay_json = json.loads(intcpt_replay_io.getvalue())
            replay_json['playernames'] = [get_cmd_name(arg) for arg in args]
            real_replay_io.write(json.dumps(replay_json))
            intcpt_replay_io.close()
            engine_options['replay_log'] = real_replay_io

        # close file descriptors
        if engine_options['stream_log']:
            engine_options['stream_log'].close()
        if engine_options['replay_log']:
            engine_options['replay_log'].close()
        if engine_options['input_logs']:
            for input_log in engine_options['input_logs']:
                input_log.close()
        if engine_options['output_logs']:
            for output_log in engine_options['output_logs']:
                output_log.close()
        if engine_options['error_logs']:
            for error_log in engine_options['error_logs']:
                error_log.close()
        if replay_path:
            if opts.nolaunch:
                if opts.html_file:
                    visualizer.visualize_locally.launch(
                        replay_path, True, opts.html_file)
            else:
                if opts.html_file == None:
                    visualizer.visualize_locally.launch(
                        replay_path,
                        generated_path="replay.{0}.html".format(game_id))
                else:
                    visualizer.visualize_locally.launch(
                        replay_path, generated_path=opts.html_file)