迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 > 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 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

Arduino 中停止循环

发布时间:2024/03/13 浏览次数:444 分类:C++

可以使用 exit(0),无限循环和 Sleep_n0m1 库在 Arduino 中停止循环。

Arduino 复位

发布时间:2024/03/13 浏览次数:315 分类:C++

可以通过使用复位按钮,Softwarereset 库和 Adafruit SleepyDog 库来复位 Arduino。

Arduino 的字符转换为整型

发布时间:2024/03/13 浏览次数:181 分类:C++

可以使用简单的方法 toInt()函数和 Serial.parseInt()函数将 char 转换为 int。

Arduino 串口打印多个变量

发布时间:2024/03/13 浏览次数:381 分类:C++

可以使用 Serial.print()和 Serial.println()函数在串口监视器上显示变量值。

Arduino if 语句

发布时间:2024/03/13 浏览次数:123 分类:C++

可以使用 if 语句检查 Arduino 中的不同条件。

Arduino ICSP

发布时间:2024/03/13 浏览次数:214 分类:C++

ICSP 引脚用于两个 Arduino 之间的通信以及对 Arduino 引导加载程序进行编程。

使用 C++ 编程 Arduino

发布时间:2024/03/13 浏览次数:127 分类:C++

本教程将讨论使用 Arduino IDE 在 C++ 中对 Arduino 进行编程。

Arduino 中的子程序

发布时间:2024/03/13 浏览次数:168 分类:C++

可以通过在 Arduino 中声明函数来处理子程序。

扫一扫阅读全部技术教程

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

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便