예제 #1
0
 def prepare(self):
     tl = self.target_list
     g = Game.getgame()
     cards = g.deck.getcards(len(tl))
     g.players.reveal(cards)
     detach_cards(cards)
     trans = InputTransaction('HarvestChoose', g.players, cards=cards)
     trans.begin()
     self.cards = cards
     self.trans = trans
예제 #2
0
 def prepare(self):
     tl = self.target_list
     g = Game.getgame()
     cards = g.deck.getcards(len(tl))
     g.players.reveal(cards)
     migrate_cards(cards, g.deck.disputed)
     trans = InputTransaction('HarvestChoose', g.players, cards=cards)
     trans.begin()
     self.cards = cards
     self.trans = trans
예제 #3
0
    def apply_action(self):
        g = Game.getgame()
        target = self.target
        if target.dead: return False

        try:
            while not target.dead:
                try:
                    g.emit_event('action_stage_action', target)
                    self.in_user_input = True
                    with InputTransaction('ActionStageAction', [target]) as trans:
                        p, rst = ask_for_action(
                            self, [target], ('cards', 'showncards'), g.players, trans
                        )
                    check(p is target)
                finally:
                    self.in_user_input = False

                cards, target_list = rst
                g.players.reveal(cards)
                card = cards[0]

                if not g.process_action(ActionStageLaunchCard(target, target_list, card)):
                    # invalid input
                    log.debug('ActionStage: LaunchCard failed.')
                    check(False)

                if self.one_shot or self._force_break:
                    break

        except CheckFailed:
            pass

        return True
예제 #4
0
    def apply_action(self):
        g = Game.getgame()
        tgt = self.target

        while True:
            dc = DrawCards(tgt, 1)
            g.process_action(dc)
            c, = dc.cards
            self.card = c
            g.process_action(ShowCards(tgt, [c]))

            with InputTransaction('ActionStageAction', [tgt]) as trans:
                p, rst = ask_for_action(self, [tgt], ('cards', 'showncards'),
                                        g.players, trans)

            if p is not tgt:
                g.process_action(WindWalkSkipAction(tgt, tgt))
                break

            cl, tl = rst
            g.players.reveal(cl)
            c, = cl

            g.process_action(WindWalkLaunch(p, tl, c))

        return True
예제 #5
0
    def handle(self, evt_type, act):
        if evt_type != 'action_after': return act
        if not isinstance(act, PlayerDeath): return act

        g = Game.getgame()

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

        g = Game.getgame()

        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', c)

        tgt = g.switch_character(tgt, c)
        g.process_action(DrawCards(tgt, 4))

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

        return act
예제 #6
0
    def apply_action(self):
        src = self.source
        tgt = self.target
        g = Game.getgame()

        pl = BatchList([tgt, src])
        pindian_card = {src: None, tgt: None}

        with InputTransaction('Pindian', pl) as trans:
            for p in pl:
                cards = user_choose_cards(self,
                                          p, ('cards', 'showncards'),
                                          trans=trans)
                if cards:
                    card = cards[0]
                else:
                    card = random_choose_card([p.cards, p.showncards])

                pindian_card[p] = card
                detach_cards([card])
                g.emit_event('pindian_card_chosen', (p, card))

        g.players.reveal([pindian_card[src], pindian_card[tgt]])
        g.emit_event('pindian_card_revealed', self)  # for ui.
        migrate_cards([pindian_card[src], pindian_card[tgt]],
                      g.deck.droppedcards,
                      unwrap=True,
                      is_bh=True)

        return pindian_card[src].number > pindian_card[tgt].number
예제 #7
0
파일: thbkof.py 프로젝트: zzkklep/thbattle
    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
예제 #8
0
    def handle(self, evt_type, act):
        if evt_type == 'action_before' and isinstance(act, SpellCardAction):
            if act.cancelled: return act  # some other thing have done the job
            if act.non_responsive:
                return act

            g = Game.getgame()

            has_reject = False
            while g.SERVER_SIDE:
                from ..characters.baseclasses import Character
                from ..characters.reimu import SpiritualAttack
                for p in g.players:
                    if isinstance(p,
                                  Character) and p.has_skill(SpiritualAttack):
                        has_reject = True
                        break

                if has_reject: break

                from .definition import RejectCard
                for c in flatten([[p.cards, p.showncards] for p in g.players]):
                    if isinstance(c, RejectCard):
                        has_reject = True
                        break

                break

            has_reject = sync_primitive(has_reject, g.players)
            if not has_reject: return act

            self.target_act = act

            pl = BatchList(p for p in g.players if not p.dead)

            with InputTransaction('AskForRejectAction', pl) as trans:
                p, rst = ask_for_action(self, pl, ('cards', 'showncards'), [],
                                        trans)

            if not p: return act
            cards, _ = rst
            assert cards and self.cond(cards)
            g.process_action(
                LaunchCard(p, [act.target], cards[0], Reject(p, act)))

        return act
