The check for loss procedure in a solitaire game really has to be a full blown auto complete of the game. If it fails, the game is over.
TBMan, your anti-churning approach is quite clever for detecting repetitive moves in German Solitaire! The idea of tracking card movements using
checklist[cardabove.cardindex] to detect when the same card pairings repeat more than 3 times is a practical heuristic that prevents infinite loops.
However, you're absolutely right that a complete solution requires a full AI auto-complete algorithm. Your current approach works well as an interim solution, but here are some suggestions to refine it:
// Enhanced version with move tracking
var
checklist: array[1..104] of byte;
previousGameStateHash: cardinal; // To detect broader state repetition
moveHistory: array[1..10] of record // Track last 10 moves
cardMoved, destination: integer;
end;
moveCount: integer;
For the full AI solution you mentioned, consider implementing a breadth-first search that explores all possible moves from the current position. If the search exhausts all possibilities without reaching a winning state, then the game is truly lost.
Your approach of only checking after moves (
moveMade boolean) is smart - it prevents unnecessary computation during idle game loops. The key insight is that you're essentially creating a finite state machine that detects when the game enters a repetitive cycle without progress.
For German Solitaire specifically, you might also want to track tableau pile states to detect broader positional repetitions, not just individual card movements.