Exemplo n.º 1
0
def toxic() -> dict:
    target = int(request.args.get('target'))
    my_role = Role.query.get(current_user.uid)
    if not my_role.alive:
        return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
    with Game.query.with_for_update().get(current_user.gid) as game:
        history = game.history
        now = StepProcessor.current_step(game)
        if now is not GameEnum.ROLE_TYPE_WITCH or my_role.role_type is not GameEnum.ROLE_TYPE_WITCH:
            return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
        if not my_role.args['toxic']:
            return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
        if history['elixir'] or history[
                'toxic'] != GameEnum.TARGET_NOT_ACTED.value:
            return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
        if target > 0:
            target_role = _get_role_by_pos(game, target)
            if not target_role.alive:
                return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
        history['toxic'] = target
        if target > 0:
            my_role.args['toxic'] = False
        StepProcessor.move_on(game)
        if target > 0:
            return GameEnum.OK.digest(result=f'你毒杀了{target}号玩家')
        else:
            return GameEnum.OK.digest()
Exemplo n.º 2
0
def guard() -> dict:
    target = int(request.args.get('target'))
    my_role = Role.query.get(current_user.uid)
    if not my_role.alive:
        return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
    with Game.query.with_for_update().get(current_user.gid) as game:
        history = game.history
        now = StepProcessor.current_step(game)
        if now is not GameEnum.ROLE_TYPE_SAVIOR or my_role.role_type is not GameEnum.ROLE_TYPE_SAVIOR:
            return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
        if my_role.args[
                'guard'] != GameEnum.TARGET_NO_ONE.value and my_role.args[
                    'guard'] == target:
            return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
        if history['guard'] != GameEnum.TARGET_NOT_ACTED.value:
            return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
        if target > 0:
            target_role = _get_role_by_pos(game, target)
            if not target_role.alive:
                return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
        history['guard'] = target
        my_role.args['guard'] = target
        StepProcessor.move_on(game)
        if target > 0:
            return GameEnum.OK.digest(result=f'你守护了{target}号玩家')
        else:
            return GameEnum.OK.digest(result=f'你选择空守')
Exemplo n.º 3
0
def setup_game() -> dict:
    victory_mode = GameEnum['VICTORY_MODE_{}'.format(
        request.form['victoryMode'].upper())]
    captain_mode = GameEnum['CAPTAIN_MODE_{}'.format(
        request.form['captainMode'].upper())]
    witch_mode = GameEnum['WITCH_MODE_{}'.format(
        request.form['witchMode'].upper())]
    villager_cnt = int(request.form['villager'])
    normal_wolf_cnt = int(request.form['normal_wolf'])
    cards = [GameEnum.ROLE_TYPE_VILLAGER] * villager_cnt + [
        GameEnum.ROLE_TYPE_NORMAL_WOLF
    ] * normal_wolf_cnt

    single_roles = request.form.getlist('single_roles')
    for r in single_roles:
        cards.append(GameEnum[f'ROLE_TYPE_{r.upper()}'])

    new_game = Game(
        host_uid=current_user.uid,
        victory_mode=victory_mode,
        captain_mode=captain_mode,
        witch_mode=witch_mode,
        wolf_mode=_get_wolf_mode_by_cards(cards),
        cards=cards,
    )
    StepProcessor.init_game(new_game)
    db.session.add(new_game)
    db.session.commit()

    return GameEnum.OK.digest(gid=new_game.gid)
Exemplo n.º 4
0
def suicide():
    my_role = Role.query.get(current_user.uid)
    if not my_role.alive:
        return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()

    with Game.query.with_for_update().get(current_user.gid) as game:
        if game.status is not GameEnum.GAME_STATUS_DAY:
            return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
        game.steps = []
        publish_history(game.gid, f'{my_role.position}号玩家自爆了')
        StepProcessor.kill(game, my_role.position, GameEnum.SKILL_SUICIDE)
        return StepProcessor.move_on(game)
Exemplo n.º 5
0
def handover() -> dict:
    target = int(request.args.get('target'))
    my_role = Role.query.get(current_user.uid)
    if not my_role.alive:
        current_app.logger.info('my_role is not alive')
        return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
    with Game.query.with_for_update().get(current_user.gid) as game:
        now = StepProcessor.current_step(game)
        if now is not GameEnum.TURN_STEP_LAST_WORDS:
            current_app.logger.info(f'wrong now step:{now.label}')
            return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
        if str(my_role.position) not in game.history['dying']:
            current_app.logger.info(
                f'not in dying: my position={my_role.position},dying={game.history["dying"]}'
            )
            return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
        if game.captain_pos != my_role.position:
            current_app.logger.info(
                f'I am not captain, my position={my_role.position},captain pos={game.captain_pos}'
            )
            return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
        if target > 0:
            target_role = _get_role_by_pos(game, target)
            if not target_role.alive:
                current_app.logger.info(f'target not alive, target={target}')
                return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
        game.captain_pos = target
        publish_history(game.gid, f'{my_role.position}号玩家将警徽移交给了{target}号玩家')
        return GameEnum.OK.digest()
