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