summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2019-08-27 16:48:51 -0400
committerJune McEnroe <june@causal.agency>2019-08-27 16:48:51 -0400
commitf1666bdb5d840123d0e3652e1a0dd10198d1b4b8 (patch)
tree1cffca2fdfc3350d90836ca9853a3a00f7cc3518
parentMove as deep a stack as possible to empty columns (diff)
downloadwep-f1666bdb5d840123d0e3652e1a0dd10198d1b4b8.tar.gz
wep-f1666bdb5d840123d0e3652e1a0dd10198d1b4b8.zip
Replicate the FreeCell LCG and deal algorithm
-rw-r--r--freecell.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/freecell.c b/freecell.c
index 3400306..0e74793 100644
--- a/freecell.c
+++ b/freecell.c
@@ -89,16 +89,34 @@ static bool undo(void) {
 	return true;
 }
 
+static uint lcgState = 1;
+static uint lcgRand(void) {
+	lcgState = (214013 * lcgState + 2531011) % (1 << 31);
+	return lcgState / (1 << 16);
+}
+
+// <https://rosettacode.org/wiki/Deal_cards_for_FreeCell>
 static void deal(void) {
+	kingIndex = Cards_KingRight;
 	for (uint i = 0; i < StacksLen; ++i) {
 		clear(&stacks[i]);
 	}
-	struct Stack deck = Deck;
-	shuffle(&deck);
-	for (uint i = Tableau1; i <= Tableau8; ++i) {
-		flipTo(&stacks[i], &deck, (i < Tableau5 ? 7 : 6));
+
+	struct Stack deck = {0};
+	for (Card i = Cards_A; i <= Cards_K; ++i) {
+		push(&deck, Cards_Club + i);
+		push(&deck, Cards_Diamond + i);
+		push(&deck, Cards_Heart + i);
+		push(&deck, Cards_Spade + i);
+	}
+
+	uint stack = 0;
+	while (deck.len) {
+		uint i = lcgRand() % deck.len;
+		Card card = deck.cards[i];
+		deck.cards[i] = deck.cards[--deck.len];
+		push(&stacks[Tableau1 + stack++ % 8], card);
 	}
-	kingIndex = Cards_KingRight;
 }
 
 static bool win(void) {