迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 > C++ >

在 C++ 数组中表示一副纸牌

作者:迹忆客 最近更新:2023/03/31 浏览次数:

本篇文章将通过 C++ 数组表示一副纸牌。

首先,我们将讨论卡片组的准备工作,然后是 C++ 中卡片表示的可能方式。 最后,我们将展示一副纸牌表示的实际示例。


纸牌

一副标准的纸牌有四种套件或类型:红心、梅花、黑桃和方块。 每组有十三张牌:Ace、2、3、4、5、6、7、8、9、10、Jack、Queen 和 King; 因此,整副牌共有 52 张牌。

卡片有很多游戏; 但是,我们不会对此进行详细说明。 在不同的游戏中,Jack、Queen 和 King 的值分别为 10、11 和 12。

在某些游戏中,A 可以视为 13 或 1,甚至两者。


C++ 中的单个卡片表示

我们必须存储卡类型/套件信息以及每张卡的卡号/值。 卡片值只是一个可以存储在整数变量中的数字,而卡片类型可以编码为 type-0type-1type-2type-3

我们可以为 type-0 存储 0(假设它是 Hearts 的类型)。 同样,我们可以为类型 1 存储 1,可能为梅花,等等为黑桃和方块。

让我们看看下面这个概念的实现代码:

//Representation of jack of hearts
int type = 0;
int value = 11;
//Representation of king of club
int type = 1;
int value = 13;
//Representation of three of spade
int type = 2;
int value = 3;

这种表示可以用于处理任何纸牌游戏。 例如,我们现在可以比较 value 变量来检查哪个玩家拥有更大价值的牌。

如果我们想检查未考虑玩家的牌类型,我们可以检查类型变量。


C++ 中的一副纸牌数组表示

我们已经讨论了单张卡片的表示。 让我们看看一副纸牌的不同 C++ 表示。

在 C++ 中通过并行数组表示

为了表示一副纸牌,我们可以采用两个平行数组。 一个数组存储卡类型,另一个数组存储相应位置的值。

以下是这些并行数组的数组声明和初始化:

int type[52]={0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3};
int value[52]={1,2,3,4,5,6,7,8,9,10,11,12,13,1,2,3,4,5,6,7,8,9,10,11,12,13,1,2,3,4,5,6,7,8,9,10,11,12,13,1,2,3,4,5,6,7,8,9,10,11,12,13};

在此代码中,type[i]value[i] 代表一副牌中的第 i 张牌。

在 C++ 中使用模数和整数除法表示

还有另一种聪明的表示方式,它甚至比这个方案更好。 我们可以将 0 到 51 存储在一个整数数组中。

我们可以使用整数除法和取余运算来得到卡的类型和值。

我们将为前 13 个索引分配 0 到 12。 C++中的算术除法运算符默认执行整数除法; 因此,如果我们将 0 到 12 之间的数字除以 13,我们将得到 0 作为一种牌(即在我们的例子中是红心花色)。

而且,如果我们用13取余数,我们将得到0到12。这个余数可以作为该卡的实际值。

因此,我们将为接下来的 13 个索引分配 13 到 25,其余卡片依此类推。

同样,如果我们用 13 对这些卡片进行整数除法,我们将得到值 1(即,在我们的例子中,俱乐部的卡片类型)。 同样,如果我们用 13 取余,我们将得到 0 到 12,这是卡值。

让我们看一个总结这个想法的示例代码:

int card[52]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16...,51};
int type = card[i] / 13;
int value = card[i] % 13;

在这种表示中,空间复杂度要好得多(即,我们不必使用两个并行数组)。

在前面的表示中,如果我们想交换一个数组中的元素,我们必须交换第二个数组中的相应元素,以保持相应位置的类型和值一致。 在第二种表示中,我们可以洗牌而不用担心。

原因是只有一个数字代表卡片类型和价值。

使用像 10 和 11 这样的数字会降低代码的可读性。 因此,为了让代码更具可读性,我们可以定义一些常量:

#define JACK 10
#define QUEEN 11
#define KING 12
#define ACE 1
#define HEART 0
#define DIAMOND 1
#define CLUB 2
#define SPADE 3

现在,我们可以进行如下比较:

type = card[i] / 13;
value = card[i] % 13;
...
if (type == CLUB)...
if (value == JACK)...

最后,我们可以定义一个字符串数组来打印卡片:

string type_name[]={"Heart", "Diamond", "Club", "Spade"};
string value_name[]{"Ace", "Two",...,"Jack","Queen","King"};
...
cout << value_name[value]<< "of"<< type_name[type] << '\n';

输出将是这样的:

Three of Spade
Jack of Diamond
Queen of Diamond
...

完整的 C++ 实现

现在,C++ 数组中卡片组的表示必须清楚。 然而,为了对表示有一个认知的看法,让我们将上面所有的代码块组合成一个准备好编译的代码:

#include<iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

void Shuffle(int *Deck){
  srand(time(NULL));
  int shufflePosition1, shufflePosition2, temp;
  int shuffleCount = 100;
  for(int i= 0 ; i< shuffleCount; i++){
      shufflePosition1= rand()%52;
      shufflePosition2 = rand() % 52;
      //swap cards at the shuffle positions
      temp =Deck[shufflePosition1];
      Deck[shufflePosition1] = Deck[shufflePosition2];
      Deck[shufflePosition2]= temp;
  }
}

