예제 #1
0
    def on_message(self, *args):
        global currentTableId
        if not args or isinstance(args[0], bytes):
            return
        mtype: str = args[0]['type']
        if mtype in ['hello', 'advanced']:
            args[0]['resp'] = {}
        data: dict = args[0]['resp']

        if mtype == 'denied':
            print(data['reason'])
            sys.exit()
        elif mtype == 'error':
            print(data['error'])
        elif mtype == 'table':
            pass
        elif mtype == 'table_gone':
            pass
        elif mtype == 'joined':
            pass
        elif mtype == 'left':
            print(self.username + ': Game Terminated')
            pass
            self.game = None
        elif mtype == 'table_ready':
            pass
        elif mtype == 'game':
            pass
        elif mtype == 'game_player':
            pass
        elif mtype == 'game_start':
            while not startGame:
                time.sleep(.1)
            print(self.username + ': Game Started')
            self.conn.emit('message', {'type': 'hello', 'resp': {}})
        elif mtype == 'init':
            self.game = Game(self.conn, Variant(data['variant']),
                             data['names'], data['seat'], self.botCls,
                             **self.botconfig)
            print(self.username + ': Game Loaded')
            self.conn.emit('message', {'type': 'ready', 'resp': {}})
        elif mtype in ['hello', 'user', 'user_left', 'chat',
                       'game_history', 'history_detail', 'game_error',
                       'connected']:
            pass
        elif self.game is not None:
            self.game.received(mtype, data)
            if mtype == 'notify' and data['type'] == 'game_over':
                self.game = None
        elif mtype == 'notify' and data['type'] == 'reveal':
            pass
        elif mtype == 'action':
            pass
        else:
            print(mtype, data)
            raise Exception()
예제 #2
0
 def message_sent(self, mtype, data):
     if mtype == 'game_start':
         pass
     elif mtype == 'init':
         self.game = Game(self.connection, Variant(data['variant']),
                          data['names'], self.position, self.botcls,
                          **self.botkwargs)
         self.bot = self.game.bot
         self.connection.game = self.game
         self.connection.bot = self.bot
     elif self.game is not None:
         if mtype == 'notify' and data['type'] == 'draw':
             card = TestCard(Suit(data['suit']), Rank(data['rank']),
                             data['order'])
             self.deck[data['order']] = card
         self.game.received(mtype, data)
     elif mtype == 'notify' and data['type'] == 'reveal':
         pass
     elif mtype == 'action':
         pass
     else:
         print(mtype, data)
         raise Exception()
예제 #3
0
파일: main.py 프로젝트: jeanlange/Hanabi-AI
def on_message(*args):
    global currentTable, currentTableId, currentTablePosition
    global game, readyToStart
    if not args or isinstance(args[0], bytes):
        return
    mtype: str = args[0]['type']
    if mtype in ['hello', 'advanced']:
        args[0]['resp'] = {}
    data: dict = args[0]['resp']

    if mtype == 'denied':
        print(data['reason'])
        sys.exit()
    elif mtype == 'error':
        print(data['error'])
    elif mtype == 'table':
        tables[data['id']] = data
    elif mtype == 'table_gone':
        if data['id'] in tables:
            del tables[data['id']]
    elif mtype == 'joined':
        currentTableId = data['table_id']
    elif mtype == 'left':
        print('Game Terminated')
        currentTable = None
        currentTableId = None
        game = None
    elif mtype == 'table_ready':
        readyToStart = data['ready']
    elif mtype == 'game':
        currentTable = data
        tablePlayers.clear()
    elif mtype == 'game_player':
        tablePlayers.append(data['name'])
        if data['you']:
            currentTablePosition = data['index']
    elif mtype == 'game_start':
        print('Game Started: ' + tables[currentTableId]['name'])
        conn.emit('message', {'type': 'hello', 'resp': {}})
    elif mtype == 'init':
        kwargs = botconfig['BOT']
        if botconfig['BOT']['bot'] in botconfig:
            kwargs = ChainMap(botconfig[botconfig['BOT']['bot']],
                              botconfig['BOT'])
        game = Game(conn, Variant(data['variant']), data['names'],
                    data['seat'], botCls, **kwargs)
        print('Game Loaded')
        conn.emit('message', {'type': 'ready', 'resp': {}})
    elif mtype in ['hello', 'user', 'user_left', 'chat',
                   'game_history', 'history_detail', 'game_error',
                   'connected']:
        pass
    elif game is not None:
        game.received(mtype, data)
        if mtype == 'notify' and data['type'] == 'game_over':
            game = None
    elif mtype == 'notify' and data['type'] == 'reveal':
        pass
    elif mtype == 'action':
        pass
    else:
        print(mtype, data)
        raise Exception()
