Esempio n. 1
0
def readCommand(argv):
    """
  Processes the command used to run pacman from the command line.
  """
    from optparse import OptionParser
    usageStr = """
  USAGE:      python pacman.py <options>
  EXAMPLES:   (1) python capture.py
                  - starts a game with two baseline agents
              (2) python capture.py --keys0
                  - starts a two-player interactive game where the arrow keys control agent 0, and all other agents are baseline agents
              (3) python capture.py -r baselineTeam -b myTeam
                  - starts a fully automated game where the red team is a baseline team and blue team is myTeam
  """
    parser = OptionParser(usageStr)

    parser.add_option('-r',
                      '--red',
                      help=default('Red team'),
                      default='baselineTeam')
    parser.add_option('-b',
                      '--blue',
                      help=default('Blue team'),
                      default='baselineTeam')
    parser.add_option('--red-name',
                      help=default('Red team name'),
                      default='Red')
    parser.add_option('--blue-name',
                      help=default('Blue team name'),
                      default='Blue')
    parser.add_option('--redOpts',
                      help=default('Options for red team (e.g. first=keys)'),
                      default='')
    parser.add_option('--blueOpts',
                      help=default('Options for blue team (e.g. first=keys)'),
                      default='')
    parser.add_option('--keys0',
                      help='Make agent 0 (first red player) a keyboard agent',
                      action='store_true',
                      default=False)
    parser.add_option('--keys1',
                      help='Make agent 1 (second red player) a keyboard agent',
                      action='store_true',
                      default=False)
    parser.add_option('--keys2',
                      help='Make agent 2 (first blue player) a keyboard agent',
                      action='store_true',
                      default=False)
    parser.add_option(
        '--keys3',
        help='Make agent 3 (second blue player) a keyboard agent',
        action='store_true',
        default=False)
    parser.add_option(
        '-l',
        '--layout',
        dest='layout',
        help=default(
            'the LAYOUT_FILE from which to load the map layout; use RANDOM for a random maze; use RANDOM<seed> to use a specified random seed, e.g., RANDOM23'
        ),
        metavar='LAYOUT_FILE',
        default='defaultCapture')
    parser.add_option('-t',
                      '--textgraphics',
                      action='store_true',
                      dest='textgraphics',
                      help='Display output as text only',
                      default=False)

    parser.add_option('-q',
                      '--quiet',
                      action='store_true',
                      help='Display minimal output and no graphics',
                      default=False)

    parser.add_option('-Q',
                      '--super-quiet',
                      action='store_true',
                      dest="super_quiet",
                      help='Same as -q but agent output is also suppressed',
                      default=False)

    parser.add_option('-z',
                      '--zoom',
                      type='float',
                      dest='zoom',
                      help=default('Zoom in the graphics'),
                      default=1)
    parser.add_option('-i',
                      '--time',
                      type='int',
                      dest='time',
                      help=default('TIME limit of a game in moves'),
                      default=1200,
                      metavar='TIME')
    parser.add_option('-n',
                      '--numGames',
                      type='int',
                      help=default('Number of games to play'),
                      default=1)
    parser.add_option(
        '-f',
        '--fixRandomSeed',
        action='store_true',
        help='Fixes the random seed to always play the same game',
        default=False)
    parser.add_option(
        '--record',
        action='store_true',
        help=
        'Writes game histories to a file (named by the time they were played)',
        default=False)
    parser.add_option('--replay',
                      default=None,
                      help='Replays a recorded game file.')
    parser.add_option(
        '-x',
        '--numTraining',
        dest='numTraining',
        type='int',
        help=default('How many episodes are training (suppresses output)'),
        default=0)
    parser.add_option('-c',
                      '--catchExceptions',
                      action='store_true',
                      default=False,
                      help='Catch exceptions and enforce time limits')

    options, otherjunk = parser.parse_args(argv)
    assert len(otherjunk) == 0, "Unrecognized options: " + str(otherjunk)
    args = dict()

    # Choose a display format
    #if options.pygame:
    #   import pygameDisplay
    #    args['display'] = pygameDisplay.PacmanGraphics()
    if options.textgraphics:
        import pacman.textDisplay as textDisplay
        args['display'] = textDisplay.PacmanGraphics()
    elif options.quiet:
        import pacman.textDisplay as textDisplay
        args['display'] = textDisplay.NullGraphics()
    elif options.super_quiet:
        import pacman.textDisplay as textDisplay
        args['display'] = textDisplay.NullGraphics()
        args['muteAgents'] = True
    else:
        import pacman.captureGraphicsDisplay as captureGraphicsDisplay
        # Hack for agents writing to the display
        captureGraphicsDisplay.FRAME_TIME = 0
        args['display'] = captureGraphicsDisplay.PacmanGraphics(options.red,
                                                                options.blue,
                                                                options.zoom,
                                                                0,
                                                                capture=True)
        import __main__
        __main__.__dict__['_display'] = args['display']

    args['redTeamName'] = options.red_name
    args['blueTeamName'] = options.blue_name

    if options.fixRandomSeed: random.seed('cs188')

    # Special case: recorded games don't use the runGames method or args structure
    if options.replay != None:
        # print('Replaying recorded game %s.' % options.replay)
        import pickle
        with open(options.replay, 'rb') as f:
            recorded = pickle.load(open(options.replay, 'rb'))
            recorded['display'] = args['display']
            replayGame(**recorded)
        sys.exit(0)

    # Choose a pacman agent
    redArgs, blueArgs = parseAgentArgs(options.redOpts), parseAgentArgs(
        options.blueOpts)
    if options.numTraining > 0:
        redArgs['numTraining'] = options.numTraining
        blueArgs['numTraining'] = options.numTraining
    nokeyboard = options.textgraphics or options.quiet or options.numTraining > 0
    redAgents = loadAgents(True, options.red, nokeyboard, redArgs)
    blueAgents = loadAgents(False, options.blue, nokeyboard, blueArgs)
    args['agents'] = sum([list(el) for el in zip(redAgents, blueAgents)],
                         [])  # list of agents

    numKeyboardAgents = 0
    for index, val in enumerate(
        [options.keys0, options.keys1, options.keys2, options.keys3]):
        if not val: continue
        if numKeyboardAgents == 0:
            agent = keyboardAgents.KeyboardAgent(index)
        elif numKeyboardAgents == 1:
            agent = keyboardAgents.KeyboardAgent2(index)
        else:
            raise Exception('Max of two keyboard agents supported')
        numKeyboardAgents += 1
        args['agents'][index] = agent

    args['layout'] = options.layout
    args['length'] = options.time
    args['numGames'] = options.numGames
    args['numTraining'] = options.numTraining
    args['record'] = options.record
    args['catchExceptions'] = options.catchExceptions
    return args