예제 #9
0
            def resp(evt_type, act):
                if evt_type == 'action_before' and isinstance(act, Demolition):
                    g.pause(1.5)
                    dialog(Cirno, u'哈哈,早知道你会用这一招,怎能让你轻易得逞!', 17)
                    g.process_action(
                        LaunchCard(cirno, [cirno], cirnoreject,
                                   Reject(cirno, act)))

                elif evt_type == 'action_before' and isinstance(
                        act, Reject) and act.associated_card is cirnoreject:
                    g.pause(1.5)
                    dialog(Meirin, u'这又是怎么回事……好像|G城管执法|r并没有起作用?', 38)
                    dialog(Sakuya, u'咦,这笨蛋居然知道用|G好人卡|r啊……', 19)
                    dialog(Cirno, u'什么笨蛋,老娘是天才,天~才~', 18)
                    text = (u'|G好人卡|r的效果是|R抵消符卡效果|r,也就是说,你的|G城管执法|r的效果被无效化了。\n'
                            u'(在PC版中鼠标移动到卡牌/人物上,或者手机版中长按卡牌/人物头像,就会弹出说明,很有用的)')
                    dialog(Sakuya, text, 20)
                    dialog(Sakuya,
                           u'但是,|G好人卡|r的“无效符卡”的效果,本身也是符卡效果,是可以被|G好人卡|r抵消的!',
                           21)

                    meirinreject = g.deck.inject(RejectCard, Card.CLUB, 4)
                    g.process_action(DrawCards(meirin, 1))

                    while not act.cancelled:
                        dialog(Meirin, u'我知道了,我也用|G好人卡|r去抵消她的|G好人卡|r效果就好了!',
                               39)

                        rej = RejectHandler()
                        rej.target_act = act
                        with InputTransaction('AskForRejectAction',
                                              [meirin]) as trans:
                            p, rst = ask_for_action(rej, [meirin],
                                                    ('cards', 'showncards'),
                                                    [],
                                                    trans=trans)

                        if not p: continue
                        cards, _ = rst
                        assert cards[0] is meirinreject
                        g.process_action(
                            LaunchCard(meirin, [cirno], meirinreject,
                                       Reject(meirin, act)))

                return act
