示例#1
0
    def getInputletInstances(self):
        from thb.cards import AttackCard
        from thb.characters.youmu import Youmu
        from thb.common import CharChoice
        from thb.inputlets import ActionInputlet
        from thb.inputlets import ChooseGirlInputlet
        from thb.inputlets import ChooseIndividualCardInputlet
        from thb.inputlets import ChooseOptionInputlet
        from thb.inputlets import ChoosePeerCardInputlet
        from thb.inputlets import ProphetInputlet

        g, p = self.makeGame()

        ilets = [
            ActionInputlet(self, ['cards', 'showncards'], []),
            ChooseGirlInputlet(self, {p: [CharChoice(Youmu)]}),
            ChooseIndividualCardInputlet(self, [AttackCard()]),
            ChooseOptionInputlet(self, (False, True)),
            ChoosePeerCardInputlet(self, p, ['cards']),
            ProphetInputlet(self, [AttackCard()]),
        ]

        for i in ilets:
            i.actor = p

        return g, p, ilets
示例#2
0
    def switch(p):
        g = Game.getgame()
        mapping = {p: p.choices}

        with InputTransaction('ChooseGirl', [p], mapping=mapping) as trans:
            rst = user_input([p], ChooseGirlInputlet(g, mapping), timeout=30, trans=trans)
            rst = rst or p.choices[0]

        p = g.next_character(p, rst)
        p.choices.remove(rst)
        return p
示例#3
0
    def testChooseGirlInputlet(self):
        from game.autoenv import user_input
        from thb.common import CharChoice
        from thb.characters.youmu import Youmu
        from thb.characters.seiga import Seiga
        from thb.inputlets import ChooseGirlInputlet

        g, p = self.makeGame()
        choices = [CharChoice(Youmu), CharChoice(Seiga)]
        mapping = {p: choices}

        ilet = ChooseGirlInputlet(self, mapping)
        ilet.actor = p
        ilet.set_choice(choices[0])
        eq_(ilet.data(), 0)

        p.client.gdlist.append([r'>I:ChooseGirl:\d+', 0])
        ilet = ChooseGirlInputlet(self, mapping)
        eq_(user_input([p], ilet), choices[0])
示例#4
0
    def handle(self, evt_type, act):
        if evt_type == 'action_apply' and isinstance(act, PlayerDeath):
            g = Game.getgame()

            tgt = act.target
            force = tgt.force
            if len(force.pool) <= 1:
                forces = g.forces[:]
                forces.remove(force)
                g.winners = forces[0][:]
                g.game_end()

        elif evt_type == 'action_after' and isinstance(act, PlayerDeath):
            g = Game.getgame()

            tgt = act.target
            pool = tgt.force.pool
            assert pool

            mapping = {tgt: pool}
            with InputTransaction('ChooseGirl', [tgt],
                                  mapping=mapping) as trans:
                c = user_input([tgt],
                               ChooseGirlInputlet(g, mapping),
                               timeout=30,
                               trans=trans)
                c = c or [_c for _c in pool if not _c.chosen][0]
                c.chosen = tgt
                pool.remove(c)
                trans.notify('girl_chosen', (tgt, c))

            tgt = g.switch_character(tgt, c)

            c = getattr(g, 'current_player', None)

            g.process_action(DistributeCards(tgt, 4))

            if user_input([tgt], ChooseOptionInputlet(self, (False, True))):
                g.process_action(RedrawCards(tgt, tgt))

        return act
示例#5
0
    def testChooseGirlInputlet(self):
        from game.autoenv import user_input
        from thb.common import CharChoice
        from thb.characters.youmu import Youmu
        from thb.characters.seiga import Seiga
        from thb.inputlets import ChooseGirlInputlet

        g, p = self.makeGame()
        choices = [CharChoice(Youmu), CharChoice(Seiga)]
        mapping = {p: choices}

        ilet = ChooseGirlInputlet(self, mapping)
        ilet.actor = p
        ilet.set_choice(choices[0])
        eq_(ilet.data(), 0)

        p.client.gdlist.append([r'>I:ChooseGirl:\d+', 0])
        ilet = ChooseGirlInputlet(self, mapping)
        eq_(user_input([p], ilet), choices[0])