Exemplo n.º 6
0
def next_step() -> dict:
    with Game.query.with_for_update().get(current_user.gid) as game:
        if game.status not in [
                GameEnum.GAME_STATUS_READY, GameEnum.GAME_STATUS_DAY
        ]:
            return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
        return StepProcessor.move_on(game)
Exemplo n.º 7
0
def game():
    current_setting = []
    current_game = Game.query.get(current_user.gid)
    current_setting.append('游戏模式为:' + current_game.victory_mode.label)
    current_setting.append('警长模式为:' + current_game.captain_mode.label)
    current_setting.append('女巫模式为:' + current_game.witch_mode.label)
    current_setting.append('游戏总人数为:' + str(current_game.get_seats_cnt()) + '人')
    for role, cnt in Counter(current_game.cards).items():
        current_setting.append(role.label + ' = ' + str(cnt))

    current_role = Role.query.get(current_user.uid)
    return render_template(
        "werewolf_game.html",
        ishost=current_user.uid == current_game.host_uid,
        nickname=current_user.nickname,
        gid=current_game.gid,
        uid=current_user.uid,
        current_setting=current_setting,
        role_name=current_role.role_type.label,
        role_type=current_role.role_type.name.lower().replace(
            'role_type_', '', 1),
        seat_cnt=current_game.get_seats_cnt(),
        days=current_game.days,
        game_status=current_game.status,
        skills=current_role.skills,
        next_step=StepProcessor.get_instruction_string(current_game) or '等待中',
        dbtxt=(str(current_game.players) + str(type(current_game.players)) +
               '\n<br />\n' + str(type(current_game.steps))))
Exemplo n.º 8
0
def elect() -> dict:
    choice = request.args.get('choice')
    my_role = Role.query.get(current_user.uid)
    if not my_role.alive:
        return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
    with Game.query.with_for_update().get(current_user.gid) as game:
        now = StepProcessor.current_step(game)
        if choice in ['yes', 'no'] and now is not GameEnum.TURN_STEP_ELECT:
            return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
        if choice == 'quit' and now is not GameEnum.TURN_STEP_ELECT_TALK:
            return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
        if choice in ['yes', 'no'
                      ] and (GameEnum.TAG_ELECT in my_role.tags
                             or GameEnum.TAG_NOT_ELECT in my_role.tags):
            return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
        if choice == 'quit' and (GameEnum.TAG_ELECT not in my_role.tags or
                                 GameEnum.TAG_GIVE_UP_ELECT in my_role.tags):
            return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()

        if choice == 'yes':
            my_role.tags.append(GameEnum.TAG_ELECT)
        elif choice == 'no':
            my_role.tags.append(GameEnum.TAG_NOT_ELECT)
        elif choice == 'quit':
            publish_history(game.gid, f'{my_role.position}号玩家退水')
            my_role.tags.remove(GameEnum.TAG_ELECT)
            my_role.tags.append(GameEnum.TAG_GIVE_UP_ELECT)
            votee = game.history['voter_votee'][1]
            votee.remove(my_role.position)
            if len(votee) == 1:
                while game.now_index + 1 < len(
                        game.steps) and game.steps[game.now_index + 1] in {
                            GameEnum.TURN_STEP_ELECT_TALK,
                            GameEnum.TURN_STEP_ELECT_VOTE
                        }:
                    game.steps.pop(game.now_index + 1)
                captain_pos = votee[0]
                game.captain_pos = captain_pos
                publish_history(game.gid, f'仅剩一位警上玩家,{captain_pos}号玩家自动当选警长')
                return StepProcessor.move_on(game)
        else:
            raise ValueError(f'Unknown choice: {choice}')
        return GameEnum.OK.digest()
Exemplo n.º 9
0
def discover() -> dict:
    target = int(request.args.get('target'))
    my_role = Role.query.get(current_user.uid)
    if not my_role.alive:
        return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
    with Game.query.with_for_update().get(current_user.gid) as game:
        history = game.history
        now = StepProcessor.current_step(game)
        if now is not GameEnum.ROLE_TYPE_SEER or my_role.role_type is not GameEnum.ROLE_TYPE_SEER:
            return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
        if history['discover'] != GameEnum.TARGET_NOT_ACTED.value:
            return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
        if target > 0:
            target_role = _get_role_by_pos(game, target)
            if not target_role.alive:
                return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
        history['discover'] = target
        group_result = '<span style="color:red">狼人</span>' if target_role.group_type is GameEnum.GROUP_TYPE_WOLVES else '<span style="color:green">好人</span>'
        StepProcessor.move_on(game)
        return GameEnum.OK.digest(result=f'你查验了{target}号玩家为:{group_result}')
