Example #1
0
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"それでは制限時間内にお題を予測してください。正解が出たらマスターは「正解が出ました」ボタンを押してください。 ")
    )
Example #2
0
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)]
    )
Example #3
0
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)
Example #4
0
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
Example #5
0
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)
Example #6
0
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']))]
    )
Example #7
0
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)
    )
Example #8
0
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())
Example #9
0
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}")
         ]
    )
Example #10
0
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