def do_switch_dead(cls): g = Game.getgame() for p in [p for p in g.players if p.dead and p.choices]: new = cls.switch(p) g.process_action(DistributeCards(new, 4)) g.emit_event('character_debut', (p, new))
def handle(self, evt_type, act): if evt_type == 'action_apply' and isinstance(act, PlayerDeath): g = Game.getgame() tgt = act.target force = tgt.force if len(force.pool) <= 1: forces = g.forces[:] forces.remove(force) g.winners = forces[0][:] g.game_end() elif evt_type == 'action_after' and isinstance(act, PlayerDeath): g = Game.getgame() tgt = act.target pool = tgt.force.pool assert pool mapping = {tgt: pool} with InputTransaction('ChooseGirl', [tgt], mapping=mapping) as trans: c = user_input([tgt], ChooseGirlInputlet(g, mapping), timeout=30, trans=trans) c = c or [_c for _c in pool if not _c.chosen][0] c.chosen = tgt pool.remove(c) trans.notify('girl_chosen', (tgt, c)) tgt = g.switch_character(tgt, c) c = getattr(g, 'current_player', None) g.process_action(DistributeCards(tgt, 4)) if user_input([tgt], ChooseOptionInputlet(self, (False, True))): g.process_action(RedrawCards(tgt, tgt)) return act
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 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 apply_action(self): g = Game.getgame() params = self.params from cards import Deck g.picks = [] g.deck = Deck() g.ehclasses = list(action_eventhandlers) + g.game_ehs.values() H, M = Identity.TYPE.HAKUREI, Identity.TYPE.MORIYA if params['random_seat']: # reseat seed = get_seed_for(g.players) random.Random(seed).shuffle(g.players) g.emit_event('reseat', None) 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 L, s, rnd else: idlist = [H, M, H, M, H, M] del H, M 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 = characters.get_characters('faith') g.random.shuffle(chars) # ANCHOR(test) testing = list(settings.TESTING_CHARACTERS) testing = filter_out(chars, lambda c: c.__name__ in testing) chars = g.random.sample(chars, 30 - len(testing)) chars.extend(testing) 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} rst = user_input(g.players, SortCharacterInputlet(g, mapping, 2), timeout=30, type='all') for p in g.players: p.choices_chosen = [mapping[p][i] for i in rst[p][:2]] 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 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(DistributeCards(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 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() params = self.params from 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 ------ roll = range(len(pl)) g.random.shuffle(roll) roll = sync_primitive(roll, pl) roll = [pl[i] for i in roll] g.emit_event('game_roll', roll) for i in range(1, 3): if roll[i].force == roll[0].force: roll.append(roll.pop(i)) g.players[:] = roll g.emit_event('game_roll_result', g.players[0]) g.emit_event('reseat', None) # ---- # ban / choose girls --> from . import characters chars = characters.get_characters('2v2') 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) 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