As a final project in my CS003A (Fundamentals of Computer Science II) class, students were asked to choose a game to create with two main rules. The program had to contain SFML to make a graphical interface, and it had to use a linked list (Stack/Queue).
1 - Clone the master repository (git clone https://github.com/Sebastian-git/Solitaire.git
)
2 - Install SFML here
3 - Run the program and enjoy!
( You do not need the folder "readmeImages", it just contains the preview images for Github )
The graphical display was created using SFML. In order to play the game, simply select a card by left clicking on it, then place it on a valid card. The game ends when you have all cards on the foundation (top four slots).
One of the most important parts of the program is the validMousePosition(sf::Vector2i pos)
function, which returns a boolean and handles nearly all of the logic to determine if there is a card where the user clicks. The function is a little over 50 lines of code, and is split into three main sections.
1 - If there is no card selected
if (!cardSelected) {
if (waste.containsPos(pos) && waste.getCardAt(pos).getOrientation() == 1) {
saveCard(waste.getCardAt(pos), pos);
saveCardClass = 1;
cardSelected = true;
return true;
} else if (tableau.containsPos(pos) && tableau.getCardAt(pos).getOrientation() == 1) {
tableau.saveCards(pos, tableau.getCardAt(pos), savedCards);
savedPos = pos;
saveCardClass = 2;
cardSelected = true;
return true;
}
}
2 - If a card is selected, check if you are allowed to place it on this new position
else if (cardSelected && (inStock(pos) || waste.containsPos(pos) || tableau.containsPos(pos)) || foundation.containsPos(pos)) {
// Tableau card placement logic
if (tableau.cascadeIsEmpty(pos) || (tableau.containsPos(pos) && validCardPlacement(tableau.getCardAt(pos)) &&
tableau.containsTopCard(tableau.getCardAt(pos)))) {
if (tableau.cascadeIsEmpty(pos) && savedCards[0].getRank() != 13) {
unsaveCard();
return false;
}
tableau.addCardAt(pos, savedCards);
if (saveCardClass == 1) waste.removeCardAt(savedPos);
else if (saveCardClass == 2) tableau.removeCardAt(savedPos);
}
// Foundation card placement logic
if (savedCards.size() == 1 && ((foundation.containsPos(pos)) && foundation.stackIsEmpty(pos) && savedCards[0].getRank() == 1 || (foundation.containsPos(pos) && foundation.validNextCard(savedCards[0], pos)))) {
foundation.addCardAt(pos, savedCards);
if (saveCardClass == 1) waste.removeCardAt(savedPos);
else if (saveCardClass == 2) tableau.removeCardAt(savedPos);
}
unsaveCard();
return true;
}
3 - If you are clicking off screen, unsave card
else {
unsaveCard();
}
C++ (GCC 9.2.0)
Visual Studio
In progress