#include <windows.h>
#include <stdlib.h>
#include <time.h>
#define D 1 //雪花下降速度 
COLORREF snowcolor=0x2711EE; //雪花颜色 
COLORREF snowcolor1=0x0000FF; //积雪颜色 
int FENG;  //风向风速值 
int MINX; //屏幕X坐标最大值 
int MINY; //屏幕Y坐标最大值 
//////////////////////////////////////////////////////////////////////////////// 
//获取屏幕分辨率 
int getXY(int *MINX,int *MINY)
{
    HDC hdc=GetDC(NULL);
    int t=1;
    int x=600;
    int y=600;
    for(;t;)
    {
     if(GetPixel(hdc,x,100)==CLR_INVALID) t=0;
     x++;
     }
     t=1;
     for(;t;)
    {
     if(GetPixel(hdc,100,y)==CLR_INVALID) t=0;
     y++;
     }
     *MINX=x;
     *MINY=y;
     ReleaseDC(NULL, hdc);
}
//雪花点属性结构体 
struct xue {
       int x;  //雪花的当前坐标点 
       int y;
       COLORREF oldcolor; //当前雪花点的原始颜色值
       int del;    //是否删除该节点标志值不等于0则删除此节点 
       int nextx;  //将要移动到的坐标点 
       int nexty;
       int shudu;  //下降速度 
       }; 
//雪花布局链表标准节点             
struct xhbiao {       //此结构体用于创建雪花的布局链表 
       struct xue xh;
       struct xhbiao *next; //后继 
       struct xhbiao *quet; //前驱 
       };
//初始化单点雪花 
int huaxue (struct xue *xuehua)  //函数功能是初始化一个新的雪花点 
{
    HDC hdc=GetDC(NULL);
    xuehua->y=0;
    xuehua->x=(int)(rand()%MINX); 
    xuehua->oldcolor=GetPixel(hdc,xuehua->x,xuehua->y);
    xuehua->shudu=(int)((rand()%10)*D+1);
    xuehua->del=0;
    ReleaseDC(NULL,hdc); 
    return 0;
} 
//创建链表 
int link(struct xhbiao **tou,struct xhbiao **wei)
{
    struct xhbiao *p;
    p=(struct xhbiao*)malloc(sizeof(struct xhbiao));
    huaxue(&p->xh);
    p->next=NULL;
    p->quet=NULL;
    (*tou)=p;
    (*wei)=p;
    return 0;
}
//插入节点
int linkCHA(struct xhbiao **tou,struct xhbiao **wei)
{
    if((*tou)!=NULL)
    {
    struct xhbiao *p;
    p=(struct xhbiao*)malloc(sizeof(struct xhbiao));
    huaxue(&p->xh);
    p->next=NULL;
    p->quet=(*wei);
    (*wei)->next=p;
    (*wei)=p;
    }
    return 0;
}
//删除节点
int linkDEL(struct xhbiao *del)
{
    del->quet->next=del->next;
    del->next->quet=del->quet;
    free(del);
    return 0;
}
//维护雪堆链表清除需要删除的雪粒节点
int linkWUI(struct xhbiao **tou,struct xhbiao **wei)
{
    struct xhbiao *p;
    p=(*tou);
    for(;p!=NULL;)
    { 
                       
     if(p->xh.del!=0)
     {                    
       if(p==(*tou))
       {                      
        (*tou)=p->next;
        p->next->quet=NULL;       
        free(p);
       }else if(p==(*wei))
             {
              (*wei)=p->quet;
              p->quet->next=NULL;
              free(p);
              }else {
                      linkDEL(p);
                     }               
     }   
     p=p->next;         
    }
    return 0;
} 
//物理信息处理
int luoxue(struct xhbiao *tou,struct xhbiao *wei)
{
    struct xhbiao *p;  //处理雪花的物理动作 
    p=tou;
    for(;p!=NULL;)
    {
     p->xh.nexty=p->xh.y+p->xh.shudu; //下降 
     p->xh.nextx=p->xh.x+FENG; //(风向风速)
     p=p->next; 
    }
    return 0;
}
//雪堆更新到屏幕
int xuehuagdi(struct xhbiao *tou,struct xhbiao *wei)
{
    HDC hdc=GetDC(NULL);
    COLORREF color,color1;
    int R,G,B,RGB;
    struct xhbiao *p1; //显示雪堆链表的数据 
    p1=tou;
    for(;p1!=NULL;)
    {                               
    SetPixel(hdc,p1->xh.x,p1->xh.y,p1->xh.oldcolor);
    if((p1->xh.nexty<=MINY)&&(p1->xh.nextx>=0)&&(p1->xh.nextx<=MINX)) //超出屏幕边界则删除节点 
    {
    color=GetPixel(hdc,p1->xh.nextx,p1->xh.nexty);
    if(color!=snowcolor)  //如果雪点下一个显示目标点与别的雪点重合则不处理等待维护函数删除此节点 
    {
    color1=GetPixel(hdc,p1->xh.nextx,(p1->xh.nexty-1));
    B=abs((color>>16)&0xff-(color1>>16)&0xff); 
    G=abs((color>>8)&0xff-(color1>>8)&0xff); 
    R=abs((color)&0xff-(color1)&0xff);
    RGB=(R+G+B)/3;  //根据对比度判断是否堆积雪花 
    if(RGB<50){                        
    p1->xh.oldcolor=color;                                                                                                                                                        
    SetPixel(hdc,p1->xh.nextx,p1->xh.nexty,snowcolor);
    p1->xh.x=p1->xh.nextx;
    p1->xh.y=p1->xh.nexty;
    }else if(RGB>50){
          SetPixel(hdc,p1->xh.nextx,(p1->xh.nexty-1),snowcolor1);
          p1->xh.del=1;
          }
    }else if(color==snowcolor){
          p1->xh.del=1;
          }  
    } else if((p1->xh.nexty>MINY)||(p1->xh.nextx<0)||(p1->xh.nextx>MINX)){
          p1->xh.del=1;
          SetPixel(hdc,p1->xh.x,p1->xh.y,p1->xh.oldcolor);
          }
    p1=p1->next;
    }  
    ReleaseDC(NULL,hdc);
    return 0;
} 
/////////////////////////////////////////////////////////////////////////////////           
int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nFunsterStil)

{
  srand(time(NULL));                  
  struct xhbiao *tou,*p,*wei;  //tou为新建表的表头wei为表尾p为新节点的指针 
  tou=NULL;
  wei=NULL;
  FENG=0;
  int i,j,k;
  k=0;
  ////////////////////////////////////////////////////////////////////////////////               
  MINY=1100;
  MINX=1300;
  link(&tou,&wei);
  for(i=0;i<=8;)
  {
  for(j=0;j<=k;j++)
  { 
   linkCHA(&tou,&wei);                 
  }              
  luoxue(tou,wei);
  xuehuagdi(tou,wei);
  linkWUI(&tou,&wei);
  Sleep(30);
  k=rand()%22;
  }
    return 0;
}