# Coverage for thb/characters/kogasa.py : 96%

## 77 statements 75 run 2 missing 0 excluded 2 partial

Hot-keys on this page

r m x p toggle line displays

j k next/prev highlighted chunk

0 (zero) top of page

1 (one) first highlighted chunk

1# -*- coding: utf-8 -*-

2

3# -- stdlib --

4# -- third party --

5# -- own --

6 from thb.actions import Damage, DrawCardStage, DrawCards, UserAction, detach_cards, migrate_cards

7 from thb.actions import user_choose_players

8 from thb.cards.base import Card, Skill, VirtualCard

9 from thb.cards.classes import t_None, t_OtherOne

10 from thb.characters.base import Character, register_character_to

11 from thb.inputlets import ChooseOptionInputlet

12 from thb.mode import THBEventHandler

13

14

15# -- code --

16 class Jolly(Skill):

17 associated_action = None

18 skill_category = ['character', 'passive', 'compulsory']

19 target = t_None()

20

21

22 class SurpriseAction(UserAction):

23

24 def apply_action(self):

25 src = self.source

26 tgt = self.target

27 options = (

28 Card.SPADE, Card.HEART,

29 Card.CLUB, Card.DIAMOND,

30 )

31

32 card = self.associated_card

33 detach_cards([card])

34 g = self.game

35 suit = g.user_input([tgt], ChooseOptionInputlet(self, options))

36

37 src.tags['surprise_tag'] = src.tags['turn_count']

38 assert card

39

40 g.players.reveal(card.associated_cards)

41 migrate_cards([card], tgt.showncards, unwrap=True)

42

43 if card.suit != suit:

44 g.process_action(Damage(src, tgt))

45 rst = True

46 else:

47 rst = False

48

49 return rst

50

51 def is_valid(self):

52 t = self.source.tags

53 if t['turn_count'] <= t['surprise_tag']: return False

54 return True

55

56

57 class Surprise(Skill):

58 associated_action = SurpriseAction

59 skill_category = ['character', 'active']

60 target = t_OtherOne()

61 no_reveal = True

62 no_drop = True

63 usage = 'handover'

64

65 def check(self):

66 cl = self.associated_cards

67 if not len(cl) == 1: return False

68 c, = cl

69 if c.is_card(VirtualCard): 69 ↛ 70 line 69 didn't jump to line 70, because the condition on line 69 was never true

70 return False

71

72 if c.resides_in.type not in ('cards', 'showncards'):

73 return False

74

75 return True

76

77

78 class JollyDrawCard(DrawCards):

79 def __init__(self, source, target):

80 self.source = source

81 self.target = target

82 self.amount = 1

83 self.back = False

84

85

86 class JollyHandler(THBEventHandler):

87 interested = ['action_after']

88

89 def handle(self, evt_type, act):

90 if evt_type == 'action_after' and isinstance(act, DrawCardStage):

91 tgt = act.target

92

93 if not tgt.has_skill(Jolly): return act

94

95 g = self.game

96 pl = user_choose_players(self, tgt, [p for p in g.players if not p.dead])

97 if not pl: pl = [tgt]

98

99 p = pl[0]

100

101 g.process_action(JollyDrawCard(tgt, p))

102

103 return act

104

105 def cond(self, cards):

106 return not cards

107

108 def choose_player_target(self, tl):

109 if not tl: return (tl, False) 109 ↛ exit line 109 didn't return from function 'choose_player_target', because the return on line 109 wasn't executed

110 return (tl[-1:], True)

111

112

113@register_character_to('common')

114 class Kogasa(Character):

115 skills = [Surprise, Jolly]

116 eventhandlers = [JollyHandler]

117 maxlife = 3