def single_turn_main(room, room_id, event): members = get_room_members(room) round_info = room['rounds_info'] master = round_info[-1]['master'] nth_round = len(round_info) line_bot_api.multicast(get_room_members(room), [TextSendMessage(text=f'第{nth_round}ラウンドをスタートしました'), TextSendMessage(text='各自の役割を遂行してください。')] ) start_timestamp = int(str(event.timestamp)[:10]) line_bot_api.push_message( master, get_end_button(room_id, nth_round, start_timestamp) ) reminder_timings = reminder_timings_setting q = Queue(connection=r) guessing_time = 182 guessed_object = "word" q.enqueue(set_reminders, start_timestamp, reminder_timings, members, room_id, master, guessing_time, guessed_object) line_bot_api.multicast( members, TextSendMessage(text=f"それでは制限時間内にお題を予測してください。正解が出たらマスターは「正解が出ました」ボタンを押してください。 ") )
def start_vote_of_insider(room, room_id): members_without_master = get_members_without_master(room) line_bot_api.multicast( get_room_members(room), [TextSendMessage(text='時間切れです。すぐに以下のボタンからインサイダーと思う人を投票してください。全員の票が集まったら、結果を発表します。'), get_guess_insider_carousel(room_id, members_without_master, False)] )
def close_participation(event, room, room_id, rooms_dict): print(room) members = get_room_members(room) line_bot_api.push_message( "U0a028f903127e2178bd789b4b4046ba7", TextSendMessage(text=f"this is {func_mode} mode") ) if len(members) < 4: line_bot_api.reply_message( event.reply_token, [TextSendMessage(text=f"最低でも4人必要です。5~8人がおすすめです。"), TextSendMessage(text=f"上の参加ボタンをあと{4-len(members)}人以上に押してもらってから、もう一度「参加を締め切るボタン」を押してください。」")] ) else: line_bot_api.reply_message( event.reply_token, [TextSendMessage(text=f"皆様の役割を個人メッセージでお送りしました。これ以降は、そちらをご参考ください。")] ) rounds = int(room['total_rounds']) line_bot_api.multicast( members, [TextSendMessage(text=f"ゲームID{room_id}に参加します"), TextSendMessage(text=f"全部で{rounds}ラウンドです。")] ) single_round_intro(members, room, room_id, rooms_dict)
def send_insider_guess_reminder(text, members, room, room_id): line_bot_api.multicast( members, TextSendMessage(text=f'インサイダー予想時間:残り{text}秒') ) if text == 0: start_vote_of_insider(room, room_id) pass
def single_turn_guess_insider(room, room_id, start_timestamp): time_left = int(time.time()) - start_timestamp line_bot_api.multicast( get_room_members(room), [TextSendMessage(text='お題の正解が出たようです。'), TextSendMessage(text=f'それではインサイダーは誰だったか、議論しましょう。{time_left}秒議論したので、残り時間は{time_left}秒です。')] ) guessing_time = time_left reminder_timings = list(range(2, guessing_time, 30)) reminder_timings.append(guessing_time) add_job_insider_guess_reminder(time_left, room, room_id)
def single_round_intro(members, room, room_id, rooms_dict): members_copy = copy.deepcopy(members) insider = random.choice(members_copy) members_copy.remove(insider) master = random.choice(members_copy) members_copy.remove(master) commons = members_copy room['rounds_info'].append({ 'insider': insider, 'master': master, 'started': False, 'answered': False, 'insider_guess': [], 'commons_who_already_voted': [] }) rooms_dict[room_id] = room with open('rooms.json', 'w') as room_json: json.dump(rooms_dict, room_json, indent=2) nth_round = len(room['rounds_info']) word = room["words"][nth_round - 1] line_bot_api.multicast( members, [ImageSendMessage(original_content_url=round_img[nth_round], preview_image_url=round_img[nth_round])] ) line_bot_api.multicast( commons, [TextSendMessage(text='あなたの役割は庶民です。'), TextSendMessage(text=f'お題を当てるためにマスターに質問をしていきましょう。'), TextSendMessage(text='なお、「はい」「いいえ」「わからない」でマスターが答えられる質問にしましょう'), TextSendMessage(text='それでは、マスターからの指示を待ちましょう')] ) line_bot_api.push_message( insider, [TextSendMessage(text='インサイダーはあなたです。'), TextSendMessage(text=f'お題は"{word}"です。(お題はあなたとマスター以外には送られていません。)'), TextSendMessage(text='庶民のふりをしつつ、庶民を裏で操り、お題を当てさせてあげましょう。'), TextSendMessage(text='それでは、マスターからの指示を待ちましょう')] ) line_bot_api.push_message( master, [TextSendMessage(text='マスターはあなたです。マスターであることを皆に伝えてください。'), TextSendMessage(text=f'お題は"{word}"です。(お題はあなたとインサイダー以外には送られていません。)'), TextSendMessage(text=f'お題に関しての庶民からの質問に「はい」「いいえ」「わからない」の3択で答えていきましょう。'), TextSendMessage(text=f'お題の"{word}"を当てられたら「正解です」と答え、「正解が出ました」ボタンを押しましょう'), get_start_button(room_id, len(room['rounds_info']))] )
def insider_guess_tournament(room, room_id, members, guessed_insiders): master = room['rounds_info'][-1]['master'] print("printing guessed insiders") print(guessed_insiders) guessed_insiders_str = ', '.join([get_display_name(guessed_insider) for guessed_insider in guessed_insiders]) line_bot_api.multicast( members, [TextSendMessage(text="投票の結果、同率一位がいました。"), TextSendMessage(text=f"{guessed_insiders_str} が最もインサイダーの疑惑がかけられています。"), TextSendMessage(text="マスターが議論をして、最終インサイダー予想をしてください。"), TextSendMessage(text="マスターに投票ボタンを送りました。")] ) line_bot_api.push_message( master, get_guess_insider_carousel(room_id, get_members_without_master(room), True) )
def single_turn_guess_insider_when_time_is_up(room, room_id): line_bot_api.multicast( get_room_members(room), [TextSendMessage(text='インサイダーは世論を操るのに失敗しました。'), TextSendMessage(text=f'ですが参考までに、インサイダーは誰だったか、議論しましょう。残り時間は\n{time_limit_when_word_guess_failed}秒です。')] ) time_lefts = [0, 15, 30] remind_dts = [{ "dt": datetime.datetime.now() + datetime.timedelta(seconds=time_limit_when_word_guess_failed - time_left), "time_left": time_left } for time_left in time_lefts] members = get_room_members(room) for remind_dt in remind_dts: scheduler.add_job(send_insider_guess_reminder, 'date', run_date=remind_dt["dt"], args=[remind_dt["time_left"], members, room, room_id]) print(scheduler.print_jobs())
def result_of_guess_message(room, current_round, most_guessed_insider): real_insider = current_round['insider'] if real_insider == most_guessed_insider: guess_result_message = "庶民がインサイダーを見事当てました。" calculate_score_when_insider_guess_was_correct(real_insider, room) else: guess_result_message = "インサイダーが狡猾にも庶民を騙すことに成功しました。" calculate_score_when_insider_guess_was_wrong(real_insider, room) scores_text_list = \ [f'{get_display_name(user_info["user_id"])}: {user_info["score"]}' for user_info in room["members"]] scores_text = '\n'.join(scores_text_list) line_bot_api.multicast( get_room_members(room), [TextSendMessage(text=f"インサイダー(容疑):{get_display_name_from_json(most_guessed_insider, room)}\n" f"インサイダー(実際):{get_display_name_from_json(real_insider, room)}"), TextSendMessage(text=f"{guess_result_message}"), TextSendMessage(text=f"現在のスコアです。\n\n{scores_text}") ] )
def callback(): signature = request.headers['X-Line-Signature'] # get request body as text body = request.get_data(as_text=True) app.logger.info("Request body: " + body) # parse webhook body events = [] try: events = parser.parse(body, signature) except InvalidSignatureError: abort(400) for event in events: if isinstance(event, FollowEvent): line_bot_api.reply_message( event.reply_token, [TextSendMessage(text="インサイダー風ゲームBot友だちとなって頂きありがとうございます!\n"), TextSendMessage(text="一緒にゲームをするメンバーがいるルームで、'す'を入力するとスタート!"), TextSendMessage(text="'る'を入力するとルールが表示されます!")] ) if isinstance(event, JoinEvent): line_bot_api.reply_message( event.reply_token, [TextSendMessage(text="インサイダー風ゲームBotを招待していただきありがとうございます!\n"), TextSendMessage(text="'す'を入力するとスタート、'る'を入力するとルールが表示されます!")] ) if isinstance(event, MessageEvent): if isinstance(event.message, TextMessage): text = event.message.text if text in ['s', 'す']: new_room_id = add_room_info_to_json_and_return_room_id() line_bot_api.reply_message( event.reply_token, [TextSendMessage(text="このアカウントを友達登録をしてから、以下の参加ボタンを押してください。"), get_participation_button(new_room_id)] ) if text in ['r', 'rule', 'ルール', 'る', '説明', 'ル']: line_bot_api.reply_message( event.reply_token, [TextSendMessage(text=rule)] ) post_text_to_db(event) if isinstance(event, PostbackEvent): data_str = event.postback.data data_dict = dict(urlparse.parse_qsl(data_str)) room_id = data_dict['room_id'] with open('rooms.json', 'r') as room_json: rooms_dict = json.load(room_json) room = rooms_dict[room_id] current_round_count = len(room["rounds_info"]) nth_round_in_data_dict = -1 if "nth_round" in data_dict.keys(): nth_round_in_data_dict = int(data_dict["nth_round"]) latest_button = True if nth_round_in_data_dict != current_round_count: latest_button = False try: next_action = data_dict['next_action'] except KeyError: next_action = '' if next_action == 'get-participation': display_name = get_display_name(event.source.user_id) new_user = event.source.user_id if new_user not in get_room_members(room) or func_mode == "one_phone_dev": room['members'].append({ 'user_id': event.source.user_id, "score": 0, "display_name": display_name }) with open('rooms.json', 'w') as room_json: json.dump(rooms_dict, room_json, indent=2) line_bot_api.reply_message( event.reply_token, TextSendMessage(text=f'参加受付:{display_name}') ) else: line_bot_api.reply_message( event.reply_token, TextSendMessage(text=f'{display_name}は参加済みです。') ) if next_action == 'close': close_participation(event, room, room_id, rooms_dict) if next_action == 'start': if room["rounds_info"][-1]["started"] is False: single_turn_main(room, room_id, event) room["rounds_info"][-1]["started"] = True with open('rooms.json', 'w') as room_json: json.dump(rooms_dict, room_json, indent=2) else: line_bot_api.reply_message( event.reply_token, TextSendMessage(text="開始済みです") ) if next_action == 'answered' and latest_button: if room['rounds_info'][-1]["answered"] is False: room['rounds_info'][-1]["answered"] = True rooms_dict[room_id] = room real_insider = room['rounds_info'][-1]["insider"] calculate_score_when_insider_guess_was_correct(real_insider, room) with open('rooms.json', 'w') as room_json: json.dump(rooms_dict, room_json, indent=2) start_timestamp = int(data_dict["start_timestamp"]) single_turn_guess_insider(room, room_id, start_timestamp) else: line_bot_api.reply_message( event.reply_token, TextSendMessage(text="既に正解が出てます。") ) if next_action == 'word_guess_time_up' and latest_button: if room['rounds_info'][-1]["answered"] is False: room['rounds_info'][-1]["answered"] = True real_insider = room['rounds_info'][-1]["insider"] calculate_score_when_word_guess_timed_up(real_insider, room) single_turn_guess_insider_when_time_is_up(room, room_id) with open('rooms.json', 'w') as room_json: json.dump(rooms_dict, room_json, indent=2) else: line_bot_api.reply_message( event.reply_token, TextSendMessage(text="すでにインサイダー予想に移っています。") ) if "insider_guess" in data_dict and "last_guess" not in data_dict: current_round = room['rounds_info'][-1] accept_vote(current_round, data_dict, event, rooms_dict, room) members = get_room_members(room) if len(current_round["insider_guess"]) >= len(members): # noinspection PyArgumentList c = collections.Counter(current_round['insider_guess'][:len(members)]) vote_result_sorted = c.most_common() has_same_rate, guessed_insiders = has_same_rate_first_place(vote_result_sorted) most_guessed_insider = vote_result_sorted[0][0] if has_same_rate: insider_guess_tournament(room, room_id, members, guessed_insiders) else: result_of_guess_message(room, current_round, most_guessed_insider) if len(room['rounds_info']) == room["total_rounds"]: line_bot_api.multicast( members, TextSendMessage(text=f"{room['total_rounds']}ラウンドが終わりました。ゲームを終了します。") ) else: # single_round_intro(members, room, room_id, rooms_dict) run_date = datetime.datetime.now() + datetime.timedelta(seconds=6) scheduler.add_job(single_round_intro, 'date', run_date=run_date, args=[members, room, room_id, rooms_dict]) if "last_guess" in data_dict: members = get_room_members(room) current_round = room['rounds_info'][-1] last_guessed_insider = data_dict["insider_guess"] result_of_guess_message(room, current_round, last_guessed_insider) if current_round == room["total_rounds"]: line_bot_api.multicast( members, TextSendMessage(text=f"{current_round}ラウンドが終わりました。ゲームを終了します。") ) else: single_round_intro(members, room, room_id, rooms_dict) post_postback_to_db(event) return 'OK'
async def timer(delay): while True: now = time.time() set_list = r.zrange("timer", 0, -1, withscores=True) for i, value_score in enumerate(set_list): end_timestamp = value_score[1] value_dict = json.loads(value_score[0].decode()) room_id = value_dict["room_id"] members = value_dict["members"] time_left = value_dict["time_left"] print("type of time left") print(type(time_left)) master = value_dict["master"] guessed_object = value_dict["guessed_object"] diff = end_timestamp - now with open('rooms.json', 'r') as room_json: rooms_dict = json.load(room_json) answered = rooms_dict[room_id]["rounds_info"][-1]["answered"] current_round_count = len(rooms_dict[room_id]["rounds_info"]) print(f'\nroom_id{room_id} time_left:{time_left}') print( f'i:{i}, set_list_len:{len(r.zrange("timer", 0, -1, withscores=True))}' ) print(f'answered: {answered}') print(f'guessed_object: {guessed_object}') print(f'diff:{diff}') if guessed_object == "insider": guessed_object_jpn = "インサイダー推理" elif guessed_object == "word": guessed_object_jpn = "お題あて" if answered is True and guessed_object == "word": print("removing since it was answered") r.zrem("timer", value_score[0]) if (diff <= 0 and answered is False) or ( diff <= 0 and guessed_object == "insider"): # message_id, sender_id, text = name.decode().split(':') print(end_timestamp) line_bot_api.multicast( members, TextSendMessage( text=f'{guessed_object_jpn}の残り時間、{time_left}秒です。')) r.zrem("timer", value_score[0]) print("removed one") print( f'z range length :{len(r.zrange("timer", 0, -1, withscores=True))}\n' ) if len(r.zrange("timer", 0, -1, withscores=True)) == 0 or time_left == 0: if guessed_object == "word": line_bot_api.multicast(members, [ TextSendMessage(text=f'お題あての時間が切れました。'), TextSendMessage( text='マスターはまず答えを言ってください。次に表示されている確認ボタンを押してください。' ) ]) line_bot_api.push_message(master, [ get_confirm_button_moving_to_insider_guess( room_id, current_round_count) ]) else: print("breaking from 'for'\n") break await asyncio.sleep(delay) # indent position is important