c语言-扑克牌小魔术

简介: /************************************* Copyright(C) 2004-2005 vision,math,NJU. File Name: guess_card.
/*************************************
Copyright(C) 2004-2005  vision,math,NJU.
File Name: guess_card.cpp
Author: vision    Version: 1.0    Data: 23-2-2004
Description: 给你9张牌,然后让你在心中记住那张牌,然后电脑分组让你猜你记住的牌在第几组,然后猜出你记住的那张牌.
Other: 出自儿童时的一个小魔术
History:修改历史
**************************************/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <assert.h>
#define CARDSIZE 52   /*牌的总张数*/
#define SUITSIZE 13   /*一色牌的张数*/

int input = 1;


/*扑克牌结构*/
typedef struct Card
{
    char val;/*扑克牌面上的大小*/
    int  kind : 4; /*扑克牌的花色*/
}Card;
/*************************************************
Function:       // riffle
Description:    // 洗牌,然后随机的得到9张牌,要求九张牌不能有重复.
Calls:          //
Called By:      // main()
Table Accessed: //被修改的表(此项仅对于牵扯到数据库操作的程序)
Table Updated:  // 被修改的表(此项仅对于牵扯到数据库操作的程序)
Input:          //Card card[]  牌结构, int size  结构数组的大小
Output:         //
Return:         // void
Others:         // 此函数修改card[]的值,希望得到九张随机牌
Bug:            //此函数有bug,有时会产生两个相同的牌,有待修订
*************************************************/
void riffle(Card *cards, int size);
/*************************************************
Function:       // show
Description:    // 显示数组的内容
Calls:          //
Called By:      // main()
Table Accessed: //被修改的表(此项仅对于牵扯到数据库操作的程序)
Table Updated:  // 被修改的表(此项仅对于牵扯到数据库操作的程序)
Input:          //Card *card  牌结构指针, int size  结构数组的大小
Output:         //
Return:         // void
Others:         //
*************************************************/
void show(const Card *cards, int size);
/*************************************************
Function:       // grouping
Description:    //把9张牌分别放到3个数组中,每组3张,a.e分组
Calls:          //
Called By:      // main()
Table Accessed: //被修改的表(此项仅对于牵扯到数据库操作的程序)
Table Updated:  // 被修改的表(此项仅对于牵扯到数据库操作的程序)
Input:          //Card *card  牌结构指针, int size  结构数组的大小
Output:         //
Return:         // void
Others:         // 此函数修改 *carr1,*carr2,* carr3的值
*************************************************/
void grouping(const Card *cards, Card *carr1, Card *carr2, Card *carr3);
/*************************************************
Function:       // result_process
Description:    //用递归计算,所选的牌
Calls:          // rshift
Called By:      // main()
Table Accessed: //被修改的表(此项仅对于牵扯到数据库操作的程序)
Table Updated:  // 被修改的表(此项仅对于牵扯到数据库操作的程序)
Input:          //Card *carr1, Card *carr2, Card *carr3
Output:         //
Return:         // void
Others:         // 此函数修改 *carr1,*carr2,* carr3的值
*************************************************/
Card* result_process(Card *carr1, Card *carr2, Card *carr3, int counter);
/*************************************************
Function:       // rshift
Description:    //右移操作
Calls:          //
Called By:      // result_process
Table Accessed: //被修改的表(此项仅对于牵扯到数据库操作的程序)
Table Updated:  // 被修改的表(此项仅对于牵扯到数据库操作的程序)
Input:          //Card *carr1, Card *carr2, Card *carr3 ,int counter
Output:         //
Return:         // Card*
Others:         // 此函数修改 *carr1,*carr2,* carr3的值
*************************************************/
void rshift(Card *carr1, Card *carr2, Card *carr3, int counter);
void main()
{
    Card cards[9]; /*存放九张牌*/
    Card carr1[3]; /*第一组牌,cards array 1*/
    Card carr2[3]; /*第二组牌,cards array 2*/
    Card carr3[3]; /*第三组牌,cards array 3*/
    int select = 0; /*玩家的选择*/
    Card *selected_card;/*存放玩家所记住(选)的牌*/
    int counter = 0;

    riffle(cards, 9); /*洗牌,得到九张牌*/
    puts("请记住一张牌千万别告诉我!最多经过下面三次我与你的对话,我就会知道你所记的那张牌!");
    puts("如果想继续玩,请准确的回答我问你的问题,根据提示回答!");
    puts("请放心,我不会问你你选了哪张牌的!");
    grouping(cards, carr1, carr2, carr3); /*把9张牌分别放到3个数组中,每组3张,a.e分组*/
    show(carr1, 3);
    show(carr2, 3);
    show(carr3, 3);
    puts("请告诉我你记住的那张牌所在行数");
    select = getchar();
    switch (select)/*分支猜你玩家记住的牌*/
    {
    case '1':
        selected_card = result_process(carr1, carr2, carr3, counter);
        break;
    case '2':
        selected_card = result_process(carr2, carr3, carr1, counter);
        break;
    case '3':
        selected_card = result_process(carr3, carr1, carr2, counter);
        break;
    default:
        puts("你在撒谎!不和你玩了!");
        fflush(stdin);
        getchar();
        exit(0);
    }
    if (selected_card == NULL)
    {
        fflush(stdin);
        getchar();
        exit(0);
    }
    puts("你猜的牌为:");
    show(selected_card, 1);
    puts("我猜的对吧,哈哈~~~~");
    fflush(stdin);
    getchar();
}
/*riffle的原代码*/
void riffle(Card *cards, int size)
{
    char deck[CARDSIZE];/*临时数组,用于存储牌*/
    unsigned int seed;/*最为产生随机数的种的*/
    int deckp = 0; /*在牌的产生中起着指示作用*/

    seed = (unsigned int)time(NULL);
    srand(seed);

    /*洗牌*/
    while (deckp < CARDSIZE)
    {
        char num = rand() % CARDSIZE;
        if ((memchr(deck, num, deckp)) == 0)
        {
            assert(!memchr(deck, num, deckp));
            deck[deckp] = num;
            deckp++;
        }
    }

    /*找9张牌给card*/
    for (deckp = 0; deckp < size; deckp++)
    {
        div_t card = div(deck[deckp], SUITSIZE);
        cards[deckp].val = "A23456789TJQK"[card.rem]; /*把余数给card.val*/
        cards[deckp].kind = "3456"[card.quot]; /*把商给card.kind*/
    }
}
/*show的原代码,将会自动换行*/
void show(const Card *cards, int size)
{
    int i;
    for (i = 0; i < size; i++)
    {
        printf("%c%c  ", cards[i].kind, cards[i].val);
        if ((i != 0) && (((i + 1) % 3) == 0))
            puts("");
    }
    puts(""); /*自动换行*/
}
/*grouping 的原代码*/
void grouping(const Card *cards, Card *carr1, Card *carr2, Card *carr3)
{
    int i = 0;/*循环参数*/

    /*分给carr1三个数*/
    while (i < 3)
    {
        carr1[i].val = cards[i].val;
        carr1[i].kind = cards[i].kind;
        i++;
    }
    /*分给carr2接下来的三个数*/
    while (i < 6)
    {
        carr2[i - 3].val = cards[i].val;
        carr2[i - 3].kind = cards[i].kind;
        i++;
    }
    /*分给carr3接下来的三个数*/
    while (i < 9)
    {
        carr3[i - 6].val = cards[i].val;
        carr3[i - 6].kind = cards[i].kind;
        i++;
    }
}
/*rshift的实现*/
void rshift(Card *carr1, Card *carr2, Card *carr3, int counter)
{
    Card temp2;/*用于存放carr2[counter]*/
    Card temp3;/*用于存放carr3[counter]*/
    /*temp = carr2*/
    temp2.val = carr2[counter].val;
    temp2.kind = carr2[counter].kind;

    /*carr2 = carr1*/
    carr2[counter].val = carr1[counter].val;
    carr2[counter].kind = carr1[counter].kind;

    /*temp3 = carr3*/
    temp3.val = carr3[counter].val;
    temp3.kind = carr3[counter].kind;
    /*carr3 = carr2*/
    carr3[counter].val = temp2.val;
    carr3[counter].kind = temp2.kind;
    /*carr1 = carr3*/
    carr1[counter].val = temp3.val;
    carr1[counter].kind = temp3.kind;
}
Card* result_process(Card *carr1, Card *carr2, Card *carr3, int counter)
{
    rshift(carr1, carr2, carr3, counter); /* 把数组的第一个元素依次右移*/
    if (counter == 2)
    {
        return(&carr2[2]);
    }
    show(carr1, 3);
    show(carr2, 3);
    show(carr3, 3);
    puts("请给出你记住的牌所在行数:");
    fflush(stdin);


    input = getchar(); /*获取你选的组*/
    switch (input)
    {
    case '1':
        return(result_process(carr1, carr2, carr3, ++counter));
        break;
    case '2':
        return(&carr2[counter]);
        break;
    default:
        puts("你在撒谎!不和你玩了!");
        return NULL;
    }
}

 

