【调试+随机数 + 算法思想】
【任取两手牌】扑克牌2,3,4,...,10,J,Q,K,A 13张牌,4个花色,以及大小王组成54。 用C语言从中抽取 5 张牌 ,要求不能重复数字,不能少,不能是大小王。
2) 将上述随机产生的两手牌输出到文件output.txt中;
3) 【比较大小】判断上述随机抽取的牌是否是个顺子(各牌的大小邻接关系为:2<3<4<...<10<J<Q<K<A,其中J为11,Q为12,K为13,A为14);并比较两手牌的大小
4) 将排序结果追加输出到output.txt文件中。
#include "stdafx.h"
#include "stdio.h"
#include "time.h"
#include "stdlib.h"
#include<iostream>
using namespace std;
#define N 5 //抽出牌的张数
typedef struct card
{
int number; // 牌的号码
int type; // 花色 0:红桃,1:方片,2:梅花,3:黑桃
}CARD;
int cmp(const void *a, const void *b)
{
return(*(int *)b - *(int *)a); //实现的是降序排序
}
void GenerateCard(CARD card[],int n)//表示花色 0-12为红桃,13-25为方块,26-38为梅花,39-51为黑桃,
{
for (int i = 0; i < n; ++i)
{
card[i].number = rand() % 54;//0-53范围
if (card[i].number > 51)//52,53代表大小王,抽到大小王则重新抽取
{
i--;
continue;
}
for (int j = 0; j < i; j++)//判断当前抽到的牌和之前抽到的牌是否一样
{
if (card[i].number == card[j].number)
{
i--;
break;
}
}
}
for (int i = 0; i < n; i++)
{
card[i].type = card[i].number / 13;
card[i].number = card[i].number % 13+2;
}
}
void ShowCard(CARD card[], int n) //屏幕显示
{
for (int i = 0; i < n; i++)
{
switch (card[i].type)
{
case 0:
cout << "红桃" << card[i].number << endl; break;
case 1:
cout << "方块" << card[i].number << endl; break;
case 2:
cout << "梅花" << card[i].number << endl; break;
case 3:
cout << "黑桃" << card[i].number << endl; break;
}
}
cout << endl;
}
void WriteCard(FILE *fp,CARD card[],int n)
{
for (int i = 0; i < n; i++)
{
switch (card[i].type)
{
case 0:
fprintf(fp, "%s %d\n", "红桃", card[i].number); break;
case 1:
fprintf(fp, "%s %d\n", "方块", card[i].number); break;
case 2:
fprintf(fp, "%s %d\n", "梅花", card[i].number); break;
case 3:
fprintf(fp, "%s %d\n", "黑桃", card[i].number); break;
}
}
fprintf(fp, "\n");
}
bool IsStraight(CARD card[], int n)//是否是顺子
{
if (card[0].number - card[4].number == 4)
return true;
else
return false;
}
int main()
{
//srand((unsigned)time(NULL));
//cout << rand() << endl;
CARD card1[5],card2[5];
bool flag;
cout << "选择有放回抽取还是无放回抽取(0,有放回,1,无放回)" << endl;
cin >> flag;
srand((unsigned)time(NULL));//产生随机种子。将srand放在for循环外,解决有放回抽取时两次得到 同一手牌的问题
if (!flag)
{
GenerateCard(card1, N);
GenerateCard(card2, N);
}
else
{
CARD card[2 * N];
GenerateCard(card, 2 * N);//memmove
for (int i = 0; i < N; i++)
{
card1[i] = card[i];
card2[i] = card[i + N];
}
}
FILE*fp;
fopen_s(&fp,"output.txt", "w");
printf("%s\n", "第一手五张牌的顺序是:");
ShowCard(card1, N);
fprintf(fp, "%s\n", "第一手五张牌的顺序是:");
WriteCard(fp, card1, N);
qsort(card1, N, sizeof(CARD), cmp);
cout << "排序后的结果为:" << endl;
ShowCard(card1, N);
fprintf(fp, "%s\n","排序后的结果为:");
WriteCard(fp, card1, N);
if (IsStraight(card1, N))
{
cout << "该手牌是顺子" << endl<<endl;
fprintf(fp, "%s\n\n\n", "该手牌是顺子");
}
else
{
cout << "该手牌不是顺子" << endl<<endl;
fprintf(fp, "%s\n\n\n", "该手牌不是顺子");
}
printf("%s\n", "第二手五张牌的顺序是:");
ShowCard(card2, N);
fprintf(fp, "%s\n", "第二手五张牌的顺序是:");
WriteCard(fp, card2, N);
qsort(card2, N, sizeof(CARD), cmp);
cout << "排序后的结果为:" << endl;
ShowCard(card2, N);
fprintf(fp, "%s\n","排序后的结果为:");
WriteCard(fp, card2, N);
if (IsStraight(card2, N))
{
cout << "该手牌是顺子" << endl<<endl;
fprintf(fp, "%s\n\n\n", "该手牌是顺子");
}
else
{
cout << "该手牌不是顺子" << endl<<endl;
fprintf(fp, "%s\n\n\n", "该手牌不是顺子");
}
if (IsStraight(card1, N) && IsStraight(card2, N))//比较两手牌的大小
{
if (card1[0].number < card2[0].number)
{
cout << "第一手牌小于第二手牌" << endl;
fprintf(fp, "%s\n", "第一手牌小于第二手牌");
}
else if (card1[0].number < card2[0].number)
{
cout << "第一手牌小于第二手牌" << endl;
fprintf(fp, "%s\n", "第一手牌小于第二手牌");
}
else
{
cout << "第一手牌小于第二手牌" << endl;
fprintf(fp, "%s\n", "第一手牌小于第二手牌");
}
}
else
{
cout << "两手牌不同时是顺子,无法比较" << endl;
fprintf(fp, "两手牌不同时是顺子,无法比较");
}
fclose(fp);
fp = NULL;
cout << "finish" << endl;
return 0;
}
srand()是为了是每次运行产生的结果不一样,rand()本身就可以产生随机数;