示例#6
0
    def apply_action(self):
        g = Game.getgame()
        params = self.params

        from thb.cards import Deck

        g.stats = []

        g.deck = Deck()
        g.ehclasses = []

        if params['random_force']:
            seed = get_seed_for(g.players)
            random.Random(seed).shuffle(g.players)

        g.draw_extra_card = params['draw_extra_card']

        f1 = BatchList()
        f2 = BatchList()
        g.forces = BatchList([f1, f2])

        H, M = Identity.TYPE.HAKUREI, Identity.TYPE.MORIYA
        for p, id, f in zip(g.players, [H, H, M, M], [f1, f1, f2, f2]):
            p.identity = Identity()
            p.identity.type = id
            p.force = f
            f.append(p)

        pl = g.players
        for p in pl:
            g.process_action(RevealIdentity(p, pl))

        roll_rst = roll(g, self.items)
        f1, f2 = partition(lambda p: p.force is roll_rst[0].force, roll_rst)
        final_order = [f1[0], f2[0], f2[1], f1[1]]
        g.players[:] = final_order
        g.emit_event('reseat', None)

        # ban / choose girls -->
        from . import characters
        chars = characters.get_characters('common', '2v2')

        seed = get_seed_for(g.players)
        random.Random(seed).shuffle(chars)

        # ANCHOR(test)
        testing = list(settings.TESTING_CHARACTERS)
        testing, chars = partition(lambda c: c.__name__ in testing, chars)
        chars.extend(testing)

        chars = chars[-20:]
        choices = [CharChoice(cls) for cls in chars]

        banned = set()
        mapping = {p: choices for p in g.players}
        with InputTransaction('BanGirl', g.players, mapping=mapping) as trans:
            for p in g.players:
                c = user_input([p],
                               ChooseGirlInputlet(g, mapping),
                               timeout=30,
                               trans=trans)
                c = c or [_c for _c in choices if not _c.chosen][0]
                c.chosen = p
                banned.add(c.char_cls)
                trans.notify('girl_chosen', (p, c))

        assert len(banned) == 4

        g.stats.extend([{
            'event': 'ban',
            'attributes': {
                'gamemode': g.__class__.__name__,
                'character': i.__name__
            }
        } for i in banned])

        chars = [_c for _c in chars if _c not in banned]

        g.random.shuffle(chars)

        if Game.CLIENT_SIDE:
            chars = [None] * len(chars)

        for p in g.players:
            p.choices = [CharChoice(cls) for cls in chars[-4:]]
            p.choices[-1].as_akari = True

            del chars[-4:]

            p.reveal(p.choices)

        g.pause(1)

        mapping = {p: p.choices for p in g.players}
        with InputTransaction('ChooseGirl', g.players,
                              mapping=mapping) as trans:
            ilet = ChooseGirlInputlet(g, mapping)

            @ilet.with_post_process
            def process(p, c):
                c = c or p.choices[0]
                trans.notify('girl_chosen', (p, c))
                return c

            rst = user_input(g.players,
                             ilet,
                             timeout=30,
                             type='all',
                             trans=trans)

        # reveal
        for p, c in rst.items():
            c.as_akari = False
            g.players.reveal(c)
            g.set_character(p, c.char_cls)

        # -------
        for p in g.players:
            log.info(
                u'>> Player: %s:%s %s',
                p.__class__.__name__,
                Identity.TYPE.rlookup(p.identity.type),
                p.account.username,
            )
        # -------

        g.emit_event('game_begin', g)

        for p in g.players:
            g.process_action(DistributeCards(p, amount=4))

        for i, p in enumerate(cycle(pl)):
            if i >= 6000: break
            if not p.dead:
                g.emit_event('player_turn', p)
                try:
                    g.process_action(PlayerTurn(p))
                except InterruptActionFlow:
                    pass

        return True
