As promised, an update.....
I did lots of work on the game with each player having a range of QQ+ on a 2♥ 7♣ J♦ flop with a single bet available. It's a bit like the AKQ game, but over three streets, with QQ and KK having some equity against AA. The problem is that I kept getting a solution where the first player bets with some fraction of his KK. Now it's not impossible that this turns out to be the correct solution, since this folds out QQ's equity. I think I've written the CFR minimization subroutine properly, but it's such an unexpected result that I decided I need to check it very carefully. The difficulty is that it takes a long while to do enough iterations to see whether the solution has converged properly. In most problems that I've worked on in the past, it's very important to get everything working before fretting about efficiency, but in this case, I need to get a good turn of speed out of my code to be able to check it. Now that I have a cobbled together seven card hand evaluator, I decided to write some code to bucket hands, turn cards and river cards more efficiently. There's an algorithm called Gameshrink that does this, but I wanted to go my own way so that I understand what's going on. I decided it's just an exercise in linear algebra. Unfortunately, I discovered that linear algebra with lots of entries of -1 thrown randomly into the, otherwise positive, matrices (that's bloody card removal, the new bane of my life) is rather more difficult. Also, although the final hand rank partitions the players' river ranges, there's no function that partitions the river card ranges. In other words, you can construct examples where, using a sensible definition of '=', you can construct flops and ranges for which there are river cards x, y and z such that x=y and y=z, but x~=z.
That cost me some sleep to work out, because I'm a discrete maths fish, but I think I've fixed it this evening. I can now get on and do CFR minimisation over buckets rather than hands. For the example above, there are only three flop hand buckets per player, and no more that four turn and river card buckets. Hopefully this will let me sort out what's going on, as well as get more speed going for realistic ranges. I also have some other ideas about how to speed up my code. It turns out that how you store and access the regret and strategy sum and average data (it's a big data structure) has a huge effect on efficiency, so I need to get that right.
In other news, I'm playing only on my iPad at the moment, so basically not at all seriously. I may have an MTT night again soon, but I'm really very focussed on seeing how far I can get with this code at the moment. Just working evenings and some lunchtimes makes it slow going, but I'm now more confident than I was that I can get this working.