예제 #4
0
파일: main.py 프로젝트: jeanlange/Hanabi-AI
def run(username: str, password: str, botIni: str='bot.init') -> None:
    global conn, botconfig, botCls
    botconfig = configparser.ConfigParser()
    botconfig.read(botIni)

    print('Loading Bot AI')
    botModule = importlib.import_module(botconfig['BOT']['bot'] + '.bot')
    botCls = botModule.Bot  # type: ignore
    print('Loaded ' + botCls.BOT_NAME)  # type: ignore

    conn = socketIO_client.SocketIO('keldon.net', 32221)
    conn.on('message', on_message)

    print('Connected to keldon.net')


    passBytes = b'Hanabi password ' + password.encode()
    passSha: str
    passSha = hashlib.sha256(passBytes).hexdigest()

    try:
        login: dict = {'username': username, 'password': passSha}
        conn.emit('message', {'type': 'login', 'resp': login})
        conn.wait(seconds=1)

        i: int = 0
        d: dict
        t: int
        id: int
        table: dict
        while True:
            print()
            print('What would you like to do?')
            print('(1) Create a table')
            print('(2) Join a table')
            print('(3) Rejoin a game')
            print('(0) Quit')
            try:
                i = int(input('--> '))
                if i < 1 or i > 3:
                    raise ValueError()
            except ValueError:
                break

            conn.wait(seconds=waitTime)

            if i in [1, 2]:
                if i == 1:
                    name = input('Game Name --> ')
                    max_players = int_input('Max Players (2 - 5) --> ',
                                            min=2, max=5)
                    print('Variant')
                    for variant in Variant:  # type: ignore
                        print('({}) {}'.format(variant.value,
                                               variant.full_name))
                    variant = int_input(min=0, max=len(Variant) - 1)  # type: ignore
                    print('Allow Spectators? (y or 1 for yes)')
                    allow_spec: bool = input('--> ') in ['1', 'y', 'Y']
                    d = {'type': 'create_table',
                         'resp': {'name': name,
                                  'max': max_players,
                                  'variant': variant,
                                  'allow_spec': allow_spec}}
                    conn.emit('message', d)
                else:
                    while True:
                        print('Join a table')
                        print('(Blank) Refresh')
                        print('''(    0) Don't Join A Table''')
                        for id, table in sorted(tables.items()):
                            if table['running']:
                                continue
                            print('({:>5}) {}, Players: {}/{}, Variant: '
                                  '{}'.format(
                                id, table['name'], table['num_players'],
                                table['max_players'],
                                Variant(table['variant']).full_name))
                        try:
                            t = int(input('--> '))
                        except ValueError:
                            conn.wait(seconds=waitTime)
                            continue
                        if t == 0:
                            break
                        conn.wait(seconds=waitTime)
                        if t not in tables:
                            print('Table does not exist')
                            continue
                        if tables[t]['running']:
                            print('Game already started')
                            continue
                        if tables[t]['joined']:
                            d = {'type': 'reattend_table',
                                 'resp': {'table_id': t}}
                        else:
                            d = {'type': 'join_table',
                                 'resp': {'table_id': t}}
                        conn.emit('message', d)
                        break

                conn.wait(seconds=waitTime)
                while currentTableId in tables and game is None:
                    conn.wait(seconds=waitTime)
                    if currentTableId in tables and game is None:
                        print('Current Players', tablePlayers)
                        print('(Blank) Refresh')
                        print('(0) Abandon Game')
                        if tables[currentTableId]['owned'] and readyToStart:
                            print('(1) Start Game')
                        try:
                            i = int(input('--> '))
                            if i == 0:
                                conn.emit('message', {'type': 'leave_table',
                                                      'resp': {}})
                                break
                            if (tables[currentTableId]['owned']
                                    and readyToStart):
                                if i == 1:
                                    d = {'type': 'start_game', 'resp': {}}
                                    conn.emit('message', d)
                                    break
                        except:
                            conn.wait(seconds=waitTime)
                            continue
                conn.wait(seconds=waitTime)
            elif i == 3:
                while True:
                    print('Rejoin a game')
                    print('(Blank) Refresh')
                    print('''(    0) Don't Rejoin a Game''')
                    for id, table in sorted(tables.items()):
                        if not table['running']:
                            continue
                        if table['running'] and not table['joined']:
                            continue
                        print('({:>5}) {}, Players: {}/{}, Variant: {}'.format(
                            id, table['name'], table['num_players'],
                            table['max_players'],
                            Variant(table['variant']).full_name))
                    try:
                        t = int(input('--> '))
                    except ValueError:
                        conn.wait(seconds=waitTime)
                        continue
                    if t == 0:
                        break
                    conn.wait(seconds=waitTime)
                    if t not in tables:
                        print('Game does not exist')
                        continue
                    if not tables[t]['running']:
                        print('Table has not yet started')
                        continue
                    d = {'type': 'reattend_table', 'resp': {'table_id': t}}
                    conn.emit('message', d)
                    break
                conn.wait(seconds=waitTime)

            conn.wait(seconds=waitTime)
            while game is not None:
                conn.wait(seconds=waitTime)
    finally:
        conn.disconnect()

    print('Ended')
