So, I’m still prepping the stick game for uploading to the web site. When I wrote it originally, I thought it would be cool to allow arbitrarily large numbers of rows – probably something about showing off the robustness of the data structures. The problem is, when I wrote it, I gave short shrift to performance optimization. The AI enumerates all possible moves and possible games, then plays a move which leads to it winning (or taking the longest possible time to lose). That’s fine for when you have a small number of sticks, but when you have a larger number of sticks, the process of enumeration consumes all available RAM, and causes the program to become non-responsive. As a result, the fact that the AI will only play once it’s found the correct move means that it (effectively) never plays once it has to deal with a large number of sticks.
Now, if I’d been thinking about performance optimization when I originally wrote the game, I would have done something marginally clever, like have a calculation thread constantly running the background, enumerating away, rather than waiting till it’s the computer’s turn to start thinking. I could also have done something like add a timer on the computer’s thinking, and forced it to make a move after it had been enumerating for some set period (e.g., 30 seconds). That second one would actually go hand-in-hand with a third optimization that I didn’t implement: I could have written the code to save intermediate results, rather than only saving the results once the enumeration’s finished (the current approach).
So there are all sorts of optimizations I could implement to help clean up the mess from when I originally wrote it. Alternatively, I could just remove the user’s ability to start the game with an arbitrarily large number of sticks (thereby making sure the game is only played with the smaller numbers where the lack of optimization isn’t a problem). As it happens, in my relatively old age, I have found that there’s another optimization that is more important than the ones I described above: minimizing my own time expenditure. Given that, what will actually happen is that I’m going to remove the functionality that’s causing the problems, and leave the task of optimizing for another day.