diff --git a/Solitaire/main.cpp b/Solitaire/main.cpp index 46e94d5..5599e43 100644 --- a/Solitaire/main.cpp +++ b/Solitaire/main.cpp @@ -51,75 +51,89 @@ class Solitaire : public olc::PixelGameEngine } } + void RenderCard(vf2d pos, Suit s, int number) { + if (number == -1) { return; } + if (s == FACEDOWN) { + FillRectDecal(pos, CARD_SIZE, DARK_CYAN); + DrawRectDecal(pos, CARD_SIZE, BLACK); + } + else { + FillRectDecal(pos, CARD_SIZE, WHITE); + DrawStringDecal(pos + vf2d{ 2,2 }, number == 1 ? "A" : number == 13 ? "K" : number == 12 ? "Q" : number == 11 ? "J" : std::to_string(number), s == CLUB || s == SPADE ? BLACK : DARK_RED, number == 10 ? vf2d{ 0.6,1 } : vf2d{ 1,1 }); + DrawDecal(pos + vf2d{ 2,12 }, GetSprite(s), { 0.25,0.25 }); + DrawRotatedStringDecal(pos + CARD_SIZE - vf2d{ 2,2 }, number == 1 ? "A" : number == 13 ? "K" : number == 12 ? "Q" : number == 11 ? "J" : std::to_string(number), PI, { 0,0 }, s == CLUB || s == SPADE ? BLACK : DARK_RED, number == 10 ? vf2d{ 0.6,1 } : vf2d{ 1,1 }); + DrawRotatedDecal(pos + CARD_SIZE - vf2d{ 2,12 }, GetSprite(s), PI, { 0,0 }, { 0.25, 0.25 }); + DrawRectDecal(pos, CARD_SIZE, BLACK); + } + } + struct CardSlot { vf2d pos; SlotType type; std::vector faceDownCards; std::vector faceUpCards; - std::vector flippedOverCards; //Just for active play deck. Face up cards will contain the rest of the pile. - void RenderCard(vf2d pos, Suit s, int number) { - if (s == FACEDOWN) { - game->FillRectDecal(pos, CARD_SIZE, DARK_CYAN); - game->DrawRectDecal(pos, CARD_SIZE, BLACK); - } - else { - game->FillRectDecal(pos, CARD_SIZE, WHITE); - game->DrawStringDecal(pos + vf2d{ 2,2 }, number == 1 ? "A" : number == 13 ? "K" : number == 12 ? "Q" : number == 11 ? "J" : std::to_string(number), s == CLUB || s == SPADE ? BLACK : DARK_RED, number == 10 ? vf2d{ 0.6,1 } : vf2d{ 1,1 }); - game->DrawDecal(pos + vf2d{ 2,12 }, game->GetSprite(s), { 0.25,0.25 }); - game->DrawRotatedStringDecal(pos + CARD_SIZE - vf2d{ 2,2 }, number == 1 ? "A" : number == 13 ? "K" : number == 12 ? "Q" : number == 11 ? "J" : std::to_string(number), PI, { 0,0 }, s == CLUB || s == SPADE ? BLACK : DARK_RED, number == 10 ? vf2d{ 0.6,1 } : vf2d{ 1,1 }); - game->DrawRotatedDecal(pos + CARD_SIZE - vf2d{ 2,12 }, game->GetSprite(s), PI, { 0,0 }, { 0.25, 0.25 }); - game->DrawRectDecal(pos, CARD_SIZE, BLACK); - } - } void RenderCards() { game->DrawRectDecal(pos, CARD_SIZE, BLACK); switch (type) { case PLAYDECK: { if (faceDownCards.size() > 6*3) { - RenderCard(pos+vi2d{-2,-2}, FACEDOWN, 0); - RenderCard(pos + vi2d{ -1,-1 }, FACEDOWN, 0); - RenderCard(pos, FACEDOWN, 0); + game->RenderCard(pos+vi2d{-2,-2}, FACEDOWN, 0); + game->RenderCard(pos + vi2d{ -1,-1 }, FACEDOWN, 0); + game->RenderCard(pos, FACEDOWN, 0); } else if (faceDownCards.size() > 3 * 3) { - RenderCard(pos + vi2d{ -1,-1 }, FACEDOWN, 0); - RenderCard(pos, FACEDOWN, 0); + game->RenderCard(pos + vi2d{ -1,-1 }, FACEDOWN, 0); + game->RenderCard(pos, FACEDOWN, 0); } - else { - RenderCard(pos, FACEDOWN, 0); + else + if (faceDownCards.size()>0){ + game->RenderCard(pos, FACEDOWN, 0); } }break; case ACTIVE_PLAYDECK: { - if (flippedOverCards.size() > 0) { - for (int i = 0; i < flippedOverCards.size(); i++) { - Card& c = flippedOverCards[i]; - RenderCard(pos + vi2d{ i * 12,0 }, c.s, c.number); + if (faceUpCards.size() > 2) { + if (faceUpCards.size() >= 4) { + Card& c = faceUpCards[faceUpCards.size() - 3 - 1]; + game->RenderCard(pos + vi2d{ -1,-1 }, c.s, c.number); } - } else { - if (faceUpCards.size() > 0) { - Card& c = faceUpCards[faceUpCards.size() - 1]; - RenderCard(pos, c.s, c.number); + for (int i = 2; i >=0; i--) { + Card& c = faceUpCards[faceUpCards.size() - i - 1]; + game->RenderCard(pos + vi2d{ (2-i) * 12,0 }, c.s, c.number); + } + } else + if (faceUpCards.size() > 1) { + for (int i = 1; i >= 0; i--) { + Card& c = faceUpCards[faceUpCards.size() - i - 1]; + game->RenderCard(pos + vi2d{ (1 - i) * 12,0 }, c.s, c.number); + } + } + else + if (faceUpCards.size() == 1) { + for (int i = 0; i >= 0; i--) { + Card& c = faceUpCards[faceUpCards.size() - i - 1]; + game->RenderCard(pos + vi2d{ (0 - i) * 12,0 }, c.s, c.number); } } }break; case HOME: { if (faceUpCards.size() > 2) { Card& c = faceUpCards[faceUpCards.size() - 1]; - RenderCard(pos+vi2d{-2,-2}, c.s, c.number); + game->RenderCard(pos+vi2d{-2,-2}, c.s, c.number); c = faceUpCards[faceUpCards.size() - 2]; - RenderCard(pos + vi2d{ -1,-1 }, c.s, c.number); + game->RenderCard(pos + vi2d{ -1,-1 }, c.s, c.number); c = faceUpCards[faceUpCards.size() - 3]; - RenderCard(pos, c.s, c.number); + game->RenderCard(pos, c.s, c.number); } else if (faceUpCards.size() > 1) { Card& c = faceUpCards[faceUpCards.size() - 1]; - RenderCard(pos + vi2d{ -1,-1 }, c.s, c.number); + game->RenderCard(pos + vi2d{ -1,-1 }, c.s, c.number); c = faceUpCards[faceUpCards.size() - 2]; - RenderCard(pos, c.s, c.number); + game->RenderCard(pos, c.s, c.number); } else if (faceUpCards.size() == 1) { Card& c = faceUpCards[faceUpCards.size() - 1]; - RenderCard(pos, c.s, c.number); + game->RenderCard(pos, c.s, c.number); } }break; case FIELD: { @@ -131,12 +145,12 @@ class Solitaire : public olc::PixelGameEngine spaceTakenUp = CARD_SIZE.y + totalCards * cardSpacing; } for (int i = 0; i < faceDownCards.size(); i++) { - RenderCard(pos + vi2d{ 0,i * cardSpacing },FACEDOWN, 0); + game->RenderCard(pos + vi2d{ 0,i * cardSpacing },FACEDOWN, 0); } if (faceUpCards.size() > 0) { for (int i = 0; i < faceUpCards.size(); i++) { Card& c = faceUpCards[i]; - RenderCard(pos + vi2d{ 0,(i+(int)faceDownCards.size()) * cardSpacing }, c.s, c.number); + game->RenderCard(pos + vi2d{ 0,(i+(int)faceDownCards.size()) * cardSpacing }, c.s, c.number); } } }break; @@ -144,6 +158,54 @@ class Solitaire : public olc::PixelGameEngine } }; + bool MouseOver(CardSlot& slot) { + switch (slot.type) { + case PLAYDECK: { + return GetMouseX() >= slot.pos.x && GetMouseX() <= slot.pos.x + CARD_SIZE.x && + GetMouseY() >= slot.pos.y && GetMouseY() <= slot.pos.y + CARD_SIZE.y; + }break; + case ACTIVE_PLAYDECK: { + return GetMouseX() >= slot.pos.x && GetMouseX() <= slot.pos.x + CARD_SIZE.x && + GetMouseY() >= slot.pos.y && GetMouseY() <= slot.pos.y + CARD_SIZE.y; + }break; + } + return false; + } + void UpdateCardSlots() { + if (GetMouse(0).bPressed&&MouseOver(PlayDeck)) { + if (PlayDeck.faceDownCards.size() > 0) { + for (int i = 0; i < 3; i++) { + if (PlayDeck.faceDownCards.size() > 0) { + Card c = PlayDeck.faceDownCards[PlayDeck.faceDownCards.size() - 1]; + ActivePlayDeck.faceUpCards.push_back(c); + PlayDeck.faceDownCards.erase(PlayDeck.faceDownCards.end() - 1); + } + } + } + else { + while (ActivePlayDeck.faceUpCards.size() > 0) { + Card c = ActivePlayDeck.faceUpCards[ActivePlayDeck.faceUpCards.size() - 1]; + PlayDeck.faceDownCards.push_back(c); + ActivePlayDeck.faceUpCards.erase(ActivePlayDeck.faceUpCards.end() - 1); + } + } + } + if (GetMouse(0).bPressed && MouseOver(ActivePlayDeck)) { + if (ActivePlayDeck.faceUpCards.size() > 0) { + Card& card = ActivePlayDeck.faceUpCards[ActivePlayDeck.faceUpCards.size() - 1]; + draggedCard = { card.s,card.number }; + previousCardInteraction = &ActivePlayDeck.faceUpCards[ActivePlayDeck.faceUpCards.size() - 1]; + ActivePlayDeck.faceUpCards[ActivePlayDeck.faceUpCards.size() - 1].number = -1; + } + } + + if (GetMouse(0).bReleased && draggedCard.number !=-1) { + previousCardInteraction->number = draggedCard.number; + previousCardInteraction->s = draggedCard.s; + draggedCard.number = -1; + } + } + public: Solitaire() @@ -158,6 +220,8 @@ class Solitaire : public olc::PixelGameEngine CardSlot ActivePlayDeck{ {56,8},ACTIVE_PLAYDECK }; std::array Home; std::array Field; + Card draggedCard = {HEART,-1}; + Card*previousCardInteraction=NULL; Card DrawCard() { std::uniform_int_distribution distribution(0, cardDeck.size()-1); @@ -206,6 +270,9 @@ class Solitaire : public olc::PixelGameEngine { // called once per frame //RenderCard({ 48,48 }, HEART, 7); + + UpdateCardSlots(); + PlayDeck.RenderCards(); ActivePlayDeck.RenderCards(); for (CardSlot& c : Home) { @@ -214,6 +281,7 @@ class Solitaire : public olc::PixelGameEngine for (CardSlot& c : Field) { c.RenderCards(); } + RenderCard(GetMousePos() - CARD_SIZE/2, draggedCard.s, draggedCard.number); return true; } };