Fixed typo
[advent-of-code-15.git] / advent22.ipynb
1 {
2 "cells": [
3 {
4 "cell_type": "code",
5 "execution_count": 1,
6 "metadata": {
7 "collapsed": true
8 },
9 "outputs": [],
10 "source": [
11 "import copy"
12 ]
13 },
14 {
15 "cell_type": "code",
16 "execution_count": 2,
17 "metadata": {
18 "collapsed": false
19 },
20 "outputs": [
21 {
22 "data": {
23 "text/plain": [
24 "[{'boss_hp': -4, 'cost': 53, 'name': 'Magic missile'},\n",
25 " {'boss_hp': -2, 'cost': 73, 'name': 'Drain', 'pc_hp': 2},\n",
26 " {'cost': 113,\n",
27 " 'name': 'Shield',\n",
28 " 'ongoing': [{'armour': 7},\n",
29 " {'armour': 7},\n",
30 " {'armour': 7},\n",
31 " {'armour': 7},\n",
32 " {'armour': 7},\n",
33 " {'armour': 7}]},\n",
34 " {'cost': 173,\n",
35 " 'name': 'Poison',\n",
36 " 'ongoing': [{'boss_hp': -3},\n",
37 " {'boss_hp': -3},\n",
38 " {'boss_hp': -3},\n",
39 " {'boss_hp': -3},\n",
40 " {'boss_hp': -3},\n",
41 " {'boss_hp': -3}]},\n",
42 " {'cost': 229,\n",
43 " 'name': 'Recharge',\n",
44 " 'ongoing': [{'mana': 101},\n",
45 " {'mana': 101},\n",
46 " {'mana': 101},\n",
47 " {'mana': 101},\n",
48 " {'mana': 101}]}]"
49 ]
50 },
51 "execution_count": 2,
52 "metadata": {},
53 "output_type": "execute_result"
54 }
55 ],
56 "source": [
57 "spells = [\n",
58 " {'name': 'Magic missile', 'cost': 53, 'boss_hp': -4},\n",
59 " {'name': 'Drain', 'cost': 73, 'boss_hp': -2, 'pc_hp': 2},\n",
60 " {'name': 'Shield', 'cost': 113, 'ongoing': [{'armour': 7}] * 6},\n",
61 " {'name': 'Poison', 'cost': 173, 'ongoing': [{'boss_hp': -3}] * 6},\n",
62 " {'name': 'Recharge', 'cost': 229, 'ongoing': [{'mana': 101}] * 5}]\n",
63 "spells"
64 ]
65 },
66 {
67 "cell_type": "code",
68 "execution_count": 3,
69 "metadata": {
70 "collapsed": false
71 },
72 "outputs": [],
73 "source": [
74 "initial_state = {'pc_hp': 50, 'mana': 500, 'boss_hp': 58, 'boss_damage': 9, 'ongoing': [], \n",
75 " 'spent': 0, 'cast': []}"
76 ]
77 },
78 {
79 "cell_type": "code",
80 "execution_count": 4,
81 "metadata": {
82 "collapsed": true
83 },
84 "outputs": [],
85 "source": [
86 "def cast_spell(spell, state):\n",
87 " new_state = copy.deepcopy(state)\n",
88 " new_state['mana'] -= spell['cost']\n",
89 " new_state['spent'] += spell['cost']\n",
90 " new_state['cast'] += [spell['name']]\n",
91 " if 'boss_hp' in spell:\n",
92 " new_state['boss_hp'] += spell['boss_hp']\n",
93 " if 'pc_hp' in spell:\n",
94 " new_state['pc_hp'] += spell['pc_hp']\n",
95 " if 'ongoing' in spell:\n",
96 " new_state['ongoing'] += [spell['ongoing']]\n",
97 " return new_state"
98 ]
99 },
100 {
101 "cell_type": "code",
102 "execution_count": 5,
103 "metadata": {
104 "collapsed": false
105 },
106 "outputs": [
107 {
108 "data": {
109 "text/plain": [
110 "{'boss_damage': 9,\n",
111 " 'boss_hp': 54,\n",
112 " 'cast': ['Magic missile'],\n",
113 " 'mana': 447,\n",
114 " 'ongoing': [],\n",
115 " 'pc_hp': 50,\n",
116 " 'spent': 53}"
117 ]
118 },
119 "execution_count": 5,
120 "metadata": {},
121 "output_type": "execute_result"
122 }
123 ],
124 "source": [
125 "cast_spell(spells[0], initial_state)"
126 ]
127 },
128 {
129 "cell_type": "code",
130 "execution_count": 6,
131 "metadata": {
132 "collapsed": false
133 },
134 "outputs": [
135 {
136 "data": {
137 "text/plain": [
138 "{'boss_damage': 9,\n",
139 " 'boss_hp': 58,\n",
140 " 'cast': [],\n",
141 " 'mana': 500,\n",
142 " 'ongoing': [],\n",
143 " 'pc_hp': 50,\n",
144 " 'spent': 0}"
145 ]
146 },
147 "execution_count": 6,
148 "metadata": {},
149 "output_type": "execute_result"
150 }
151 ],
152 "source": [
153 "initial_state"
154 ]
155 },
156 {
157 "cell_type": "code",
158 "execution_count": 7,
159 "metadata": {
160 "collapsed": false
161 },
162 "outputs": [
163 {
164 "data": {
165 "text/plain": [
166 "{'boss_damage': 9,\n",
167 " 'boss_hp': 58,\n",
168 " 'cast': ['Shield', 'Poison'],\n",
169 " 'mana': 214,\n",
170 " 'ongoing': [[{'armour': 7},\n",
171 " {'armour': 7},\n",
172 " {'armour': 7},\n",
173 " {'armour': 7},\n",
174 " {'armour': 7},\n",
175 " {'armour': 7}],\n",
176 " [{'boss_hp': -3},\n",
177 " {'boss_hp': -3},\n",
178 " {'boss_hp': -3},\n",
179 " {'boss_hp': -3},\n",
180 " {'boss_hp': -3},\n",
181 " {'boss_hp': -3}]],\n",
182 " 'pc_hp': 50,\n",
183 " 'spent': 286}"
184 ]
185 },
186 "execution_count": 7,
187 "metadata": {},
188 "output_type": "execute_result"
189 }
190 ],
191 "source": [
192 "s2 = cast_spell(spells[2], initial_state)\n",
193 "cast_spell(spells[3], s2)"
194 ]
195 },
196 {
197 "cell_type": "code",
198 "execution_count": 37,
199 "metadata": {
200 "collapsed": false
201 },
202 "outputs": [],
203 "source": [
204 "def valid_spells(spells, state):\n",
205 " valid_spells = []\n",
206 " for spell in spells:\n",
207 " add_this_spell = True\n",
208 " if spell['cost'] > state['mana']:\n",
209 " add_this_spell = False\n",
210 " if 'ongoing' in spell:\n",
211 " for s in spell['ongoing'][0]:\n",
212 " for status in state['ongoing']:\n",
213 " if s in status[0]:\n",
214 " add_this_spell = False\n",
215 " if spell['name'] == 'Magic missile' and state['cast'] and state['cast'][-1] == 'Drain':\n",
216 " add_this_spell = False\n",
217 " if add_this_spell:\n",
218 " valid_spells += [spell]\n",
219 " return valid_spells"
220 ]
221 },
222 {
223 "cell_type": "code",
224 "execution_count": 57,
225 "metadata": {
226 "collapsed": false
227 },
228 "outputs": [
229 {
230 "data": {
231 "text/plain": [
232 "[{'boss_hp': -4, 'cost': 53, 'name': 'Magic missile'},\n",
233 " {'boss_hp': -2, 'cost': 73, 'name': 'Drain', 'pc_hp': 2},\n",
234 " {'cost': 113,\n",
235 " 'name': 'Shield',\n",
236 " 'ongoing': [{'armour': 7},\n",
237 " {'armour': 7},\n",
238 " {'armour': 7},\n",
239 " {'armour': 7},\n",
240 " {'armour': 7},\n",
241 " {'armour': 7}]},\n",
242 " {'cost': 173,\n",
243 " 'name': 'Poison',\n",
244 " 'ongoing': [{'boss_hp': -3},\n",
245 " {'boss_hp': -3},\n",
246 " {'boss_hp': -3},\n",
247 " {'boss_hp': -3},\n",
248 " {'boss_hp': -3},\n",
249 " {'boss_hp': -3}]},\n",
250 " {'cost': 229,\n",
251 " 'name': 'Recharge',\n",
252 " 'ongoing': [{'mana': 101},\n",
253 " {'mana': 101},\n",
254 " {'mana': 101},\n",
255 " {'mana': 101},\n",
256 " {'mana': 101}]}]"
257 ]
258 },
259 "execution_count": 57,
260 "metadata": {},
261 "output_type": "execute_result"
262 }
263 ],
264 "source": [
265 "valid_spells(spells, initial_state)"
266 ]
267 },
268 {
269 "cell_type": "code",
270 "execution_count": 58,
271 "metadata": {
272 "collapsed": false
273 },
274 "outputs": [
275 {
276 "data": {
277 "text/plain": [
278 "{'boss_damage': 9,\n",
279 " 'boss_hp': 58,\n",
280 " 'cast': ['Shield', 'Poison'],\n",
281 " 'mana': 214,\n",
282 " 'ongoing': [[{'armour': 7},\n",
283 " {'armour': 7},\n",
284 " {'armour': 7},\n",
285 " {'armour': 7},\n",
286 " {'armour': 7},\n",
287 " {'armour': 7}],\n",
288 " [{'boss_hp': -3},\n",
289 " {'boss_hp': -3},\n",
290 " {'boss_hp': -3},\n",
291 " {'boss_hp': -3},\n",
292 " {'boss_hp': -3},\n",
293 " {'boss_hp': -3}]],\n",
294 " 'pc_hp': 50,\n",
295 " 'spent': 286}"
296 ]
297 },
298 "execution_count": 58,
299 "metadata": {},
300 "output_type": "execute_result"
301 }
302 ],
303 "source": [
304 "s2 = cast_spell(spells[2], initial_state)\n",
305 "s3 = cast_spell(spells[3], s2)\n",
306 "s3"
307 ]
308 },
309 {
310 "cell_type": "code",
311 "execution_count": 59,
312 "metadata": {
313 "collapsed": false
314 },
315 "outputs": [
316 {
317 "data": {
318 "text/plain": [
319 "[{'boss_hp': -4, 'cost': 53, 'name': 'Magic missile'},\n",
320 " {'boss_hp': -2, 'cost': 73, 'name': 'Drain', 'pc_hp': 2}]"
321 ]
322 },
323 "execution_count": 59,
324 "metadata": {},
325 "output_type": "execute_result"
326 }
327 ],
328 "source": [
329 "valid_spells(spells, s3)"
330 ]
331 },
332 {
333 "cell_type": "code",
334 "execution_count": 60,
335 "metadata": {
336 "collapsed": false
337 },
338 "outputs": [
339 {
340 "data": {
341 "text/plain": [
342 "[{'boss_hp': -2, 'cost': 73, 'name': 'Drain', 'pc_hp': 2}]"
343 ]
344 },
345 "execution_count": 60,
346 "metadata": {},
347 "output_type": "execute_result"
348 }
349 ],
350 "source": [
351 "s4 = cast_spell(spells[1], s3)\n",
352 "valid_spells(spells, s4)"
353 ]
354 },
355 {
356 "cell_type": "code",
357 "execution_count": 61,
358 "metadata": {
359 "collapsed": false
360 },
361 "outputs": [
362 {
363 "data": {
364 "text/plain": [
365 "[{'boss_hp': -4, 'cost': 53, 'name': 'Magic missile'},\n",
366 " {'boss_hp': -2, 'cost': 73, 'name': 'Drain', 'pc_hp': 2}]"
367 ]
368 },
369 "execution_count": 61,
370 "metadata": {},
371 "output_type": "execute_result"
372 }
373 ],
374 "source": [
375 "s4 = cast_spell(spells[0], s3)\n",
376 "valid_spells(spells, s4)"
377 ]
378 },
379 {
380 "cell_type": "code",
381 "execution_count": 12,
382 "metadata": {
383 "collapsed": true
384 },
385 "outputs": [],
386 "source": [
387 "def boss_turn(state):\n",
388 " new_state = apply_ongoing(state)\n",
389 " if new_state['boss_hp'] > 0:\n",
390 " new_state['pc_hp'] -= max(new_state['boss_damage'] - new_state['armour'], 1)\n",
391 " return new_state"
392 ]
393 },
394 {
395 "cell_type": "code",
396 "execution_count": 13,
397 "metadata": {
398 "collapsed": true
399 },
400 "outputs": [],
401 "source": [
402 "def apply_ongoing(state):\n",
403 " new_state = copy.deepcopy(state)\n",
404 " new_state['armour'] = 0\n",
405 " new_state['ongoing'] = []\n",
406 " for status in state['ongoing']:\n",
407 " for k in status[0]:\n",
408 " new_state[k] += status[0][k]\n",
409 " if len(status) > 1:\n",
410 " new_state['ongoing'] += [status[1:]]\n",
411 " return new_state"
412 ]
413 },
414 {
415 "cell_type": "code",
416 "execution_count": 44,
417 "metadata": {
418 "collapsed": false
419 },
420 "outputs": [
421 {
422 "data": {
423 "text/plain": [
424 "{'armour': 7,\n",
425 " 'boss_damage': 9,\n",
426 " 'boss_hp': 55,\n",
427 " 'cast': ['Shield', 'Poison'],\n",
428 " 'mana': 214,\n",
429 " 'ongoing': [[{'armour': 7},\n",
430 " {'armour': 7},\n",
431 " {'armour': 7},\n",
432 " {'armour': 7},\n",
433 " {'armour': 7}],\n",
434 " [{'boss_hp': -3},\n",
435 " {'boss_hp': -3},\n",
436 " {'boss_hp': -3},\n",
437 " {'boss_hp': -3},\n",
438 " {'boss_hp': -3}]],\n",
439 " 'pc_hp': 48,\n",
440 " 'spent': 286}"
441 ]
442 },
443 "execution_count": 44,
444 "metadata": {},
445 "output_type": "execute_result"
446 }
447 ],
448 "source": [
449 "boss_turn(s3)"
450 ]
451 },
452 {
453 "cell_type": "code",
454 "execution_count": 45,
455 "metadata": {
456 "collapsed": false
457 },
458 "outputs": [
459 {
460 "data": {
461 "text/plain": [
462 "{'armour': 0,\n",
463 " 'boss_damage': 8,\n",
464 " 'boss_hp': 10,\n",
465 " 'cast': ['Poison'],\n",
466 " 'mana': 77,\n",
467 " 'ongoing': [[{'boss_hp': -3},\n",
468 " {'boss_hp': -3},\n",
469 " {'boss_hp': -3},\n",
470 " {'boss_hp': -3},\n",
471 " {'boss_hp': -3}]],\n",
472 " 'pc_hp': 2,\n",
473 " 'spent': 173}"
474 ]
475 },
476 "execution_count": 45,
477 "metadata": {},
478 "output_type": "execute_result"
479 }
480 ],
481 "source": [
482 "test_state_1 = {'pc_hp': 10, 'mana': 250, 'boss_hp': 13, 'boss_damage': 8, 'ongoing': [], 'spent': 0, 'cast': []}\n",
483 "s2 = cast_spell([s for s in spells if s['name'] == 'Poison'][0], test_state_1)\n",
484 "s3 = boss_turn(s2)\n",
485 "s3"
486 ]
487 },
488 {
489 "cell_type": "code",
490 "execution_count": 46,
491 "metadata": {
492 "collapsed": false
493 },
494 "outputs": [
495 {
496 "data": {
497 "text/plain": [
498 "{'armour': 0,\n",
499 " 'boss_damage': 8,\n",
500 " 'boss_hp': 0,\n",
501 " 'cast': ['Poison', 'Magic missile'],\n",
502 " 'mana': 24,\n",
503 " 'ongoing': [[{'boss_hp': -3}, {'boss_hp': -3}, {'boss_hp': -3}]],\n",
504 " 'pc_hp': 2,\n",
505 " 'spent': 226}"
506 ]
507 },
508 "execution_count": 46,
509 "metadata": {},
510 "output_type": "execute_result"
511 }
512 ],
513 "source": [
514 "s4 = apply_ongoing(s3)\n",
515 "s5 = cast_spell([s for s in spells if s['name'] == 'Magic missile'][0], s4)\n",
516 "s6 = boss_turn(s5)\n",
517 "s6"
518 ]
519 },
520 {
521 "cell_type": "code",
522 "execution_count": 47,
523 "metadata": {
524 "collapsed": false
525 },
526 "outputs": [
527 {
528 "data": {
529 "text/plain": [
530 "{'armour': 0,\n",
531 " 'boss_damage': 8,\n",
532 " 'boss_hp': 14,\n",
533 " 'cast': ['Recharge'],\n",
534 " 'mana': 122,\n",
535 " 'ongoing': [[{'mana': 101}, {'mana': 101}, {'mana': 101}, {'mana': 101}]],\n",
536 " 'pc_hp': 2,\n",
537 " 'spent': 229}"
538 ]
539 },
540 "execution_count": 47,
541 "metadata": {},
542 "output_type": "execute_result"
543 }
544 ],
545 "source": [
546 "test_state_2 = {'pc_hp': 10, 'mana': 250, 'boss_hp': 14, 'boss_damage': 8, 'ongoing': [], 'spent': 0, 'cast': []}\n",
547 "s2 = cast_spell([s for s in spells if s['name'] == 'Recharge'][0], test_state_2)\n",
548 "s3 = boss_turn(s2)\n",
549 "s3"
550 ]
551 },
552 {
553 "cell_type": "code",
554 "execution_count": 48,
555 "metadata": {
556 "collapsed": false
557 },
558 "outputs": [
559 {
560 "data": {
561 "text/plain": [
562 "{'armour': 7,\n",
563 " 'boss_damage': 8,\n",
564 " 'boss_hp': 14,\n",
565 " 'cast': ['Recharge', 'Shield'],\n",
566 " 'mana': 211,\n",
567 " 'ongoing': [[{'mana': 101}, {'mana': 101}],\n",
568 " [{'armour': 7}, {'armour': 7}, {'armour': 7}, {'armour': 7}, {'armour': 7}]],\n",
569 " 'pc_hp': 1,\n",
570 " 'spent': 342}"
571 ]
572 },
573 "execution_count": 48,
574 "metadata": {},
575 "output_type": "execute_result"
576 }
577 ],
578 "source": [
579 "s4 = apply_ongoing(s3)\n",
580 "s5 = cast_spell([s for s in spells if s['name'] == 'Shield'][0], s4)\n",
581 "s6 = boss_turn(s5)\n",
582 "s6"
583 ]
584 },
585 {
586 "cell_type": "code",
587 "execution_count": 49,
588 "metadata": {
589 "collapsed": false
590 },
591 "outputs": [
592 {
593 "data": {
594 "text/plain": [
595 "{'armour': 7,\n",
596 " 'boss_damage': 8,\n",
597 " 'boss_hp': 12,\n",
598 " 'cast': ['Recharge', 'Shield', 'Drain'],\n",
599 " 'mana': 340,\n",
600 " 'ongoing': [[{'armour': 7}, {'armour': 7}, {'armour': 7}]],\n",
601 " 'pc_hp': 2,\n",
602 " 'spent': 415}"
603 ]
604 },
605 "execution_count": 49,
606 "metadata": {},
607 "output_type": "execute_result"
608 }
609 ],
610 "source": [
611 "s7 = apply_ongoing(s6)\n",
612 "s8 = cast_spell([s for s in spells if s['name'] == 'Drain'][0], s7)\n",
613 "s9 = boss_turn(s8)\n",
614 "s9"
615 ]
616 },
617 {
618 "cell_type": "code",
619 "execution_count": 50,
620 "metadata": {
621 "collapsed": false
622 },
623 "outputs": [
624 {
625 "data": {
626 "text/plain": [
627 "{'armour': 7,\n",
628 " 'boss_damage': 8,\n",
629 " 'boss_hp': 9,\n",
630 " 'cast': ['Recharge', 'Shield', 'Drain', 'Poison'],\n",
631 " 'mana': 167,\n",
632 " 'ongoing': [[{'armour': 7}],\n",
633 " [{'boss_hp': -3},\n",
634 " {'boss_hp': -3},\n",
635 " {'boss_hp': -3},\n",
636 " {'boss_hp': -3},\n",
637 " {'boss_hp': -3}]],\n",
638 " 'pc_hp': 1,\n",
639 " 'spent': 588}"
640 ]
641 },
642 "execution_count": 50,
643 "metadata": {},
644 "output_type": "execute_result"
645 }
646 ],
647 "source": [
648 "s10 = apply_ongoing(s9)\n",
649 "s11 = cast_spell([s for s in spells if s['name'] == 'Poison'][0], s10)\n",
650 "s12 = boss_turn(s11)\n",
651 "s12"
652 ]
653 },
654 {
655 "cell_type": "code",
656 "execution_count": 51,
657 "metadata": {
658 "collapsed": false
659 },
660 "outputs": [
661 {
662 "data": {
663 "text/plain": [
664 "{'armour': 0,\n",
665 " 'boss_damage': 8,\n",
666 " 'boss_hp': -1,\n",
667 " 'cast': ['Recharge', 'Shield', 'Drain', 'Poison', 'Magic missile'],\n",
668 " 'mana': 114,\n",
669 " 'ongoing': [[{'boss_hp': -3}, {'boss_hp': -3}, {'boss_hp': -3}]],\n",
670 " 'pc_hp': 1,\n",
671 " 'spent': 641}"
672 ]
673 },
674 "execution_count": 51,
675 "metadata": {},
676 "output_type": "execute_result"
677 }
678 ],
679 "source": [
680 "s13 = apply_ongoing(s12)\n",
681 "s14 = cast_spell([s for s in spells if s['name'] == 'Magic missile'][0], s13)\n",
682 "s15 = boss_turn(s14)\n",
683 "s15"
684 ]
685 },
686 {
687 "cell_type": "code",
688 "execution_count": 22,
689 "metadata": {
690 "collapsed": true
691 },
692 "outputs": [],
693 "source": [
694 "def finished(state):\n",
695 " return state['boss_hp'] <= 0 or state['pc_hp'] <= 0\n",
696 "\n",
697 "def victory(state):\n",
698 " return finished(state) and state['pc_hp'] > 0\n",
699 "\n",
700 "def defeat(state):\n",
701 " return finished(state) and state['pc_hp'] <= 0"
702 ]
703 },
704 {
705 "cell_type": "code",
706 "execution_count": 23,
707 "metadata": {
708 "collapsed": false
709 },
710 "outputs": [],
711 "source": [
712 "def ahistoric(state):\n",
713 " return {k: state[k] for k in state if k != 'cast'}"
714 ]
715 },
716 {
717 "cell_type": "code",
718 "execution_count": 30,
719 "metadata": {
720 "collapsed": false
721 },
722 "outputs": [
723 {
724 "data": {
725 "text/plain": [
726 "{'armour': 7,\n",
727 " 'boss_damage': 9,\n",
728 " 'boss_hp': 0,\n",
729 " 'cast': ['Poison',\n",
730 " 'Recharge',\n",
731 " 'Drain',\n",
732 " 'Poison',\n",
733 " 'Recharge',\n",
734 " 'Shield',\n",
735 " 'Poison',\n",
736 " 'Magic missile',\n",
737 " 'Magic missile'],\n",
738 " 'mana': 241,\n",
739 " 'ongoing': [[{'boss_hp': -3}, {'boss_hp': -3}]],\n",
740 " 'pc_hp': 1,\n",
741 " 'spent': 1269}"
742 ]
743 },
744 "execution_count": 30,
745 "metadata": {},
746 "output_type": "execute_result"
747 }
748 ],
749 "source": [
750 "agenda = [initial_state]\n",
751 "closed = []\n",
752 "while agenda:\n",
753 " current_state = agenda[0]\n",
754 " new_states = []\n",
755 " if ahistoric(current_state) not in closed:\n",
756 " closed += [ahistoric(current_state)]\n",
757 " # print(current_state)\n",
758 " if victory(current_state):\n",
759 " # return current_state\n",
760 " break\n",
761 " for spell in valid_spells(spells, current_state):\n",
762 " s2 = cast_spell(spell, current_state)\n",
763 " if victory(s2):\n",
764 " new_states += [s2]\n",
765 " else:\n",
766 " s3 = boss_turn(s2)\n",
767 " if victory(s3):\n",
768 " new_states += [s3]\n",
769 " if not finished(s3):\n",
770 " new_states += [apply_ongoing(s3)]\n",
771 " # print(new_states)\n",
772 " states_to_add = [s for s in new_states \n",
773 " if ahistoric(s) not in closed\n",
774 " if len(s['cast']) <= 50]\n",
775 " agenda = sorted(states_to_add + agenda[1:], key=lambda s: s['spent'])\n",
776 " # agenda = new_states + agenda[1:]\n",
777 "current_state"
778 ]
779 },
780 {
781 "cell_type": "code",
782 "execution_count": 31,
783 "metadata": {
784 "collapsed": false
785 },
786 "outputs": [
787 {
788 "data": {
789 "text/plain": [
790 "(1587, 2908)"
791 ]
792 },
793 "execution_count": 31,
794 "metadata": {},
795 "output_type": "execute_result"
796 }
797 ],
798 "source": [
799 "len(agenda), len(closed)"
800 ]
801 },
802 {
803 "cell_type": "code",
804 "execution_count": 65,
805 "metadata": {
806 "collapsed": false
807 },
808 "outputs": [
809 {
810 "data": {
811 "text/plain": [
812 "{'armour': 0,\n",
813 " 'boss_damage': 9,\n",
814 " 'boss_hp': 0,\n",
815 " 'cast': ['Poison',\n",
816 " 'Recharge',\n",
817 " 'Shield',\n",
818 " 'Poison',\n",
819 " 'Drain',\n",
820 " 'Recharge',\n",
821 " 'Poison',\n",
822 " 'Magic missile',\n",
823 " 'Magic missile'],\n",
824 " 'mana': 241,\n",
825 " 'ongoing': [[{'boss_hp': -3}, {'boss_hp': -3}]],\n",
826 " 'pc_hp': 1,\n",
827 " 'spent': 1269}"
828 ]
829 },
830 "execution_count": 65,
831 "metadata": {},
832 "output_type": "execute_result"
833 }
834 ],
835 "source": [
836 "agenda = [initial_state]\n",
837 "closed = []\n",
838 "while agenda:\n",
839 " current_state = agenda[0]\n",
840 " new_states = []\n",
841 " # print(current_state)\n",
842 " if victory(current_state):\n",
843 " # return current_state\n",
844 " break\n",
845 " for spell in valid_spells(spells, current_state):\n",
846 " s2 = cast_spell(spell, current_state)\n",
847 " if victory(s2):\n",
848 " new_states += [s2]\n",
849 " else:\n",
850 " s3 = boss_turn(s2)\n",
851 " if victory(s3):\n",
852 " new_states += [s3]\n",
853 " if not finished(s3):\n",
854 " new_states += [apply_ongoing(s3)]\n",
855 " # print(new_states)\n",
856 " states_to_add = [s for s in new_states \n",
857 " if len(s['cast']) <= 50]\n",
858 " agenda = sorted(states_to_add + agenda[1:], key=lambda s: s['spent'])\n",
859 " # agenda = new_states + agenda[1:]\n",
860 "current_state"
861 ]
862 },
863 {
864 "cell_type": "code",
865 "execution_count": 66,
866 "metadata": {
867 "collapsed": false
868 },
869 "outputs": [
870 {
871 "data": {
872 "text/plain": [
873 "(165616, 0)"
874 ]
875 },
876 "execution_count": 66,
877 "metadata": {},
878 "output_type": "execute_result"
879 }
880 ],
881 "source": [
882 "len(agenda), len(closed)"
883 ]
884 },
885 {
886 "cell_type": "markdown",
887 "metadata": {},
888 "source": [
889 "#Part 2"
890 ]
891 },
892 {
893 "cell_type": "code",
894 "execution_count": 25,
895 "metadata": {
896 "collapsed": true
897 },
898 "outputs": [],
899 "source": [
900 "def player_bleed(state):\n",
901 " new_state = copy.deepcopy(state)\n",
902 " new_state['pc_hp'] -= 1\n",
903 " return new_state"
904 ]
905 },
906 {
907 "cell_type": "code",
908 "execution_count": 32,
909 "metadata": {
910 "collapsed": false
911 },
912 "outputs": [
913 {
914 "data": {
915 "text/plain": [
916 "{'armour': 0,\n",
917 " 'boss_damage': 9,\n",
918 " 'boss_hp': -1,\n",
919 " 'cast': ['Poison',\n",
920 " 'Recharge',\n",
921 " 'Shield',\n",
922 " 'Poison',\n",
923 " 'Recharge',\n",
924 " 'Shield',\n",
925 " 'Poison',\n",
926 " 'Magic missile',\n",
927 " 'Magic missile'],\n",
928 " 'mana': 201,\n",
929 " 'ongoing': [[{'boss_hp': -3}]],\n",
930 " 'pc_hp': 12,\n",
931 " 'spent': 1309}"
932 ]
933 },
934 "execution_count": 32,
935 "metadata": {},
936 "output_type": "execute_result"
937 }
938 ],
939 "source": [
940 "agenda = [initial_state]\n",
941 "closed = []\n",
942 "while agenda:\n",
943 " current_state = agenda[0]\n",
944 " new_states = []\n",
945 " if ahistoric(current_state) not in closed:\n",
946 " closed += [ahistoric(current_state)]\n",
947 " # print(current_state)\n",
948 " if victory(current_state):\n",
949 " # return current_state\n",
950 " break\n",
951 " for spell in valid_spells(spells, current_state):\n",
952 " s2 = cast_spell(spell, current_state)\n",
953 " if victory(s2):\n",
954 " new_states += [s2]\n",
955 " else:\n",
956 " s3 = boss_turn(s2)\n",
957 " if victory(s3):\n",
958 " new_states += [s3]\n",
959 " s4 = player_bleed(s3)\n",
960 " if not finished(s4):\n",
961 " new_states += [apply_ongoing(s4)]\n",
962 " # print(new_states)\n",
963 " states_to_add = [s for s in new_states \n",
964 " if ahistoric(s) not in closed\n",
965 " if len(s['cast']) <= 50]\n",
966 " agenda = sorted(states_to_add + agenda[1:], key=lambda s: s['spent'])\n",
967 " # agenda = new_states + agenda[1:]\n",
968 "current_state"
969 ]
970 },
971 {
972 "cell_type": "code",
973 "execution_count": 33,
974 "metadata": {
975 "collapsed": false
976 },
977 "outputs": [
978 {
979 "data": {
980 "text/plain": [
981 "(872, 2354)"
982 ]
983 },
984 "execution_count": 33,
985 "metadata": {},
986 "output_type": "execute_result"
987 }
988 ],
989 "source": [
990 "len(agenda), len(closed)"
991 ]
992 },
993 {
994 "cell_type": "code",
995 "execution_count": null,
996 "metadata": {
997 "collapsed": true
998 },
999 "outputs": [],
1000 "source": []
1001 }
1002 ],
1003 "metadata": {
1004 "kernelspec": {
1005 "display_name": "Python 3",
1006 "language": "python",
1007 "name": "python3"
1008 },
1009 "language_info": {
1010 "codemirror_mode": {
1011 "name": "ipython",
1012 "version": 3
1013 },
1014 "file_extension": ".py",
1015 "mimetype": "text/x-python",
1016 "name": "python",
1017 "nbconvert_exporter": "python",
1018 "pygments_lexer": "ipython3",
1019 "version": "3.4.3"
1020 }
1021 },
1022 "nbformat": 4,
1023 "nbformat_minor": 0
1024 }