예제 #10
0
    def game_start(g):
        # game started, init state
        from cards import Deck

        g.deck = Deck()

        g.ehclasses = list(action_eventhandlers) + g.game_ehs.values()

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

        H, M = Identity.TYPE.HAKUREI, Identity.TYPE.MORIYA
        L = [[H, H, M, M, H, M], [H, M, H, M, H, M]]
        rnd = random.Random(get_seed_for(g.players))
        L = rnd.choice(L) * 2
        s = rnd.randrange(0, 6)
        idlist = L[s:s+6]
        del H, M, L, s, rnd

        for p, identity in zip(g.players, idlist):
            p.identity = Identity()
            p.identity.type = identity
            g.process_action(RevealIdentity(p, g.players))

        force_hakurei = BatchList()
        force_moriya = BatchList()
        force_hakurei.pool = []
        force_moriya.pool = []

        for p in g.players:
            if p.identity.type == Identity.TYPE.HAKUREI:
                force_hakurei.append(p)
                p.force = force_hakurei
            elif p.identity.type == Identity.TYPE.MORIYA:
                force_moriya.append(p)
                p.force = force_moriya

        g.forces = BatchList([force_hakurei, force_moriya])

        # ----- roll ------
        roll = range(len(g.players))
        g.random.shuffle(roll)
        pl = g.players
        roll = sync_primitive(roll, pl)
        roll = [pl[i] for i in roll]
        g.emit_event('game_roll', roll)
        first = roll[0]
        g.emit_event('game_roll_result', first)
        # ----

        # choose girls -->
        from . import characters
        chars = list(characters.characters)
        g.random.shuffle(chars)

        if Game.SERVER_SIDE:
            choices = [CharChoice(cls) for cls in chars[-24:]]
        else:
            choices = [CharChoice(None) for _ in xrange(24)]

        del chars[-24:]

        for p in g.players:
            c = choices[-3:]
            del choices[-3:]
            akari = CharChoice(characters.akari.Akari)
            akari.real_cls = chars.pop()
            c.append(akari)
            p.choices = c
            p.choices_chosen = []
            p.reveal(c)

        mapping = {p: p.choices for p in g.players}
        remaining = {p: 2 for p in g.players}

        deadline = time.time() + 30
        with InputTransaction('ChooseGirl', g.players, mapping=mapping) as trans:
            while True:
                pl = [p for p in g.players if remaining[p]]
                if not pl: break

                p, c = user_input(
                    pl, ChooseGirlInputlet(g, mapping),
                    timeout=deadline - time.time(),
                    trans=trans, type='any'
                )
                p = p or pl[0]

                c = c or [_c for _c in p.choices if not _c.chosen][0]
                c.chosen = p
                p.choices.remove(c)
                p.choices_chosen.append(c)
                remaining[p] -= 1

                trans.notify('girl_chosen', c)

        for p in g.players:
            a, b = p.choices_chosen
            b.chosen = None
            p.force.reveal(b)
            g.switch_character(p, a)
            p.force.pool.append(b)
            del p.choices_chosen

        for p in g.players:
            if p.player is first:
                first = p
                break

        try:
            pl = g.players
            first_index = pl.index(first)
            order = BatchList(range(len(pl))).rotate_to(first_index)

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

            g.emit_event('game_begin', g)

            for p in pl:
                g.process_action(DrawCards(p, amount=4))

            pl = g.players.rotate_to(first)
            rst = user_input(pl[1:], ChooseOptionInputlet(DeathHandler(), (False, True)), type='all')

            for p in pl[1:]:
                rst.get(p) and g.process_action(RedrawCards(p, p))

            pl = g.players
            for i, idx in enumerate(cycle(order)):
                if i >= 6000: break
                p = pl[idx]
                if p.dead: continue

                g.emit_event('player_turn', p)
                try:
                    g.process_action(PlayerTurn(p))
                except InterruptActionFlow:
                    pass

        except GameEnded:
            pass

        log.info(u'>> Winner: %s', Identity.TYPE.rlookup(g.winners[0].identity.type))
예제 #11
0
    def apply_action(self):
        g = Game.getgame()

        from cards import Deck

        g.deck = Deck()
        g.ehclasses = list(action_eventhandlers) + g.game_ehs.values()

        H, M, A = Identity.TYPE.HAKUREI, Identity.TYPE.MORIYA, Identity.TYPE.ADMIN
        idlist = [A, H, H, M, M]
        del H, M, A

        pl = g.players[1:]
        seed = sync_primitive(g.random.getrandbits(32), g.players)
        random.Random(seed).shuffle(pl)
        g.players[1:] = pl
        g.emit_event('reseat', None)

        for p, identity in zip(g.players, idlist):
            p.identity = Identity()
            p.identity.type = identity
            g.process_action(RevealIdentity(p, g.players))

        force_hakurei = BatchList(g.players[1:3])
        force_moriya  = BatchList(g.players[3:5])
        g.forces = BatchList([force_hakurei, force_moriya])

        from . import characters

        g.switch_character(g.players[0], CharChoice(characters.koakuma.Koakuma))
        g.koakuma = koakuma = g.players[0]
        koakuma.tags['books'] = g.total_books
        koakuma.maxlife += 4
        koakuma.life += 4

        # choose girls -->
        chars = characters.get_characters('book')
        try:
            chars.remove(characters.koakuma.Koakuma)
        except:
            pass

        g.random.shuffle(chars)

        testing = list(settings.TESTING_CHARACTERS)
        testing = filter_out(chars, lambda c: c.__name__ in testing)
        chars = g.random.sample(chars, 24)

        if Game.SERVER_SIDE:
            choices = [CharChoice(cls) for cls in chars[-20:]]
        else:
            choices = [CharChoice(None) for _ in xrange(20)]

        del chars[-20:]

        for p in g.players[1:]:
            c = choices[-4:]
            del choices[-4:]
            akari = CharChoice(characters.akari.Akari)
            akari.real_cls = chars.pop()
            c.append(akari)
            c.extend([CharChoice(cls) for cls in testing])
            p.choices = c
            p.reveal(c)

        pl = g.players[1:]
        mapping = {p: p.choices for p in pl}

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

        for p in pl:
            c = rst[p] or p.choices[0]
            g.switch_character(p, c)

        g.emit_event('game_begin', g)

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

        pl = g.players
        for i, idx in enumerate(cycle(range(len(pl)))):
            if i >= 6000: break
            p = pl[idx]
            if p.dead:
                g.process_action(PlayerRevive(p, p, 2))
                g.process_action(DrawCards(p, 2))
                continue

            g.emit_event('player_turn', p)
            try:
                g.process_action(PlayerTurn(p))
            except InterruptActionFlow:
                pass
예제 #12
0
    def game_start(g):
        # game started, init state

        g.action_types[LaunchCard] = RaidLaunchCard
        g.action_types[ActionStageLaunchCard] = RaidActionStageLaunchCard

        g.ehclasses = []

        # reveal identities
        mutant = g.mutant = g.players[0]
        attackers = g.attackers = BatchList(g.players[1:])

        mutant.identity = Identity()
        mutant.identity.type = Identity.TYPE.MUTANT

        g.process_action(RevealIdentity(mutant, g.players))

        for p in attackers:
            p.identity = Identity()
            p.identity.type = Identity.TYPE.ATTACKER

            g.process_action(RevealIdentity(p, g.players))

        # mutant's choose
        from characters import ex_characters as ex_chars

        choices = [CharChoice(cls) for cls in ex_chars]
        mapping = {mutant: choices}
        with InputTransaction('ChooseGirl', [mutant],
                              mapping=mapping) as trans:
            c = user_input([mutant],
                           ChooseGirlInputlet(g, mapping),
                           timeout=5,
                           trans=trans)
            c = c or choices[0]
            c.chosen = mutant
            trans.notify('girl_chosen', c)

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

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

            mutant.life = mutant.maxlife
            mutant.morphed = False

        # init deck & mutant's initial equip
        # (SinsackCard, SPADE, 1)
        # (SinsackCard, HEART, Q)
        from cards import Deck, SinsackCard, ElementalReactorCard, card_definition
        raid_carddef = [
            carddef for carddef in card_definition
            if carddef[0] not in (SinsackCard, ElementalReactorCard)
        ]

        g.deck = Deck(raid_carddef)

        # attackers' choose
        from characters import characters as chars
        chars = list(chars)
        seed = get_seed_for(g.players)
        random.Random(seed).shuffle(chars)

        for p in g.attackers:
            p.choices = [CharChoice(cls) for cls in chars[:5]]
            del chars[:5]

        # -----------
        mapping = {p: p.choices for p in g.attackers}
        with InputTransaction('ChooseGirl', g.attackers,
                              mapping=mapping) as trans:
            ilet = ChooseGirlInputlet(g, mapping)
            ilet.with_post_process(
                lambda p, rst: trans.notify('girl_chosen', rst) or rst)
            result = user_input(g.attackers, ilet, 30, 'all', trans)

        # mix char class with player -->
        for p in g.attackers:
            c = result[p] or CharChoice(chars.pop())
            c.chosen = p
            p = g.switch_character(p, c.char_cls)
            p.skills.extend([
                Cooperation,
                Protection,
                Parry,
                OneUp,
            ])

        g.update_event_handlers()

        g.emit_event('game_begin', g)

        # -------
        log.info(u'>> Game info: ')
        log.info(u'>> Mutant: %s', mutant.__class__.__name__)
        for p in attackers:
            log.info(u'>> Attacker: %s', p.__class__.__name__)

        # -------

        try:
            g.process_action(DrawCards(mutant, amount=6))
            for p in attackers:
                g.process_action(DrawCards(p, amount=4))

            # stage 1
            try:
                for i in xrange(500):
                    g.process_action(CollectFaith(mutant, mutant, 1))

                    avail = [
                        p for p in attackers
                        if not p.dead and len(p.faiths) < 5
                    ]
                    if avail:
                        p, _ = user_input(
                            avail,
                            ChooseOptionInputlet(GetFaith, (None, True)),
                            type='any',
                        )
                        p = p or avail[0]
                        g.process_action(CollectFaith(p, p, 1))

                    g.emit_event('round_start', False)

                    for p in attackers:
                        p.tags['action'] = True

                    while True:
                        try:
                            g.process_action(PlayerTurn(mutant))
                        except InterruptActionFlow:
                            pass

                        avail = BatchList([
                            p for p in attackers
                            if p.tags['action'] and not p.dead
                        ])
                        if not avail:
                            break

                        p, _ = user_input(
                            avail,
                            ChooseOptionInputlet(RequestAction, (None, True)),
                            type='any',
                        )

                        p = p or avail[0]
                        p.tags['action'] = False

                        try:
                            g.process_action(PlayerTurn(p))
                        except InterruptActionFlow:
                            pass

                        if not [
                                p for p in attackers
                                if p.tags['action'] and not p.dead
                        ]:
                            break

            except MutantMorph:
                pass

            # morphing
            stage1 = mutant.__class__
            stage2 = stage1.stage2

            for s in stage1.skills:
                try:
                    mutant.skills.remove(s)
                except ValueError:
                    pass

            mutant.skills.extend(stage2.skills)

            ehclasses = g.ehclasses
            for s in stage1.eventhandlers_required:
                try:
                    ehclasses.remove(s)
                except ValueError:
                    pass

            ehclasses.extend(stage2.eventhandlers_required)

            g.process_action(
                MaxLifeChange(mutant, mutant, -(stage1.maxlife // 2)))
            mutant.morphed = True

            mutant.__class__ = stage2

            g.update_event_handlers()

            for p in attackers:
                g.process_action(CollectFaith(p, p, 1))

            g.process_action(DropCards(mutant, mutant.fatetell))

            g.emit_event('mutant_morph', mutant)

            g.pause(4)

            # stage 2
            for i in xrange(500):
                g.process_action(CollectFaith(mutant, mutant, 1))

                avail = [
                    p for p in attackers if not p.dead and len(p.faiths) < 5
                ]
                if avail:
                    p, _ = user_input(
                        avail,
                        ChooseOptionInputlet(GetFaith, (None, True)),
                        type='any',
                    )
                    p = p or avail[0]
                    g.process_action(CollectFaith(p, p, 1))

                g.emit_event('round_start', False)

                for p in attackers:
                    p.tags['action'] = True

                try:
                    g.process_action(PlayerTurn(mutant))
                except InterruptActionFlow:
                    pass

                while True:
                    avail = BatchList([
                        p for p in attackers if p.tags['action'] and not p.dead
                    ])
                    if not avail:
                        break

                    p, _ = user_input(avail,
                                      ChooseOptionInputlet(
                                          RequestAction, (None, True)),
                                      type='any')

                    p = p or avail[0]

                    p.tags['action'] = False
                    try:
                        g.process_action(PlayerTurn(p))
                    except InterruptActionFlow:
                        pass

        except GameEnded:
            pass

        winner_force = 'Mutant' if g.winners == [mutant] else 'Attackers'
        log.info(u'>> Winner: %s', winner_force)
예제 #13
0
    def game_start(g):
        # game started, init state
        from cards import Deck

        g.deck = Deck()

        g.ehclasses = ehclasses = list(
            action_eventhandlers) + g.game_ehs.values()

        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)

        # choose girls -->
        from . import characters
        chars = list(characters.characters)

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

        # ANCHOR(test)
        chars.extend([
            # characters.kokoro.Kokoro,
        ])

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

        for c in choices[:4]:
            c.char_cls = characters.akari.Akari

        if Game.SERVER_SIDE:
            for c, cls in zip(choices[:4],
                              g.random.sample(chars,
                                              4)):  # yes, must random.sample
                c.real_cls = cls

        # ----- roll ------
        roll = range(len(g.players))
        g.random.shuffle(roll)
        pl = g.players
        roll = sync_primitive(roll, pl)
        roll = [pl[i] for i in roll]
        g.emit_event('game_roll', roll)
        first = roll[0]
        g.emit_event('game_roll_result', first)
        # ----

        first_index = g.players.index(first)
        n = len(g.order_list)
        order = [g.players[(first_index + i) % n] for i in g.order_list]

        # akaris = {}  # DO NOT USE DICT! THEY ARE UNORDERED!
        akaris = []
        mapping = {p: choices for p in g.players}
        with InputTransaction('ChooseGirl', g.players,
                              mapping=mapping) as trans:
            for p in order:
                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

                if issubclass(c.char_cls, characters.akari.Akari):
                    akaris.append((p, c))
                else:
                    g.set_character(p, c.char_cls)

                trans.notify('girl_chosen', c)

        # reveal akaris
        if akaris:
            for p, c in akaris:
                c.char_cls = c.real_cls

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

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

        g.event_handlers = EventHandler.make_list(ehclasses)

        # -------
        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]

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

            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

        except GameEnded:
            pass

        log.info(u'>> Winner: %s',
                 Identity.TYPE.rlookup(g.winners[0].identity.type))
예제 #14
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
예제 #15
0
    def apply_action(self):
        g = Game.getgame()
        params = self.params

        from cards import Deck

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

        g.double_curtain = params['double_curtain']

        if g.double_curtain:
            g.identities = g.identities[1:] + g.identities[-1:]

        # choose girls init -->
        from .characters import get_characters
        chars = get_characters(*g.character_categories)
        from .characters.akari import Akari

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

        def choosed(char):
            try:
                chars.remove(char)
            except:
                pass

            try:
                testing.remove(char)
            except:
                pass

        def random_char():
            return g.random.choice(testing + chars)

        # choose boss
        candidates = g.random.sample(chars, 4)
        candidates.extend(testing)

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

        idx = sync_primitive(g.random.randrange(len(g.players)), g.players)
        boss = g.boss = g.players[idx]

        boss.identity = Identity()
        boss.identity.type = Identity.TYPE.BOSS

        g.process_action(RevealIdentity(boss, g.players))

        boss.choices = [CharChoice(c) for c in candidates]
        boss.choices.append(CharChoice(Akari))
        boss.reveal(boss.choices)

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

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

            if c.char_cls is Akari:
                c = CharChoice(random_char())
                g.players.reveal(c)

            choosed(c.char_cls)

            # 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

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

        # tell the others their own identity
        il = list(g.identities)
        g.random.shuffle(il)
        for p in g.players.exclude(boss):
            p.identity = Identity()
            id = il.pop()
            if Game.SERVER_SIDE:
                p.identity.type = id
            g.process_action(RevealIdentity(p, p))

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

        candidates = g.random.sample(chars, 3 * len(pl) - len(testing))
        candidates.extend(testing)
        g.random.shuffle(candidates)

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

        del c
        for p in pl:
            p.choices = [CharChoice(c) for c in candidates[:3]]
            p.choices.append(CharChoice(Akari))
            p.reveal(p.choices)
            del candidates[:3]

        mapping = {p: p.choices for p in pl}  # CAUTION, DICT HERE
        with InputTransaction('ChooseGirl', pl, mapping=mapping) as trans:
            ilet = ChooseGirlInputlet(g, mapping)
            ilet.with_post_process(
                lambda p, rst: trans.notify('girl_chosen', (p, rst)) or rst)
            result = user_input(pl, ilet, type='all', trans=trans)

        # not enough chars for random, reuse unselected
        for p in pl:
            if result[p]:
                result[p].chosen = p
                choosed(result[p].char_cls)

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

            if c.char_cls is Akari:
                c = CharChoice(random_char())
                g.players.reveal(c)

            choosed(c.char_cls)
            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))

        pl = g.players.rotate_to(boss)

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

        return True
