-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path22.coffee
191 lines (161 loc) · 3 KB
/
22.coffee
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
_log = require 'ololog'
input = '''
Hit Points: 58
Damage: 9
'''
apply_effects = ( state )->
state.p.def = 0
ne = {}
for k, v of state.p.e ? {}
state.b.hp -= v.a if v.a?
state.p.def += v.def if v.def?
state.p.mp += v.mp if v.mp?
if --v.len > 0
ne[k] = v
state.p.e = ne
state.b.hp <= 0
cast = ( state, sp )->
if state.p.mp < sp.c
return no
if sp.e? and state.p.e[sp.i]?
return no
state.p.mp -= sp.c
state.p.c += sp.c
state.b.hp -= sp.a if sp.a?
state.p.hp += sp.hp if sp.hp?
if sp.e?
state.p.e[sp.i] = Object.assign {}, sp.e
yes
last_dump = undefined
dumped = 0
dump = ( label, state, track )->
if track? and state.id is track[...state.id.length]
json = JSON.stringify state
if last_dump is json
_log label, 'unchanged'
else
if ++dumped%2
_log.yellow label, state
else
_log.lightYellow label, state
last_dump = json
return
find_min_mana_to_win = ( state, sps, hard, track )->
next = [JSON.stringify state]
min = Infinity
min_id = ''
while next.length > 0
#_log.darkGray 'spread', next.length
last = next
next = []
for json in last
state = JSON.parse json
if hard and --state.p.hp <= 0
continue
dump 'init', state, track
#
# 0. check if fight can become leader in cost-efficiency
#
unless state.p.c < min
continue
#
# 1. apply effects for player's turn
#
if apply_effects state
dump 'effect 1: win', state, track
min = state.p.c
min_id = state.id
_log.yellow min, min_id
continue
dump 'effect 1', state, track
# 2. save, as it will get loaded for each spell
json = JSON.stringify state
#
# 3. fight
#
for sp in sps
state = JSON.parse json
state.id += sp.i
#
# 3.1 Player's turn: cast a spell
#
unless cast( state, sp ) and state.p.c < min
continue
# 3.2 check for dead boss
if state.b.hp <= 0
dump 'cast: win', state, track
min = state.p.c
min_id = state.id
_log.cyan min, min_id
continue
dump 'cast', state, track
# 3.3 apply effects for boss's turn
if apply_effects state
dump 'effect 2: win', state, track
min = state.p.c
min_id = state.id
_log.red min, min_id
continue
dump 'effect 2', state, track
# 3.4 Boss' turn
if (state.p.hp -= state.b.a - state.p.def) <= 0
continue
dump 'def', state, track
# 3.5 save
next.push JSON.stringify state
_log 'best id', min_id
min
do ->
try
boss =
hp: 58
a: 9
player =
hp: 50
mp: 500
def: 0
e: {}
c: 0
spells = [
{
c: 53
a: 4
i: 0
}
{
c: 73
a: 2
hp: 2
i: 1
}
{
c: 113
i: 2
e:
len: 6
def: 7
}
{
c: 173
i: 3
e:
len: 6
a: 3
}
{
c: 229
i: 4
e:
len: 5
mp: 101
}
]
state =
id:''
p:player
b:boss
_log.green find_min_mana_to_win state, spells, no #, '304324310'
_log.green find_min_mana_to_win state, spells, yes #, '342342300'
catch e
_log.red e
return