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()
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()
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()
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')
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))
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: