⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 raindoc.cpp

📁 好用的键盘超人源代码
💻 CPP
字号:
// rainDoc.cpp : implementation of the CRainDoc class
//

#include "stdafx.h"
#include "rain.h"

#include "rainDoc.h"
#include "rainView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


extern CRainDoc *PDocument;  

/////////////////////////////////////////////////////////////////////////////
// CRainDoc

IMPLEMENT_DYNCREATE(CRainDoc, CDocument)

BEGIN_MESSAGE_MAP(CRainDoc, CDocument)
	//{{AFX_MSG_MAP(CRainDoc)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CRainDoc construction/destruction

CRainDoc::CRainDoc()
{
	// TODO: add one-time construction code here
   CString tmpStr;

   PDocument=this;
    
   stepBetweenStr=0;       
   maxStrlen=0;
   stepTime=DFT_TIMER;
   allStr=50;  
   localUsrName="";
   fileName="";
   rainType=RT_LOCAL;
   rainSource=RS_RANDOM;
   rainLevel=RL_0;

   rainState=RS_STOPPED; 
   rainMsg=STOPPED_MSG;

   isFileOpened=0;

   initRain();

   if(!recordFile.Open(RECORD_FILE,CFile::modeRead,NULL))
   {
#if DEBUG_RAIN
	   TRACE("\nno record file\n");
#endif
	   recordSpeed=0;
	   recordUsrName="*";
	   recordCreateTime="*";       
   }
   else
   {
       recordFile.ReadString(tmpStr);
       recordSpeed=atoi(tmpStr);

       recordFile.ReadString(tmpStr);
	   int i=tmpStr.GetLength();
	   recordUsrName=tmpStr.Left(i-1);

	   recordFile.ReadString(tmpStr);
	   i=tmpStr.GetLength();
	   recordCreateTime=tmpStr.Left(i-1);

	   recordFile.Close();
   }
}

CRainDoc::~CRainDoc()
{
	char buffer[]={13,10};
	CString tmpStr;
	
    if(recordFile.Open(RECORD_FILE,CFile::modeCreate|CFile::modeWrite,NULL))
    {
        tmpStr.Format("%d",recordSpeed);
		recordFile.WriteString(tmpStr);
		recordFile.Write(buffer,2);

		recordFile.WriteString(recordUsrName);
		recordFile.Write(buffer,2);
       
        recordFile.WriteString(recordCreateTime);
		recordFile.Write(buffer,2);

		recordFile.Close();
	}
    
}

void CRainDoc::initRain()
{
	for (int i=0;i<RAIN_Y;i++)
    { 
         rainStr[i].state=STR_FREE;
		 rainStr[i].strlen=0;
	     rainStr[i].timer=0;
	}
	totalStr=0;
    stepBeforeNewStr=0;      
    usrRightLen=0;
    rightStr=0;    
    maxFitStrAddr=-1;
    rightChar=0;
	totalTime=0;
	tmpTime=0;
	lastNumber=-1;

	StrSequence=0; 
	tick_timer=0;

	demoStep=0;
	demoTick=0;
	demoState=0;

	currentSpeed=0;

	closeFile();
	server.init();
	client.init();

}

int CRainDoc::strNew()
{ 		
    int find;
    int len,i,j;
	int returnVaule;
	int ret;

	find=0;
	for (i=0;i<RAIN_Y;i++)
    {
    	if (rainStr[i].state==STR_FREE)
    	{
			find=1;
            break;    
        }   	
    }	
    if (!find)
	{
      return 0;
    }
    
	returnVaule=0;
    switch(rainType)
	{
	case RT_SERVER:
	case RT_LOCAL:
		 if(rainSource==RS_RANDOM)
         { 
            if(totalStr<allStr)
			{	
               len=MapRand(maxStrlen-1)+1;// len < RAIN_X  
               for (j=0;j<len;j++)
			   {
                   rainStr[i].string[j]='a'+MapRand(25); 
			   }
			   rainStr[i].string[len]=0;
			   rainStr[i].strlen=len;
			   if(rainType==RT_SERVER)
               {
			      rainStr[i].whereX=STATE_WIDE+MapRand(RAIN_X-STATE_WIDE-len);//
               }
			   else//rainType==RT_LOCAL
               {
                   rainStr[i].whereX=MapRand(RAIN_X-len);
			   }	   
               rainStr[i].whereY=0;			
			   stepBeforeNewStr=stepBetweenStr;
			   totalStr++;
			   rainStr[i].state=STR_USE;
            }
			else
            {
				returnVaule=1;
            }
		 }
		 else//rainSource==RS_FILE 
         {
           if(rainType==RT_SERVER)
           {
               ret=readFileStr(rainStr[i].string,RAIN_X-STATE_WIDE);
           }
		   else//rainType==RT_LOCAL
           {
               ret=readFileStr(rainStr[i].string,RAIN_X);
		   }	   
		   if(ret) 
           { 
			  rainStr[i].strlen=strlen(rainStr[i].string);//
              if(rainType==RT_SERVER)
			  {
                rainStr[i].whereX=STATE_WIDE+MapRand(RAIN_X-STATE_WIDE-rainStr[i].strlen);//
			  }
		      else//rainType==RT_LOCAL
			  {
                rainStr[i].whereX=MapRand(RAIN_X-rainStr[i].strlen);//
			  }	   
              rainStr[i].whereY=0; 
			  totalStr++;
			  stepBeforeNewStr=stepBetweenStr;
			  rainStr[i].state=STR_USE;
		   } 
		   else
           {
              returnVaule=1;
           }
         }
		 // as server,must dispatch new string to clients
         if((rainType==RT_SERVER)&&(!returnVaule))
         {
             rainStr[i].sequence=StrSequence;

			 server.dispatchStr(rainStr[i].string,
				                rainStr[i].strlen,
								rainStr[i].whereX,
							    StrSequence);
			 StrSequence++;
		 } 
		 break;
	}
 	
    return returnVaule;    
}

void CRainDoc::insertStr(char *str,int strlen,int whereX,ULONG seq)
{
	int i,j;

	for (i=0;i<RAIN_Y;i++)
    {
    	if (rainStr[i].state==STR_FREE)
    	{
			for(j=0;j<strlen;j++)
            {
				rainStr[i].string[j]=str[j];
			}
			rainStr[i].string[strlen]=0;
			rainStr[i].strlen=strlen;
			rainStr[i].sequence=seq;
			rainStr[i].whereX=whereX;
            rainStr[i].whereY=0;
			rainStr[i].state=STR_USE;
            break;    
        }   	
    }	

}

int CRainDoc::rainStep()
{
    int returnVaule;

    returnVaule=0;
    for (int i=0;i<RAIN_Y;i++)
    {
		//process USE string
    	if (rainStr[i].state==STR_USE)
    	{
    	    rainStr[i].whereY++;
    	    if (rainStr[i].whereY==RAIN_Y) // the string is fall!
    	    {
    	        strFree(i,STR_FREE);
    	    }		
    	}       
		//process FREEING string
		if ((rainStr[i].state==STR_FREEING)
			||(rainStr[i].state==STR_FREEING2))
        {
            strFree(i,STR_FREE);
		}
		//process WAITING string
		if (rainStr[i].state==STR_WAITING)
		{
			rainStr[i].whereY++;//
		}
    }
    
	//check lastNumber if flag is set
	if(lastNumber==-1)
    {
        if (stepBeforeNewStr==0)
		{
          if(strNew())//end of rain source
		  {
             lastNumber=findUseStr();//set this flag now,later it will down to 0  
#if DEBUG_RAIN
			 TRACE("\nlastNumber %d\n",lastNumber);
#endif
		  }	
		}
        else
		{   
	      stepBeforeNewStr--;	         
		}
    }
    else
    {
		if (lastNumber==0)
        { 
		  returnVaule=1;
		} 
    }

	return returnVaule;
}

void CRainDoc::rainDemo()
{
	/*
	 *   demoState==0 : need re paint
	 *   demoState==1 : need not
	 *   demoState==2 : slient state 
	 */

	if(demoState==2)
    {
		return;
	}

	demoTick++;
	if(demoTick==5)
    {
		demoStep=1;
		demoState=0;
	}
	if(demoTick==15)
    {
		demoStep=0;
		demoTick=0;
	}
}
int CRainDoc::charInput(char aChar)
{
	int tmpUsrRightLen=0;
    int tmpMaxFitStrAddr=-1;
	int returnVaule;
	int i;

    
	// put a new char to the end,usrRightLen+1==input string len 
	if ((aChar==8)||(aChar==32)) //backspace or blank
    {
		if (usrRightLen>0)
        {
			usrRightLen=0;
			maxFitStrAddr=-1;
        }
		return 0;
	}	
    usrPressed[usrRightLen]=aChar;
    
	returnVaule=0;
	// check the user input
	for (i=0;i<RAIN_Y;i++)
    {
        if (rainStr[i].state==STR_USE)
        {
			for (int j=0;j<usrRightLen+1;j++)
            {
				if (usrPressed[j]!=rainStr[i].string[j])
                   break;   				
			}	
            if (j>tmpUsrRightLen) 
            {   
				// I'm the fittest at this time
                tmpUsrRightLen=j;
				tmpMaxFitStrAddr=i;
            }  
            if ((j==tmpUsrRightLen)&&(rainStr[i].whereY>rainStr[tmpMaxFitStrAddr].whereY))
            {
                tmpMaxFitStrAddr=i;
			} 
        }
    }
	// find the fittest string
    maxFitStrAddr=tmpMaxFitStrAddr;
	usrRightLen=tmpUsrRightLen;

    if(maxFitStrAddr>=0)
    {
       // the user input hit the string!
	   if(usrRightLen==rainStr[maxFitStrAddr].strlen)
	   {
           returnVaule=1;         
	   }
    }

	return returnVaule;
}
	
void CRainDoc::setRainMsg(CString msg)
{
	rainMsg=msg;
}

CString CRainDoc::getRainMsg()
{
   return rainMsg;
}

void CRainDoc::strHit()
{
  CString tmpStr;
  ULONG tmpTickTimer;

  switch(rainType)
  {
  case RT_SERVER:
	   usrPressed[usrRightLen]=0;
	   tmpTickTimer=tick_timer;
#if DEBUG_RAIN
	   TRACE("server tick_timer:0x%x\n",tick_timer);
#endif
	   if(server.checkUsrHit(rainStr[maxFitStrAddr].sequence,tmpTickTimer))
	   {
	      //insert this string into server hit list 
		   server.insertUsrHit(rainStr[maxFitStrAddr].sequence,tmpTickTimer,usrRightLen);
	   }
	   strFree(maxFitStrAddr,STR_WAITING);
	   /* if user press fast,then rain fast */
	   if (!findUseStr())
       {
	       stepBeforeNewStr=0;
       }
	   break;
	   //maybe some msg
  case RT_LOCAL:
	   usrPressed[usrRightLen]=0;
	   rightStr++; 
	   rightChar+=usrRightLen;
       strFree(maxFitStrAddr,STR_FREEING);
	   /* if user press fast,then rain fast */
	   if (!findUseStr())
       {
	       stepBeforeNewStr=0;
       }
	   tmpStr.Format("' %s '",usrPressed);
	   tmpStr+=" OK";
	   setRainMsg(tmpStr);
	   break;
  case RT_CLIENT:
	   usrPressed[usrRightLen]=0;
	   client.hit(rainStr[maxFitStrAddr].sequence,tick_timer,usrRightLen);
       strFree(maxFitStrAddr,STR_WAITING);
	   break;
  }
}

void CRainDoc::strHitAck(ULONG seq,CString usrName,int flag)
{
	int i;
    CString tmpStr;
	
	for(i=0;i<RAIN_Y;i++)
    {
		if(rainStr[i].sequence==seq)//&&(rainStr[i].state!=STR_FREEING))
        {
           if(!flag)
           {  
		      strFree(i,STR_FREEING);
           }
		   else
           {
              strFree(i,STR_FREEING2);
           }
		   tmpStr.Format("' %s '",rainStr[i].string);
		   tmpStr+=" hitted by ";
		   tmpStr+="' ";
           tmpStr+=usrName;
		   tmpStr+=" '";
		   setRainMsg(tmpStr);
		   break;
		}
	}
}

int CRainDoc::findUseStr()
{
   int i,count=0;
   
   for (i=0;i<RAIN_Y;i++)
   {
       if((rainStr[i].state==STR_USE)
		  ||(rainStr[i].state==STR_FREEING)
		  ||(rainStr[i].state==STR_FREEING2))//
       {
		  count++;
	   }
   }
   return count;
}

void CRainDoc::strFree(int i,int state)
{
  switch(state)
  {
  case STR_FREE:
	   // if from USE to FREE
	   if(rainStr[i].state==STR_USE)
       {
		   //this show user not hit this string
		   rainStr[i].state=STR_FREE;
		   rainStr[i].timer=0;
		   if (i==maxFitStrAddr)
           {
              usrRightLen=0;
		      maxFitStrAddr=-1;
		   }				
           if (lastNumber!=-1)
           {
			  lastNumber--;
		   }	
	   }
	   // if from FREEING to FREE
	   if((rainStr[i].state==STR_FREEING)
		  ||(rainStr[i].state==STR_FREEING2))
       {
          //wait some step before free 
		  if (rainStr[i].timer==1)
          { 
			  rainStr[i].state=STR_FREE;
              rainStr[i].timer=0;
			  if (lastNumber!=-1)
			  {
			     lastNumber--;
			  }	
          }
		  else// not this time
          {
              rainStr[i].timer++;
          }
	   }	   
	   break;
  case STR_FREEING:
  case STR_FREEING2:
	   if(rainStr[i].state!=STR_WAITING)
       {
          usrRightLen=0;
	      maxFitStrAddr=-1;
       }  
	   rainStr[i].state=state;
	   break;
  case STR_WAITING: //this not use for local
	   rainStr[i].state=STR_WAITING;
	   usrRightLen=0;
	   maxFitStrAddr=-1;
	   break;
  }

}

int CRainDoc::getRainState()
{
   return rainState;
}

int CRainDoc::getStrState(int i)
{
   
   int j=rainStr[i].state;
   return j;
}

int CRainDoc::getStrWhereX(int i)
{
   return rainStr[i].whereX;
}

int CRainDoc::getStrWhereY(int i)
{
    return rainStr[i].whereY;
}

CString CRainDoc::getStr(int i)
{
   char tmpBuffer[RAIN_X];
   CString tmpString;

   for(int j=0;j<rainStr[i].strlen;j++)
   {
	   tmpBuffer[j]=rainStr[i].string[j];
   }
   tmpBuffer[rainStr[i].strlen]=0;
   tmpString.Format("%s",tmpBuffer);

   return tmpString;
}

BOOL CRainDoc::isFittestStr(int i)
{
  if(i==maxFitStrAddr)
  {
	  return 1;
  }
	return 0;
}

CString CRainDoc::getFittestStr()
{
   char tmpBuffer[RAIN_X];
   CString tmpString;

   for(int i=0;i<usrRightLen;i++)
   {
	   tmpBuffer[i]=rainStr[maxFitStrAddr].string[i];
   }
   tmpBuffer[usrRightLen]=0;
   tmpString.Format("%s",tmpBuffer);

   return tmpString;
}

int CRainDoc::openFile(CString filename)
{
  int ret;
  if(isFileOpened)
  {
	  return 0;
  }
  ret=file.Open(fileName,CFile::modeRead,NULL);
  if(ret)
  {
	  isFileOpened=1;
  }

  return ret;
}

void CRainDoc::closeFile()
{
   if(isFileOpened)
   {
     file.Close();
	 isFileOpened=0;
   }
}


int CRainDoc::readFileStr(char *buffer,int max)
{
   char tmp; 
   int  index,ret;
   
   if(!isFileOpened)
   {
	   return 0;
   }
  
   //get first char
   tmp=0;
   ret=file.Read(&tmp,1); 
   while((tmp==13)||(tmp==10)||(tmp==32)) 
   {
      ret=file.Read(&tmp,1);
      if(ret==0)  /* ret==0 ,reach file end */
      {          
		 break;
	  }
   }
   
   index=0;
   for(;;)
   {
	 if(ret==1)
     {
	   if((tmp==13)||(tmp==10)||(tmp==32)) 
       {  	
		    if(index>0)//may be needn't check here
            {
              buffer[index]=0; 
			}
			break;
       } 
	   else
	   {		  
		  buffer[index++]=tmp;
		  if(index==max)
          {
			   buffer[index]=0;
			   break;
		  }
       }
	 }
	 else /* ret==0 ,reach file end */
     {
       if(index>0)
	   {	   
          buffer[index]=0;
       } 
	   break;
     }
	 
	 ret=file.Read(&tmp,1); //get a new char
   }

   return index;  
}

void CRainDoc::setRainState(int state)
{
   rainState=state;
}

void CRainDoc::countTime()
{
   tmpTime+=stepTime;
   totalTime+=tmpTime/1000;
   tmpTime%=1000;
}

int CRainDoc::getTotalTime()
{
   return totalTime;
}

int CRainDoc::getTotalStrNum()
{
   return totalStr;
}


int CRainDoc::getRightStrNum()
{
    return rightStr;
}

int CRainDoc::getRightCharNum()
{
    return rightChar;
}

int CRainDoc::getDemoStep()
{
	return demoStep;
}

void CRainDoc::setDemoState(int state)
{
    demoState=state;
	if(state==0)
    {
		demoStep=0;
        demoTick=0;
	}
}

int CRainDoc::getDemoState()
{
	return demoState;
}


///////////////////////////////////////////////////////////////
// CRainDoc diagnostics

#ifdef _DEBUG
void CRainDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CRainDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -