|
|
|
@ -1,21 +1,24 @@ |
|
|
|
|
#define OLC_PGE_APPLICATION |
|
|
|
|
#include "pixelGameEngine.h" |
|
|
|
|
#include <random> |
|
|
|
|
|
|
|
|
|
using namespace olc; |
|
|
|
|
|
|
|
|
|
const float PI = 3.14159f; |
|
|
|
|
const vi2d CARD_SIZE = vi2d{32,48}; |
|
|
|
|
|
|
|
|
|
PixelGameEngine*game; |
|
|
|
|
class Solitaire; |
|
|
|
|
Solitaire*game; |
|
|
|
|
|
|
|
|
|
class Example : public olc::PixelGameEngine |
|
|
|
|
class Solitaire : public olc::PixelGameEngine |
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
std::default_random_engine generator; |
|
|
|
|
Renderable club_spr, spade_spr, diamond_spr, heart_spr; |
|
|
|
|
enum Suit { |
|
|
|
|
SPADE, |
|
|
|
|
CLUB, |
|
|
|
|
DIAMOND, |
|
|
|
|
HEART, |
|
|
|
|
DIAMOND |
|
|
|
|
SPADE, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
enum SlotType { |
|
|
|
@ -30,6 +33,23 @@ struct Card { |
|
|
|
|
int number; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
Decal*GetSprite(Suit s) { |
|
|
|
|
switch (s) { |
|
|
|
|
case CLUB: { |
|
|
|
|
return club_spr.Decal(); |
|
|
|
|
}break; |
|
|
|
|
case DIAMOND: { |
|
|
|
|
return diamond_spr.Decal(); |
|
|
|
|
}break; |
|
|
|
|
case HEART: { |
|
|
|
|
return heart_spr.Decal(); |
|
|
|
|
}break; |
|
|
|
|
case SPADE: { |
|
|
|
|
return spade_spr.Decal(); |
|
|
|
|
}break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct CardSlot { |
|
|
|
|
vf2d pos; |
|
|
|
|
SlotType type; |
|
|
|
@ -38,11 +58,14 @@ struct CardSlot { |
|
|
|
|
std::vector<Card> flippedOverCards; //Just for active play deck. Face up cards will contain the rest of the pile.
|
|
|
|
|
void RenderCard(vf2d pos, Suit s, int number) { |
|
|
|
|
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 ? BLACK : DARK_RED, number == 10 ? vf2d{0.6,1} : vf2d{1,1}); |
|
|
|
|
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 ? BLACK : DARK_RED, number == 10 ? vf2d{ 0.6,1 } : vf2d{ 1,1 }); |
|
|
|
|
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() > 0) { |
|
|
|
@ -62,30 +85,69 @@ struct CardSlot { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}break; |
|
|
|
|
case HOME: { |
|
|
|
|
if (faceUpCards.size() > 0) { |
|
|
|
|
Card& c = faceUpCards[faceUpCards.size() - 1]; |
|
|
|
|
RenderCard(pos, c.s, c.number); |
|
|
|
|
} |
|
|
|
|
}break; |
|
|
|
|
case FIELD: { |
|
|
|
|
if (faceUpCards.size() > 0) { |
|
|
|
|
for (int i = 0; i < faceUpCards.size(); i++) { |
|
|
|
|
Card& c = faceUpCards[i]; |
|
|
|
|
RenderCard(pos + vi2d{ 0,i * 16 }, c.s, c.number); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else
|
|
|
|
|
if (faceDownCards.size()>0){ |
|
|
|
|
game->FillRectDecal(pos, CARD_SIZE, DARK_CYAN); |
|
|
|
|
} |
|
|
|
|
}break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
|
|
|
|
|
Example() |
|
|
|
|
Solitaire() |
|
|
|
|
{ |
|
|
|
|
sAppName = "Solitaire"; |
|
|
|
|
game = this; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
std::vector<Card> cardDeck; |
|
|
|
|
CardSlot PlayDeck{ {16,8},PLAYDECK }; |
|
|
|
|
CardSlot ActivePlayDeck{ {56,8},ACTIVE_PLAYDECK }; |
|
|
|
|
std::array<CardSlot, 4> Home; |
|
|
|
|
std::array<CardSlot, 7> Field; |
|
|
|
|
|
|
|
|
|
Card DrawCard() { |
|
|
|
|
std::uniform_int_distribution<int> distribution(0, cardDeck.size()-1); |
|
|
|
|
int dice_roll = distribution(generator); |
|
|
|
|
std::cout << dice_roll << std::endl; |
|
|
|
|
Card drawnCard = cardDeck[dice_roll]; |
|
|
|
|
cardDeck.erase(cardDeck.begin() + dice_roll); |
|
|
|
|
return drawnCard; |
|
|
|
|
} |
|
|
|
|
bool OnUserCreate() override |
|
|
|
|
{ |
|
|
|
|
PlayDeck.faceDownCards.push_back({SPADE,4}); |
|
|
|
|
ActivePlayDeck.faceUpCards.push_back({ CLUB,9 }); |
|
|
|
|
ActivePlayDeck.flippedOverCards.push_back({ HEART,3 }); |
|
|
|
|
ActivePlayDeck.flippedOverCards.push_back({ HEART,10 }); |
|
|
|
|
ActivePlayDeck.flippedOverCards.push_back({ SPADE,1 }); |
|
|
|
|
for (int i = 0; i <= SPADE; i++) { |
|
|
|
|
for (int j = 1; j < 14; j++) { |
|
|
|
|
cardDeck.push_back({ (Suit)i,j }); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
Clear(VERY_DARK_GREEN); |
|
|
|
|
club_spr.Load("assets/club.png"); |
|
|
|
|
diamond_spr.Load("assets/diamond.png"); |
|
|
|
|
heart_spr.Load("assets/heart.png"); |
|
|
|
|
spade_spr.Load("assets/spade.png"); |
|
|
|
|
for (int i = 0; i < Field.size(); i++) { |
|
|
|
|
for (int j = 0; j < i; j++) { |
|
|
|
|
Field[i].faceDownCards.push_back(DrawCard()); |
|
|
|
|
} |
|
|
|
|
Field[i].faceUpCards.push_back(DrawCard()); |
|
|
|
|
} |
|
|
|
|
for (int i = 0; i < Home.size();i++) { |
|
|
|
|
CardSlot&c = Home[i]; |
|
|
|
|
c.pos = vi2d{ 136 + i * 40,8 }; |
|
|
|
@ -96,6 +158,9 @@ public: |
|
|
|
|
c.pos = vi2d{ 16 + i * 40,64 }; |
|
|
|
|
c.type = SlotType::FIELD; |
|
|
|
|
} |
|
|
|
|
while (cardDeck.size()>0) { |
|
|
|
|
PlayDeck.faceDownCards.push_back(DrawCard()); |
|
|
|
|
} |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -118,7 +183,7 @@ public: |
|
|
|
|
|
|
|
|
|
int main() |
|
|
|
|
{ |
|
|
|
|
Example demo; |
|
|
|
|
Solitaire demo; |
|
|
|
|
if (demo.Construct(312, 200, 4, 4)) |
|
|
|
|
demo.Start(); |
|
|
|
|
|
|
|
|
|