所以我试图创建一副牌,我仍然是C ++和指针的新手,所以我有几个问题
所以我有Card
课程getRank
,getSuit
,以及两个Card
对象的比较。
他们的方式我设置牌组的等级为1-13,套装为1-4。所以这是一个简单的比较,比较一张卡的等级+套装与另一张卡的等级+套装。
所以我初始化并声明了这两个数组:
char Rank[13] = {1,...13};
char Suit[4] = ...
我的方法是这样的:
char* getSuit(){ return Suit; }
char* getRank(){ return Rank; }
int Comp(Card *card) {
if (rank+suit < card->rank+card->suit)
return 1;
else if...
else ...
}
我的问题是,拥有一个char数组是一个坏主意,因为我只存储整数? 后来我计划将这些数字转换为输出“Three Spade”,这就是我使用char的原因。
我的另一个问题是,我的get方法看起来是否合适? get方法,它会返回整个数组还是数组的索引,这就是我想要的。我使用' - &gt;'正确?
我仍处于绘图过程中,这就是为什么我只有代码片段
答案 0 :(得分:2)
->
将获得LHS引用的对象的RHS元素的值。所以,只要您处理LHS上的指针,这是正确的。
你可以看看使用Enums for suit。
我建议再次查看你的逻辑评估,因为@littleadv已经说过了。
答案 1 :(得分:1)
以下是一些供您考虑的草稿,可能会在其上构建您的课程:
class Card
{
public:
// TODO: provide suitable constructor...
enum Suit {Hearts, Diamonds, Clubs, Spades};
enum Rank {A, K, Q, J, _10, _9, _8, _7, _6, _5, _4, _3, _2};
Suit getSuit() { return suit; }
Rank getRank() { return rank; }
// TODO: implement setters, etc...
bool operator==(const Card& c) const
{
return rank == c.rank && suit == c.suit;
}
private:
Suit suit;
Rank rank;
};
所以我建议你使用枚举并使用精确的比较标准来比较两张牌 同样,您可以实现运算符&gt;和运算符&lt;根据你的游戏规则和逻辑。
你明白了......
答案 2 :(得分:0)
这是一个坏主意,因为这是浪费空间。您只需要存储一个号码,而不是所有号码。
此外,您可以实现==
运算符,而不是编写一组方法来执行此操作,使用起来会更自然。
重新提出有关使用->
和get
方法的问题 - 查看编译器错误。是的,在get
方法中,您返回数组。但是如果你停止使用数组,只存储你需要的东西 - 那么这些方法就可以了。
如果您想因任何原因返回字符串 - 您可以将存储的整数索引映射到某个静态数组中的正确字符串,这样就不会在类的不同实例中存储冗余字符串。
答案 3 :(得分:0)
通过这个比较过程,你最终将拥有相同的牌......我猜错了...... 编辑:在视觉工作室中还有一个二十一点入门套件,你可以看看。
答案 4 :(得分:0)
您开始使用工作代码逐步构建课程。从一个只有getSuit
和getRank
方法的简单类开始。编写一个测试它的小应用程序,例如:
int main() {
Card card(10, 4);
if (card.getSuit() != 4) {
std::cout << "Wrong suit!" << std::endl;
}
return 0;
}
通过为您实现的每个功能编写这样的小测试,您可以确保工作正常。此外,如果您考虑首先如何使用课程,您将更好地理解实施。
关于实际实施,其中大部分取决于课堂上的教学内容。一个简单的考虑因素是使用enum
来表示等级和套装。
答案 5 :(得分:0)
这种受歧视的联盟最好用ML家族的语言处理。
例如在OCaml中:
type suit = Hearts | Diamonds | Clubs | Spades
type rank = Ace | King | Queen | Jack | Num of int
type card = rank * suit
是的我知道,海报要求C ++回答......
答案 6 :(得分:0)
一张牌是一个不好的候选人 - 它没有行为,因此没有方法。因此最好将其建模为结构。卡是不可变的(除非你作弊),所以指示const成员数据:
enum Suit {Hearts, Diamonds, Clubs, Spades};
enum Rank {A, K, Q, J, _10, _9, _8, _7, _6, _5, _4, _3, _2};
struct Card
{
Card(Suit suit, Rank rank) : suit(suit), rank(rank) {}
const Suit suit;
const Rank rank;
};
如果你可以使用语法card.first而不是card.suit,你可以使用标准对免费获得:
#include <utility>
typedef const std::pair<Suit, Rank> Card;
Card aceOfSpades(Spades, A);
奖金:你也可以合理地==和&lt;运营商免费。
答案 7 :(得分:0)
使用界面
它为学生提供了一种简单的方法,可以在他们编写的代码中使用卡而无需访问 卡的内部,无法创建特定的卡,也不知道卡是如何 实现。这个过程从卡接口的代码开始,我们称之为ICard接口。
public interface ICard extends Comparable
{
public static final int SPADES = 0;
public static final int HEARTS = 1;
public static final int DIAMONDS = 2;
public static final int CLUBS = 3;
public int getSuit();
public int getRank();
}
接口指定卡的行为,但不提供有关卡的信息
实现。一旦他们知道getSuit()
返回类似ICard.HEARTS的值,那就是
getRank()
返回1(ace)到13(king)范围内的值,学生可以从中编写代码
规格。例如,这里的代码用于检查卡阵列是否已排序。我们没有
知道它是如何分类的(例如,所有的A在两个之前出现或者做所有的黑桃来
在心灵之前?),但我们可以确定数组是否已排序。
1以大写字母I开头的接口名称,后跟大写名称,是一个常见的命名
面向对象编程中的约定,使用多种语言,而不仅仅是Java。
public boolean isSorted(ICard[] list){
for(int k=1; k < list.length; k++){
if (list[k-1].compareTo(list[k]) > 0){
return false;
}
}
return true;
}
从这个简单的ICard界面开始,我们可以向学生提出多种选择 用于测试和审查从Java语法到解决问题的概念的问题 关于一张,两张或许多卡片。这里包含一些简单的例子, 网站上提供了更多内容。在回答这些问题时,学生必须 了解界面,因为没有实现。学生专注于 行为而不是实例变量和其他实现细节,例如 如何创建一个字符串来表示黑桃的王牌。 ICard学习/代码问题
编写函数isRed,如果其ICard参数为红色(heart或 钻石)并且否则返回false。 public boolean isRed(ICard card){...}
一对是同一等级的两张牌(例如,两个国王或两个八个)。写功能 isPair如果其两个ICard参数表示一对并返回false,则返回true 除此以外。 public boolean isPair(ICard a,ICard b){...}
在扑克牌中,同花顺是一手牌,其中所有牌都有相同的牌(例如,五个心, 或者五张牌的五个俱乐部)。编写函数isFlush,如果返回则返回true 卡数组是刷新,否则返回false。 public boolean isFlush(ICard [] hand){...}
在二十一点或21中,一手牌的价值是牌的总数,其中是千斤顶,皇后和 国王(11,12和13,分别由getRank()返回)每个计为10,和a ace计为1或10,以较好者为准。总共超过21岁是一个半身像;破产是不好的。 写函数handTotal,返回手的总值。 public int handTotal(ICard [] hand){...} 从接口到实现 ICard接口提供了足够的信息来编写卡片代码, 但是没有办法创建一系列卡片,例如,甚至一个卡片 卡来测试上面写的函数(如isPair和handTotal)。哪里 卡来自哪里?在大多数现实世界的例子中,卡片来自甲板。好 设计一个模拟甲板的类 - 它基本上是用于创建和获取卡的工厂。 为了简单起见,并鼓励学习一些标准的Java接口,这个类 Deck将实现java.util.Iterator接口。例如,存储所有 从卡片到ArrayList变量的卡片,我们可以使用以下代码:
甲板d =新甲板(); ArrayList cards = new ArrayList(); while(d.hasNext()){ ICard卡=(ICard)d.next(); 的System.out.println(卡); cards.add(卡); } System.out.println(&#34;处理的牌数=&#34; + cards.size());
此代码段输出的最后几行可能如下所示。他们将是不同的 每一次,因为这里开发的Deck类通过迭代对其处理的卡进行洗牌。 ... 黑桃王牌 俱乐部的杰克 六个黑桃 十颗心 十个黑桃 发卡数量= 52 如果我们按如下方式更改循环后的行,则输出也会发生变化。
Collections.sort(cards);
for(int k=0; k < cards.size(); k++){
System.out.println(cards.get(k));
}
System.out.println(&#34;处理的牌数=&#34; + cards.size()); 输出显示从Deck类返回的卡如何实现Comparable接口。 ... 九个俱乐部 十个俱乐部 俱乐部的杰克 俱乐部女王 俱乐部之王 发卡数量= 52 Deck类的完整代码如下所示。方法hasNext(),next()和 实现Iterator接口的类需要remove()。下面的代码 显示了如何构造Card类型的对象。
public class Deck implements Iterator{
private ArrayList myCardList;
private int myIndex;
public Deck(){
myCardList = new ArrayList();
for(int suit = ICard.SPADES; suit <= ICard.CLUBS; suit++){
for (int rank = 1; rank <= 13; rank++){
myCardList.add(new Card(suit,rank));
}
}
shuffle();
}
private void shuffle(){
Collections.shuffle(myCardList);
myIndex = 0;
}
public boolean hasNext() {
return myIndex < myCardList.size();
}
public Object next() {
ICard card = (ICard) myCardList.get(myIndex);
myIndex++;
return card;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
Deck对象存储52张卡片 - 这些卡片可以从Deck获得 对象通过迭代,但Deck对象不能重新洗牌和重复使用。 相反,必须创建一个新的Deck对象来处理新卡。这保持不变 事情很简单,并提供了一个易于理解的类的例子 实现Iterator接口。方法remove()是可选的--- for 调用此方法的Deck类会抛出异常。 甲板研究/代码问题
在构造函数中调用shuffle方法之前,描述了它的顺序 存储在myCardList中的对象。
描述如果更改实例变量myCardList,每个Deck方法如何更改 例如,一组Card对象, private ICard [] myCardList; myCardList的哪个选择更好?为什么呢?
编写定义Deck对象的客户端代码,并创建一个包含13个ICard对象的数组 代表从甲板处理的黑桃。通过检查处理的每个对象来完成 并且只存储铁锹卡。
编写下面指定的假设Hand类构造函数的主体
private ArrayList myCards; / **
从甲板到卡片 我们最初关注的是使用ICard接口而不是担心如何使用 卡已实施。然而,在某些时候,需要有一个 实现。不容易争辩说Card对象应该是由。创建的 甲板课。这是我们在这里使用的方法。 Card类是私有类 在甲板课堂内宣布。实际上没有充分的理由在其中宣布它 Deck(Deck.java文件)。但是,通过宣布它是私有的,我们就做到了 任何代码class2都不可能;它可以很容易地被宣布为非公共类 Deck类以外的方法来构造Card对象。这有助于实现我们的最初目标。 客户端程序可以从Deck获取卡,但不能创建卡。自甲板供应以来 ICARD对象,一旦从卡片中获得卡片,就无法更换卡片。 ICard interfaced不支持修改卡片。
如上所述,Deck类中定义的私有Card类不支持 修改,因为它的私有状态实例变量是最终的,但这是额外的 因为没有客户端代码访问私人卡类,所以可能不需要保护。 2通常在另一个类中声明的类通常引用封闭对象的状态。在这 case嵌套类Card被声明为私有静态类,因此它不能引用私有非静态状态 在Deck对象中。 Card类可以引用静态Deck状态,但此代码中没有。 Card类可在网站上找到;自实施以来,我们不在此处 与我们关于设计的讨论没有直接关系。 细心的读者可能会声称我们的原始目标尚未实现。客户端代码可以作弊 例如,通过创建一个Deck对象然后从该对象处理卡片直到空格 (或任何其他卡)被处理。在Deck类的当前设计中,这是真的。但是,我们 可以创建单个Deck对象,与Random类的单个实例相同 用于海洋生物学案例研究。 Singleton对象通常通过声明来创建 构造者,以便他们私下。在这种情况下,Deck构造函数将从public更改为 私人的。客户端代码通过调用公共getInstance()方法获取Deck 返回存储在Deck类中的私有静态Deck对象。 getInstance方法 在第一次调用getInstance时创建此私有对象。