Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cmath>
- #include <string>
- #include <stdio.h>
- #include <stdlib.h>
- #include <vector>
- #include <algorithm>
- #include <random>
- #include <ctime>
- #include <iomanip>
- using namespace std;
- class Card{
- friend ostream & operator<<(ostream &output, const Card &C){
- if(C.face && C.rank > 0){
- if(C.rank == 1){
- output << "A";
- }
- else if (C.rank == 11){
- output << "J";
- }
- else if (C.rank == 12){
- output << "Q";
- }
- else if (C.rank == 13){
- output << "K";
- }
- else{
- output << C.rank;
- }
- }
- else{
- if (C.rank > 0)
- output << "X";
- else
- output << " ";
- }
- return output;
- }
- public:
- Card(int r = 0, bool f = false){
- rank = r;
- face = f;
- }
- int getRank(){
- if(face && (rank>0)){
- return rank;
- }
- else{
- return -1;
- }
- }
- int getTrueRank(){
- return rank;
- }
- void setRank(Card c){
- face = c.face;
- rank = c.rank;
- }
- void setRank(){
- face = false;
- rank = 0;
- }
- bool getFace(){
- return face;
- }
- void flip(){
- face = true;
- }
- private:
- int rank;
- bool face;
- };
- vector<Card> writeDeck(int decks){
- vector<Card> deck;
- int repeats = decks*4;
- for(int i = 0;i<repeats;i++){
- for(int j = 1;j<=13;j++){
- Card c =Card(j);
- deck.push_back(c);
- }
- }
- random_shuffle(deck.begin(), deck.end());
- return deck;
- }
- vector<vector<Card>> makeBoard(vector<Card>& deck){
- Card t;
- vector<vector<Card>> board(5,vector<Card> (10,t));
- for(int i = 0;i<4;i++){
- for(int j = 0;j<10;j++){
- board[i][j] = deck.back();
- deck.pop_back();
- }
- }
- for(int i = 0;i<4;i++){
- board[4][i] = deck.back();
- deck.pop_back();
- }
- for(int i =4;i<10;i++){
- deck.back().flip();
- board[4][i] = deck.back();
- deck.pop_back();
- }
- board.resize(7,vector<Card>(10,t));
- for(int i =0;i<4;i++){
- deck.back().flip();
- board[5][i] = deck.back();
- deck.pop_back();
- }
- return board;
- }
- void checkAndRemoveMatch(vector<vector<Card>> b){
- // Not Tested
- bool match = true;
- for (int i = 0; i < 10; i ++){
- for (int j = 0; j < b.size(); j++){
- //when king found
- if (b[j][i].getRank() == 13){
- for (int k =j; k < b.size(); k++){
- if (b[k+1][i].getRank() == 0){
- break;
- }
- if (!(b[k][i].getRank() == b[k+1][i].getRank()+1)){
- match = false;
- break;
- }
- }
- if (match){
- for (int k =b.size()-1; k >j; k--){
- b[k][i].setRank();
- }
- }
- }
- }
- }
- }
- bool checkWin(vector<vector<Card>> b, vector<Card> d){
- // slightly Tested
- bool win = true;
- for (int i = 0; i < b.size() -1; i++){
- for (int j = 0; j < 10; j++){
- if (b[i][j].getRank() != 0){
- win = false;
- break;
- }
- }
- if (!win){
- break;
- }
- }
- if (win && d.size() == 0){
- return true;
- } else {
- return false;
- }
- }
- bool checkLose (vector<vector<Card>> b, vector<Card> d){
- // kill me
- // Not Tested
- // probably wont work, but might
- if (!(d.size() > 0)){
- bool canMoveSomething = false;
- for (int i = 0; i < 10; i++){
- for (int j = 0; j < b[i].size(); i++){
- bool placeable = false;
- bool moveable = true;
- if (b[i][j].getFace()){
- //card can be seen
- if (b[i][j].getRank() == 13){
- // is a king, moving wont matter
- moveable = false;
- }
- for (int k = j; j < b[i].size()-1; i++){
- // make sure everything below is moveable with the moving card
- if (!(b[i][k].getRank() == b[i][k+1].getRank()+1)){
- moveable = false;
- }
- }
- }else{
- placeable = false;
- }
- if (moveable){
- //card can be picked up
- // find where it can be placed
- int rankMatch = b[i][j].getRank() + 1;
- for (int k = 0; k < 10; k++){
- // ugly but looking for last card in each column and seeing if we can place stack there
- if (b[k][b[k].size()-1].getRank() == rankMatch){
- placeable==true;
- }
- }
- }
- if (placeable){
- // no need to look anymore in this column and hopefully should rule out moving a 6 on top of a 7 and counting it as a helpful move (it's not)
- canMoveSomething = true;
- break;
- }
- }
- }
- }
- }
- void displayBoard(vector<vector<Card>> b){
- for(int i = 0;i<b.size();i++){
- for(int j = 0;j<10;j++){
- cout << " " << setw(3) << b[i][j];
- }
- cout << endl;
- }
- }
- Card dealCard(vector<Card> &d){
- Card r = d.back();
- d.pop_back();
- r.flip();
- return r;
- }
- void newGame(vector<vector<Card>> &b, vector<Card> &d){
- cout <<"Please pick a difficulty: " << endl;
- cout <<"1) Easy (2 decks or 104 cards)" << endl;
- cout <<"2) Medium (4 decks or 208 cards)" << endl;
- cout <<"3) Hard (6 decks or 312 cards)" << endl;
- int difficulty;
- cin >> difficulty;
- while (difficulty < 1 || difficulty > 3){
- cout <<"Please pick a difficulty: " << endl;
- cout <<"1) Easy (2 decks or 104 cards)" << endl;
- cout <<"2) Medium (4 decks or 208 cards)" << endl;
- cout <<"3) Hard (6 decks or 312 cards)" << endl;
- cin >> difficulty;
- }
- d = writeDeck(2*difficulty);
- b = makeBoard(d);
- }
- int main(){
- srand(time(NULL));
- Card t;
- vector<vector<Card>> board;
- vector<Card> deck;
- bool game = true, play = true;
- cout << "Welcome to Spider Solitaire :D\n" << endl;
- cout << "Instructions: \n The goal of the game is to place King through ace in order on the board."<<endl;
- cout <<"You win the game when there are no more cards left in the deck or on the board. "<<endl;
- cout << "1. pick and action"<<endl;
- cout << "2. To move a card choose the row and column of the card you wish to move and the row and collum of the card you wish to place it on."<<endl;
- cout << "3. You can restart the game at anytime."<< endl;
- newGame(board, deck);
- while(play){
- while(game){
- displayBoard(board);
- cout << "Options: " << endl;
- cout << "1) Move a card" << endl;
- cout << "2) New row from deck" << endl;
- cout << "3) Deck Size" << endl;
- cout << "4) Get a position from a value" << endl;
- cout << "5) New Game" << endl;
- int input;
- cin >> input;
- switch (input){
- case 0:{
- cout << "Dealer Area accessed: " << endl;
- cout << "1) See the deck " << endl;
- cout << "2) Size of board " << endl;
- cout << "3) See any card" << endl;
- cout << "4) Win the game" << endl;
- cout << "5) Free clear board" << endl;
- cout << "6) Lost game board " << endl;
- int ip;
- cin >> ip;
- switch (ip){
- case 1:
- for(int i = 0;i<deck.size();i++){
- cout << i << ") " << deck.at(i).getTrueRank() << " ";
- break;
- }
- case 2:
- cout << "Rows: " << board.size() << " " ;
- cout << "Columns: " << board[0].size();
- break;
- case 3:{
- int r1, c1;
- cout << "Which row? " << endl;
- cin >> r1;
- cout << "Which column? " << endl;
- cin >> c1;
- r1--;c1--;
- cout << "You picked a " << board[r1][c1].getTrueRank() << endl;
- break;
- }
- case 4:{
- game = false;
- }
- case 5:{
- Card t;
- board.resize(0,vector<Card>(10,t));
- board.resize(13,vector<Card>(10,t));
- for(int i = 0;i<12;i++){
- board[i][0] = Card(13-i, true);
- }
- board[6][1] = Card(1, true);
- break;
- }
- case 6:{
- board.resize(0,vector<Card>(10,t));
- deck.resize(0);
- board.resize(13,vector<Card>(10,t));
- for(int i =0;i<10;i++){
- board[0][i] = Card(1, true);
- }
- }
- cout << endl;
- }
- break;
- }
- case 1:{
- int r1, c1, r2, c2;
- cout << "Which row to move from? " << endl;
- cin >> r1;
- cout << "Which column to move from? " << endl;
- cin >> c1;
- r1--;c1--;
- bool validMove = false;
- //test for valid move
- if(r1 > board.size()){
- validMove = false;
- }
- else{
- if(board[r1][c1].getRank() != -1 && board[r1][c1].getRank() != 0){
- validMove = true;
- }
- bool checkBelow = true;
- int i = r1;
- //Needs more testing, sometimes gives inifinate while loop and breaks
- while (!(board[i+1][c1].getRank() <= 0)&&!(i == board.size() -2)){
- int one = board[i][c1].getRank();
- int two = board[i+1][c1].getRank()+1;
- if(one != two){
- checkBelow = false;
- }
- i++;
- }
- validMove = checkBelow;
- if (board[r1][c1].getFace() == false){
- validMove = false;
- }
- }
- if (!validMove){
- cout <<"Error, that is not a valid move" << endl;
- }
- else{
- cout << "You chose a " << board[r1][c1] << endl;
- cout << "Which row to move to? " << endl;
- cin >> r2;
- cout << "Which column to move to? " << endl;
- cin >> c2;
- r2--;c2--;
- bool validPlace = true;
- //test for valid place
- // is giving errors
- if(r2 > board.size()){
- validPlace = false;
- }
- else{
- if(board[r2+1][c2].getRank() > 0){
- validPlace = false;
- }
- if(board[r2][c2].getRank() -1 != board[r1][c1].getRank()){
- validPlace = false;
- }
- //Not Tested
- else if (r2 == 0 && board[r2][c2].getRank() == 0 && r2 < board.size()){
- //when the card spot is blank at the beginning (row 0) a card can be placed there
- validPlace = true;
- }
- }
- if (!validPlace){
- cout <<"Error, that is not a valid move" << endl;
- }
- else {
- //Tried to add way for whole row to be moved with cards (like move 7 and 6)
- //tested slightly
- // had an error trying to move card in row 1
- vector<Card> row;
- for (int i = r1; i < board.size(); i++){
- if (board[i][c1].getRank() >0){
- board[i][c1].flip();
- row.push_back(board[i][c1]);
- board[i][c1].setRank();
- }
- }
- if (r1 > 0){
- board[r1-1][c1].flip();
- }
- if (r2+row.size()+1 >= board.size()){
- board.resize(r2+row.size()+2,vector<Card>(10,t));
- }
- for (int i = r2; i < r2+row.size(); i ++){
- board[i+1][c2] = row.at(i-r2);
- }
- // old solution just in case
- /*
- board[r2+1][c2].setRank(board[r1][c1].getTrueRank());
- board[r2+1][c2].flip();
- board[r1-1][c1].flip();
- board[r1][c1].setRank();
- */
- }
- }
- break;
- }
- case 2:{
- // needs testing
- /*
- bool freeSpot = false;
- for (int i =0; i < 10; i++){
- if (board[0][i].getRank() == 0){
- freeSpot = true;
- }
- } */
- if (deck.size() > 0){
- //each column
- for(int i = 0;i < 10;i++){
- //search column to find the last filled entry.
- int j = 0;
- while((board[j][i].getTrueRank()!= 0)&&(j!=board.size())){
- j++;
- if (j == board.size()){
- break;
- }
- }
- if (j == board.size()){
- board.resize(j+2,vector<Card>(10,t));
- }
- if(board[j][i].getTrueRank()==-1){
- board[j+1][i] = dealCard(deck);
- }
- else{
- board[j][i] = dealCard(deck);
- }
- if (j+1 == board.size()){
- board.resize(j+2,vector<Card>(10,t));
- }
- }
- } else {
- cout <<"error, there are no more cards left to place" << endl;
- }
- }
- cout << endl;
- break;
- case 3:{
- cout << deck.size() << endl;
- }
- //cout << 1 << endl;
- break;
- case 4:
- int r1, c1;
- cout << "Which row? " << endl;
- cin >> r1;
- cout << "Which column? " << endl;
- cin >> c1;
- r1--;c1--;
- cout << "You picked a " << board[r1][c1].getRank() << endl;
- break;
- case 5:
- // new game
- //needs more test
- newGame(board, deck);
- break;
- }
- //slightlyyyy tested, none should crash program, hopefully
- checkAndRemoveMatch(board); // doesn't crash program
- /*
- if (checkWin(board, deck)){ // doesn't crash the program
- cout<<"You have cleared all the cards, congrats, you win"<< endl;
- }
- if (checkLose(board , deck)){ // doesn't crash the program
- cout <<"You suck, there are no more moves left, you lose" << endl;
- } */
- }
- cout << "1) Play again" << endl;
- cout << "2) Quit and close program" << endl;
- int x;
- cin >> x;
- if(x==1){
- game = true;
- newGame(board, deck);
- }
- if(x==2){
- play = false;
- }
- }
- /*
- Card c = Card(1);
- Card c1 = Card(3, true);
- Card c2 = Card(12, true);
- cout << c2;
- */
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement