diff options
author | June McEnroe <june@causal.agency> | 2019-08-26 01:29:47 -0400 |
---|---|---|
committer | June McEnroe <june@causal.agency> | 2019-08-26 01:29:47 -0400 |
commit | 0d4585d435c71e3aa615326b5f2c2e744756af72 (patch) | |
tree | 86faaa004eb945e4a89d2e7d7dc49bd0a7e9f7a0 | |
parent | Rewrite FreeCell (diff) | |
download | wep-0d4585d435c71e3aa615326b5f2c2e744756af72.tar.gz wep-0d4585d435c71e3aa615326b5f2c2e744756af72.zip |
Clean up naming
Diffstat (limited to '')
-rw-r--r-- | freecell.c | 176 |
1 files changed, 76 insertions, 100 deletions
diff --git a/freecell.c b/freecell.c index 332be63..eae8413 100644 --- a/freecell.c +++ b/freecell.c @@ -56,42 +56,40 @@ struct Move { uint src; }; -enum { QueueLen = 32 }; +enum { QueueLen = 16 }; static struct { struct Move moves[QueueLen]; - uint r, w; + uint r, w, u; } queue; -static uint undo; - -static void gameEnqueue(uint dst, uint src) { +static void enqueue(uint dst, uint src) { queue.moves[queue.w % QueueLen].dst = dst; queue.moves[queue.w % QueueLen].src = src; queue.w++; } -static void gameDequeue(void) { +static void dequeue(void) { struct Move move = queue.moves[queue.r++ % QueueLen]; stackPush(&stacks[move.dst], stackPop(&stacks[move.src])); - if (move.dst >= Foundation1 && move.dst <= Foundation4) { + if (move.dst <= Foundation4) { kingIndex = Cards_KingRight; - } else if (move.dst >= Cell1 && move.dst <= Cell4) { + } else if (move.dst <= Cell4) { kingIndex = Cards_KingLeft; } } -static bool gameUndo(void) { - uint len = queue.w - undo; +static bool undo(void) { + uint len = queue.w - queue.u; if (!len || len > QueueLen) return false; for (uint i = len - 1; i < len; --i) { - struct Move move = queue.moves[(undo + i) % QueueLen]; + struct Move move = queue.moves[(queue.u + i) % QueueLen]; stackPush(&stacks[move.src], stackPop(&stacks[move.dst])); } - queue.r = queue.w = undo; + queue.r = queue.w = queue.u; return true; } -static void gameDeal(void) { +static void deal(void) { for (uint i = 0; i < StacksLen; ++i) { stackClear(&stacks[i]); } @@ -103,14 +101,14 @@ static void gameDeal(void) { kingIndex = Cards_KingRight; } -static bool gameWin(void) { +static bool win(void) { for (uint i = Foundation1; i <= Foundation4; ++i) { if (stacks[i].len != 13) return false; } return true; } -static bool gameValid(uint dst, Card card) { +static bool valid(uint dst, Card card) { Card top = stackTop(&stacks[dst]); if (dst >= Foundation1 && dst <= Foundation4) { if (!top) return cardRank(card) == Cards_A; @@ -125,7 +123,7 @@ static bool gameValid(uint dst, Card card) { return false; } -static void gameAuto(void) { +static void autoEnqueue(void) { Card min[] = { Cards_K, Cards_K }; for (uint i = Cell1; i <= Tableau8; ++i) { for (uint j = 0; j < stacks[i].len; ++j) { @@ -143,23 +141,22 @@ static void gameAuto(void) { if (min[!cardColor(card)] < cardRank(card)) continue; } for (uint dst = Foundation1; dst <= Foundation4; ++dst) { - if (gameValid(dst, card)) { - gameEnqueue(dst, src); + if (valid(dst, card)) { + enqueue(dst, src); return; } } } } -static uint gameFree(uint list[]) { - uint len = 0; - for (uint i = Cell1; i <= Tableau8; ++i) { - if (!stacks[i].len) list[len++] = i; +static void moveSingle(uint dst, uint src) { + if (valid(dst, stackTop(&stacks[src]))) { + queue.u = queue.w; + enqueue(dst, src); } - return len; } -static uint gameDepth(uint src) { +static uint moveDepth(uint src) { struct Stack stack = stacks[src]; if (stack.len < 2) return stack.len; uint n = 1; @@ -170,34 +167,36 @@ static uint gameDepth(uint src) { return n; } -static void gameMoveSingle(uint dst, uint src) { - if (gameValid(dst, stackTop(&stacks[src]))) { - undo = queue.w; - gameEnqueue(dst, src); +static uint freeCells(uint list[], uint dst) { + uint len = 0; + for (uint i = Cell1; i <= Tableau8; ++i) { + if (i == dst) continue; + if (!stacks[i].len) list[len++] = i; } + return len; } -static void gameMoveColumn(uint dst, uint src) { +static void moveColumn(uint dst, uint src) { uint depth; - for (depth = gameDepth(src); depth; --depth) { - if (gameValid(dst, stacks[src].cards[stacks[src].len - depth])) break; + for (depth = moveDepth(src); depth; --depth) { + if (valid(dst, stacks[src].cards[stacks[src].len - depth])) break; } if (depth < 2 || dst <= Cell4) { - gameMoveSingle(dst, src); + moveSingle(dst, src); return; } uint list[StacksLen]; - uint free = gameFree(list); + uint free = freeCells(list, dst); if (free < depth - 1) return; - undo = queue.w; + queue.u = queue.w; for (uint i = 0; i < depth - 1; ++i) { - gameEnqueue(list[i], src); + enqueue(list[i], src); } - gameEnqueue(dst, src); + enqueue(dst, src); for (uint i = depth - 2; i < depth - 1; --i) { - gameEnqueue(dst, list[i]); + enqueue(dst, list[i]); } } @@ -280,37 +279,15 @@ static void err(const char *title) { exit(EXIT_FAILURE); } -static Card hiliteRank; -static SDL_Point revealPoint; -static uint sourceStack = StacksLen; - -enum Choice { - Cancel, - Column, - Single, -}; - -static enum Choice chooseMove(void) { +static bool playAgain(void) { SDL_MessageBoxButtonData buttons[] = { - { - .buttonid = Column, - .text = "Move column", - .flags = SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, - }, - { - .buttonid = Single, - .text = "Move single card", - }, - { - .buttonid = Cancel, - .text = "Cancel", - .flags = SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, - }, + { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, true, "Yes" }, + { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, false, "No" }, }; SDL_MessageBoxData data = { .window = window, - .title = "Move to Empty Column...", - .message = "", + .title = "Game Over", + .message = "Congratulations, you win!\n\nDo you want to play again?", .buttons = buttons, .numbuttons = SDL_arraysize(buttons), }; @@ -319,23 +296,22 @@ static enum Choice chooseMove(void) { return choice; } -static bool chooseAgain(void) { +enum Choice { + Cancel, + Column, + Single, +}; + +static enum Choice chooseMove(void) { SDL_MessageBoxButtonData buttons[] = { - { - .buttonid = true, - .text = "Yes", - .flags = SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, - }, - { - .buttonid = false, - .text = "No", - .flags = SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, - }, + { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, Column, "Move column" }, + { 0, Single, "Move single card" }, + { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, Cancel, "Cancel" }, }; SDL_MessageBoxData data = { .window = window, - .title = "Game Over", - .message = "Congratulations, you win!\n\nDo you want to play again?", + .title = "Move to Empty Column...", + .message = "", .buttons = buttons, .numbuttons = SDL_arraysize(buttons), }; @@ -344,10 +320,14 @@ static bool chooseAgain(void) { return choice; } +static Card hiliteRank; +static SDL_Point revealPoint; +static uint fromStack = StacksLen; + static bool keyDown(SDL_KeyboardEvent key) { switch (key.keysym.sym) { - case SDLK_F2: gameDeal(); return true; - case SDLK_BACKSPACE: return gameUndo(); + case SDLK_F2: deal(); return true; + case SDLK_BACKSPACE: return undo(); } if (key.repeat) return false; switch (key.keysym.sym) { @@ -389,12 +369,9 @@ static bool mouseButtonDown(SDL_MouseButtonEvent button) { } static bool mouseButtonUp(SDL_MouseButtonEvent button) { - if (gameWin()) { - if (chooseAgain()) { - gameDeal(); - return true; - } - return false; + if (win() && playAgain()) { + deal(); + return true; } if (button.button == SDL_BUTTON_RIGHT && revealPoint.x) { @@ -411,25 +388,24 @@ static bool mouseButtonUp(SDL_MouseButtonEvent button) { } } - if (sourceStack < StacksLen && stack < StacksLen) { - if (gameDepth(sourceStack) > 1 && stack > Cell4 && !stacks[stack].len) { + if (fromStack < StacksLen && stack < StacksLen) { + if (moveDepth(fromStack) > 1 && stack > Cell4 && !stacks[stack].len) { switch (chooseMove()) { - break; case Single: gameMoveSingle(stack, sourceStack); - break; case Column: gameMoveColumn(stack, sourceStack); + break; case Single: moveSingle(stack, fromStack); + break; case Column: moveColumn(stack, fromStack); break; case Cancel: break; } } else { - gameMoveColumn(stack, sourceStack); + moveColumn(stack, fromStack); } } - if (sourceStack < StacksLen) { - sourceStack = StacksLen; + if (fromStack < StacksLen) { + fromStack = StacksLen; return true; } - if (stack < StacksLen && stack > Foundation4 && stacks[stack].len) { - sourceStack = stack; + fromStack = stack; return true; } @@ -471,7 +447,7 @@ static void renderOutlines(void) { static void renderKing(void) { SDL_Rect box = { KingX, KingY, KingWidth, KingHeight }; renderOutline(box, true); - if (gameWin()) { + if (win()) { SDL_Rect king = { KingWinX, KingWinY, KingWinWidth, KingWinHeight }; SDL_RenderCopy(render, tex.kings[Cards_KingWin], NULL, &king); } else { @@ -498,7 +474,7 @@ static void renderStack(uint stack) { revealCard = card; revealRect = rect; } - bool hilite = (stack == sourceStack && i == stacks[stack].len - 1); + bool hilite = (stack == fromStack && i == stacks[stack].len - 1); renderCard(rect, card, hilite || cardRank(card) == hiliteRank); rect.y += StackDeltaY; } @@ -511,7 +487,7 @@ static void renderStacks(void) { for (uint i = Foundation1; i <= Cell4; ++i) { Card card = stackTop(&stacks[i]); if (!card) continue; - bool hilite = (i == sourceStack || cardRank(card) == hiliteRank); + bool hilite = (i == fromStack || cardRank(card) == hiliteRank); renderCard(rects[i], card, hilite); } for (uint i = Tableau1; i <= Tableau8; ++i) { @@ -587,7 +563,7 @@ int main(void) { } srand(time(NULL)); - gameDeal(); + deal(); initRects(); for (;;) { @@ -599,8 +575,8 @@ int main(void) { SDL_RenderPresent(render); if (queue.r < queue.w) { - gameDequeue(); - if (queue.r == queue.w) gameAuto(); + dequeue(); + if (queue.r == queue.w) autoEnqueue(); if (queue.r < queue.w) SDL_Delay(50); continue; } |