I reached #43 legend using smitsimax; this algorithm was definitely not a good choice for this contest, and without any modifications, I think it would have trouble reaching even high gold because long, precise sequences of turns that maximize inventory value are extremely important in this game, and smitsimax just cannot find them (or might never revisit them because of random terrible rollouts in the same subtree and the need to expand nodes). My plan was to completely rewrite my bot during the week, but due to real life, I had time only during the weekends - so instead, knowing I couldn’t compete for the top ranks, I decided to try to somehow make smitsimax work.
I used smitsimax only to reach a fixed depth (anywhere between 10 and 25 depending on the version of my bot; the depth didn’t make any difference) and then evaluated the state: ([my score] + [my inventory]*0.5 - [opponent’s score] - [opponent’s inventory]*0.5 + [±25 points for winning/losing]). The results aren’t between 0 and 1, so I “fixed” that by using a higher exploration parameter. When the servers were working properly, I could reach ~100K nodes in each tree.
The most important thing that made me even reach #1 back in bronze league was that my rollouts weren’t random; for every possible inventory (there are only 1001 of them) I precalculated all the possible brews and casts and sorted them (brews first, then casts that add more value to my inventory), and when expanding a node, I tried the actions in this order.
That was good enough for high gold; for legend, I needed to somehow make smitsimax learn spells; at first, I tried adding actions “learn (1-6)”(only usable once per rollout) and “cast learned spell” to my smitsimax, but that didn’t work too well, so I switched to learning the first 8 0-cost spells instead. However, to reach mid-legend, I had to use another approach: statistics and if/else. I wrote a simple beam search (width ~3000; who knows, maybe it could do better on the leaderboard than what I submitted), I let it run overnight millions of times for random combinations of potions and spells, and I stored the result. I found average score per turn for every spell and every combination of two spells, copied these stats into my bot, I was willing to pay a tier0 ingredient for 0.08 score per turn, and I added some simple conditions for when to learn - depends on number of already known spells and the score of available spells.
On the final day, I noticed that my smitsimax used the order of spells that I precalculated for myself also when expanding opponent’s nodes; fixing this bug made me drop 15 ranks and for example my 80%+ winrate against wlesavo disappeared (expanding randomly was even worse than that), even if the evaluation of nodes in the endgame was much better. That made me realize that I had absolutely no idea why did my bot work. Back in bronze, I also noticed that at depth 15+, my bot played better if it could brew one potion multiple times, which is somewhat understandable unlike the bug with my opponent simulation. I couldn’t bring myself to reintroduce these bugs for the final submit.