简体   繁体   English

帮助小型C ++游戏

[英]Help With Small C++ Game

I'm writing a game of solitaire that runs in the terminal. 我正在写一个在终端上运行的单人纸牌游戏。 As of now, the program compiles and runs and gives the player four cards, placed in four columns and allows them to press 0 for more cards, which are added onto the columns. 到目前为止,该程序已编译并运行,并为播放器提供了四张纸牌,并放置在四列中,并允许他们按0获得更多纸牌,这些纸牌将添加到这些列中。 As the column grows, it's output should be placed in a vector (actually, a vector of vectors). 随着列的增长,其输出应放置在向量中(实际上是向量的向量)。

Ideally, after gathering more cards if necessary, the player inputs a number ranging from 1-4 to select the column they'd like to compare to the others. 理想情况下,在必要时收集更多卡后,玩家输入1-4之间的数字以选择他们想与其他人进行比较的列。 It should then compare the top card of that column to the other top cards and see if one can be deleted. 然后,它应该将该列的顶部卡片与其他顶部卡片进行比较,看看是否可以删除。 This is the part that I'm having trouble with. 这是我遇到麻烦的部分。 First of all, I'm not sure if I'm inputing the cards correctly into the vector of vectors and I'm not sure how to compare them to each other. 首先,我不确定是否将卡正确地输入到向量的向量中,也不确定如何将它们相互比较。 I've tried using something like: 我试过使用类似:

column[2].back().getSuit() to acces the suit of the top card of column two, then giving it a numerical value and comparing it to the suit of the other. column[2].back().getSuit()以访问第二列顶部卡的花色,然后为其提供一个数值并将其与另一个花色进行比较。 I did a similar thing to compare the ranks of the cards but I'm not having any luck. 我做了类似的事情来比较纸牌的等级,但是我没有任何运气。

Can anyone show me an example using my or your own code? 任何人都可以使用我或您自己的代码向我展示示例吗? How should I properly compare the suit and rank of the top cards in each column? 我应该如何正确比较每列中排名靠前的牌的花色和排名?

Here is my code so far: 到目前为止,这是我的代码:

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstdlib>
#include <ctime>

using namespace std;

enum suits 
{
    diamond, club, heart, spade
};

class Card
{
private:
    int rank;
    suits suit;
public:
    Card();
    Card(suits, int);
    int getRank() { return rank; }
    suits getSuit() { return suit; }
    void setRank(int rankvalue) { rank = rankvalue; }
    void setSuit(suits suitvalue) { suit = suitvalue; }
};

ostream & operator<<(ostream &, Card);

Card::Card()
{
    rank = 1;
    suit = spade;
}

Card::Card(suits suitvalue, int rankvalue)
{
    rank = rankvalue;
    suit = suitvalue;
}

ostream & operator<<(ostream & out, Card aCard)
{
    switch (int rank = aCard.getRank())
    {
        case 14: out << "Ace"; break;
        case 11: out << "Jack"; break;
        case 12: out << "Queen"; break;
        case 13: out << "King"; break;
        default: out << rank;
    }

    switch (suits suit = aCard.getSuit())
    {
        case diamond: out << " of Diamonds"; break;
        case spade: out << " of Spades"; break;
        case heart: out << " of Hearts"; break;
        case club: out << " of Clubs"; break;
    }

    return out;
}

class RandomInteger 
{
public: 
    RandomInteger();
    unsigned int operator() (unsigned int max);
};

RandomInteger::RandomInteger()
{
    srand(time(0));
}

unsigned int RandomInteger::operator()(unsigned int max)

{
    unsigned int rval = rand();
    return rval % max;
}

RandomInteger randomizer;

class Deck
{
    Card cards[52];
    int topCard;
public:
    Deck();
    void shuffle();
    bool isEmpty() { return topCard <= 0; }
    Card draw();
};

extern RandomInteger randomizer;

Deck::Deck()
{
    topCard = 0;
    for (int i = 1; i <= 13; i++)
    {
        Card c1(diamond, i), c2(spade, i), c3(heart, i), c4(club, i);
        cards[topCard++] = c1;
        cards[topCard++] = c2;
        cards[topCard++] = c3;
        cards[topCard++] = c4;
    }
}

Card Deck::draw()
{
    if (!isEmpty())
        return cards[--topCard];
    else
    {
        Card spadeAce(spade, 1);
        return spadeAce;
    }
}

void Deck::shuffle()
{
    random_shuffle(cards, cards+52, randomizer);
}

class Player
{
public:
    Player();
    void print();
    Card draw(Deck &);
    typedef vector<Card> cards;
    vector<cards> column;
};

//ostream & operator<<(ostream &, Player&);

Player::Player()
{
    column.push_back(vector<Card>());
    column.push_back(vector<Card>());
    column.push_back(vector<Card>());
    column.push_back(vector<Card>());
}

Card Player::draw(Deck & aDeck)
{
    for (int i = 0; i < 4; i++)
        column[i].push_back(aDeck.draw());
}

void Player::print()
{
    cout << "Col 1 \t\t Col 2 \t\t Col 3 \t\t Col 4 \n";
    bool more = true;
    for (int j = 0; more; j++)
    {
        more = false;
        for (int i = 0; i < 4; i++)
            if (j < column[i].size())
        {
        cout << column[i][j] << "\t";
        more = true;
        }
            else
            cout << "\t\t";
    cout << endl;
    }
}