예제 #5
0
def simulate(config, mapFunc):
    bot = importlib.import_module(config['BOT']['bot'] + '.bot').Bot

    kwargs = config['BOT']
    if config['BOT']['bot'] in config:
        kwargs = ChainMap(config[config['BOT']['bot']], config['BOT'])

    runs = int(config['SIMULATOR']['runs'])
    if runs < 0:
        print('Invalid number of runs')
        return

    variant = Variant(int(config['SIMULATOR']['variant']))
    players = int(config['SIMULATOR']['players'])
    if players < 2 or players > 5:
        print('Invalid number of players')
        return

    print('Starting Game Simulator')
    print('Bot: {}'.format(bot.BOT_NAME))
    print('Variant: {}'.format(variant.full_name))
    print('Players: {}'.format(players))
    print('Started: {}'.format(datetime.now()))
    print()

    start = time.time()
    args = variant, players, bot, dict(kwargs)
    allArgs = (args + (i, ) for i in range(runs))

    maxScore = len(variant.pile_suits) * len(Rank)
    doneScores = {s: 0 for s in range(maxScore + 1)}
    lossScores = {s: 0 for s in range(maxScore + 1)}

    check = max(min(100, runs // 100), 1)
    completed = 0
    for game in mapFunc(run, allArgs):
        completed += 1
        scores = doneScores if not game.loss else lossScores
        scores[game.score] += 1
        if completed % check == 0:
            print('{}/{} completed, Current Time: {}'.format(
                completed, runs, datetime.now()))
    if completed % check != 0:
        print('{}/{} completed, Current Time: {}'.format(
            completed, runs, datetime.now()))
    duration = time.time() - start
    allScores = {s: doneScores[s] + lossScores[s] for s in range(maxScore + 1)}

    scoreDisplay = (('All Games', allScores), ('Non-Loss Games', doneScores),
                    ('Loss Games', lossScores))

    print()
    print('Bot: {}'.format(bot.BOT_NAME))
    print('Variant: {}'.format(variant.full_name))
    print('Players: {}'.format(players))
    print()
    print('Number of Games: {}'.format(completed))
    print('Number of Best Score: {}'.format(doneScores[maxScore]))
    print('Number of Losses: {}'.format(sum(lossScores.values())))
    for scoreType, scores in scoreDisplay:
        print()
        print(scoreType)
        average = 0
        middle = 0
        stdDev = 0
        error = 0
        count = sum(scores.values())
        if count >= 1:
            average = mean(iterateScores(scores))
            middle = median(iterateScores(scores))
        if count >= 2:
            stdDev = stdev(iterateScores(scores))
            error = stdDev / sqrt(count)
        print('Average Score: {:.5f}'.format(average))
        print('Median Score: {:.5f}'.format(middle))
        print('Standard Deviation: {:.5f}'.format(stdDev))
        print('Standard Error: {:.5f}'.format(error))
    print()
    print('Non-loss Score Distribution')
    for score in range(maxScore, -1, -1):
        print('Score {}: {}'.format(score, doneScores[score]))
    print()
    print('Loss Score Distribution')
    for score in range(maxScore + 1):
        print('Score {}: {}'.format(score, lossScores[score]))
    print()
    print('Time to Complete: {:.6f}'.format(duration))
예제 #6
0
    parser = argparse.ArgumentParser(
        description='Run multiple AI bots on keldon.net')
    parser.add_argument('-c', '--config', default='multiple.ini',
                        help='config ini')
    args: argparse.Namespace = parser.parse_args()
    config: configparser.ConfigParser = configparser.ConfigParser()
    config.read(args.config)

    numBots: int = int(config['MULTIPLE']['bots'])
    numHuman: int = int(config['MULTIPLE']['human'])
    totalPlayers = numBots + numHuman
    if numBots < 1:
        raise ValueError('No bots?')
    if totalPlayers < 2 or totalPlayers > 5:
        raise ValueError('Too many/too little players')
    variant: Variant = Variant(int(config['MULTIPLE']['variant']))
    spectators: bool = bool(config['MULTIPLE']['spectator'])
    gameName: str = config['MULTIPLE']['game-name']
    logins: List[Tuple[str, str]] = []
    botModule: List[str] = []
    botConfig: List[ChainMap] = []
    for i in range(numBots):
        username: str
        password: str
        if ('login' in config['LOGIN.' + str(i)]
                and os.path.isfile(config['LOGIN.' + str(i)]['login'])):
            login: configparser.ConfigParser = configparser.ConfigParser()
            login.read(config['LOGIN.' + str(i)]['login'])
            username = login['USER']['username']
            password = login['USER']['password']
        else: