-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy patheffects.py
More file actions
271 lines (238 loc) · 11.1 KB
/
Copy patheffects.py
File metadata and controls
271 lines (238 loc) · 11.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
from constants import option
import globe
from constants import ai_hint
from constants import trigger
from frames import card_frame, persona_frame
import model
from typing import Union
import enum
"""
effects.py is the intercafe bettween the cointroelrs (player and/or ai's) and the cards
Cards call different an effects function when a choice has to be made by a player
These functions then ask the coresponding controler, who then returns a result.
The result is then verified, and a program friendly answer is returned
The common uses for effects is:
attack (where a choice to defend if possible is implied)
choose a player
choose a card (from a provided list of cards)
may choose a card (same as choose a card except the player can choose none)
ok or no (Boolean questions)
even or odd (This is a special one for the riddler. Maybe i should alloe ok_or_no to cover this)
choose_however_many (allows the player to choose from none to all of the cards listed)
reveal. This is a special one, as it dosnt actaully ask a question, but just reveals somehting to a player,
Like what was in an opponents hand, or what was on top of their deck, ect.
"""
# deprecited. i guess i forgot about .copy()
def new_assemble(list):
assemble = []
for i in list:
assemble.append(i)
return assemble
def ensure_int(i):
if not type(i) is int:
print("ERR: not an integer")
return False
else:
return True
# depreciated
def attack_all(card):
total_hit = 0
for p in globe.boss.players:
if attack(p, card):
total_hit += 1
return total_hit
# Returns true if hit by attack
def attack(player, card: card_frame.card, by_player=None, avoid_twise: bool = False, cannot_defend_with=None):
if by_player is not None:
# Triggers that dosn't affect the parent code return None
# if the trigger wants to override this attack, it returns
# True or False
result = trigger.all(trigger.ATTACKING, [player, card], by_player, first_result=True)
if result is not None:
return result
# Looks for any available defense cards
assemble = []
for c in player.hand.contents:
if c.defense and not c.ongoing:
assemble.append(c)
for c in player.ongoing.contents:
if c.defense:
assemble.append(c)
# Just used so that the AI's dont get caught in an infinite loop if a card fails to defend
if cannot_defend_with is not None:
for c in cannot_defend_with:
if c in assemble:
assemble.remove(c)
# If there are any defense cards, ask the defender if they would like to use one of them
if len(assemble) > 0:
result = player.controler.may_defend(assemble, card, by_player)
if result[0] == option.OK:
if not ensure_int(result[1]):
return attack(player, card, by_player, avoid_twise=avoid_twise, cannot_defend_with=cannot_defend_with)
elif result[1] < 0 or result[1] >= len(assemble):
print("Err: invalid number")
return attack(player, card, by_player, avoid_twise=avoid_twise, cannot_defend_with=cannot_defend_with)
else:
# Attack avoided
did_defend = assemble[result[1]].defend(attacker=by_player, defender=player)
if did_defend is not None and did_defend is False:
print("Err: Card did not defend.")
if cannot_defend_with is None:
cannot_defend_with = [assemble[result[1]]]
else:
cannot_defend_with.append(assemble[result[1]])
return attack(player, card, by_player, avoid_twise=avoid_twise, cannot_defend_with=cannot_defend_with)
# avoid twise, like in crossover 2's deadshot
if avoid_twise:
return attack(player, card, by_player, avoid_twise=False, cannot_defend_with=cannot_defend_with)
else:
# If you avoid the attack but not twise when nessesary (crossover 2's deadshot)
# do you get to trigger your avoided attack abilities?
# player.persona.avoided_attack(assemble[result[1]])
# sent to the defending player
trigger.all(trigger.AVOIDED_ATTACK, [by_player, card, assemble[result[1]]], player,
first_result=True)
return False
elif result[0] == option.NO:
if by_player != None:
# Sent to the attacking player
result = trigger.all(trigger.FAILED_TO_AVOID, [player, card], by_player, first_result=True)
# by_player.persona.failed_to_avoid_power()
return True
else:
print("Err: responce")
return attack(player, card, by_player)
else:
if by_player is not None:
result = trigger.all(trigger.FAILED_TO_AVOID, [player, card], by_player, first_result=True)
# by_player.persona.failed_to_avoid_power()
return True
def choose_a_player(instruction_text: str, player, includes_self: bool = True,
hint: ai_hint = ai_hint.WORST, source: Union[card_frame.card, persona_frame.persona] = None):
assemble = []
for i, p in enumerate(globe.boss.players):
if p != player or includes_self:
assemble.append(p.persona)
result = player.controler.choose_a_player(instruction_text, player, assemble, hint, source=source)
if globe.DEBUG:
print("choose_a_player", result)
if not ensure_int(result):
return choose_a_player(instruction_text, player, includes_self)
elif result < 0 or result >= len(assemble):
print(f"ERR: invalid number. max:{len(assemble) - 1}")
return choose_a_player(instruction_text, player, includes_self)
return assemble[result].player
def choose_one_of(instruction_text, player, cards: Union[list[card_frame.card], enum.Enum], hint=ai_hint.WORST,
source=None) -> card_frame.card:
result = player.controler.choose_one_of(instruction_text, player, cards, hint, source=source)
if globe.DEBUG:
print("choose_one_of", result)
if type(result[0]) == int:
# return
# if not ensure_int(result[0]):
# return choose_one_of(instruction_text, player, cards)
if result[0] < 0 or result[0] >= len(cards):
print(f"ERR: invalid number. max:{len(cards) - 1}")
return choose_one_of(instruction_text, player, cards)
return cards[result[0]]
elif result[0] in cards:
return result[0]
print(f"ERR: invalid responce code. Got {result}, not in {cards}.")
return choose_one_of(instruction_text, player, cards)
def may_choose_one_of(instruction_text, player, cards: Union[list[card_frame.card], list[enum.Enum]], hint=ai_hint.BEST,
source=None) -> card_frame.card:
if len(cards) == 0:
return None
result = player.controler.may_choose_one_of(instruction_text, player, cards, hint, source=source)
if globe.DEBUG:
print("may_choose_one_of", result)
if result[0] == option.NO or len(result) == 0:
return None
elif result[0] == option.OK:
if not ensure_int(result[1]):
return may_choose_one_of(instruction_text, player, cards, hint, source)
elif result[1] < 0 or result[1] >= len(cards):
print(f"ERR: invalid number. max:{len(cards) - 1}")
return may_choose_one_of(instruction_text, player, cards, hint, source)
return cards[result[1]]
elif result[0] in cards:
return result[0]
else:
print(f"ERR: invalid responce code. Got {result[0]}, not in {cards}.")
return may_choose_one_of(instruction_text, player, cards, hint, source)
def ok_or_no(instruction_text, player, card=None, hint=ai_hint.IFBAD):
result = player.controler.ok_or_no(instruction_text, player, card, hint)
if globe.DEBUG:
print("ok_or_no", result)
if result[0] == option.OK:
return True
elif result[0] == option.NO:
return False
else:
print(f"ERR: invalid responce code")
return ok_or_no(instruction_text, player, hint)
def reveal(reveal_text, player, cards):
for p in globe.boss.players:
p.controler.reveal(reveal_text, player, cards)
# True for even
def choose_even_or_odd(instruction_text, player):
result = player.controler.choose_even_or_odd(instruction_text, player)
if globe.DEBUG:
print("choose_even_or_odd", result)
if result[0] == option.EVEN:
return True
if result[0] == option.ODD:
return False
else:
return choose_even_or_odd(instruction_text, player)
# depreciated
# (no/hand/disccard, if hand or discard: #)
def may_destroy_card_in_hand_or_discard(player):
result = player.controler.may_destroy_card_in_hand_or_discard()
if globe.DEBUG:
print("may_destroy_card_in_hand_or_discard", result)
if len(result) != 2:
print("ERR: not 2 attributes")
return may_destroy_card_in_hand_or_discard(player)
if result[0] == option.NO:
return (option.NO,)
elif result[0] == option.HAND or result[0] == option.DISCARD:
if not ensure_int(result[1]):
return may_destroy_card_in_hand_or_discard(player)
elif result[0] == option.HAND and (result[1] < 0 or result[1] >= player.hand.size()):
print(f"ERR: invalid number. max:{player.hand.size() - 1}")
return may_destroy_card_in_hand_or_discard(player)
elif result[0] == option.DISCARD and (result[1] < 0 or result[1] >= player.discard.size()):
print(f"ERR: invalid number. max:{player.discard.size() - 1}")
return may_destroy_card_in_hand_or_discard(player)
card_to_destroy = None
if result[0] == option.HAND:
card_to_destroy = player.hand.contents.pop(result[1])
else:
card_to_destroy = player.discard.contents.pop(result[1])
card_to_destroy.destroy()
return (result[0], card_to_destroy)
else:
print(f"ERR: invalid responce code: {result[0]}")
return may_destroy_card_in_hand_or_discard(player)
def choose_however_many(instruction_text, player, cards, hint):
result = player.controler.choose_however_many(instruction_text, player, cards, hint=ai_hint.IFBAD)
if globe.DEBUG:
print("choose_however_many", result)
if result[0] == option.NO:
return None
elif result[0] == option.OK:
assemble = []
for r in result[1:]:
# print("FJFHJFHFHFHF",r)
if not ensure_int(r):
print(f"ERR: invalid symbol {r}.")
return choose_however_many(instruction_text, player, cards, hint)
elif r < 0 or r >= len(cards):
print(f"ERR: invalid number {r}. max:{len(cards) - 1}")
return choose_however_many(instruction_text, player, cards, hint)
assemble.append(cards[r])
return assemble
else:
print(f"ERR: invalid responce code: {result[0]}")
return choose_however_many(instruction_text, player, cards, hint)