Beispiel #1
0
def UCTPlayGame(nn, nn2=None):
    """ Self-play using MCTS, returns s_t's, pi_t's, and z to use for training.
    """
    width = config.board_width
    height = config.board_height
    cells_each_player = config.cells_each_player

    field = Field()
    field.width = width
    field.height = height
    field.parse(init_cells(field.width, field.width, cells_each_player))
    state = GOLADState(field)

    data = {}
    data['s'] = []
    data['pi'] = []
    c = None
    current_nn = nn  # use nn for first player
    while (state.GetMoves() != []):
        c, pi = UCT(rootstate=state,
                    itermax=config.mcts_itermax,
                    nn=current_nn,
                    verbose=config.verbose,
                    rootnode=c)
        m = c.move
        data['s'].append(state.Convert())
        data['pi'].append(pi)
        if config.verbose:
            print ("\nTurn {}, Player {}, Best Move: {}" \
                .format(state.timestep, state.current_player, str(m)))
            state.field.pprint()
        state.DoMove(m)
        if nn2 is not None:
            if current_nn == nn:
                current_nn = nn2
            else:
                current_nn = nn

    if config.verbose:
        print('Result: {}'.format(state.GetResult(0)))
        state.field.pprint()
    data['z'] = [[state.GetResult(0)]] * len(
        data['s'])  # get result from perspective of first player (ie rootnode)

    return data
class Game:
    def __init__(self):
        self.time_per_move = -1
        self.timebank = -1
        self.last_update = None
        self.max_rounds = -1

        self.round = 0
        self.player_names = []
        self.players = {}
        self.me = None
        self.opponent = None
        self.field = Field()

    def update(self, data):
        # start timer
        self.last_update = time.time()
        for line in data.split('\n'):

            line = line.strip()
            if len(line) <= 0:
                continue

            tokens = line.split()
            if tokens[0] == "settings":
                self.parse_settings(tokens[1], tokens[2])
            elif tokens[0] == "update":
                if tokens[1] == "game":
                    self.parse_game_updates(tokens[2], tokens[3])
                else:
                    self.parse_player_updates(tokens[1], tokens[2], tokens[3])
            elif tokens[0] == "action":
                self.timebank = int(tokens[2])
                # Launching bot logic happens after setup finishes

    def parse_settings(self, key, value):
        if key == "timebank":
            self.timebank = int(value)
        elif key == "time_per_move":
            self.time_per_move = int(value)
        elif key == "player_names":
            self.player_names = value.split(',')
            self.players = {name: Player(name) for name in self.player_names}
        elif key == "your_bot":
            self.me = self.players[value]
            self.opponent = self.players[[name for name in self.player_names if name != value][0]]
        elif key == "your_botid":
            self.me.id = value
            self.opponent.id = str(2 - (int(value) + 1))
        elif key == "field_width":
            self.field.width = int(value)
        elif key == "field_height":
            self.field.height = int(value)
        elif key == "max_rounds":
            self.max_rounds = int(value)
        else:
            stderr.write('Cannot parse settings input with key {}'.format(key))

    def parse_game_updates(self, key, value):
        if key == "round":
            self.round = int(value)
        elif key == "field":
            self.field.parse(value)
        else:
            stderr.write('Cannot parse game update with key {}'.format(key))

    def parse_player_updates(self, player_name, key, value):
        player = self.players.get(player_name)

        if player is None:
            stderr.write('Cannot find player with name {}'.format(player_name))
            return

        if key == "living_cells":
            player.living_cells = int(value)
        elif key == "move":
            player.previous_move = value
        else:
            stderr.write('Cannot parse {} update with key {}'.format(player_name, key))

    def time_remaining(self):
        return self.timebank - int(1000 * (time.clock() - self.last_update))

    @staticmethod
    def print_move(move):
        """issue an order"""
        stdout.write('{}\n'.format(move))
        stdout.flush()

    def run(self, bot):
        """parse input, update game state and call the bot classes do_turn method"""
        not_finished = True
        data = ''

        while not stdin.closed and not_finished:
            try:
                current_line = stdin.readline().rstrip('\r\n')

                if len(current_line) <= 0:
                    time.sleep(1)
                    continue

                data += current_line + "\n"
                if current_line.lower().startswith("action"):
                    self.update(data)

                    move = bot.make_move(self)
                    self.print_move(move)

                    data = ''
                elif current_line.lower().startswith("quit"):
                    not_finished = False
            except EOFError:
                break
            except KeyboardInterrupt:
                raise
            except:
                # don't raise error or return so that bot attempts to stay alive
                traceback.print_exc(file=stderr)
                stderr.flush()