Exemplo n.º 10
0
def shoot() -> dict:
    target = int(request.args.get('target'))
    my_role = Role.query.get(current_user.uid)
    if not my_role.alive:
        return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
    with Game.query.with_for_update().get(current_user.gid) as game:
        history = game.history
        now = StepProcessor.current_step(game)
        if now is not GameEnum.TURN_STEP_LAST_WORDS:
            return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
        if not my_role.args['shootable'] or str(
                my_role.position) not in game.history['dying']:
            return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
        if target > 0:
            target_role = _get_role_by_pos(game, target)
            if not target_role.alive:
                return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
        publish_history(game.gid,
                        f'{my_role.position}号玩家发动技能“枪击”,带走了{target}号玩家')
        StepProcessor.kill(game, target, GameEnum.SKILL_SHOOT)
        return GameEnum.OK.digest()
Exemplo n.º 11
0
def witch() -> dict:
    my_role = Role.query.get(current_user.uid)
    if not my_role.alive:
        return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
    with Game.query.with_for_update().get(current_user.gid) as game:
        history = game.history
        now = StepProcessor.current_step(game)
        if now is not GameEnum.ROLE_TYPE_WITCH or my_role.role_type is not GameEnum.ROLE_TYPE_WITCH:
            return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
        if not my_role.args['elixir']:
            return GameEnum.OK.digest(result=GameEnum.TARGET_NOT_ACTED.value)
        else:
            return GameEnum.OK.digest(result=history['wolf_kill_decision'])
Exemplo n.º 12
0
def wolf_kill() -> dict:
    target = int(request.args.get('target'))
    my_role = Role.query.get(current_user.uid)
    if not my_role.alive:
        return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
    with Game.query.with_for_update().get(current_user.gid) as game:
        now = StepProcessor.current_step(game)
        history = game.history
        if now != GameEnum.TAG_ATTACKABLE_WOLF or GameEnum.TAG_ATTACKABLE_WOLF not in my_role.tags:
            return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
        if target > 0:
            target_role = _get_role_by_pos(game, target)
            if not target_role.alive:
                return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
        if game.wolf_mode is GameEnum.WOLF_MODE_FIRST:
            history['wolf_kill_decision'] = target
        else:
            history['wolf_kill'][my_role.position] = target
            history.changed()
            all_players = Role.query.filter(Role.gid == game.gid,
                                            Role.alive == int(True)).limit(
                                                len(game.players)).all()
            attackable_cnt = 0
            for p in all_players:
                if GameEnum.TAG_ATTACKABLE_WOLF in p.tags:
                    attackable_cnt += 1
            if attackable_cnt == len(history['wolf_kill']):
                decision = set(history['wolf_kill'].values())
                if len(decision) == 1:
                    history['wolf_kill_decision'] = decision.pop()
                else:
                    history[
                        'wolf_kill_decision'] = GameEnum.TARGET_NO_ONE.value
        StepProcessor.move_on(game)
        if target > 0:
            return GameEnum.OK.digest(result=f'你选择了击杀{target}号玩家')
        else:
            return GameEnum.OK.digest(result=f'你选择空刀')
Exemplo n.º 13
0
def vote() -> dict:
    target = int(request.args.get('target'))
    my_role = Role.query.get(current_user.uid)
    if not my_role.alive:
        return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
    with Game.query.with_for_update().get(current_user.gid) as game:
        if not my_role.voteable or my_role.position not in game.history[
                'voter_votee'][0]:
            return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
        if target != GameEnum.TARGET_NO_ONE.value and target not in game.history[
                'voter_votee'][1]:
            return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
        if target > 0:
            target_role = _get_role_by_pos(game, target)
            if not target_role.alive:
                return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()

        now = StepProcessor.current_step(game)
        if now in [GameEnum.TURN_STEP_VOTE, GameEnum.TURN_STEP_ELECT_VOTE]:
            game.history['vote_result'][my_role.position] = target
            game.history.changed()
            if target > 0:
                return GameEnum.OK.digest(result=f'你投了{target}号玩家')
            else:
                return GameEnum.OK.digest(result=f'你弃票了')
        elif now in [
                GameEnum.TURN_STEP_PK_VOTE, GameEnum.TURN_STEP_ELECT_PK_VOTE
        ]:
            if target == GameEnum.TARGET_NO_ONE.value:
                return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()
            else:
                game.history['vote_result'][my_role.position] = target
                game.history.changed()
                if target > 0:
                    return GameEnum.OK.digest(result=f'你投了{target}号玩家')
                else:
                    return GameEnum.OK.digest(result=f'你弃票了')
        else:
            return GameEnum.GAME_MESSAGE_CANNOT_ACT.digest()