void ShowFirstTenCards(int* Deck, string* TypeName, string* ValueName){

    int valueNamePosition;
    int typeNamePosition;
    for(int t=0; t<=10;t++){
       valueNamePosition= Deck[t]%13;
       typeNamePosition = Deck[t] / 13;
        cout<<"Position "<<t<<": ";
        cout<<ValueName[valueNamePosition] << " of ";
        cout<<TypeName[typeNamePosition]<<endl;
    }
}

int main(){
    int Deck[52];
    for(int itr=0; itr<=51;itr++){
        Deck[itr] = itr;
    }
    string TypeName[]={"Heart", "Diamond", "Club", "Spade"};
    string ValueName[]{"Ace", "Two", "Three", "Four", "Five","six",
                       "Seven", "Eight", "Nine", "Ten", "Jack","Queen","King"};
    cout<<"Top 10 cards before shuffle:"<<endl;
    ShowFirstTenCards(Deck, TypeName, ValueName);
    Shuffle(Deck);
    cout<<"\nTop 10 cards After shuffle:"<<endl;
    ShowFirstTenCards(Deck, TypeName, ValueName);

    return 0;
}

上面的代码示例是表示一副纸牌并执行洗牌操作的直接实现。 在讨论细节之前,让我们看一下输出。

输出结果:

Top 10 cards before shuffle:
Position 0: Ace of Heart
Position 1: Two of Heart
Position 2: Three of Heart
Position 3: Four of Heart
Position 4: Five of Heart
Position 5: six of Heart
Position 6: Seven of Heart
Position 7: Eight of Heart
Position 8: Nine of Heart
Position 9: Ten of Heart
Position 10: Jack of Heart

Top 10 cards After shuffle:
Position 0: Queen of Diamond
Position 1: Eight of Spade
Position 2: Five of Heart
Position 3: King of Diamond
Position 4: Nine of Heart
Position 5: Eight of Heart
Position 6: Seven of Heart
Position 7: Seven of Diamond
Position 8: six of Spade
Position 9: Ace of Club
Position 10: Two of Heart

上面的程序主要有三个代码段:

  1. 驱动程序代码 (main())
  2. ShowFirstTenCards() 函数
  3. Shuffle() 函数

让我们从上到下开始讨论代码段。 主要的驱动程序代码创建了三个数组:

  1. Deck Array:按照上一节中讨论的方法存储卡组信息及其面值。
  2. TypeName:存储四个可用套件的名称。
  3. ValueName:存储面值的英文名称,以便更体面地显示输出。

在重要声明之后,驱动程序代码将这三个数组作为参数传递给 ShowFirstTenCards() 方法。 该方法然后使用值和花色转换策略来显示一副牌的前十张牌。

之后,驱动程序函数以 Deck 数组作为参数调用 Shuffle() 函数。 此 Shuffle() 函数从 [0-51] 范围内随机选择两个位置并交换这些位置的内容。

它重复相同的过程一百次以确保良好的洗牌。

此外,shuffle() 函数使用当前的 UNIX 时间戳作为 rand() 函数的种子值(在 srand() 函数中),以确保 shuffle 在不同的调用中保持唯一性。

如果我们不将此时间戳作为种子传递给 rand() 函数,那么 rand() 将始终为随机位置生成相同的序列,这对于这些概率游戏来说是不可取的。 可以在此处找到有关 rand() 函数及其种子的更多信息。

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

在 C++ 中通过掷骰子生成随机值

发布时间:2023/04/09 浏览次数:169 分类:C++

本文解释了如何使用时间因子方法和模拟 C++ 中的掷骰子的任意数方法生成随机数。了解它是如何工作的以及它包含哪些缺点。提供了一个 C++ 程序来演示伪数生成器。

在 C++ 中使用模板的链表

发布时间:2023/04/09 浏览次数:158 分类:C++

本文解释了使用模板在 C++ 中创建链表所涉及的各个步骤。工作程序演示了一个链表,该链表使用模板来避免在创建新变量时声明数据类型的需要。

在 C++ 中添加定时延迟

发布时间:2023/04/09 浏览次数:142 分类:C++

本教程将为你提供有关在 C++ 程序中添加定时延迟的简要指南。这可以使用 C++ 库为我们提供的一些函数以多种方式完成。

在 C++ 中创建查找表

发布时间:2023/04/09 浏览次数:155 分类:C++

本文重点介绍如何创建查找表及其在不同场景中的用途。提供了三个代码示例以使理解更容易,并附有代码片段以详细了解代码。

如何在 C++ 中把字符串转换为小写

发布时间:2023/04/09 浏览次数:63 分类:C++

介绍了如何将 C++ std::string 转换为小写的方法。当我们在考虑 C++ 中的字符串转换方法时,首先要问自己的是我的输入字符串有什么样的编码

如何在 C++ 中确定一个字符串是否是数字

发布时间:2023/04/09 浏览次数:163 分类:C++

本文介绍了如何检查给定的 C++ 字符串是否是数字。在我们深入研究之前,需要注意的是,以下方法只与单字节字符串和十进制整数兼容。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便