Esempio n. 2
0
def runGames(
    layout,
    pacman,
    ghosts,
    display,
    numGames,
    record,
    numTraining=0,
    numTesting=0,
    catchExceptions=False,
    timeout=30,
):
    import __main__

    __main__.__dict__["_display"] = display

    rules = ClassicGameRules(timeout)
    games = []

    if numTraining > 0:
        from pacman import textDisplay

        gameDisplay = textDisplay.NullGraphics()
        rules.quiet = True
        pbar = trange(
            numTraining, desc="Training Games" if numTesting == 0 else "Testing Games"
        )
        for i in pbar:
            game = rules.newGame(
                layout, pacman, ghosts, gameDisplay, True, catchExceptions
            )
            game.run()

            if record:
                import time, cPickle

                fname = ("recorded-game-%d" % (i + 1)) + "-".join(
                    [str(t) for t in time.localtime()[1:6]]
                )
                f = file(fname, "w")
                components = {"layout": layout, "actions": game.moveHistory}
                cPickle.dump(components, f)
                f.close()

    gameDisplay = display
    rules.quiet = False
    for i in range(numGames - numTraining):
        game = rules.newGame(
            layout, pacman, ghosts, gameDisplay, False, catchExceptions
        )
        game.run()
        games.append(game)

        if record:
            import time, cPickle

            fname = ("recorded-game-%d" % (i + 1)) + "-".join(
                [str(t) for t in time.localtime()[1:6]]
            )
            f = file(fname, "w")
            components = {"layout": layout, "actions": game.moveHistory}
            cPickle.dump(components, f)
            f.close()

    if (numGames - numTraining) > 0:
        scores = [game.state.getScore() for game in games]
        wins = [game.state.isWin() for game in games]
        winRate = wins.count(True) / float(len(wins))
        print("Average Score:", sum(scores) / float(len(scores)))
        print("Scores:       ", ", ".join([str(score) for score in scores]))
        print("Win Rate:      %d/%d (%.2f)" % (wins.count(True), len(wins), winRate))
        print("Record:       ", ", ".join([["Loss", "Win"][int(w)] for w in wins]))

    return games
Esempio n. 3
0
def runGames(agents,
             display,
             length,
             numGames,
             record,
             numTraining,
             redTeamName,
             blueTeamName,
             muteAgents=False,
             catchExceptions=False,
             seed=None,
             layout='RANDOM'):
    if seed is not None:
        random.seed(seed)
    # Choose a layout
    import pacman.layout as lay
    layouts = []
    for i in range(numGames):
        if layout == 'RANDOM':
            l = lay.Layout(randomLayout().split('\n'))
        elif layout.startswith('RANDOM'):
            l = lay.Layout(randomLayout(int(layout[6:])).split('\n'))
        elif layout.lower().find('capture') == -1:
            raise Exception('You must use a capture layout with capture.py')
        else:
            l = lay.getLayout(layout)
        if l == None:
            raise Exception("The layout " + layout + " cannot be found")

        layouts.append(l)

    rules = CaptureRules()
    games = []

    # if numTraining > 0:
    # print('Playing %d training games' % numTraining)

    for i in range(numGames):
        beQuiet = i < numTraining
        layout = layouts[i]
        if beQuiet:
            # Suppress output and graphics
            import pacman.textDisplay as textDisplay
            gameDisplay = textDisplay.NullGraphics()
            rules.quiet = True
        else:
            gameDisplay = display
            rules.quiet = False
        g = rules.newGame(layout, agents, gameDisplay, length, muteAgents,
                          catchExceptions)
        g.run()
        if not beQuiet: games.append(g)

        g.record = None
        if record:
            import time, pickle, datetime, json
            import pacman.game as game
            #fname = ('recorded-game-%d' % (i + 1)) +  '-'.join([str(t) for t in time.localtime()[1:6]])
            #f = file(fname, 'w')
            components = {
                'layout': layout,
                'agents': [game.Agent() for a in agents],
                'actions': g.moveHistory,
                'length': length,
                'redTeamName': redTeamName,
                'blueTeamName': blueTeamName
            }
            #f.close()
            g.record = pickle.dumps(components)
            replay_id = 'replays/replay-{}-{}'.format(
                datetime.datetime.now().strftime("%Y-%m-%d %H_%M_%S"),
                random.randint(0, 99999))
            print(replay_id)
            with open(replay_id, 'wb') as f:
                f.write(g.record)

            # IB: Added basic game->json conversion for js graphic display
            with open(replay_id + '.klvr', 'w') as f:
                import pacman.textDisplay as textDisplay
                states = []

                class js_recorded(textDisplay.PacmanGraphics):
                    def pause(self):
                        pass

                    def draw(self, state):
                        pass

                    def update(self, state):
                        super().update(state)
                        states.append(str(state))

                    def finish(self):
                        json_components = {
                            'history': states,
                            'redTeamName': redTeamName,
                            'blueTeamName': blueTeamName
                        }
                        json.dump(json_components, f)

                replayGame(layout, agents, g.moveHistory, js_recorded(),
                           length, redTeamName, blueTeamName)

    if numGames > 1:
        scores = [g.state.data.score for g in games]
        redWinRate = [s > 0 for s in scores].count(True) / float(len(scores))
        blueWinRate = [s < 0 for s in scores].count(True) / float(len(scores))
    return games
