diff options
-rw-r--r-- | freecell.c | 64 |
1 files changed, 40 insertions, 24 deletions
diff --git a/freecell.c b/freecell.c index 39bdb12..bc38bf8 100644 --- a/freecell.c +++ b/freecell.c @@ -25,8 +25,6 @@ #include "layout.h" #include "stack.h" -#define ARRAY_LEN(a) (sizeof(a) / sizeof((a)[0])) - enum { Foundation1, Foundation2, @@ -51,6 +49,12 @@ static struct Stack stacks[StacksLen]; static uint kingFace = Cards_KingRight; +static struct { + bool avail; + uint dst; + uint src; +} undo; + static void gameDeal(void) { for (uint i = 0; i < StacksLen; ++i) { stackClear(&stacks[i]); @@ -67,6 +71,7 @@ static void gameDeal(void) { stackMoveTo(&stacks[i], &deck, 6); } kingFace = Cards_KingRight; + undo.avail = false; } static bool gameWin(void) { @@ -92,28 +97,38 @@ static bool gameAvail(Card card) { return card == stackTop(&stacks[stack]); } -static bool gameMove(uint dest, Card card) { - uint source, index; - if (!gameFind(&source, &index, card)) return false; - Card destTop = stackTop(&stacks[dest]); +static bool gameMove(uint dst, Card card) { + uint src, index; + if (!gameFind(&src, &index, card)) return false; + Card top = stackTop(&stacks[dst]); - if (source == dest) return false; - if (dest >= Cell1 && dest <= Cell4) { - if (stacks[dest].len) return false; + if (src == dst) return false; + if (dst >= Cell1 && dst <= Cell4) { + if (stacks[dst].len) return false; kingFace = Cards_KingLeft; } - if (dest >= Foundation1 && dest <= Foundation4) { - 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; + if (dst >= Foundation1 && dst <= Foundation4) { + if (!top && cardRank(card) != Cards_A) return false; + if (top && cardSuit(card) != cardSuit(top)) return false; + if (top && cardRank(card) != cardRank(top) + 1) return false; kingFace = Cards_KingRight; } - if (dest >= Tableau1 && dest <= Tableau8) { - if (destTop && cardColor(card) == cardColor(destTop)) return false; - if (destTop && cardRank(card) != cardRank(destTop) - 1) return false; + if (top >= Tableau1 && top <= Tableau8) { + if (top && cardColor(card) == cardColor(top)) return false; + if (top && cardRank(card) != cardRank(top) - 1) return false; } - stackPush(&stacks[dest], stackPop(&stacks[source])); + undo.dst = src; + undo.src = dst; + undo.avail = true; + stackPush(&stacks[dst], stackPop(&stacks[src])); + return true; +} + +static bool gameUndo(void) { + if (!undo.avail) return false; + stackPush(&stacks[undo.dst], stackPop(&stacks[undo.src])); + undo.avail = false; return true; } @@ -133,8 +148,8 @@ static bool gameAuto(void) { if (cardRank(card) > Cards_2) { if (min[!cardColor(card)] < cardRank(card)) continue; } - for (uint dest = Foundation1; dest <= Foundation4; ++dest) { - if (gameMove(dest, card)) return true; + for (uint dst = Foundation1; dst <= Foundation4; ++dst) { + if (gameMove(dst, card)) return true; } } return false; @@ -220,6 +235,7 @@ static void revealRank(Card rank) { static bool keyDown(SDL_KeyboardEvent key) { switch (key.keysym.sym) { case SDLK_F2: gameDeal(); return true; + case SDLK_BACKSPACE: return gameUndo(); } if (key.repeat) return false; switch (key.keysym.sym) { @@ -265,17 +281,17 @@ static bool mouseButtonDown(SDL_MouseButtonEvent button) { if (!item) return false; card = item->card; } - for (uint dest = Cell1; dest <= Cell4; ++dest) { - if (gameMove(dest, card)) break; + for (uint dst = Cell1; dst <= Cell4; ++dst) { + if (gameMove(dst, card)) break; } layout.dragItem.card = 0; return true; } if (layout.dragItem.card) { - for (uint dest = 0; dest < StacksLen; ++dest) { - if (SDL_PointInRect(&point, &stackRects[dest])) { - if (gameMove(dest, layout.dragItem.card)) break; + for (uint dst = 0; dst < StacksLen; ++dst) { + if (SDL_PointInRect(&point, &stackRects[dst])) { + if (gameMove(dst, layout.dragItem.card)) break; } } layout.dragItem.card = 0; |