我正在尝试制作一个简单的二十一点程序。可悲的是,我现在遇到了问题,产生了一副牌。
#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。显然我无法编译,但我确定当我尝试将卡值分配给矢量卡时我也会收到错误,因为我使用了变量类型'char'。知道使用什么样的变量类型似乎在扼杀我。还有'deck.push_back(card [j] suit [i]);'是卡和套装相结合的正确代码,还是你必须在卡[j]和套装[i]之间放一些东西?如果你们中的任何人能够带领我朝着正确的方向前进,我将不胜感激。另外作为一个侧面说明,这是家庭作业的一部分,所以请不要只给我整个代码块。谢谢你的帮助。
答案 0 :(得分:31)
我认为您要使用的是枚举。它将使您的代码更清晰并解决您的问题。
enum SUIT { HEART, CLUB, DIAMOND, SPADE };
enum VALUE { ONE, TWO, THREE, ..., TEN, JACK, QUEEN, KING};
答案 1 :(得分:12)
尝试使用suit和card作为成员创建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;
}
也使用枚举而不是西装和卡片中的字符会使它更清晰。
答案 2 :(得分:9)
你建模的方式实际上取决于你想要做什么。
你是在创造一个真正的游戏吗?数据结构只需要支持游戏玩法吗?
如果是这样,我会创建一个卡片类,其中包含套装的枚举字段和面值的数字类型(值为1 - 13)。
另一方面,如果您正在构建分析应用程序或AI播放器,那么该模型可能会略有不同。
几年前,我编写了一个模拟器来计算各种德州扑克场景中的概率,我希望它能够快速逼近数字。我从一个非常简单的模型(卡类,套装枚举等)开始,但经过大量的分析和优化后,我最终得到了一个按位表示。
每张卡的值为16位,十三个高位表示面值,两个低位表示套装,位[2]表示一个特殊标记(仅用于ace可能出现在A2345笔直的情况下。
以下是一些例子:
0000000000001001 <---- Two of hearts
0100000000000011 <---- King of spades
1000000000000110 <---- Ace of diamonds
^^^^^^^^^^^^^ ("face-value" bits)
^ ("low-ace" flag)
^^ ("suit" bits)
你可以想象,通过这样的设计,它可以快速点亮成对,三种类型和直道(冲洗稍微有些棘手)。
我不会涉及所有特定操作,但足以说这种模型每秒支持数百万次操作......
当然,请记住,我并不是在提倡你在简单的游戏实现中使用这样的设计。我最终得出这个设计的唯一原因是因为我需要进行大规模的统计模拟。
因此,请仔细考虑您希望如何建模:
整体应用程序模型以及应用程序的总体目标将在很大程度上决定最合适的数据结构类型。
玩得开心!!!
答案 3 :(得分:6)
使用'T'代替10。
答案 4 :(得分:5)
您是否尝试将J替换为11,Q替换为12而K替换为13?然后你可以使用int
egers而不是char
acters。稍后用适当的字母替换11-13。
答案 5 :(得分:3)
嗯,首先,deck [0]是一个char,但是你正在尝试将“2h”填入其中。 (目前,我们会忽略你的做法,这是错误的。)
基本上,你需要制作一个vector<std::string>
套牌。使卡成为const char * s的数组,并将元素转换为字符串。
然后使用:
deck.push_back(std::string(card[j]) + suit[i]);
答案 6 :(得分:2)
正如其他人所说,你可以使用'T'代表十,J,Q和K的数字。 至于push_back ..因为deck是chars的向量,你只能将一个char传递给push_back作为参数。传递卡片值(1 ... 9,T,J,Q,K)及其套件不起作用。
我个人会创建一个小结构来表示一张具有Value和Suite属性的Card。然后,你可以让你的套牌成为卡片的载体。
编辑:修复自矢量后的最后一个字(小于)卡(大于)被渲染为矢量(没有)。
答案 7 :(得分:2)
这可能无法编译,但这是我会(并且已经使用过)的方法。您将要使用整数来表示您的卡片,但您可以轻松地在课堂上对其进行抽象。我会为你写的。
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;
}
我没有编译任何这个,但它应该很接近。
答案 8 :(得分:1)
由于这是一个二十一点程序,您将添加并比较卡的价值。
在这种情况下,您可以通过提供卡 int 值(1-13)而不是 char 值来节省一些额外的编程和痛苦。
答案 9 :(得分:1)
当我创建my C++ Deck of cards class时,我遇到了一些我自己的问题。首先,我试图将my PHP deck of cards class转换为C ++,运气最少。我决定坐下来把它放在纸上。我决定使用面向对象的设置,主要是因为我觉得它最容易用于扩展。我使用卡和甲板这些对象,例如,如果您想将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,Jack,Queen,King,Ace,每件套装。那些永远不会改变。所以我使用了两个循环,一个用于套装,另一个用于值。
这是这样的:
for(int suit = 1; suit <= 4; suit++){
for(int card = 1; card <= 13; card++){
// Add card to array
}
}
现在,你会注意到在每个循环中,我使用一个整数值。原因很简单,卡片是数字。 4件套装。 13个值。甚至是二十一点游戏中的数值。面值,直到你击中面值卡,这是数字值10,直到你击中Ace为数值1或11.一切都是数字。所以你可以使用这些数字不仅可以分配卡的价值,还可以分配卡的套装,以及数字序列中的数字。
一个想法是在Card类中存储一个地图,其中包含卡片的char或String名称,1,2,3 ...是每个卡片的索引。
答案 10 :(得分:0)
我会按照Ross的建议使用整数。大多数纸牌游戏都会涉及一些数学运算,因此这是一种更好的表现形式。
在输出中转换为'A'或'ACE'等。
答案 11 :(得分:0)
由于这是C ++的功课,我猜你应该使用类。 否则使用枚举,如果这是C,则使用结构或其他东西。
对于某些游戏,除了积分值之外,你还想为卡片存储某种等级,这取决于当前的游戏模式。
我没有永远做过普通的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
二十一点很无聊。 这段代码可以编译。