Esempio n. 4
0
def readCommand():
    """
    Processes the command used to run pacman from the command line.
    """
    from argparse import ArgumentParser

    usageStr = """
    USAGE:      python pacman.py <options>
    EXAMPLES:   (1) python pacman.py
                    - starts an interactive game
                (2) python pacman.py --layout smallClassic --zoom 2
                OR  python pacman.py -l smallClassic -z 2
                    - starts an interactive game on a smaller board, zoomed in
    """
    parser = ArgumentParser(description=usageStr)

    parser.add_argument(
        "-n",
        "--numGames",
        dest="numGames",
        type=int,
        help="the number of GAMES to play",
        metavar="GAMES",
        default=1,
    )
    parser.add_argument(
        "-l",
        "--layout",
        dest="layout",
        help="the LAYOUT_FILE from which to load the map layout",
        metavar="LAYOUT_FILE",
        default="mediumClassic",
    )
    parser.add_argument(
        "-p",
        "--pacman",
        dest="pacman",
        help="the agent TYPE in the pacmanAgents module to use",
        metavar="TYPE",
        default="KeyboardAgent",
    )
    parser.add_argument(
        "-t",
        "--textGraphics",
        action="store_true",
        dest="textGraphics",
        help="Display output as text only",
        default=False,
    )
    parser.add_argument(
        "-q",
        "--quietTextGraphics",
        action="store_true",
        dest="quietGraphics",
        help="Generate minimal output and no graphics",
        default=False,
    )
    parser.add_argument(
        "-g",
        "--ghosts",
        dest="ghost",
        help="the ghost agent TYPE in the ghostAgents module to use",
        metavar="TYPE",
        default="RandomGhost",
    )
    parser.add_argument(
        "-k",
        "--numghosts",
        type=int,
        dest="numGhosts",
        help="The maximum number of ghosts to use",
        default=4,
    )
    parser.add_argument(
        "-z",
        "--zoom",
        type=float,
        dest="zoom",
        help="Zoom the size of the graphics window",
        default=1.0,
    )
    parser.add_argument(
        "-f",
        "--fixRandomSeed",
        action="store_true",
        dest="fixRandomSeed",
        help="Fixes the random seed to always play the same game",
        default=False,
    )
    parser.add_argument(
        "-r",
        "--recordActions",
        action="store_true",
        dest="record",
        help="Writes game histories to a file (named by the time they were played)",
        default=False,
    )
    parser.add_argument(
        "--replay",
        dest="gameToReplay",
        help="A recorded game file (pickle) to replay",
        default=None,
    )
    parser.add_argument(
        "-x",
        "--numTraining",
        dest="numTraining",
        type=int,
        help="How many episodes are training (suppresses output)",
        default=0,
    )
    parser.add_argument(
        "--frameTime",
        dest="frameTime",
        type=float,
        help="Time to delay between frames; <0 means keyboard",
        default=0.1,
    )
    parser.add_argument(
        "-c",
        "--catchExceptions",
        action="store_true",
        dest="catchExceptions",
        help="Turns on exception handling and timeouts during games",
        default=False,
    )
    parser.add_argument(
        "--timeout",
        dest="timeout",
        type=int,
        help="Maximum length of time an agent can spend computing in a single game",
        default=30,
    )
    parser.add_argument("--from-experiment")
    parser.add_argument("--nb-testing-episodes", default=100, type=int)
    parser.add_argument("--show-board", action="store_true")

    options, _ = parser.parse_known_args()
    args = dict()

    # This is a fragile hack, don't touch it
    config = {}
    if options.from_experiment is not None:
        path = f"experiments/{options.from_experiment}/config.json"
        if not os.path.exists(path):
            raise ValueError(
                "`--from-experiment` must be a valid directory and contain a valid `config.json`"
            )
        with open(path, "r") as f:
            config = json.load(f)

        config["is_training"] = False

        if "model_dir" not in config:
            raise ValueError(
                "When using `--from-experiment` to test models, the model directory must exist"
            )

        config["model_paths"] = glob.glob(
            f"saved_models/{config['model_dir']}/policy*.th"
        )
        config["numTraining"] = options.nb_testing_episodes * len(config["model_paths"]) if not options.show_board else 0
        config["numGames"] = options.nb_testing_episodes * len(config["model_paths"])
        config["nb_testing_episodes"] = options.nb_testing_episodes
        if options.show_board:
          config["quietGraphics"] = False
          config["textGraphics"] = False
        args["numTesting"] = options.nb_testing_episodes

    options.__dict__.update(config)

    # Fix the random seed
    if options.fixRandomSeed or options.from_experiment is not None:
        random.seed("cs188")
        np.random.seed(seed=0)
        torch.manual_seed(0)

    # Choose a layout
    args["layout"] = layout.getLayout(options.layout)
    if args["layout"] == None:
        raise Exception("The layout " + options.layout + " cannot be found")

    # Choose a Pacman agent
    noKeyboard = options.gameToReplay == None and (
        options.textGraphics or options.quietGraphics
    )
    pacmanType = loadAgent(options.pacman, noKeyboard)
    pacmanType.add_args(parser)
    options = parser.parse_args()
    options.__dict__.update(config)
    pacman = pacmanType(
        settings=options.__dict__, **options.__dict__
    )  # Instantiate Pacman with agentArgs
    args["pacman"] = pacman

    args["numTraining"] = options.numTraining

    # Choose a ghost agent
    ghostType = loadAgent(options.ghost, noKeyboard)
    args["ghosts"] = [ghostType(i + 1) for i in range(options.numGhosts)]

    # Choose a display format
    if options.quietGraphics:
        from pacman import textDisplay

        args["display"] = textDisplay.NullGraphics()
    elif options.textGraphics:
        from pacman import textDisplay

        textDisplay.SLEEP_TIME = options.frameTime
        args["display"] = textDisplay.PacmanGraphics()
    else:
        from pacman import graphicsDisplay

        args["display"] = graphicsDisplay.PacmanGraphics(
            options.zoom, frameTime=options.frameTime
        )
    args["numGames"] = options.numGames
    args["record"] = options.record
    args["catchExceptions"] = options.catchExceptions
    args["timeout"] = options.timeout

    # Special case: recorded games don't use the runGames method or args structure
    if options.gameToReplay != None:
        print("Replaying recorded game %s." % options.gameToReplay)
        import cPickle

        f = open(options.gameToReplay)
        try:
            recorded = cPickle.load(f)
        finally:
            f.close()
        recorded["display"] = args["display"]
        replayGame(**recorded)
        sys.exit(0)

    return args