网名:浩秦; 邮箱:root#landv.pw; 只要我能控制一個國家的貨幣發行,我不在乎誰制定法律。金錢一旦作響,壞話隨之戛然而止。
目录
相关文章
|
8月前
|
安全 C语言
【C语言】解析刘谦春晚魔术《守岁共此时》
【C语言】解析刘谦春晚魔术《守岁共此时》
78 0
|
14天前
|
存储 算法 C语言
【C语言程序设计——函数】素数判定(头歌实践教学平台习题)【合集】
本内容介绍了编写一个判断素数的子函数的任务,涵盖循环控制与跳转语句、算术运算符(%)、以及素数的概念。任务要求在主函数中输入整数并输出是否为素数的信息。相关知识包括 `for` 和 `while` 循环、`break` 和 `continue` 语句、取余运算符 `%` 的使用及素数定义、分布规律和应用场景。编程要求根据提示补充代码,测试说明提供了输入输出示例,最后给出通关代码和测试结果。 任务核心:编写判断素数的子函数并在主函数中调用,涉及循环结构和条件判断。
52 23
|
14天前
|
算法 C语言
【C语言程序设计——函数】利用函数求解最大公约数和最小公倍数(头歌实践教学平台习题)【合集】
本文档介绍了如何编写两个子函数,分别求任意两个整数的最大公约数和最小公倍数。内容涵盖循环控制与跳转语句的使用、最大公约数的求法(包括辗转相除法和更相减损术),以及基于最大公约数求最小公倍数的方法。通过示例代码和测试说明,帮助读者理解和实现相关算法。最终提供了完整的通关代码及测试结果,确保编程任务的成功完成。
44 15
|
14天前
|
C语言
【C语言程序设计——函数】亲密数判定(头歌实践教学平台习题)【合集】
本文介绍了通过编程实现打印3000以内的全部亲密数的任务。主要内容包括: 1. **任务描述**:实现函数打印3000以内的全部亲密数。 2. **相关知识**: - 循环控制和跳转语句(for、while循环,break、continue语句)的使用。 - 亲密数的概念及历史背景。 - 判断亲密数的方法:计算数A的因子和存于B,再计算B的因子和存于sum,最后比较sum与A是否相等。 3. **编程要求**:根据提示在指定区域内补充代码。 4. **测试说明**:平台对代码进行测试,预期输出如220和284是一组亲密数。 5. **通关代码**:提供了完整的C语言代码实现
54 24
|
10天前
|
存储 C语言
【C语言程序设计——函数】递归求斐波那契数列的前n项(头歌实践教学平台习题)【合集】
本关任务是编写递归函数求斐波那契数列的前n项。主要内容包括: 1. **递归的概念**:递归是一种函数直接或间接调用自身的编程技巧,通过“俄罗斯套娃”的方式解决问题。 2. **边界条件的确定**:边界条件是递归停止的条件,确保递归不会无限进行。例如,计算阶乘时,当n为0或1时返回1。 3. **循环控制与跳转语句**:介绍`for`、`while`循环及`break`、`continue`语句的使用方法。 编程要求是在右侧编辑器Begin--End之间补充代码,测试输入分别为3和5,预期输出为斐波那契数列的前几项。通关代码已给出,需确保正确实现递归逻辑并处理好边界条件,以避免栈溢出或结果
48 16
|
10天前
|
存储 编译器 C语言
【C语言程序设计——函数】分数数列求和2(头歌实践教学平台习题)【合集】
函数首部:按照 C 语言语法,函数的定义首部表明这是一个自定义函数,函数名为fun,它接收一个整型参数n,用于指定要求阶乘的那个数,并且函数的返回值类型为float(在实际中如果阶乘结果数值较大,用float可能会有精度损失,也可以考虑使用double等更合适的数据类型,这里以float为例)。例如:// 函数体代码将放在这里函数体内部变量定义:在函数体中,首先需要定义一些变量来辅助完成阶乘的计算。比如需要定义一个变量(通常为float或double类型,这里假设用float。
21 3
|
10天前
|
存储 算法 安全
【C语言程序设计——函数】分数数列求和1(头歌实践教学平台习题)【合集】
if 语句是最基础的形式,当条件为真时执行其内部的语句块;switch 语句则适用于针对一个表达式的多个固定值进行判断,根据表达式的值与各个 case 后的常量值匹配情况,执行相应 case 分支下的语句,直到遇到 break 语句跳出 switch 结构,若没有匹配值则执行 default 分支(可选)。例如,在判断一个数是否大于 10 的场景中,条件表达式为 “num> 10”,这里的 “num” 是程序中的变量,通过比较其值与 10 的大小关系来确定条件的真假。常量的值必须是唯一的,且在同一个。
12 2
|
14天前
|
存储 编译器 C语言
【C语言程序设计——函数】回文数判定(头歌实践教学平台习题)【合集】
算术运算于 C 语言仿若精密 “齿轮组”,驱动着数值处理流程。编写函数求区间[100,500]中所有的回文数,要求每行打印10个数。根据提示在右侧编辑器Begin--End之间的区域内补充必要的代码。如果操作数是浮点数,在 C 语言中是不允许直接进行。的结果是 -1,因为 -7 除以 3 商为 -2,余数为 -1;注意:每一个数据输出格式为 printf("%4d", i);的结果是 1,因为 7 除以 -3 商为 -2,余数为 1。取余运算要求两个操作数必须是整数类型,包括。开始你的任务吧,祝你成功!
45 1
|
1月前
|
存储 C语言 开发者
【C语言】字符串操作函数详解
这些字符串操作函数在C语言中提供了强大的功能,帮助开发者有效地处理字符串数据。通过对每个函数的详细讲解、示例代码和表格说明,可以更好地理解如何使用这些函数进行各种字符串操作。如果在实际编程中遇到特定的字符串处理需求,可以参考这些函数和示例,灵活运用。
82 10
|
1月前
|
存储 程序员 C语言
【C语言】文件操作函数详解
C语言提供了一组标准库函数来处理文件操作,这些函数定义在 `<stdio.h>` 头文件中。文件操作包括文件的打开、读写、关闭以及文件属性的查询等。以下是常用文件操作函数的详细讲解,包括函数原型、参数说明、返回值说明、示例代码和表格汇总。
63 9

热门文章

最新文章