黄金点游戏(C语言)

黄金点游戏是一个数字小游戏,其游戏规则是:
N个同学(N通常大于10),每人写一个0~100之间的有理数 (不包括0或100),交给裁判,裁判算出所有数字的平均值,然后乘以0.618(所谓黄金分割常数),得到G值。提交的数字最靠近G(取绝对值)的同学得到N分,离G最远的同学得到-2分,其他同学得0分。玩了几天以后,大家发现了一些很有意思的现象,比如黄金点在逐渐地往下移动。
话不多说,先上代码:

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include <windows.h>

void Udecide_n();
int  Decide_n();
void Delete_n(int n);           //申请空间的释放
void Delete_u();                //申请空间的释放
void color(short x);           //自定义函根据参数改变颜色 
typedef struct Pnode            //一个人的信息:输入的数,获得的分数
{
    float number;              //输入的数
    float absoluten_n;         //与黄金点差的绝对值
    int grade;                   //获得的分数
}Pnode;
typedef struct PNode
{
    float number;              //输入的数
    float absoluten_n;         //与黄金点差的绝对值
    int grade;                   //获得的分数
    struct PNode * next;
};
typedef struct Decide_Node     //决定进行游戏轮数的结构体
{
    float average;               //黄金点的值
    Pnode *node;               //
}Decide_Node;
typedef struct U_decide_Node   //未决定进行游戏轮数的结构体
{
    float average;             //黄金点的值
    PNode *node;               //每轮数据的成员
    struct U_decide_Node  *next;
}U_decide_Node;
Decide_Node   *Dhead;         //决定游戏使用的是结构数组,结构数组的头部
U_decide_Node *udhead, *udnext, *udtail;  //未决定的游戏轮数的,游戏每一局由一个结构体来表示,使用结构的3个指针
PNode *phead, *pnext, *ptail;  //每一轮游戏下的,参加的游戏的人是不确定得是,使用结构来表示,这里是表示人结构的3个指针
int main(void)
{
    int i;
    int n;                   //知道游戏轮数的   游戏轮数
    color(1); printf("\t\t************************************************\n");
    color(1); printf("\t\t*                                              *\n");
    color(1); printf("\t\t*                                              *\n");
    color(1); printf("\t\t*             欢迎来到召唤师——               *\n");
    color(1); printf("\t\t*                                              *\n");
    color(1); printf("\t\t*                                              *\n");
    color(1); printf("\t\t************************************************\n\n\n");
    getchar();
    color(14);
    printf("\t\t\t\t害,骗你的!\n");
	printf("\t\t************************************************\n");
    printf("\t\t*                                              *\n");
    printf("\t\t*                                              *\n");
    printf("\t\t*              ——黄金点游戏                  *\n");
    printf("\t\t*                                              *\n");
    printf("\t\t*                                              *\n");
    printf("\t\t************************************************\n");
    color(2);
    printf("先看游戏规则:\n");
    printf("N个同学(N通常大于10),每人写一个0~100之间的有理数 (不包括0或100)\n");
    printf("交给裁判,裁判算出所有数字的平均值,然后乘以0.618(所谓黄金分割常数)\n" );
    printf("得到G值。提交的数字最靠近G(取绝对值)的同学得到N分,离G最远的同学得到-2分,其他同学得0分。\n");
    color(3);
    printf("1.先玩一下试试吧!\n2.不想玩了,拜拜!\n"); //每一轮的次数是N次
next2:color(3);printf("请选择选项:");
    //color(16);
    scanf("%d",&i);
    color(16);
    switch (i)
    {
    case 1:
    {
              n = Decide_n();

              break;
    }
    case 2:; break;
    default:
    {
               printf("咋输入这么大呢,不是说好的1和2吗?\n");
               goto next2;
    }
    }
    
    system("cls");
     

    color(12);
    float x, y, z, f;
	for (y = 1.5f; y>-1.5f; y -= 0.1f)
	{
		for (x = -1.5f; x<1.5f; x += 0.05f)
		{
			z = x*x + y*y - 1;
			f = z*z*z - x*x*y*y*y;
			putchar(f <= 0.0f ? ".:-=*#%@"[(int)(f*-8.0f)] : ' ');
		}
		putchar('\n');
	}
	color(11);
	printf("\t**************************************************************\n");
    printf("\t*        青山不改,绿水长流,谢谢客官赏脸,有缘再见!        *\n");
    printf("\t**************************************************************\n");
	getchar();
	return 0;

    Delete_n(n);                             //释放空间
    Delete_u();                              //释放空间
}

