Closed ichabod801 closed 4 years ago
Part of the problem might be Mutlisolitaire.find_foundation. Check that it is correctly finding all the foundations, especially in one and two suit games. Also check that Solitaire.sort_check is returning True.
Here's a case, from Gargantua:
7C 8D 6H TS 8C 9D 9H JS
KD KS KH KC QC KD -- KH ??
QS QD QC QD QS ??
JD JC JH JS JH ??
TD TC TD TC QH
9C 9D JC
-- QH
What is your move? td
7C 8D 6H TS 8C 9D 9H JS
KD KS KH KC QC KD -- KH ??
QS QD QC QD QS ??
JD JC JH JS JH ??
TD TC TC QH
9C 9D JC
TD
-- QH
The TD from the fourth tableau pile could have sorted to the sixth foundation pile. Instead, it moved to the JC in the ninth tableau pile.
I went back and looked at that case. Both foundations were found for the TD, and sort_check is returning True for that card and the sixth foundation.
And note that it goes back and forth if you leave it to guessing: doing 'TD' again moves it back to the JS.
But it's not always the case that it fails to sort if it could build. Later on in the same game there was this:
7C 8D 6H JS 8C QD 9H JS
KD KS KH KC QC KD KS KH ??
QS QD QC QH QH QS 8C
JD JC JH JC JH
TD TC TC
9C 9D
-- TH
What is your move? 8c
8C 8D 6H JS 8C QD 9H JS
KD KS KH KC QC KD KS KH 9C
QS QD QC QH QH QS
JD JC JH JC JH
TD TC TC
9C 9D
-- TH
Here, the 8C was sorted correctly, even though it could have been put on the 9D.
But then we have the problem again here:
8C 8D 6H JS 9C QD 9H JS
KD KS KH KC QC KD KS KH 9C
QS QD QC QH QH QS
JD JC JH JC JH
TD TC TC
9D
-- TH
What is your move? tc
8C 8D 6H JS 9C QD 9H JS
KD KS KH KC QC KD KS KH 9C
QS QD QC QH QH QS
JD JC JH JC JH
TC TD TC
9D
-- TH
It seems like if you have a foundation that is too low, it ignores a valid but higher foundation, and then builds instead.
Got it. Here's what is happening in the last example. There are two TC's available, TC-3 and TC-8. But deck.find('TC') returns TC-8 first, so guess checks that first. TC-8 can't be sorted, but it can be built onto JD-1. So guess stops checking because of the conditional on like 1368, and never checks TC-3. What it does is return 'build TC JD'.
That goes to do_build. That method check both TCs, to keep track of alternate moves. Again, it checks TC-8 first, leaving the TC-3 move at the end of the list of possible moves. It returns the pop of the list of possible moves, returning the TC-3 move.
You have the exact same thing in the first example, just with two TD's.
Do I fix? Something needs to be done, because guess is not working as documented. I think it is possible to fix: Remove the conditional on 1368 so that all cards are checked. Then, don't just append the move text to moves. Append a sorting key and the move_text as a tuple. Then sort moves at the end. I think I was trying to avoid something like that when I set this up, but that is obviously not working.
Could I do it with a lambda? Let's see:
moves.sort(key = lambda x: ('sort', 'buil', 'matc', 'free', 'lane').index(x[:4])), reverse = True)
98 characters plus 3 indents x 4 character each puts it over the line limit. It would fit if I made it index a string and not a tuple. And actually, you only need to sort by the first character.
In any case, sleep on it (maybe there's another solution) and decide another day.
Revised lambda for the hell of it:
moves.sort(key = lambda x: 'sbmfl'.index(x[0])), reverse = True)
65 characters plus the indents puts it under the PEP 8 limit. It is less clear but could be commented.
Tested it in Spider and Gargantua. I'm seeing no problems with it in normal guessing. I potential error cases as above it worked correctly 10 times in a row. That makes the odds of it still being broken less than one in a thousand.
Often when trying to sort, especially late in the game, guess lanes a card instead of sorting it.