예제 #16
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 characters import get_characters
        chars = get_characters('kof')

        testing = list(settings.TESTING_CHARACTERS)
        testing = filter_out(chars, lambda c: c.__name__ in testing)

        _chars = g.random.sample(chars, 10)
        _chars.extend(testing)

        from characters.akari import Akari
        if Game.SERVER_SIDE:
            choice = [CharChoice(cls) for cls in _chars[-10:]]

            for c in g.random.sample(choice, 4):
                c.real_cls = c.char_cls
                c.char_cls = Akari

        elif Game.CLIENT_SIDE:
            choice = [CharChoice(None) for i in xrange(10)]

        # -----------

        g.players.reveal(choice)

        # roll
        roll = range(len(g.players))
        g.random.shuffle(roll)
        pl = g.players
        roll = sync_primitive(roll, pl)

        roll = [pl[i] for i in roll]

        g.emit_event('game_roll', roll)

        first = roll[0]
        second = roll[1]

        g.emit_event('game_roll_result', first)
        # ----

        # akaris = {}  # DO NOT USE DICT! THEY ARE UNORDERED!
        akaris = []

        A, B = first, second
        order = [A, B, B, A, A, B, B, A, A, B]
        A.choices = []
        B.choices = []
        A.remaining = [2]
        B.remaining = [2]
        choice_mapping = {A: choice, B: choice}
        del A, B

        with InputTransaction('ChooseGirl', g.players,
                              mapping=choice_mapping) as trans:
            for p in order:
                c = user_input([p], ChooseGirlInputlet(g, choice_mapping), 10,
                               'single', trans)
                if not c:
                    # first non-chosen char
                    for c in choice:
                        if not c.chosen:
                            c.chosen = p
                            break

                if issubclass(c.char_cls, Akari):
                    akaris.append((p, c))

                c.chosen = p
                p.choices.append(c)

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

        # reveal akaris for themselves
        for p, c in akaris:
            c.char_cls = c.real_cls
            p.reveal(c)

        for c in choice:
            del c.chosen

        list_shuffle(first.choices, first)
        list_shuffle(second.choices, second)

        mapping = {first: first.choices, second: second.choices}

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

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

        first, second = s(first), s(second)

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

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

        g.emit_event('game_begin', g)

        for p in pl:
            g.process_action(DistributeCards(p, amount=4 if p is first else 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
예제 #17
0
파일: thbkof.py 프로젝트: zzkklep/thbattle
    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
예제 #18
0
    def game_start(g):
        # game started, init state

        from cards import Deck

        g.deck = Deck()

        g.ehclasses = []

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

        # choose girls -->
        from characters import characters as chars
        from characters.akari import Akari

        _chars = g.random.sample(chars, 10)
        if Game.SERVER_SIDE:
            choice = [CharChoice(cls) for cls in _chars[-10:]]

            for c in g.random.sample(choice, 4):
                c.real_cls = c.char_cls
                c.char_cls = Akari

        elif Game.CLIENT_SIDE:
            choice = [CharChoice(None) for i in xrange(10)]

        # -----------

        g.players.reveal(choice)

        # roll
        roll = range(len(g.players))
        g.random.shuffle(roll)
        pl = g.players
        roll = sync_primitive(roll, pl)

        roll = [pl[i] for i in roll]

        g.emit_event('game_roll', roll)

        first = roll[0]
        second = roll[1]

        g.emit_event('game_roll_result', first)
        # ----

        # akaris = {}  # DO NOT USE DICT! THEY ARE UNORDERED!
        akaris = []

        A, B = first, second
        order = [A, B, B, A, A, B, B, A, A, B]
        A.choices = []
        B.choices = []
        choice_mapping = {A: choice, B: choice}
        del A, B

        with InputTransaction('ChooseGirl', g.players,
                              mapping=choice_mapping) as trans:
            for p in order:
                c = user_input([p], ChooseGirlInputlet(g, choice_mapping), 10,
                               'single', trans)
                if not c:
                    # first non-chosen char
                    for c in choice:
                        if not c.chosen:
                            c.chosen = p
                            break

                if issubclass(c.char_cls, Akari):
                    akaris.append((p, c))

                c.chosen = p
                p.choices.append(c)

                trans.notify('girl_chosen', c)

        # reveal akaris for themselves
        for p, c in akaris:
            c.char_cls = c.real_cls
            p.reveal(c)

        for p in g.players:
            seed = get_seed_for(p)
            random.Random(seed).shuffle(p.choices)

        mapping = {first: first.choices, second: second.choices}
        rst = user_input(g.players,
                         KOFSortInputlet(g, mapping),
                         timeout=30,
                         type='all')

        for p in g.players:
            perm = p.choices
            perm = [  # weird snap for debug
                perm[i] for i in rst[p][:3]
            ]
            p.characters = [c.char_cls for c in perm]
            del p.choices

        first = g.next_character(first)
        second = g.next_character(second)

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

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

            g.emit_event('game_begin', g)

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

            for i, idx in enumerate(cycle(order)):
                p = g.players[idx]
                if i >= 6000: break
                if p.dead:
                    assert p.characters  # if not holds true, DeathHandler should end game.
                    KOFCharacterSwitchHandler.do_switch()

                assert not p.dead

                try:
                    g.emit_event('player_turn', p)
                    g.process_action(PlayerTurn(p))
                except InterruptActionFlow:
                    pass

        except GameEnded:
            pass
예제 #19
0
파일: thb3v3.py 프로젝트: zzkklep/thbattle
    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
예제 #20
0
    def game_start(g):
        # game started, init state
        from cards import Deck

        g.deck = Deck()

        g.ehclasses = ehclasses = list(
            action_eventhandlers) + _game_ehs.values()

        # choose girls init -->
        from .characters import characters as chars
        from .characters.akari import Akari

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

        g.random.shuffle(chars)

        # choose boss
        idx = sync_primitive(g.random.randrange(len(g.players)), g.players)
        boss = g.boss = g.players[idx]

        boss.identity = Identity()
        boss.identity.type = Identity.TYPE.BOSS

        g.process_action(RevealIdentity(boss, g.players))

        boss.choices = [CharChoice(c) for c in chars[:4]]
        boss.choices.append(CharChoice(Akari))
        del chars[:4]

        for p in g.players.exclude(boss):
            p.choices = [CharChoice(c) for c in chars[:3]]
            p.choices.append(CharChoice(Akari))
            del chars[:3]

        for p in g.players:
            p.reveal(p.choices)

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

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

            if c.char_cls is Akari:
                c = CharChoice(chars.pop())
                g.players.reveal(c)

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

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

            # boss's hp bonus
            if len(g.players) > 5:
                boss.maxlife += 1

            boss.life = boss.maxlife

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

        # tell the others their own identity
        il = list(g.identities)
        g.random.shuffle(il)
        for p in g.players.exclude(boss):
            p.identity = Identity()
            id = il.pop()
            if Game.SERVER_SIDE:
                p.identity.type = id
            g.process_action(RevealIdentity(p, p))

        pl = g.players.exclude(boss)
        mapping = {p: p.choices for p in pl}  # CAUTION, DICT HERE
        with InputTransaction('ChooseGirl', pl, mapping=mapping) as trans:
            ilet = ChooseGirlInputlet(g, mapping)
            ilet.with_post_process(
                lambda p, rst: trans.notify('girl_chosen', rst) or rst)
            result = user_input(pl, ilet, type='all', trans=trans)

        # not enough chars for random, reuse unselected
        for p in pl:
            if result[p]: result[p].chosen = p
            chars.extend([
                i.char_cls for i in p.choices
                if not i.chosen and i.char_cls is not Akari
            ])

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

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

            if c.char_cls is Akari:
                c = CharChoice(chars.pop())
                g.players.reveal(c)

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

        g.event_handlers = EventHandler.make_list(ehclasses)

        g.emit_event('game_begin', g)

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

            pl = g.players.rotate_to(boss)

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

        except GameEnded:
            pass
예제 #21
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
예제 #22
0
파일: thb3v3.py 프로젝트: yuzishui/thbattle
    def apply_action(self):
        g = Game.getgame()
        params = self.params

        from 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))

        # choose girls -->
        from . import characters
        chars = characters.get_characters('3v3')

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

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

        choices = [CharChoice(cls) for cls in chars[-16:]]
        del chars[-12:]

        for c in choices[:4]:
            c.char_cls = characters.akari.Akari

        if Game.SERVER_SIDE:
            for c, cls in zip(choices[:4],
                              g.random.sample(chars,
                                              4)):  # yes, must random.sample
                c.real_cls = cls

        # ----- roll ------
        roll = range(len(g.players))
        g.random.shuffle(roll)
        pl = g.players
        roll = sync_primitive(roll, pl)
        roll = [pl[i] for i in roll]
        g.emit_event('game_roll', roll)
        first = roll[0]
        g.emit_event('game_roll_result', first)
        # ----

        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 = {}  # DO NOT USE DICT! THEY ARE UNORDERED!
        akaris = []
        mapping = {p: choices for p in g.players}
        with InputTransaction('ChooseGirl', g.players,
                              mapping=mapping) as trans:
            for p in order:
                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

                if issubclass(c.char_cls, characters.akari.Akari):
                    akaris.append((p, c))
                else:
                    g.set_character(p, c.char_cls)

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

        # reveal akaris
        if akaris:
            for p, c in akaris:
                c.char_cls = c.real_cls

            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