Помощь с небольшой игрой C ++ - PullRequest
0 голосов
/ 09 февраля 2011

Я пишу пасьянс, который запускается в терминале.На данный момент, программа компилирует и запускает и дает игроку четыре карты, помещенные в четыре столбца, и позволяет им нажимать 0 для большего количества карт, которые добавляются в столбцы.По мере роста столбца его выходные данные должны быть помещены в вектор (фактически, вектор векторов).

В идеале, после сбора большего количества карт, если необходимо, игрок вводит число в диапазоне от 1 до 4, чтобы выбратьколонку они хотели бы сравнить с другими.Затем следует сравнить верхнюю карточку этого столбца с другими верхними карточками и посмотреть, можно ли ее удалить.Это та часть, с которой у меня проблемы.Прежде всего, я не уверен, правильно ли я ввожу карты в вектор векторов, и я не уверен, как сравнить их друг с другом.Я попытался использовать что-то вроде:

column[2].back().getSuit(), чтобы получить доступ к масти верхней карты второй колонки, затем присвоить ей числовое значение и сравнить с мастью другой.Я сделал аналогичную вещь, чтобы сравнить ранги карт, но мне не повезло.

Может кто-нибудь показать мне пример, используя мой или ваш собственный код?Как мне правильно сравнивать масти и ранг верхних карт в каждом столбце?

Вот мой код:

#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();
            }

            }



}

Любые предложения, указатели, советы, это здорово, спасибо.

Ответы [ 2 ]

2 голосов
/ 09 февраля 2011

Вам не нужно переводить костюм в числовое значение для сравнения. Вы можете сравнивать перечисленные типы напрямую.

Попробуйте добавить оператор сравнения для Card s:

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

Чтобы это работало, вам нужно пометить методы getRank и getSuit с помощью const:

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

Теперь вы должны иметь возможность просто сравнивать любые две карты, в том числе и те, которые находятся в верхней части двух столбцов. Например:

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

Обратите внимание, что back не будет работать, если вектор пуст.

1 голос
/ 09 февраля 2011

Hia, вы спрашивали о предложениях, поэтому я подумал, что я предлагаю пару вещей

Прежде всего мне нравится сохранять перечисляемые типы и функцию, которая возвращает строку, на всякий случай, если я добавлю к перечисляемомувведите позже (маловероятно, в данном случае, допустим)

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
  }
};

Затем вы обращаетесь к suits::spade, suits::get_string(suits::spade) и т. д., которые могут быть немного яснее.

Тогда я бы взял костюм ичисло в их собственных классах, то вы можете сделать сравнение здесь:

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
  }
};

Затем

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

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

возвращает true

Затем вы можете наследовать от класса 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;
  }
};

, так что

  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;

возвращает ложь и истину соответственно

Наконец, оператор 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также сделает класс ранга похожим на класс CardSuit - в этом случае он будет еще более аккуратным).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...