实验要求:
1.游戏输赢的评定标准是:给定一定数量的苹果,谁取了最后一个苹果就算谁赢。游戏规则是:人和电脑双方轮流取苹果;第一次无论哪一方先取苹果,都只能取“ 1~总苹果数目-1”之间(包括边界)数目的苹果;之后的每一方取苹果的数目只能是“1~上一次对方取苹果数目的两倍”之间的苹果个数;直至某一方将苹果取完为止,游戏才告结束。
2.该实验的课内学时是 4个课时。
3.程序完成后应该完成如下基本功能:
1)游戏取苹果的先后次序可以选择(人先取或电脑先取)。
2)在游戏中人取多少个苹果由参加游戏的用户自己决定输入,输入之后程序必须判断用户是否按规则输入苹果个数(每一方取苹果的数目只能是“ 1~上一次对方取苹果数目的两倍”之间的苹果个数)。因此程序应该有明确的提示信息,提示用户输入的苹果以及应该输入的苹果个数范围。用户输入之后,程序必须检查用户输入是否正确。
3)电脑取苹果的数目由程序来决定,赢取游戏的关键是费波那契数列的应用。具体参看实验提示。
4)游戏最后必须说明哪一方赢得游戏。
4.在完成上述基本功能的前提下,有能力的同学可以完成如下加强功能:
1)游戏的速度分为快速和慢速两种。快速游戏的电脑取苹果个数方法参看实验提示。
2)游戏的提示语言清晰明确,界面美观适用。
/**********************************  源代码 ********************************************/
#include "stdio.h"
#include <time.h>
#include <stdlib.h>
#include <conio.h>
int Apple_Fenjie[40];//全局变量,用于存储将一个数分解完后的斐波那契数
int Human_Chose[100],Computer_Chose[100],Apple_Total; 
                     //全局变量,分别用来存储玩家和电脑所选的数,及剩余苹果数        
/* 1 *********************************************/
int PanDuan_Fibo(int m)
//判断一个数是否为斐波那契数,是就返回其在数列中的下标,不是则返回0
{   int Fibo[40],i,j=0;
  Fibo[0]=0;
  Fibo[1]=Fibo[2]=1;
 for(i=2;i<40;i++)
  Fibo[i]=Fibo[i-2]+Fibo[i-1]; 
 for(i=0;i<=40;i++)
    if (m==Fibo[i])
      return i;  
 return 0; 
}
/* 2 *********************************************/
int FenJie_Fibo(int Apple_Fenjie[40],int m)
//将一个数m分解,并将结果存在数组Apple_Fenjie[40]中,函数返回数组的最大下标
   { int Fibo[40],i,j=0,k;
  Fibo[0]=0;
  Fibo[1]=Fibo[2]=1;
  for(i=2;i<40;i++)
     Fibo[i]=Fibo[i-2]+Fibo[i-1]; 
  k=PanDuan_Fibo(m);
   if(k==0)
   {  for(i=0;m>0; )
     { if(m<Fibo[i])
      {Apple_Fenjie[j]=Fibo[i-1];
        m=m-Apple_Fenjie[j];
        j++;i=-1;
      }
      i++;
     }
   }
   else
     {j=1;
      Apple_Fenjie[j-1]=Fibo[k-1];
      Apple_Fenjie[j]=Fibo[k-2];
      j++;
     } 
 return j-1;       
}
/* 3 ********************************************************************/
  int Computer(int speed,int i,int Who_First)       //电脑取苹果 
        {   int min,j,Apple_Quick,floag=0,Apple_Fenjie1[40],temp=0;
          Human_Chose[0]=Apple_Total/2-1;
             Computer_Chose[0]=Apple_Total/2-1; 
         min=FenJie_Fibo(Apple_Fenjie,Apple_Total);  
            if(Who_First==1)     
              temp=1;           
           if(Apple_Total<=Human_Chose[i-1+temp]*2)  //如果游戏
             { Computer_Chose[i]=Apple_Total;
                Apple_Total=Apple_Total-Computer_Chose[i];
              }
             else if((Apple_Fenjie[min]<((Apple_Total+2)/3))&&(Apple_Fenjie[min]<=(Human_Chose[i-1+temp]*2)))
              {  if(speed==1)
                   {Computer_Chose[i]=Apple_Fenjie[min];
                     Apple_Total=Apple_Total-Computer_Chose[i];
                   }
                 else if(speed==2)
                    {  Apple_Quick=Apple_Fenjie[min];
                      for(j=1;1;j++)
                        {  Apple_Quick=Apple_Quick+Apple_Fenjie[min-j]; 
                           if((Apple_Quick<((Apple_Total+2)/3))&&(Apple_Quick<=(Human_Chose[i-1]*2)))
                               {  floag=FenJie_Fibo(Apple_Fenjie1,Apple_Total-Apple_Quick);
                                if(Apple_Fenjie1[floag]>2*Apple_Quick)
                                  continue;
                                else
                                  break; 
                               }
                           break;
                        }
                      Apple_Quick=Apple_Quick-Apple_Fenjie[min-j];
                      Computer_Chose[i]=Apple_Quick;
                       Apple_Total=Apple_Total-Computer_Chose[i];
                    }
              }
           else
               { Computer_Chose[i]=1;
                 Apple_Total=Apple_Total-Computer_Chose[i];
               }
            if(Who_First==1)
              {printf("电脑取[1~%d]:%d\n",Human_Chose[i]*2,Computer_Chose[i]);
              }
            else if(Who_First==2)
              {  
                if (i==1)
                printf("\t|第%d轮--剩下%d个苹果--电脑取[1~%d]:%d\n",i,Apple_Total+Computer_Chose[i],Apple_Total+Computer_Chose[i]-1,Computer_Chose[i]);
               else if(i>=2)
                printf("\t|第%d轮--剩下%d个苹果--电脑取[1~%d]:%d\n",i,Apple_Total+Computer_Chose[i],Human_Chose[i-1]*2,Computer_Chose[i]);  
              }
           if(Apple_Total<=0)
              { printf("\n\t电脑胜利!!\n");
                return 0;
              }
           if(Who_First==2)
           {printf("\t|第%d轮--剩下%d个苹果--玩家取[1~%d]:",i,Apple_Total,Computer_Chose[i]*2);
           }
           return 1;  
       }             
/* 4 *****************************************************/
  int Human(int i,int Who_First)           //玩家取苹果
        {  if(Who_First==1)
          {
           if (i==1)
               {printf("\t|第%d轮--剩下%d个苹果--玩家取[1~%d]:",i,Apple_Total,Apple_Total-1);
                scanf("%d",&Human_Chose[i]);
                while(Human_Chose[i]<1||Human_Chose[i]>Apple_Total-1)
                   {printf("\t\t非法取苹果,请重取[1~%d]:",Apple_Total-1);
                    scanf("%d",&Human_Chose[i]);
                   }
               }
             else if(i>=2)
               {
                 printf("\t|第%d轮--剩下%d个苹果--玩家取[1~%d]:",i,Apple_Total,Computer_Chose[i-1]*2);
                 scanf("%d",&Human_Chose[i]);
                  while(Human_Chose[i]<1||Human_Chose[i]>Computer_Chose[i-1]*2)
                     { printf("\t\t非法取苹果,请重取[1~%d]:",Computer_Chose[i-1]*2);
                      scanf("%d",&Human_Chose[i]);   
                     }
               }
          }
          else if(Who_First==2)
           { scanf("%d",&Human_Chose[i]);
              while(Human_Chose[i]<1||Human_Chose[i]>Computer_Chose[i]*2)
                   {printf("\t\t非法取苹果,请重取[1~%d]:",Computer_Chose[i]*2);
                    scanf("%d",&Human_Chose[i]);
                   }
           }
           Apple_Total=Apple_Total-Human_Chose[i];
           if(Apple_Total<=0)
              {  printf("\n\t玩家胜利!!\n");
                return 0;
              }
           if(Who_First==1)
             printf("\t|第%d轮--剩下%d个苹果--",i,Apple_Total);
           return 1;
        }
/* 5 ********************************************************/
   void Computer_FirstChose(int Apple_Total,int speed,int Who_First)  //电脑先取
       {  int i=1;
          while(1)    
           { if(Computer(speed,i,Who_First)==0)
              break;
            if(Human(i,Who_First)==0)
              break;
            i++;
           }          
       }
/* 6 ***********************************************************/
   void Human_FirstChose(int Apple_Total,int speed,int Who_First)  //玩家先取
     {  int i=1;
     while(1)
     { if(Human (i,Who_First)==0)
              break;
       if(Computer(speed,i,Who_First)==0)
              break;
      i++;
     }
     }  
/*************************************************/
  int Game_Description( )   //游戏说明
  {  system("cls");fflush(stdin);
    printf("\n\n\t|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|\n");
     printf("\t|\t\t\t   “吃苹果”游戏说明\t\t\t\t       |\n");
     printf("\t|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|\n");
     printf("\t|游戏输赢的评定标准是:给定一定数量的苹果,谁取了最后一个苹果就算谁赢。        |\n");
     printf("\t|游戏规则是:\t\t\t\t\t\t\t\t       |\n");
     printf("\t|  人和电脑双方轮流取苹果;第一次无论哪一方先取苹果,都只能取“1~总苹果数目-1”|\n");
     printf("\t|之间(包括边界)数目的苹果;之后的每一方取苹果的数目只能是“1~上一次对方取苹果|\n");
     printf("\t|数目的两倍”之间的苹果个数;直至某一方将苹果取完为止,游戏才告结束。          |\n");
     printf("\t|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|\n");
     printf("\n\n\t\t\t\t<任意键>--返回主菜单    \n");
     getch();    
     return 1;
  }   
/****************************************************/
  int Game_Enter(int speed,int Who_First )  //进入游戏
  {  char temp;
    system("cls");fflush(stdin);
    printf("\n\t  进入游戏==>游戏信息: ");
    if(speed==1)
       printf("<简单>");
    else if(speed==2)
       printf("<困难>");
    if(Who_First==1)
       printf(" <玩家>先取"); 
    if(Who_First==2)
       printf(" <电脑>先取");
    printf("\n\t|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|\n");
     printf("\t|\t\t第一步==设置苹果总数\t        |\n");
     printf("\t|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|\n");
     printf("\t|<<1>>--由玩家输入\t\t\t\t| \n");
     printf("\t|<<其他键>>--由电脑随机产生\t\t\t|\n");
     printf("\t|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|\n");
    printf("\t|\t请选择==>");
    temp=getchar();
    switch(temp)
    { case '1':
          {  printf("\t|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|\n");
           printf("\t|\t请输入苹果总数:\t");
           scanf("%d",&Apple_Total);
           while(Apple_Total<=1)
              {printf("\t|\t请重新输入苹果总数(>=2):\t");
               scanf("%d",&Apple_Total);
              }
           printf("\t|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|\n");
               printf("\n\t\t\t<任意键>--开始取苹果     \n");
           return 1;
          }
      default:
            { srand((unsigned)time(NULL));
                Apple_Total=rand()%200;
                printf("\t|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|\n");
                printf("\t|\t电脑随机产生的苹果数是:%d 个\n",Apple_Total);
                printf("\t|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|\n");
               printf("\n\t\t\t<任意键>--开始取苹果    \n");
                return 1;
            }
    }
    getch();
  }        
    
/*************************************************/
 void Game_Setting(int*speed,int*Who_First)   //游戏的开始设置
  {  int chose;
     system("cls");
     printf("\n\n\t|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|\n");
     printf("\t|\t欢迎进入“吃苹果”游戏--苏贵阳\t\t|\n");
     printf("\t|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|\n");
     printf("\t|\t<1>-进入游戏\t <2>-电脑先取\t\t|\n");
     printf("\t|\t<3>-提高难度\t <4>-游戏说明\t\t|\n");
     printf("\t|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|\n");
     chose=getchar();
     switch(chose)
     {
      case '1':
                Game_Enter(*speed,*Who_First); break;
      case '2':
              { system("cls");
               *Who_First=2;
               printf("\n\n\t\t\t设置完成,现在是由<<电脑>>先取苹果");
               printf("\n\n\t\t\t\t<任意键>--返回主菜单    \n");
                 getch();
                 Game_Setting(speed,Who_First);
              } break;
      case '3':
              { system("cls");
               *speed=2;
               printf("\n\n\t\t\t设置完成,现在游戏难度已提升为--<<困难>>");
               printf("\n\n\t\t\t\t<任意键>--返回主菜单    \n");
                 getch();
                 Game_Setting(speed,Who_First);
              } break;
      case '4':
               if(Game_Description( ))
                 Game_Setting(speed,Who_First);
                 break;
      default: Game_Setting(speed,Who_First);
     }
 }
/* 7 ****************************************************************/
void main()      //主函数
{   int speed,Who_First;
  begin:
  speed=1;Who_First=1;
  Human_Chose[0]=Apple_Total/2-1;
     Computer_Chose[0]=Apple_Total/2-1;   
   
     Game_Setting(&speed,&Who_First);
     getch();
    if(Who_First==1)
        {   printf("\n\n\t现在正式开始取苹果:\n\n");
         Human_FirstChose(Apple_Total,speed,Who_First); 
        } 
     else if(Who_First==2)
        {  printf("\n\n\t现在正式开始取苹果:\n\n");
           Computer_FirstChose(Apple_Total,speed,Who_First); 
        } 
      getch();
      printf("\n\t<任意键>-重新游戏,\n");
      getch();
      goto begin; 
     
}