void color(short x)	//自定义函根据参数改变颜色 
{
    if(x>=0 && x<=15)//参数在0-15的范围颜色
    	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), x);	//只有一个参数,改变字体颜色 
    else//默认的颜色白色
    	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
}

void Delete_n(int n)
{
    int i;
    for (i = 0; i < n;i=0)
    {
        free(Dhead[i].node);
    }
    free(Dhead);
}
int Decide_n()
{
    int n;           //玩游戏的总轮数
    int i;           //记录游戏玩到第几轮
    int m;           //玩一轮游戏,参加游戏的人数
    int j;           //在一轮游戏中,玩游戏的人
    float sum;         //一轮游戏中全部输入的数字和,同时也是黄金点的值
    float abmax;       //输入的数与黄金点相差的绝对值最大值
    float abmin;       //输入的数与黄金点相差的绝对值最小值
    int x;           //是否输出每一轮的输入的信息
    color(5);
    printf("请输入要进行的轮数:");
    scanf("%d", &n);
    Dhead = (Decide_Node*)malloc(n*sizeof(Decide_Node));
    if (Dhead == NULL)
    {
        printf("Decide_Node空间申请失败\n");
        exit(1);
    }
    for (i = 0; i < n; i++)
    {

        printf("请输入有几个人进行游戏:");
        scanf("%d", &m);
        Dhead[i].node = (Pnode *)malloc(m*sizeof(Pnode));
        if (Dhead[i].node == NULL)
        {
            printf("Dhead[%d].node申请空间失败\n", i);
            exit(1);
        }
        sum = 0;
        for (j = 0; j < m; j++)
        {
        	color(j%15+1);
            printf("请第%d个人输入数字:", j + 1);
            scanf("%f", &Dhead[i].node[j].number);
            sum = sum + Dhead[i].node[j].number;
        }
        sum = sum / j*0.618;
        Dhead[i].average = sum;
        abmax = 0;
        abmin = 100;
        for (j = 0; j < m; j++)                               //计算每一个输入的数字与黄金的绝对值,并且找出最大绝对值和最小绝对值
        {
            Dhead[i].node[j].absoluten_n = abs(Dhead[i].node[j].number - sum);
            if (abmax < Dhead[i].node[j].absoluten_n)
            {
                abmax = Dhead[i].node[j].absoluten_n;
            }
            if (abmin>Dhead[i].node[j].absoluten_n)
            {
                abmin = Dhead[i].node[j].absoluten_n;
            }
        }
        for (j = 0; j < m; j++)                                 //给每一个参加游戏的人打分
        {
            if (Dhead[i].node[j].absoluten_n == abmax)
            {
                Dhead[i].node[j].grade = -2;
            }
            else if (Dhead[i].node[j].absoluten_n == abmin)
            {
                Dhead[i].node[j].grade = m;
            }
            else
            {
                Dhead[i].node[j].grade = 0;
            }
        }
        color(5);
        printf("黄金点值:%.2f\n",Dhead[i].average);
        printf("输出各自的得分情况\n");
        for (j = 0; j < m; j++)
        {
        	color(6);
            printf("第%d个人得分是;%d\n",j+1,Dhead[i].node[j].grade);
        }
next1:    color(10);printf("是否要输出所有人数的数字\n");
        printf("1,是\t\t2,否\n");
        color(8);
        printf("请输入选项:");
        scanf("%d", &x);
        switch (x)
        {
        case 1:
        {
                  for (j = 0; j < m; j++)
                  {
                      printf("第%d个人输入的数是:%d\n", j + 1,(int)Dhead[i].node[j].number);
                  }
                  break;
        }
        case 2:break;
        default:
        {
                   printf("输入无效,请重新输入\n");
                   goto next1;
        }
        }
    }
    return n;
}
void Delete_u()
{
    udnext = udhead->next;
    while (udnext)
    {
        phead = udnext->node;
        pnext = phead->next;
        while (pnext)
        {
            phead->next == pnext->next;
            free(pnext);
            pnext = phead->next;
        }
        free(phead);
        udhead->next = udnext->next;
        free(udnext);
        udnext = udhead->next;
    }
    free(udhead);
}

下面是运行结果截图:
在这里插入图片描述

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值