diff options
Diffstat (limited to 'sol.c')
-rw-r--r-- | sol.c | 170 |
1 files changed, 40 insertions, 130 deletions
diff --git a/sol.c b/sol.c index 16a688f..f91310a 100644 --- a/sol.c +++ b/sol.c @@ -22,12 +22,11 @@ #include <time.h> #include "cards.h" +#include "layout.h" #include "stack.h" #define ARRAY_LEN(a) (sizeof(a) / sizeof((a)[0])) -typedef unsigned uint; - enum { Stock, Waste1, @@ -189,129 +188,47 @@ enum { TableauX = StackMarginX, TableauY = StockY + Cards_Height + StackMarginY, - StackDeltaX = 2, - StackDeltaY = 1, - - Waste3DeltaX = 14, - Waste3DeltaY = StackDeltaY, - - TableauDeltaX = 0, - TableauDeltaYBack = 3, - TableauDeltaYFront = 15, - WindowWidth = 7 * Cards_Width + 8 * StackMarginX, WindowHeight = 2 * (StackMarginY + Cards_Height) - + 6 * TableauDeltaYBack - + 12 * TableauDeltaYFront + + 6 * FanDownDeltaYBack + + 12 * FanDownDeltaYFront + StackMarginY, }; -struct Item { - SDL_Rect rect; - uint texture; - Card card; -}; - -struct List { - uint len; - struct Item items[52]; -}; - -static void listPush(struct List *list, struct Item item) { - assert(list->len < 52); - list->items[list->len++] = item; -} - -static struct { - SDL_Rect stacks[StacksLen]; - struct List base; - struct List main; - struct List drag; - struct Item dragItem; - uint backTexture; -} layout; - -static struct Item *layoutFind(const SDL_Point *point) { - for (uint i = layout.main.len - 1; i < layout.main.len; --i) { - if (SDL_PointInRect(point, &layout.main.items[i].rect)) { - return &layout.main.items[i]; - } - } - return NULL; -} - -static void layoutClear(void) { - layout.base.len = 0; - layout.main.len = 0; - layout.drag.len = 0; -} +static const struct Style FanWaste3 = { 1, 14, SquareDeltaY, 14, SquareDeltaY }; -static void layoutCard(struct List **list, SDL_Rect *rect, Card card) { - if (card == layout.dragItem.card) { - *list = &layout.drag; - *rect = layout.dragItem.rect; - } - uint texture = (card > 0 ? (uint)card : layout.backTexture); - struct Item item = { *rect, texture, card }; - listPush(*list, item); -} +static struct SDL_Rect stackRects[StacksLen]; +static struct Layout layout; +static uint backTexture = Cards_Back1; -static void layoutStack(SDL_Rect *rect, const struct Stack *stack, uint depth) { - struct List *list = &layout.main; - for (uint i = 0; i < stack->len; ++i) { - layoutCard(&list, rect, stack->cards[i]); - if (i > 0 && i % (depth / 3) == 0) { - rect->x += StackDeltaX; - rect->y += StackDeltaY; - } - } -} +static void updateLayout(void) { + layoutClear(&layout); -static void layoutStock(void) { - SDL_Rect rect = { StockX, StockY, Cards_Width, Cards_Height }; - struct Item item = { rect, Cards_O, 0 }; - listPush(&layout.base, item); - layout.stacks[Stock] = rect; - layoutStack(&rect, &stacks[Stock], 24); -} + SDL_Rect stock = { StockX, StockY, Cards_Width, Cards_Height }; + stackRects[Stock] = stock; + listPush(&layout.main, &stock, Cards_O); + layoutStack(&layout, &stock, &stacks[Stock], &Square); -static void layoutWaste(void) { - SDL_Rect rect = { WasteX, WasteY, Cards_Width, Cards_Height }; - layoutStack(&rect, &stacks[Waste1], 24); - struct List *list = &layout.main; - for (uint i = 0; i < stacks[Waste3].len; ++i) { - layoutCard(&list, &rect, stacks[Waste3].cards[i]); - rect.x += Waste3DeltaX; - rect.y += Waste3DeltaY; - } -} + SDL_Rect waste = { WasteX, WasteY, Cards_Width, Cards_Height }; + layoutStack(&layout, &waste, &stacks[Waste1], &Square); + layoutStack(&layout, &waste, &stacks[Waste3], &FanWaste3); -static void layoutFoundations(void) { - SDL_Rect base = { FoundationX, FoundationY, Cards_Width, Cards_Height }; + SDL_Rect found = { FoundationX, FoundationY, Cards_Width, Cards_Height }; for (uint i = Foundation1; i <= Foundation4; ++i) { - struct Item item = { base, Cards_Empty, 0 }; - listPush(&layout.base, item); - layout.stacks[i] = base; - SDL_Rect rect = base; - layoutStack(&rect, &stacks[i], 13); - base.x += Cards_Width + StackMarginX; + stackRects[i] = found; + listPush(&layout.main, &found, Cards_Empty); + SDL_Rect rect = found; + layoutStack(&layout, &rect, &stacks[i], &Square); + found.x += Cards_Width + StackMarginX; } -} -static void layoutTableau(void) { - SDL_Rect base = { TableauX, TableauY, Cards_Width, Cards_Height }; + SDL_Rect table = { TableauX, TableauY, Cards_Width, Cards_Height }; for (uint i = Tableau1; i <= Tableau7; ++i) { - SDL_Rect stack = { base.x, base.y, base.w, WindowHeight }; - layout.stacks[i] = stack; - struct List *list = &layout.main; - SDL_Rect rect = base; - for (uint j = 0; j < stacks[i].len; ++j) { - Card card = stacks[i].cards[j]; - layoutCard(&list, &rect, card); - rect.x += TableauDeltaX; - rect.y += (card > 0 ? TableauDeltaYFront : TableauDeltaYBack); - } - base.x += Cards_Width + StackMarginX; + stackRects[i] = table; + stackRects[i].h = WindowHeight; + SDL_Rect rect = table; + layoutStack(&layout, &rect, &stacks[i], &FanDown); + table.x += Cards_Width + StackMarginX; } } @@ -320,10 +237,10 @@ static bool keyDown(SDL_KeyboardEvent key) { case SDLK_F2: gameDeal(); return true; case SDLK_BACKSPACE: return gameUndo(); case SDLK_b: { - layout.backTexture -= Cards_Back1; - layout.backTexture += 1; - layout.backTexture %= 12; - layout.backTexture += Cards_Back1; + backTexture -= Cards_Back1; + backTexture += 1; + backTexture %= 12; + backTexture += Cards_Back1; return true; } case SDLK_d: { @@ -337,11 +254,11 @@ static bool keyDown(SDL_KeyboardEvent key) { static bool mouseButtonDown(SDL_MouseButtonEvent button) { struct SDL_Point point = { button.x, button.y }; - if (SDL_PointInRect(&point, &layout.stacks[Stock])) { + if (SDL_PointInRect(&point, &stackRects[Stock])) { gameDraw(); return true; } - struct Item *item = layoutFind(&point); + struct Item *item = listFind(&layout.main, &point); if (!item) return false; if (!gameAvail(item->card)) return gameReveal(item->card); if (button.clicks % 2 == 0) { @@ -358,7 +275,7 @@ static bool mouseButtonUp(SDL_MouseButtonEvent button) { (void)button; if (!layout.dragItem.card) return false; for (uint dest = 0; dest < StacksLen; ++dest) { - if (SDL_HasIntersection(&layout.dragItem.rect, &layout.stacks[dest])) { + if (SDL_HasIntersection(&layout.dragItem.rect, &stackRects[dest])) { if (gameMove(dest, layout.dragItem.card)) break; } } @@ -379,11 +296,9 @@ static SDL_Texture *textures[Cards_Count]; static void renderList(const struct List *list) { for (uint i = 0; i < list->len; ++i) { - SDL_RenderCopy( - render, - textures[list->items[i].texture], - NULL, &list->items[i].rect - ); + int tex = list->items[i].card; + if (tex < 0) tex = backTexture; + SDL_RenderCopy(render, textures[tex], NULL, &list->items[i].rect); } } @@ -451,19 +366,14 @@ int main(void) { Cards_Free(cards); srand(time(NULL)); - layout.backTexture = Cards_Back1 + randUniform(12); + backTexture = Cards_Back1 + randUniform(12); gameDeal(); for (;;) { - layoutClear(); - layoutStock(); - layoutWaste(); - layoutFoundations(); - layoutTableau(); + updateLayout(); SDL_SetRenderDrawColor(render, 0x00, 0xAA, 0x55, 0xFF); SDL_RenderClear(render); - renderList(&layout.base); renderList(&layout.main); renderList(&layout.drag); SDL_RenderPresent(render); |