about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2019-03-24 14:02:22 -0400
committerJune McEnroe <june@causal.agency>2019-03-24 14:02:22 -0400
commit140e3553ef618be2dabcb2cb0d85c8e02877481b (patch)
treee0abba84797e4f55af138c8fbf5b341ca0c238fe
parentUse rand(3) (diff)
downloadcards-140e3553ef618be2dabcb2cb0d85c8e02877481b.tar.gz
cards-140e3553ef618be2dabcb2cb0d85c8e02877481b.zip
Add undo
-rw-r--r--sol.c38
1 files changed, 32 insertions, 6 deletions
diff --git a/sol.c b/sol.c
index 6f6f434..567bf7c 100644
--- a/sol.c
+++ b/sol.c
@@ -52,7 +52,32 @@ static struct {
 	.draw = 3,
 };
 
+typedef void StackFn(struct Stack *dst, struct Stack *src, Uint8 len);
+
+static struct {
+	StackFn *fn;
+	uint dst;
+	uint src;
+	uint len;
+} undo;
+
+static void gameDo(StackFn *fn, uint dst, uint src, uint len) {
+	undo.fn = fn;
+	undo.dst = src;
+	undo.src = dst;
+	undo.len = len;
+	fn(&stacks[dst], &stacks[src], len);
+}
+
+static bool gameUndo(void) {
+	if (!undo.fn) return false;
+	undo.fn(&stacks[undo.dst], &stacks[undo.src], undo.len);
+	undo.fn = NULL;
+	return true;
+}
+
 static void gameDeal(void) {
+	undo.fn = NULL;
 	for (uint i = 0; i < StacksLen; ++i) {
 		stackClear(&stacks[i]);
 	}
@@ -68,12 +93,12 @@ static void gameDraw(void) {
 	stackMoveTo(&stacks[Waste1], &stacks[Waste3], stacks[Waste3].len);
 	if (stacks[Stock].len) {
 		if (game.draw > 1) {
-			stackFlipTo(&stacks[Waste3], &stacks[Stock], game.draw);
+			gameDo(stackFlipTo, Waste3, Stock, game.draw);
 		} else {
-			stackFlipTo(&stacks[Waste1], &stacks[Stock], 1);
+			gameDo(stackFlipTo, Waste1, Stock, 1);
 		}
 	} else {
-		stackFlipTo(&stacks[Stock], &stacks[Waste1], stacks[Waste1].len);
+		gameDo(stackFlipTo, Stock, Waste1, stacks[Waste1].len);
 	}
 }
 
@@ -111,7 +136,7 @@ static bool gameReveal(Sint8 card) {
 	if (stack < Tableau1 || stack > Tableau7) return false;
 	if (index != stacks[stack].len - 1) return false;
 	if (card > 0) return false;
-	stackFlipTo(&stacks[stack], &stacks[stack], 1);
+	gameDo(stackFlipTo, stack, stack, 1);
 	return true;
 }
 
@@ -128,7 +153,7 @@ static bool gameMove(uint dest, Sint8 card) {
 		if (!destTop && cardRank(card) != Cards_A) return false;
 		if (destTop && cardSuit(card) != cardSuit(destTop)) return false;
 		if (destTop && cardRank(card) != cardRank(destTop) + 1) return false;
-		stackMoveTo(&stacks[dest], &stacks[source], 1);
+		gameDo(stackMoveTo, dest, source, 1);
 		return true;
 	}
 
@@ -136,7 +161,7 @@ static bool gameMove(uint dest, Sint8 card) {
 		if (!destTop && cardRank(card) != Cards_K) return false;
 		if (destTop && cardColor(card) == cardColor(destTop)) return false;
 		if (destTop && cardRank(card) != cardRank(destTop) - 1) return false;
-		stackMoveTo(&stacks[dest], &stacks[source], count);
+		gameDo(stackMoveTo, dest, source, count);
 		return true;
 	}
 
@@ -289,6 +314,7 @@ static void layoutTableau(void) {
 static bool keyDown(SDL_KeyboardEvent key) {
 	switch (key.keysym.sym) {
 		case SDLK_F2: gameDeal(); return true;
+		case SDLK_BACKSPACE: return gameUndo();
 		case SDLK_b: {
 			layout.backTexture -= Cards_Back1;
 			layout.backTexture += 1;