int main()
{
    Deck deck;
    deck.shuffle();

    Player player;
    player.draw(deck);
    //while (!deck.isEmpty())
    //{
    cout << "Enter a column number (0 to draw four new cards): " << endl;
    //}
    player.print();

    int input;
    int i;
    vector<vector<Card> > columns(4);
    while (cin >> input)
    if (input == 0 )
    {
        player.draw(deck);
        player.print();
        columns.push_back(vector<Card>());
        columns.push_back(vector<Card>());
    columns.push_back(vector<Card>());
        columns.push_back(vector<Card>());
    }
        else while (cin >> input)
            if (input == 1)
            {
            for ( i = 0; i > 4; i++)
                {
                        columns.push_back(vector<Card>());
            }
            for ( i = 0; i > 4; i++)
                    {
                    columns[0].back().getSuit();
                columns[1].back().getSuit();
                columns[2].back().getSuit();
                columns[3].back().getSuit();
            }

            }



}

Any suggestions, pointers, tips, are great, thanks. 任何建议,指示,技巧都很好,谢谢。

You don't need to translate the suit to a numeric value for comparison. 您无需将西服转换为数值即可进行比较。 You can compare the enumerated types directly. 您可以直接比较枚举类型。

Try adding a comparison operator for Card s: 尝试为Card添加比较运算符:

bool operator==(const Card& a, const Card& b) {
  return a.getRank() == b.getRank() && a.getSuit() == b.getSuit();
}

For this to work, you'll have to mark the getRank and getSuit methods with const : 为此,您必须使用const标记getRankgetSuit方法:

int getRank() const { return rank; }
suits getSuit() const { return suit; }

Now you should be able to simply compare any two cards, including those on "top" of two columns. 现在,您应该能够简单地比较任何两张卡片,包括两列“顶部”的卡片。 For example: 例如:

if (columns[1].back() == columns[2].back()) { ... }

Note that back won't work if the vector is empty. 请注意,如果向量为空,则back将不起作用。

Hia, you asked for suggestions so I thought I suggest a couple of things Hia,您要求提出建议,所以我认为我有几点建议

First of all I like to keep enumerated types and the function that returns a string together, just in case I add to the enumerated type later (unlikely in this case admitadly) 首先,我希望将枚举类型和返回字符串的函数保持在一起,以防万一我稍后添加到枚举类型中(这种情况下不太可能)

class suits{
public:
  enum type{
    diamond, club, heart, spade,
  };

  static
  std::string get_string(const type& t)
  {
    switch (t) {
    case diamond: return"Diamonds";
    case spade: return"Spades"; 
    case heart: return"Hearts";
    case club: return"Clubs";
    }
    throw("invalid suit");  //this is a bit ugly - but you get the idea
  }
};

You then refer to suits::spade , suits::get_string(suits::spade) etc which can be a bit clearer. 然后,您可以参考suits::spadesuits::get_string(suits::spade)等,这可能会更清晰一些。

I would then have the suit and the number in their own classes, then you can do the comparison here: 然后,我将在他们自己的班级中找到西装和号码,然后可以在此处进行比较:

class CardSuit
{
private:
  suits::type m_suit;
protected:
  std::string get_string() const {return suits::get_string(m_suit);}
public:
  CardSuit(const suits::type& t) : m_suit(t) {}
  void setSuit(const suits::type& t)  { m_suit = t;}
  const suits::type& getSuit() const {return m_suit;}
  bool operator<(CardSuit cs)
  {
    return m_suit<cs.getSuit(); //You must have the enum in the suit order
  }
};

Then 然后

  CardSuit club(suits::club);
  CardSuit spade(suits::spade);

  if (club<spade) 
    std::cout<<"true"<<std::endl;
  else
    std::cout<<"false"<<std::endl;

returns true 返回true

You can then inherit from the CardSuit class like so 然后,您可以像这样从CardSuit类继承

class Card : public CardSuit
{
private:
  int rank;
public:
  Card();
  Card(suits::type, int);
  int getRank() { return rank; }
  void setRank(int rankvalue) { rank = rankvalue; }
  std::string get_suit() const {return CardSuit::get_string();}

 bool operator<(const Card& c)
  {
    if (CardSuit::operator<(c) )
      return true; 
    if (rank<c.getRank()) 
      return true;
    else return false;
  }
};

so that 以便

  Card c1(suits::club, 4);
  Card c2(suits::club, 5);
  Card c3(suits::diamond, 5);

  if (c2<c1) 
    std::cout<<"true"<<std::endl;
  else
    std::cout<<"false"<<std::endl;

  if (c3<c1) 
    std::cout<<"true"<<std::endl;
  else
    std::cout<<"false"<<std::endl;

returns false and true respectively 分别返回false和true

Finally utstream operator is something like 最后utstream运算符就像

ostream & operator<<(ostream & out, Card aCard)
{
  switch (int rank = aCard.getRank())
    {
    case 14: out << "Ace"; break;
    case 11: out << "Jack"; break;
    case 12: out << "Queen"; break;
    case 13: out << "King"; break;
    default: out << rank;
    }

  out << " of "<< aCard.get_suit();

  return out;
}

(I would also make a rank class similar to the CardSuit class - in which case it is even tidier). (我还将使等级类类似于CardSuit类-在这种情况下甚至更整洁)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM