黄金分割点作业进度

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了黄金分割点作业进度相关的知识,希望对你有一定的参考价值。

      结对编程的作业:

    黄金点游戏

      黄金点游戏是一个数字小游戏,其游戏规则是:

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

      现在请大家根据这个游戏规则,编一个可以多人一起玩的小游戏程序,要求如下:

      1、本作业属于结对编程项目,必须由二人共同完成,并分别将本次作业过程发到博客,同时将本次作业源代码提交到codeing系统;

      2、如果可能的话尽量以C/S或B/S方式实现,即利用服务器接收和处理所有玩家提交的数字,并将结果反馈给各玩家,玩家可以通过客户端提交的数字;

      3、如果采用单机方式实现的话,需要为用户提供便利的输入界面;

      4、该游戏每次至少可以运行10轮以上,并能够保留各轮比赛结果。

 

进行情况:

黄金分割点0.0

#include "stdio.h"
#include "math.h"
#include "stdlib.h"
void Game( );


struct Player
{
    int num;     //玩家编号
    float score;    //玩家输入的数据
    float modulus;       //绝对值数据
}m[10];




void Game()
{
    struct Player m[10];
    int i,j;
    float avescore;     //平均值
    float gloden_score;   //黄金分割点
    struct Player t;
    bool flag;
    int a;
   
while(flag)
{ 
    system("cls");       //清屏函数
    avescore=0;
    printf("\n\n\n\n\n");
    for (i=0;i<10;i++)
    {
        m[i].num = i+1;
        printf ("                    第%d位玩家输入的数据:",m[i].num);
        scanf ("%f",&m[i].score);
        avescore +=m[i].score;
    }
    avescore /=10;             //求十个数的平均值
    gloden_score=avescore*0.618;       //求黄金分割点
   
    printf("\n\n\n\n\n");
    printf ("                   黄金分割点的值:%f\n",gloden_score);  

    printf("\n\n\n\n\n");
    for (i=0;i<10;i++)
    {
        m[i].modulus=fabs (gloden_score-m[i].score);      //求绝对值
        printf("               第%d位玩家与黄金分割点的差是:%f\n",m[i].num, m[i].modulus);
    }

    printf("\n\n\n\n\n");
    for(i=1;i<10;i++)
        for(j=0;j<10-i;j++)
        if (m[j].modulus>m[j+1].modulus)
        {
            t=m[j];
            m[j]=m[j+1];
            m[j+1]=t;
        }     
        printf("   游戏排行(排行顺序由高到低):\n");
        for(i=0;i<10;i++)
            printf ("        玩家%d\n",m[i].num);         //冒泡排序 



        printf("                   Do you want try again ?\n");     //判断是否继续游戏
        printf("                   Yes choose 1,No choose 2\n");
        printf("                   你的选择是:");
        scanf("%d",&a);
        if (a==1)
            flag=true;
        else
            break;
}
    return 0;
}

这是最初的版本。

遇到的问题及解决方法

(1)问题:最开始使用的是一维数组,比较简单能进行玩家数据的存储,但玩家与数据不能一一对应,提取很不方便。

        方案:用结构体进行数据的存储,可以是玩家和输入的数据进行一一对应,并且提取方便。

      《基本实现了十个人玩一轮游戏的功能》

黄金分割点1.0

 

#include "stdafx.h"
#include "stdio.h"
#include "math.h"
#include "stdlib.h"
int Game();
void Introduce();

#define NUM 100


struct Player
{
    int num;     //玩家编号
    float score;    //玩家输入的数据
    float modulus;       //绝对值数据
}m[NUM];


void main(int argc, char* argv[])
{
    int choose=0;
    int flag01;
    while (1)
    {
        system("cls");
        printf("\n\n\n\n\n\n\n");
        printf("               请选择您要进行的操作:\n");
        printf("                               1.开始游戏\n");
        printf("                               2.游戏介绍\n");
        printf("               请输入您进行操作的序号:");
        fflush(stdin);
        flag01=scanf ("%d",&choose);
        switch (choose)
        {
        case 1:  
            system("cls");
            Game();
            break;
        case 2:
            system("cls");
            Introduce();
            system("pause");
            break;
        default:
            printf("输入错误,请重新输入!");
            break;
        }
    }
}



int Game()
{
    struct Player m[NUM];
    int i,j,k,flag01;
    int    Player_num;     //玩家人数
    int Time;            //游戏次数
    float avescore;     //平均值
    float gloden_score;   //黄金分割点
    struct Player t;
    bool flag;
    int a;


    while(flag)
    {
            system("cls");
            printf("\n\n\n\n\n");
            printf("          有几个小伙伴要试试呀!(童鞋,少于是10个人不够运费~) \n");
            printf("                     ");
            fflush(stdin);
            flag01=scanf ("%d",&Player_num);                 //错误数据处理
            if(Player_num>=10)
            {
                flag=false;
            }
    }

    flag=true;

    while(flag)    
    {
            system("cls");
            printf("\n\n\n\n\n");
            printf("          童鞋你想玩儿几轮???(勇者,你必须至少玩儿10轮哦)\n");
            printf("                     ");
            fflush(stdin);
            flag01=scanf("%d",&Time);          //错误数据处理
            if(Time>=10)
            {
                flag=false;
            }
    }


       for (k=0;k<Time;k++)
       { 
            system("cls");      //清屏函数
            avescore=0;
             printf("\n\n\n\n\n");
            for (i=0;i<Player_num;i++)
            {
                m[i].num = i+1;
                printf ("                    第%d位玩家输入的数据:",m[i].num);
                scanf ("%f",&m[i].score);
                avescore +=m[i].score;
            }
            avescore /=Player_num;             //求十个数的平均值
            gloden_score=avescore*0.618;       //求黄金分割点
            printf("\n\n\n\n\n");
            printf ("                   黄金分割点的值:%f\n",gloden_score);  

            printf("\n\n\n\n\n");
            for (i=0;i<Player_num;i++)
            {
                 m[i].modulus=fabs (gloden_score-m[i].score);      //求绝对值
                printf("               第%d位玩家与黄金分割点的差是:%f\n",m[i].num, m[i].modulus);
            }

            printf("\n\n\n\n\n");
            for(i=1;i<Player_num;i++)
                for(j=0;j<10-i;j++)
                if (m[j].modulus>m[j+1].modulus)
                {
                       t=m[j];
                     m[j]=m[j+1];
                      m[j+1]=t;
                }     
                printf("   游戏排行(排行顺序由高到低):\n");
                for(i=0;i<Player_num;i++)
                    printf ("        玩家%d\n",m[i].num);          //冒泡排序 
               

                printf("                   Do you want try again ?\n");     //判断是否继续游戏
                printf("                   Yes choose 1,No choose 2\n");
                printf("                   你的选择是:");
                scanf("%d",&a);
                if (a==2)
                {
                    printf("童鞋,游戏不符合心意吗?真要狠心抛弃哦?");
                    scanf("%d",&a);
                    if(a==2)
                        break;
                }
       }

           return 0;
}

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

}

 

经过对版本0.0进行测试之后,主要存在以下几个问题

1.如果玩家数据输入的不是数字,程序会崩溃。

技术分享
改进方法:目前还没有进展,有方法可以完成必须输入数字但情况有点不同,还在探讨中。。。。


2.玩家人数固定,不能由用户自己选择。

 

  while(flag)
    {
            system("cls");
            printf("\n\n\n\n\n");
            printf("          有几个小伙伴要试试呀!(童鞋,少于是10个人不够运费~) \n");
            printf("                     ");
            fflush(stdin);
            flag01=scanf ("%d",&Player_num);                 //错误数据处理
            if(Player_num>=10)
            {
                flag=false;
            }
    }

改进方法:在程序中加入选择模块,人数必须十人以上,才能跳出循环,而且可以容错。当你输入的不是数字时程序也可以识别出来。

错误数据处理利用的是输入缓存区处理。下面是具体解释:

这个程序首先会提示用户输入一个整数,然后等待用户输入,如果用户输入的是整数,程序会输出刚才输入的整数,并且再次提示用户输入一个整数,然后等待用户输入。但是一旦用户输入的不是整数(如小数或者字母),假设 scanf 函数最后一次得到的整数是 2 ,那么程序会不停地输出“Please input an integer: 2”。这是因为scanf("%d", &i);只能接受整数,如果用户输入了字母,则这个字母会遗留在“输入缓冲区”中。因为缓冲中有数据,故而 scanf 函数不会等待用户输入,直接就去缓冲中读取,可是缓冲中的却是字母,这个字母再次被遗留在缓冲中,如此反复,从而导致不停地输出“Please input an integer: 2”。也许有人会说:“居然这样,那么在 scanf 函数后面加上‘fflush(stdin);’,把输入缓冲清空掉不就行了?”然而这是错的!C和C++的标准里从来没有定义过 fflush(stdin)。也许有人会说:“可是我用 fflush(stdin) 解决了这个问题,你怎么能说是错的呢?”的确,某些编译器(如VC6)支持用 fflush(stdin) 来清空输入缓冲,但是并非所有编译器都要支持这个功能(linux 下的 gcc 就不支持),因为标准中根本没有定义 fflush(stdin)。MSDN 文档里也清楚地写着fflush on input stream is an extension to the C standard(fflush 操作输入流是对 C 标准的扩充)。当然,如果你毫不在乎程序的移植性,用 fflush(stdin) 也没什么大问题。以下是 C99 对 fflush 函数的定义:

int fflush(FILE *stream);

如果 stream 指向输出流或者更新流(update stream),并且这个更新流最近执行的操作不是输入,那么 fflush 函数将把这个流中任何待写数据传送至宿主环境(host environment)写入文件。否则,它的行为是未定义的。


3.游戏不能自己进行十轮以上
改进方法:与玩家人数的改进方法类似,就不再多加解释了。附上代码

 while(flag)    
    {
            system("cls");
            printf("\n\n\n\n\n");
            printf("          童鞋你想玩儿几轮???(勇者,你必须至少玩儿10轮哦)\n");
            printf("                     ");
            fflush(stdin);
            flag01=scanf("%d",&Time);          //错误数据处理
            if(Time>=10)
            {
                flag=false;
            }
    }

 

 

 

以上是关于黄金分割点作业进度的主要内容,如果未能解决你的问题,请参考以下文章

附加作业:黄金点游戏

黄金点作业

第三次作业

第三次作业

结对编程作业

第三次作业