Вопрос
Я пытаюсь сделать простую программу для блэкджека.К сожалению, у меня сразу возникли проблемы с созданием колоды карт.
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<char> deck;
char suit[] = {'h','d','c','s'};
char card[] = {'2','3','4','5','6','7','8','9','10','J','Q','K','A'};
for (int j=0; j<13; j++) {
for (int i=0; i<4; i++) {
deck.push_back(card[j] suit[i]);
}
}
return 0;
}
Я знаю, что моя проблема начинается с того, что я пытаюсь присвоить символу значение «10».Очевидно, мне не удалось скомпилировать это, но я уверен, что когда я попытаюсь присвоить значения карт векторной колоде, я также получу ошибку, поскольку я использовал тип переменной «char».Кажется, меня убивает знание того, какой тип переменной использовать.Кроме того, будет 'deck.push_back (card [j] костюм [i]);' Будьте правильным кодом, чтобы объединить карту и костюм, или вам нужно поставить что -то между картой [j] и костюмом [i]?Буду признателен, если кто-нибудь из вас поведет меня в правильном направлении.Также небольшое примечание: это часть домашнего задания, поэтому, пожалуйста, не давайте мне просто целые блоки кода.Спасибо за вашу помощь.
Решение
Попробуйте создать класс Card с мастью и картой в качестве члена и установить его в качестве типа вектора. Как
public class Card {
public:
Card(char suit, char card);
char suit, card;
};
int main() {
vector<Card> deck;
char suit[] = {'h','d','c','s'};
char card[] = {'2','3','4','5','6','7','8','9','T','J','Q','K','A'};
for (int j=0; j<13; j++) {
for (int i=0; i<4; i++) {
deck.push_back(new Card(card[j],suit[i]));
}
}
return 0;
}
также использование перечислений вместо символов в костюме и карточке сделает это более понятным.
Другие советы
Я думаю, что вы хотите использовать перечисление. Это сделает ваш код более понятным и решит вашу проблему.
enum SUIT { HEART, CLUB, DIAMOND, SPADE };
enum VALUE { ONE, TWO, THREE, ..., TEN, JACK, QUEEN, KING};
То, как вы это моделируете, действительно зависит от того, что вы пытаетесь сделать.
Вы создаете настоящую игру, и структуры данных просто необходимы для поддержки игрового процесса?
Если да, то я бы создал класс карты с полем перечисления для масти и числовым типом (со значениями 1–13) для номинала.
С другой стороны, если вы создаете приложение для анализа или ИИ-плеер, модель может быть немного другой.
Несколько лет назад я написал симулятор для расчета вероятностей в различных сценариях Техасского Холдема, и мне хотелось, чтобы он ДЕЙСТВИТЕЛЬНО быстро подсчитывал цифры.Я начал с очень простой модели (класс карты, перечисление масти и т. д.), но после длительного профилирования и оптимизации пришел к побитовому представлению.
Каждая карта имела шестнадцатибитное значение: тринадцать старших битов представляли номинал, два младших бита представляли масть, а бит[2] служил специальным флагом, обозначающим туз (использовался только в тех случаях, когда туз может появиться в стрите А2345).
Вот несколько примеров:
0000000000001001 <---- Two of hearts
0100000000000011 <---- King of spades
1000000000000110 <---- Ace of diamonds
^^^^^^^^^^^^^ ("face-value" bits)
^ ("low-ace" flag)
^^ ("suit" bits)
Вы можете себе представить, как с такой конструкцией становится очень быстро искать пары, тройки и стриты (с флешами немного сложнее).
Я не буду вдаваться во все конкретные операции, достаточно сказать, что такая модель поддерживает миллионы операций в секунду...
Конечно, имейте в виду, что на самом деле я не призываю использовать подобный дизайн в простой реализации игры.Единственная причина, по которой я остановился на этом проекте, заключается в том, что мне нужно было провести масштабное статистическое моделирование.
Поэтому тщательно подумайте о том, как вы хотите моделировать:
- Каждая карта
- Рука игрока
- Вся колода
- Состояние стола...включая все руки игроков (включая игроков, которые разделили свою первоначальную руку), возможно, шестиколодный башмак, стопку сброса и т. д.
Общая модель приложения и цели приложения в целом будут в значительной степени определять типы структур данных, которые будут наиболее подходящими.
Веселиться!!!
Используйте 'T' вместо 10.
Вы пробовали заменить J на 11, Q на 12 и K на 13?Тогда вы могли бы использовать int
скорее, чем char
актеры.Позже замените 11-13 на соответствующую букву.
Ну, во-первых, колода [0] - это один символ, но вы пытаетесь набить " 2h " внутрь. (на данный момент мы проигнорируем то, что вы делаете, это неправильно.)
Как правило, вам нужно сделать колоду vector<std::string>
. Сделайте card массивом const char * s и преобразуйте элементы в строку.
затем используйте:
deck.push_back(std::string(card[j]) + suit[i]);
Как уже упоминалось, вы можете использовать «T» для десяти, J, Q и K для цифр. Что касается push_back .., поскольку deck является вектором символов, вы можете передать только один символ в push_back в качестве аргумента. Передача как значения карты (1 ... 9, T, J, Q, K), так и ее комплекта не работает.
Лично я бы создал небольшую структуру для представления Карты со свойством Value и Suite. Затем вы можете сделать свою колоду вектором карт.
Отредактировано: исправление последнего слова, поскольку вектор (меньше-чем) Карта (больше-чем) отображалась как вектор (ничего).
Это может не скомпилироваться, но вот подход, который я бы (и использовал). Вы захотите использовать целые числа для представления своих карточек, но вы можете легко абстрагировать их в классе. Который я напишу для вас.
class Card
{
public:
enum ESuit
{
kSuit_Heart,
kSuit_Club,
kSuit_Diamond,
kSuit_Spade,
kSuit_Count
};
enum ERank
{
kRank_Ace,
kRank_Two,
kRank_Three,
kRank_Four,
kRank_Five,
kRank_Six,
kRank_Seven,
kRank_Eight,
kRank_Nine,
kRank_Ten,
kRank_Jack,
kRank_Queen,
kRank_King,
kRank_Count
};
static int const skNumCards = kSuit_Count * kRank_Count;
Card( int cardIndex )
: mSuit( static_cast<ESuit>( cardIndex / kRank_Count ) )
, mRank( static_cast<ERank>( cardIndex % kRank_Count ) )
{}
ESuit GetSuit() const { return mSuit );
ERank GetRank() const { return mRank );
private:
ESuit mSuit;
ERank mRank;
}
Теперь добавить этот класс очень просто, чтобы получить из него все, что вы хотите. Создать список так же просто, как показано ниже.
rstl::vector<Card> mCards;
mCards.reserve( Card::skNumCards );
for ( int cardValue = 0; cardValue < Card::skNumCards; ++cardValue )
{
mCards.push_back( Card( cardValue ) );
}
Тебе нужно перетасовать?
#include <algorithm>
std::random_shuffle( mCards.begin(), mCards.end() );
А как насчет того, какова стоимость первой карты?
if ( mCards[0].GetSuit() == Card::kRank_Club && mCards[0].GetRank() == Card::kRank_Ace )
{
std::cout << "ACE OF CLUBS!" << std::endl;
}
Я не скомпилировал ничего из этого, но он должен быть закрыт.
Поскольку это программа для блэкджека, вы будете добавлять и сравнивать ценность карточек.
В этом случае вы можете сэкономить некоторые дополнительные средства программирования и боль, задав значения int карт (1-13) вместо значений char .
Когда я создал класс C ++ для колоды карт , Я столкнулся с несколькими собственными проблемами. Прежде всего я пытался преобразовать мой класс колоды PHP-карт на C ++, с минимальной удачей. Я решил сесть и просто положить это на бумагу. Я решил пойти с объектно-ориентированной установкой, в основном потому, что мне кажется, что ее проще всего использовать для расширения. Я использую объекты Card и Deck , поэтому, например, если вы хотите положить 10 колод в Shoe вашей игры в блэкджек, вы мог создать 10 колод, что было бы достаточно просто, потому что я решил сделать все автономным. На самом деле, он настолько самодостаточен, что для создания вашей обуви необходим код:
#include "AnubisCards.cpp"
int main() {
Deck *shoe = new Deck(10);
}
Но это было для простоты, не обязательно в небольших играх, где вам нужна только одна колода.
В любом случае, как я создал колоду, создав массив из 52 объектов Card. Колоды достаточно легки, потому что вы знаете, что у вас есть 4 масти и 13 карт в каждой масти , вы также знаете, что у вас есть 2,3,4,5 , 6,7,8,9,10, Джек, Королева, Король, Туз в каждом костюме . Это никогда не изменится. Поэтому я использовал две петли: одну для костюма , а другую для значения .
Это было примерно так:
for(int suit = 1; suit <= 4; suit++){
for(int card = 1; card <= 13; card++){
// Add card to array
}
}
Теперь вы заметите, что в каждом из этих циклов я использую целочисленное значение. Причина проста, карты являются числами. 4 костюма. 13 значений. Даже числовое значение в игре Блэкджек. Номинальная стоимость, пока вы не нажмете Лицевые карты, которые имеют числовое значение 10, пока вы не нажмете на туз, который является числовым значением 1 или 11. Все это числа. Таким образом, вы можете использовать эти цифры не только для присвоения стоимости карты, но и масти карты и номера в числовой последовательности.
Одной из идей было бы сохранить карту в классе Card с именами карт типа char или String, где 1,2,3 ... являются индексами для каждой.
Я бы согласился с предложением Росса использовать целые числа. В большинстве карточных игр используется математика, так что это лучшее представление.
Преобразуйте в 'A' или 'ACE' и т. д. на выходе.
Поскольку это домашняя работа для C ++, я предполагаю, что вы должны использовать классы. В противном случае используйте перечисления, а если это C, используйте struct или что-то в этом роде.
А в некоторых играх, помимо значения очков, вы хотели бы сохранить какой-либо рейтинг для карты, который будет зависеть от текущего режима игры.
Я никогда не делал простой C, но я имею в виду что-то вроде этого:
typedef struct struct_card {
unsigned short int suit:2;
unsigned short int card:4;
// unsigned short int valu:4;
} card;
int main() {
card a_card;
card std_deck[52];
const unsigned short int rummy_value[13] = {1,2,3,4,5,6,7,8,9,10,10,10,10};
const char *std_card_name[13] = {"Ace","Two","Three","Four","Five","Six",
"Seven","Eight","Nine","Ten","Jack","Queen","King"};
const char *std_suit_name[4] = {"Spades","Clubs","Hearts","Diamonds"};
int j, k, i=0;
for(j=0; j<4; j++){
for(k=0; k<13; k++){
a_card.suit=j; a_card.card=k;
std_deck[i++] = a_card;
}
}
//check our work
printf("In a game of rummy:\n");
for(i=0;i<52;i++){
printf(" %-5s of %-8s is worth %2d points.\n",
std_card_name[std_deck[i].card],
std_suit_name[std_deck[i].suit],
rummy_value[std_deck[i].card]);
}
//a different kind of game.
enum round_mode {SHEILD_TRUMP, FLOWER_TRUMP, BELL_TRUMP, ACORN_TRUMP, BOCK, GEISS} mode;
const card jass_deck[36]={
{0,0},{0,1},{0,2},{0,3},{0,4},{0,5},{0,6},{0,7},{0,8},
{1,1},{1,1},{1,2},{1,3},{1,4},{1,5},{1,6},{1,7},{1,8},
{2,2},{2,1},{2,2},{2,3},{2,4},{2,5},{2,6},{2,7},{2,8},
{3,3},{3,1},{3,2},{3,3},{3,4},{3,5},{3,6},{3,7},{3,8},
};
#define JASS_V {11,0,0,0,0,10,2,3,4}
const unsigned short int jass_value[9] = JASS_V;
#define JASS_TRUMP_V {11,0,0,0,14,10,20,3,4}
const unsigned short int jass_trump_value[9] = JASS_TRUMP_V;
#define JASS_BOCK_V {11,0,0,8,0,10,2,3,4}
const unsigned short int jass_bock_value[9] = JASS_BOCK_V;
#define JASS_GEISS_V {0,11,0,8,0,10,2,3,4}
const unsigned short int jass_geiss_value[9] = JASS_GEISS_V;
const char *jass_card_name[9] = {"Ace","Six","Seven","Eight","Nine","Banner",
"Under","Ober","King"};
const char *jass_suit_name[4] = {"Sheilds","Flowers","Bells","Acorns"};
const unsigned short int jass_all_value[6][4][9] = {
{ JASS_TRUMP_V, JASS_V, JASS_V, JASS_V },
{ JASS_V, JASS_TRUMP_V, JASS_V, JASS_V },
{ JASS_V, JASS_V, JASS_TRUMP_V, JASS_V },
{ JASS_V, JASS_V, JASS_V, JASS_TRUMP_V },
{ JASS_BOCK_V, JASS_BOCK_V, JASS_BOCK_V, JASS_BOCK_V },
{ JASS_GEISS_V, JASS_GEISS_V, JASS_GEISS_V, JASS_GEISS_V }
};
//check our work 2: work goes on summer vacation
printf("In a game of jass with trump (Sheilds | Flowers | Bells | Acorns) | Bock | Geiss\n");
for(i=0;i<36;i++){
printf(" %-6s of %-7s is worth %8d%10d%8d%9d%8d%8d\n",
jass_card_name[jass_deck[i].card],
jass_suit_name[jass_deck[i].suit],
jass_all_value[SHEILD_TRUMP][jass_deck[i].suit][jass_deck[i].card],
jass_all_value[FLOWER_TRUMP][jass_deck[i].suit][jass_deck[i].card],
jass_all_value[BELL_TRUMP][jass_deck[i].suit][jass_deck[i].card],
jass_all_value[ACORN_TRUMP][jass_deck[i].suit][jass_deck[i].card],
jass_all_value[BOCK][jass_deck[i].suit][jass_deck[i].card],
jass_all_value[GEISS][jass_deck[i].suit][jass_deck[i].card]);
}
return 0;
}
Вывод выглядит так:
In a game of rummy:
Ace of Spades is worth 1 points.
Two of Spades is worth 2 points.
Three of Spades is worth 3 points.
Four of Spades is worth 4 points.
Five of Spades is worth 5 points.
...
Nine of Diamonds is worth 9 points.
Ten of Diamonds is worth 10 points.
Jack of Diamonds is worth 10 points.
Queen of Diamonds is worth 10 points.
King of Diamonds is worth 10 points.
In a game of jass with trump (Sheilds | Flowers | Bells | Acorns) | Bock | Geiss
Ace of Sheilds is worth 11 11 11 11 11 0
Six of Sheilds is worth 0 0 0 0 0 11
Seven of Sheilds is worth 0 0 0 0 0 0
Eight of Sheilds is worth 0 0 0 0 8 8
Nine of Sheilds is worth 14 0 0 0 0 0
Banner of Sheilds is worth 10 10 10 10 10 10
...
Under of Acorns is worth 2 2 2 20 2 2
Ober of Acorns is worth 3 3 3 3 3 3
King of Acorns is worth 4 4 4 4 4 4
Блэкджек скучный. Этот код компилируется.