示例#7
0
    def apply_action(self):
        g = Game.getgame()

        from . import cards

        g.pick_history = []

        g.deck = cards.Deck(cards.kof_card_definition)
        g.ehclasses = []
        g.current_player = None

        for i, p in enumerate(g.players):
            p.identity = Identity()
            p.identity.type = (Identity.TYPE.HAKUREI, Identity.TYPE.MORIYA)[i % 2]

        # choose girls -->
        from thb.characters import get_characters
        chars = get_characters('common', 'kof')

        A, B = roll(g, self.items)
        order = [A, B, B, A, A, B, B, A, A, B]

        choices, imperial_choices = build_choices(
            g, self.items,
            candidates=chars, players=[A, B],
            num=10, akaris=4, shared=True,
        )

        chosen = {A: [], B: []}

        with InputTransaction('ChooseGirl', g.players, mapping=choices) as trans:
            for p, c in imperial_choices:
                c.chosen = p
                chosen[p].append(c)
                trans.notify('girl_chosen', (p, c))
                order.remove(p)

            for p in order:
                c = user_input([p], ChooseGirlInputlet(g, choices), 10, 'single', trans)
                c = c or first(choices[p], lambda c: not c.chosen)

                c.chosen = p
                chosen[p].append(c)

                trans.notify('girl_chosen', (p, c))

        # reveal akaris for themselves
        for p in [A, B]:
            for c in chosen[p]:
                c.akari = False
                p.reveal(c)
                del c.chosen

        list_shuffle(chosen[A], A)
        list_shuffle(chosen[B], B)

        with InputTransaction('ChooseGirl', g.players, mapping=chosen) as trans:
            ilet = ChooseGirlInputlet(g, chosen)
            ilet.with_post_process(lambda p, rst: trans.notify('girl_chosen', (p, rst)) or rst)
            rst = user_input([A, B], ilet, type='all', trans=trans)

        def s(p):
            c = rst[p] or chosen[p][0]
            chosen[p].remove(c)
            p.choices = chosen[p]
            p.remaining = [2]
            p = g.next_character(p, c)
            return p

        A, B = s(A), s(B)

        order = [1, 0] if A is g.players[0] else [0, 1]

        for p in [A, B]:
            g.process_action(RevealIdentity(p, g.players))

        g.emit_event('game_begin', g)

        g.process_action(DistributeCards(A, amount=4))
        g.process_action(DistributeCards(B, amount=3))

        for i in order:
            g.emit_event('character_debut', (None, g.players[i]))

        for i, idx in enumerate(cycle(order)):
            p = g.players[idx]
            if i >= 6000: break
            if p.dead:
                KOFCharacterSwitchHandler.do_switch_dead()
                p = g.players[idx]  # player changed

            assert not p.dead

            try:
                g.emit_event('player_turn', p)
                g.process_action(PlayerTurn(p))
            except InterruptActionFlow:
                pass
示例#8
0
    def apply_action(self):
        g = Game.getgame()
        params = self.params

        from thb.cards import Deck

        g.deck = Deck()
        g.ehclasses = []

        # arrange identities -->
        g.double_curtain = params['double_curtain']

        mapping = {
            'B': Identity.TYPE.BOSS,
            '!': Identity.TYPE.ATTACKER,
            '&': Identity.TYPE.ACCOMPLICE,
            '?': Identity.TYPE.CURTAIN,
        }

        if g.double_curtain:
            identities = 'B!!!&&??'
        else:
            identities = 'B!!!!&&?'

        pl = g.players[:]
        identities = [mapping[i] for i in identities]
        g.identities = identities[:]
        imperial_identities = ImperialIdentity.get_chosen(self.items, pl)
        for p, i in imperial_identities:
            pl.remove(p)
            identities.remove(i)

        g.random.shuffle(identities)

        if Game.CLIENT_SIDE:
            identities = [Identity.TYPE.HIDDEN for _ in identities]

        for p, i in imperial_identities + zip(pl, identities):
            p.identity = Identity()
            p.identity.type = i
            g.process_action(RevealIdentity(p, p))

        del identities

        is_boss = sync_primitive([p.identity.type == Identity.TYPE.BOSS for p in g.players], g.players)
        boss_idx = is_boss.index(True)
        boss = g.boss = g.players[boss_idx]

        boss.identity = Identity()
        boss.identity.type = Identity.TYPE.BOSS
        g.process_action(RevealIdentity(boss, g.players))

        # choose girls init -->
        from .characters import get_characters
        pl = g.players.rotate_to(boss)

        choices, _ = build_choices(
            g, self.items,
            candidates=get_characters('common', 'id', 'id8', '-boss'),
            players=[boss],
            num=[5], akaris=[1],
            shared=False,
        )

        choices[boss][:0] = [CharChoice(cls) for cls in get_characters('boss')]

        with InputTransaction('ChooseGirl', [boss], mapping=choices) as trans:
            c = user_input([boss], ChooseGirlInputlet(g, choices), 30, 'single', trans)

            c = c or choices[boss][-1]
            c.chosen = boss
            c.akari = False
            g.players.reveal(c)
            trans.notify('girl_chosen', (boss, c))

        chars = get_characters('common', 'id', 'id8')

        try:
            chars.remove(c.char_cls)
        except:
            pass

        # mix it in advance
        # so the others could see it

        boss = g.switch_character(boss, c.char_cls)

        # boss's hp bonus
        if g.n_persons > 5:
            boss.maxlife += 1

        boss.life = boss.maxlife

        # choose boss dedicated skill
        g.process_action(ChooseBossSkillAction(boss, boss))

        # reseat
        seed = get_seed_for(g.players)
        random.Random(seed).shuffle(g.players)
        g.emit_event('reseat', None)

        # others choose girls
        pl = g.players.exclude(boss)

        choices, _ = build_choices(
            g, self.items,
            candidates=chars, players=pl,
            num=[4] * len(pl), akaris=[1] * len(pl),
            shared=False,
        )

        with InputTransaction('ChooseGirl', pl, mapping=choices) as trans:
            ilet = ChooseGirlInputlet(g, choices)
            ilet.with_post_process(lambda p, rst: trans.notify('girl_chosen', (p, rst)) or rst)
            result = user_input(pl, ilet, type='all', trans=trans)

        # mix char class with player -->
        for p in pl:
            c = result[p] or choices[p][-1]
            c.akari = False
            g.players.reveal(c)
            p = g.switch_character(p, c.char_cls)

        # -------
        for p in g.players:
            log.info(
                u'>> Player: %s:%s %s',
                p.__class__.__name__,
                Identity.TYPE.rlookup(p.identity.type),
                p.account.username,
            )
        # -------

        g.emit_event('game_begin', g)

        for p in g.players:
            g.process_action(DistributeCards(p, amount=4))

        for i, p in enumerate(cycle(g.players.rotate_to(boss))):
            if i >= 6000: break
            if not p.dead:
                try:
                    g.process_action(PlayerTurn(p))
                except InterruptActionFlow:
                    pass

        return True
示例#9
0
    def apply_action(self):
        g = Game.getgame()
        params = self.params

        from thb.cards import Deck

        g.deck = Deck()
        g.ehclasses = []

        if params['random_seat']:
            seed = get_seed_for(g.players)
            random.Random(seed).shuffle(g.players)
            g.emit_event('reseat', None)

        for i, p in enumerate(g.players):
            p.identity = Identity()
            p.identity.type = (Identity.TYPE.HAKUREI,
                               Identity.TYPE.MORIYA)[i % 2]

        g.forces = forces = BatchList([BatchList(), BatchList()])
        for i, p in enumerate(g.players):
            f = i % 2
            p.force = f
            forces[f].append(p)

        pl = g.players
        for p in pl:
            g.process_action(RevealIdentity(p, pl))

        from . import characters
        chars = characters.get_characters('common', '3v3')
        choices, imperial_choices = build_choices(
            g,
            self.items,
            candidates=chars,
            players=g.players,
            num=16,
            akaris=4,
            shared=True,
        )

        roll_rst = roll(g, self.items)
        first = roll_rst[0]
        first_index = g.players.index(first)

        order_list = (0, 5, 3, 4, 2, 1)
        n = len(order_list)
        order = [g.players[(first_index + i) % n] for i in order_list]

        akaris = []
        with InputTransaction('ChooseGirl', g.players,
                              mapping=choices) as trans:
            chosen = set()

            for p, c in imperial_choices:
                chosen.add(p)
                c.chosen = p
                g.set_character(p, c.char_cls)
                trans.notify('girl_chosen', (p, c))

            for p in order:
                if p in chosen:
                    continue

                c = user_input([p],
                               ChooseGirlInputlet(g, choices),
                               timeout=30,
                               trans=trans)
                c = c or [_c
                          for _c in reversed(choices[p]) if not _c.chosen][0]
                c.chosen = p

                if c.akari:
                    c.akari = False
                    akaris.append((p, c))
                else:
                    g.set_character(p, c.char_cls)

                trans.notify('girl_chosen', (p, c))

        # reveal akaris
        if akaris:
            g.players.reveal([i[1] for i in akaris])

            for p, c in akaris:
                g.set_character(p, c.char_cls)

        # -------
        for p in g.players:
            log.info(
                u'>> Player: %s:%s %s',
                p.__class__.__name__,
                Identity.TYPE.rlookup(p.identity.type),
                p.account.username,
            )
        # -------

        first = g.players[first_index]

        g.emit_event('game_begin', g)

        for p in g.players:
            g.process_action(DrawCards(p, amount=3 if p is first else 4))

        pl = g.players.rotate_to(first)

        for i, p in enumerate(cycle(pl)):
            if i >= 6000: break
            if not p.dead:
                g.emit_event('player_turn', p)
                try:
                    g.process_action(PlayerTurn(p))
                except InterruptActionFlow:
                    pass

        return True
示例#10
0
    def apply_action(self):
        g = Game.getgame()
        params = self.params

        from thb.cards import Deck

        g.deck = Deck()
        g.ehclasses = []

        # arrange identities -->
        g.double_curtain = params['double_curtain']

        mapping = {
            'B': Identity.TYPE.BOSS,
            '!': Identity.TYPE.ATTACKER,
            '&': Identity.TYPE.ACCOMPLICE,
            '?': Identity.TYPE.CURTAIN,
        }

        if g.double_curtain:
            identities = 'B!!!&&??'
        else:
            identities = 'B!!!!&&?'

        pl = g.players[:]
        identities = [mapping[i] for i in identities]
        g.identities = identities[:]
        imperial_identities = ImperialIdentity.get_chosen(self.items, pl)
        for p, i in imperial_identities:
            pl.remove(p)
            identities.remove(i)

        g.random.shuffle(identities)

        if Game.CLIENT_SIDE:
            identities = [Identity.TYPE.HIDDEN for _ in identities]

        for p, i in imperial_identities + zip(pl, identities):
            p.identity = Identity()
            p.identity.type = i
            g.process_action(RevealIdentity(p, p))

        del identities

        is_boss = sync_primitive(
            [p.identity.type == Identity.TYPE.BOSS for p in g.players],
            g.players)
        boss_idx = is_boss.index(True)
        boss = g.boss = g.players[boss_idx]

        boss.identity = Identity()
        boss.identity.type = Identity.TYPE.BOSS
        g.process_action(RevealIdentity(boss, g.players))

        # choose girls init -->
        from .characters import get_characters
        pl = g.players.rotate_to(boss)

        choices, _ = build_choices(
            g,
            self.items,
            candidates=get_characters('common', 'id', 'id8', '-boss'),
            players=[boss],
            num=[5],
            akaris=[1],
            shared=False,
        )

        choices[boss][:0] = [CharChoice(cls) for cls in get_characters('boss')]

        with InputTransaction('ChooseGirl', [boss], mapping=choices) as trans:
            c = user_input([boss], ChooseGirlInputlet(g, choices), 30,
                           'single', trans)

            c = c or choices[boss][-1]
            c.chosen = boss
            c.akari = False
            g.players.reveal(c)
            trans.notify('girl_chosen', (boss, c))

        chars = get_characters('common', 'id', 'id8')

        try:
            chars.remove(c.char_cls)
        except:
            pass

        # mix it in advance
        # so the others could see it

        boss = g.switch_character(boss, c.char_cls)

        # boss's hp bonus
        if g.n_persons > 5:
            boss.maxlife += 1

        boss.life = boss.maxlife

        # choose boss dedicated skill
        g.process_action(ChooseBossSkillAction(boss, boss))

        # reseat
        seed = get_seed_for(g.players)
        random.Random(seed).shuffle(g.players)
        g.emit_event('reseat', None)

        # others choose girls
        pl = g.players.exclude(boss)

        choices, _ = build_choices(
            g,
            self.items,
            candidates=chars,
            players=pl,
            num=[4] * len(pl),
            akaris=[1] * len(pl),
            shared=False,
        )

        with InputTransaction('ChooseGirl', pl, mapping=choices) as trans:
            ilet = ChooseGirlInputlet(g, choices)
            ilet.with_post_process(
                lambda p, rst: trans.notify('girl_chosen', (p, rst)) or rst)
            result = user_input(pl, ilet, type='all', trans=trans)

        # mix char class with player -->
        for p in pl:
            c = result[p] or choices[p][-1]
            c.akari = False
            g.players.reveal(c)
            p = g.switch_character(p, c.char_cls)

        # -------
        for p in g.players:
            log.info(
                u'>> Player: %s:%s %s',
                p.__class__.__name__,
                Identity.TYPE.rlookup(p.identity.type),
                p.account.username,
            )
        # -------

        g.emit_event('game_begin', g)

        for p in g.players:
            g.process_action(DistributeCards(p, amount=4))

        for i, p in enumerate(cycle(g.players.rotate_to(boss))):
            if i >= 6000: break
            if not p.dead:
                try:
                    g.process_action(PlayerTurn(p))
                except InterruptActionFlow:
                    pass

        return True