Grunge 的个人资料失乐园照片日志列表 工具 帮助

Robin Grunge

职业
地点
2月15日

别说我侵权

 
// Thinker.cpp: implementation of the CThinker class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "BaseDef.h"
#include "Thinker.h"
#include "MoveList.h"
#include "ThinkDef.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CThinker::~CThinker()
{
 if(!m_bExited)Exit();
}
UINT CThinker::ThinkProc()  //思考线程生存期与类对象生存期相同
{
 int i,cur,maxvalue[3],curvalue;
 char *bman,*btox,*btoy;
 int *pcount;
 CMove maxmove[3];
 const char strman[14][3]=
 {"帅","仕","相","马","车","炮","兵","将","士","象","马","车","炮","卒"};
 TRACE("进入思考线程\n");
 while(1)
 {
  cs.Lock();
  if(m_bWaitForExit)
  {
   cs.Unlock();
   goto _EXIT;
  }
  cs.Unlock();
  cs.Lock();
  if(m_bWaitForCut)
  {
   cs.Unlock();
   goto _CUT;
  }
  cs.Unlock();
  cs.Lock();
  if(!m_bThinking)
  {
   cs.Unlock();
   continue;
  }
  cs.Unlock();
  curvalue=-10000;
  maxvalue[0]=-10000;
  maxvalue[1]=-10001;
  maxvalue[2]=-10002;
  cs.Lock();
  tlevel = m_nLevel;
  cs.Unlock();
  tdeep  =0;
  bman=tman[0];
  btox=ttox[0];
  btoy=ttoy[0];
  pcount=& tcount[0];
  *pcount=0;
  for(i=0;i<32;i++)
  {
   tmanx[i]=m_FaceToThink.man[i].x;
   tmany[i]=m_FaceToThink.man[i].y;
  }
  tside=m_FaceToThink.side;
  FixManMap(m_FaceToThink,tmap);
  cur=0;
  EnumList();
  i=*pcount;
  while(cur<i)
  {
   curvalue=SubThink(bman[cur],btox[cur],btoy[cur]);
//---------------------------
   bman=tman[0];
   btox=ttox[0];
   btoy=ttoy[0];
//----------------------------
   //防止兑子过快:
   if(tmap[btox[cur]][btoy[cur]]!=32) curvalue-=BV1[4]/18;
   TRACE("%2d: %s(%2d,%2d) - (%2d,%2d) =%4d\n"
    ,cur
    ,strman[ManToType[bman[cur]]]
    ,tmanx[bman[cur]]
    ,tmany[bman[cur]]
    ,btox[cur]
    ,btoy[cur]
    ,curvalue);
   if(curvalue >maxvalue[0])
   {
    maxmove[2]=maxmove[1]; maxvalue[2]=maxvalue[1];
    maxmove[1]=maxmove[0]; maxvalue[1]=maxvalue[0];
    maxmove[0].man=bman[cur];
    maxmove[0].x=btox[cur];
    maxmove[0].y=btoy[cur];
    maxvalue[0]=curvalue;
   }
   else if(curvalue >maxvalue[1])
   {
    maxmove[2]=maxmove[1]; maxvalue[2]=maxvalue[1];
    maxmove[1].man=bman[cur];
    maxmove[1].x=btox[cur];
    maxmove[1].y=btoy[cur];
    maxvalue[1]=curvalue;
   }
   else if(curvalue >maxvalue[2])
   {
    maxmove[2].man=bman[cur];
    maxmove[2].x=btox[cur];
    maxmove[2].y=btoy[cur];
    maxvalue[2]=curvalue;
   }
   cur ++;
   cs.Lock();
   m_nPercent=((cur+1)*100)/i;
   cs.Unlock();
//----------这一段要保证随时能调用
   cs.Lock();
   if(m_bWaitForExit)
   {
    cs.Unlock();
    goto _EXIT;
   }
   cs.Unlock();
   cs.Lock();
   if(m_bWaitForCut)
   {
    cs.Unlock();
    goto _CUT;
   }
   cs.Unlock();
// --------------------------------
  }
//结束一次计算:
  cs.Lock();
  float f;
  f=(float(maxvalue[0]-maxvalue[2])/(float(maxvalue[0]+maxvalue[1]+maxvalue[
2])/3));
  if(f<0.1 && f>-0.1)
  m_moveResult=maxmove[rnd(3)];
  else
  {
   f=(float(maxvalue[0]-maxvalue[1])/(float(maxvalue[0]+maxvalue[1])/2));
   if(f<0.1 && f>-0.1) m_moveResult=maxmove[rnd(2)];
   else  m_moveResult=maxmove[0];
  }
  TRACE("结果: %s(%2d,%2d) - (%2d,%2d)\n"
   ,strman[ManToType[m_moveResult.man]]
   ,m_FaceToThink.man[m_moveResult.man].x
   ,m_FaceToThink.man[m_moveResult.man].y
   ,m_moveResult.x
   ,m_moveResult.y);
  m_bThinkOver=TRUE;
//-------------------------
  for(i=0;i<32;i++)
  {
   m_FaceToThink.man[i].x=tmanx[i];
   m_FaceToThink.man[i].y=tmany[i];
  }
  m_FaceToThink.side=tside;
//-------------------------------
  cs.Unlock();
  goto _DDD;
_CUT: cs.Lock();
  m_Cut.SetEvent();
  if(m_bWaitForCut)m_bWaitForCut=FALSE;
  cs.Unlock();
_DDD: cs.Lock();
  m_bThinking=FALSE;
  cs.Unlock();
 }
_EXIT: TRACE("退出思考线程\n");
 cs.Lock();
 m_Stoped.SetEvent();
 cs.Unlock();
 return 0;
}
UINT CThinker::_bogusthreadfunc(LPVOID lpparam)//线程函数不能是普通的类成员函

{             //所以通过这个static类型的函数启动线程
 CThinker* This=(CThinker*)(lpparam); //lpparam为构造器中传过来的"this"指针
 return This->ThinkProc();
}
CThinker::CThinker()
{
 ResetBV();
 m_nLevel  = 1;
  m_nPercent  = 0;
 m_bExited  = FALSE;
 m_bWaitForExit = FALSE;
 m_bWaitForCut = FALSE;
 m_bThinking  = FALSE;
 m_bThinkOver = FALSE;
 m_pThinkThread=AfxBeginThread(_bogusthreadfunc,this,THREAD_PRIORITY_NORMAL)
; //构造器中启动线程
}
BOOL CThinker::GetMove(CMove& move,CFace facetothink)
{
 //TRACE("Enter CThinker::GetMove()\n");
 if(!IsThinkOver())return FALSE;
 cs.Lock();
 if(facetothink==m_FaceToThink)
 {
  move=m_moveResult;
  cs.Unlock();
  return TRUE;
 }
 cs.Unlock();
 TRACE("CThinker::GetMove() 发现两次的棋局不同\n");
 return FALSE;
}
void CThinker::SetLevel(int level)
{
 cs.Lock();
 m_nLevel=level;
 TRACE("设置电脑等级为 %d\n",level);
 cs.Unlock();
}
void CThinker::Exit()
{
 cs.Lock();
 m_bWaitForExit=TRUE;
 cs.Unlock();
 ::WaitForSingleObject(m_Stoped,INFINITE);
 m_bExited=TRUE;
 Sleep(300);
}
void CThinker::Think(CFace face)
{
 //TRACE("Enter CThinker::Think()\n");
 if(m_bThinking)Cut();
 cs.Lock();
 m_nPercent  = 0;
 m_FaceToThink = face;
 m_bThinking  = TRUE;
 m_bThinkOver = FALSE;
 TRACE("计算 side = %d\n",face.side);
 cs.Unlock();
 //TRACE("Leave CThinker::Think()\n");
}
BOOL CThinker::IsThinkOver()
{
 //TRACE("Enter CThinker::IsThinkOver()\n");
 BOOL flag;
 cs.Lock();
 flag=m_bThinkOver;
 cs.Unlock();
 //TRACE("Leave CThinker::IsThinkOver()\n");
 return flag;
}
void CThinker::Cut()
{
 cs.Lock();
 m_bWaitForCut=TRUE;
 cs.Unlock();
 ::WaitForSingleObject(m_Cut,INFINITE);
 cs.Lock();
 m_bThinkOver=FALSE;
 m_nPercent=0;
 cs.Unlock();
 TRACE("中止计算\n");
}
UINT CThinker::GetPercent()
{
 int val;
 cs.Lock();
 val=m_nPercent;
 cs.Unlock();
 return val;
}
#define ADD(man,tx,ty) {*lman=man;*ltox=tx;*ltoy=ty;lman++;ltox++;ltoy++;(*p
count)++;if(tmap[tx][ty]==FistOfSide[!tside])goto _NOKING;}
BOOL CThinker::EnumList()
{
 static int i,j,n,x,y,* pcount;
 static BOOL flag;
 lman=tman[tdeep];
 ltox=ttox[tdeep];
 ltoy=ttoy[tdeep];
 pcount=&tcount[tdeep];
 for(n=FistOfSide[tside];n<=LastOfSide[tside];n++)
 {
  x=tmanx[n];
  if(!x)continue;
  y=tmany[n];
  switch(n)
  {
  case 0:
   if(tmanx[0]==tmanx[16])  //将帅在同一列
   {
    flag=FALSE;
    for(j=tmany[16]+1;j<tmany[0];j++)
    {
     if(tmap[x][j]!=32)
     {
      flag=TRUE;
      break;
     }
    }
    if (!flag)
    {
     ADD(0,x,tmany[16]);
    }
   }
   j=y+1;if(j<=10 && NORED(x,j)) ADD(0,x,j)
   j=y-1;if(j>=8  && NORED(x,j)) ADD(0,x,j)
   i=x+1;if(i<=6  && NORED(i,y)) ADD(0,i,y)
   i=x-1;if(i>=4  && NORED(i,y)) ADD(0,i,y)
   break;
  case 16:
   if(tmanx[0]==tmanx[16])  //将帅在同一列
   {
    flag=FALSE;
    for(j=tmany[16]+1;j<tmany[0];j++)
    {
     if(tmap[x][j]!=32)
     {
      flag=TRUE;
      break;
     }
    }
    if (!flag)
    {
     ADD(16,x,tmany[0]);
    }
   }
   j=y+1;if(j<=3 && NOBLACK(x,j)) ADD(16,x,j)
   j=y-1;if(j>=1  && NOBLACK(x,j)) ADD(16,x,j)
   i=x+1;if(i<=6  && NOBLACK(i,y)) ADD(16,i,y)
   i=x-1;if(i>=4  && NOBLACK(i,y)) ADD(16,i,y)
   break;
  case 1:
  case 2:
   i=x+1;j=y+1;if(i<=6 && j<=10 && NORED(i,j)) ADD(n,i,j)
   i=x+1;j=y-1;if(i<=6 && j>=8  && NORED(i,j)) ADD(n,i,j)
   i=x-1;j=y+1;if(i>=4 && j<=10 && NORED(i,j)) ADD(n,i,j)
   i=x-1;j=y-1;if(i>=4 && j>=8  && NORED(i,j)) ADD(n,i,j)
   break;
  case 17:
  case 18:
   i=x+1;j=y+1;if(i<=6 && j<=3 && NOBLACK(i,j)) ADD(n,i,j)
   i=x+1;j=y-1;if(i<=6 && j>=1 && NOBLACK(i,j)) ADD(n,i,j)
   i=x-1;j=y+1;if(i>=4 && j<=3 && NOBLACK(i,j)) ADD(n,i,j)
   i=x-1;j=y-1;if(i>=4 && j>=1 && NOBLACK(i,j)) ADD(n,i,j)
   break;
  case 3:
  case 4:
   i=x+2;j=y+2;if(i<=9 && j<=10   && NORED(i,j)) if(NOMAN(x+1,y+1)) ADD(n,i,
j)
   i=x+2;j=y-2;if(i<=9 && j>=6    && NORED(i,j)) if(NOMAN(x+1,y-1)) ADD(n,i,
j)
   i=x-2;j=y+2;if(i>=1 && j<=10   && NORED(i,j)) if(NOMAN(x-1,y+1)) ADD(n,i,
j)
   i=x-2;j=y-2;if(i>=1 && j>=6    && NORED(i,j)) if(NOMAN(x-1,y-1)) ADD(n,i,
j)
   break;
  case 19:
  case 20:
   i=x+2;j=y+2;if(i<=9 && j<=5  && NOBLACK(i,j)) if(NOMAN(x+1,y+1)) ADD(n,i,
j)
   i=x+2;j=y-2;if(i<=9 && j>=1  && NOBLACK(i,j)) if(NOMAN(x+1,y-1)) ADD(n,i,
j)
   i=x-2;j=y+2;if(i>=1 && j<=5  && NOBLACK(i,j)) if(NOMAN(x-1,y+1)) ADD(n,i,
j)
   i=x-2;j=y-2;if(i>=1 && j>=1  && NOBLACK(i,j)) if(NOMAN(x-1,y-1)) ADD(n,i,
j)
   break;
  case 5:
  case 6:
   i=x+1;
   if(NOMAN(i,y))
   {
    i=x+2;j=y+1;if(i<=9 && j<=10 && NORED(i,j)) ADD(n,i,j)
    i=x+2;j=y-1;if(i<=9 && j>=1  && NORED(i,j)) ADD(n,i,j)
   }
   i=x-1;
   if(NOMAN(i,y))
   {
    i=x-2;j=y+1;if(i>=1 && j<=10 && NORED(i,j)) ADD(n,i,j)
    i=x-2;j=y-1;if(i>=1 && j>=1  && NORED(i,j)) ADD(n,i,j)
   }
   j=y+1;
   if(NOMAN(x,j))
   {
    i=x+1;j=y+2;if(i<=9 && j<=10 && NORED(i,j)) ADD(n,i,j)
    i=x-1;j=y+2;if(i>=1 && j<=10 && NORED(i,j)) ADD(n,i,j)
   }
   j=y-1;
   if(NOMAN(x,j))
   {
    i=x+1;j=y-2;if(i<=9 && j>=1 && NORED(i,j)) ADD(n,i,j)
    i=x-1;j=y-2;if(i>=1 && j>=1 && NORED(i,j)) ADD(n,i,j)
   }
   break;
  case 21:
  case 22:
   i=x+1;
   if(NOMAN(i,y))
   {
    i=x+2;j=y+1;if(i<=9 && j<=10 && NOBLACK(i,j)) ADD(n,i,j)
    i=x+2;j=y-1;if(i<=9 && j>=1  && NOBLACK(i,j)) ADD(n,i,j)
   }
   i=x-1;
   if(NOMAN(i,y))
   {
    i=x-2;j=y+1;if(i>=1 && j<=10 && NOBLACK(i,j)) ADD(n,i,j)
    i=x-2;j=y-1;if(i>=1 && j>=1  && NOBLACK(i,j)) ADD(n,i,j)
   }
   j=y+1;
   if(NOMAN(x,j))
   {
    i=x+1;j=y+2;if(i<=9 && j<=10 && NOBLACK(i,j)) ADD(n,i,j)
    i=x-1;j=y+2;if(i>=1 && j<=10 && NOBLACK(i,j)) ADD(n,i,j)
   }
   j=y-1;
   if(NOMAN(x,j))
   {
    i=x+1;j=y-2;if(i<=9 && j>=1 && NOBLACK(i,j)) ADD(n,i,j)
    i=x-1;j=y-2;if(i>=1 && j>=1 && NOBLACK(i,j)) ADD(n,i,j)
   }
   break;
  case 7:
  case 8:
    i=x+1;
    while(i<=9)
    {
     if (NOMAN(i,y)) ADD(n,i,y)
     else
     {
      if(NORED(i,y)) ADD(n,i,y)
      break;
     }
     i++;
    }
    i=x-1;
    while(i>=1)
    {
     if (NOMAN(i,y)) ADD(n,i,y)
     else
     {
      if(NORED(i,y)) ADD(n,i,y)
      break;
     }
     i--;
    }
    j=y+1;
    while(j<=10)
    {
     if (NOMAN(x,j)) ADD(n,x,j)
     else
     {
      if(NORED(x,j)) ADD(n,x,j)
      break;
     }
     j++;
    }
    j=y-1;
    while(j>=1)
    {
     if (NOMAN(x,j)) ADD(n,x,j)
     else
     {
      if(NORED(x,j)) ADD(n,x,j)
      break;
     }
     j--;
    }
    break;
  case 23:
  case 24:
    i=x+1;
    while(i<=9)
    {
     if (NOMAN(i,y)) ADD(n,i,y)
     else
     {
      if(NOBLACK(i,y)) ADD(n,i,y)
      break;
     }
     i++;
    }
    i=x-1;
    while(i>=1)
    {
     if (NOMAN(i,y)) ADD(n,i,y)
     else
     {
      if(NOBLACK(i,y)) ADD(n,i,y)
      break;
     }
     i--;
    }
    j=y+1;
    while(j<=10)
    {
     if (NOMAN(x,j)) ADD(n,x,j)
     else
     {
      if(NOBLACK(x,j)) ADD(n,x,j)
      break;
     }
     j++;
    }
    j=y-1;
    while(j>=1)
    {
     if (NOMAN(x,j)) ADD(n,x,j)
     else
     {
      if(NOBLACK(x,j)) ADD(n,x,j)
      break;
     }
     j--;
    }
    break;
  case 9:
  case 10:
   i=x+1;flag=FALSE;
   while(i<=9)
   {
    if(NOMAN(i,y))
    {
     if(!flag) ADD(n,i,y)
    }
    else
    {
     if(!flag)flag=TRUE;
     else
     {
      if(NORED(i,y)) ADD(n,i,y)
      break;
     }
    }
    i++;
   }
   i=x-1;flag=FALSE;
   while(i>=1)
   {
    if(NOMAN(i,y))
    {
     if(!flag) ADD(n,i,y)
    }
    else
    {
     if(!flag)flag=TRUE;
     else
     {
      if(NORED(i,y)) ADD(n,i,y)
      break;
     }
    }
    i--;
   }
   j=y+1;flag=FALSE;
   while(j<=10)
   {
    if(NOMAN(x,j))
    {
     if(!flag) ADD(n,x,j)
    }
    else
    {
     if(!flag)flag=TRUE;
     else
     {
      if(NORED(x,j)) ADD(n,x,j)
      break;
     }
    }
    j++;
   }
   j=y-1;flag=FALSE;
   while(j>=1)
   {
    if(NOMAN(x,j))
    {
     if(!flag) ADD(n,x,j)
    }
    else
    {
     if(!flag)flag=TRUE;
     else
     {
      if(NORED(x,j)) ADD(n,x,j)
      break;
     }
    }
    j--;
   }
   break;
  case 25:
  case 26:
   i=x+1;flag=FALSE;
   while(i<=9)
   {
    if(NOMAN(i,y))
    {
     if(!flag) ADD(n,i,y)
    }
    else
    {
     if(!flag)flag=TRUE;
     else
     {
      if(NOBLACK(i,y)) ADD(n,i,y)
      break;
     }
    }
    i++;
   }
   i=x-1;flag=FALSE;
   while(i>=1)
   {
    if(NOMAN(i,y))
    {
     if(!flag) ADD(n,i,y)
    }
    else
    {
     if(!flag)flag=TRUE;
     else
     {
      if(NOBLACK(i,y)) ADD(n,i,y)
      break;
     }
    }
    i--;
   }
   j=y+1;flag=FALSE;
   while(j<=10)
   {
    if(NOMAN(x,j))
    {
     if(!flag) ADD(n,x,j)
    }
    else
    {
     if(!flag)flag=TRUE;
     else
     {
      if(NOBLACK(x,j)) ADD(n,x,j)
      break;
     }
    }
    j++;
   }
   j=y-1;flag=FALSE;
   while(j>=1)
   {
    if(NOMAN(x,j))
    {
     if(!flag) ADD(n,x,j)
    }
    else
    {
     if(!flag)flag=TRUE;
     else
     {
      if(NOBLACK(x,j)) ADD(n,x,j)
      break;
     }
    }
    j--;
   }
   break;
  case 11:
  case 12:
  case 13:
  case 14:
  case 15:
   j=y-1;
   if(j>=1 && NORED(x,j)) ADD(n,x,j)
   if(y<=5)
   {
    i=x+1;if(i<=9 && NORED(i,y)) ADD(n,i,y)
    i=x-1;if(i>=1 && NORED(i,y)) ADD(n,i,y)
   }
   break;
  case 27:
  case 28:
  case 29:
  case 30:
  case 31:
   j=y+1;
   if(j<=10 && NOBLACK(x,j)) ADD(n,x,j)
   if(y>=6)
   {
    i=x+1;if(i<=9 && NOBLACK(i,y)) ADD(n,i,y)
    i=x-1;if(i>=1 && NOBLACK(i,y)) ADD(n,i,y)
   }
   break;
  default :
   break;
  }
 }
 return TRUE;
_NOKING:
 return FALSE;
}
#define CV(man,tx,ty) {k=tmap[tx][ty];v1[man]+=1;if(k!=32)v2[man][k]=1;}
void CThinker::ContactV()
{
 static int i,j,n,x,y;
 static BOOL flag;
 for(n=0;n<=31;n++)
 {
  x=tmanx[n];
  if(!x)continue;
  y=tmany[n];
  switch(n)
  {
  case 0:
   if(tmanx[0]==tmanx[16])  //将帅在同一列
   {
    flag=FALSE;
    for(j=tmany[16]+1;j<tmany[0];j++)
    {
     if(tmap[x][j]!=32)
     {
      flag=TRUE;
      break;
     }
    }
    if (!flag)
    {
     CV(0,x,tmany[16]);
    }
   }
   j=y+1;if(j<=10 ) CV(0,x,j)
   j=y-1;if(j>=8  ) CV(0,x,j)
   i=x+1;if(i<=6  ) CV(0,i,y)
   i=x-1;if(i>=4  ) CV(0,i,y)
   break;
  case 16:
   if(tmanx[0]==tmanx[16])  //将帅在同一列
   {
    flag=FALSE;
    for(j=tmany[16]+1;j<tmany[0];j++)
    {
     if(tmap[x][j]!=32)
     {
      flag=TRUE;
      break;
     }
    }
    if (!flag)
    {
     CV(16,x,tmany[0]);
    }
   }
   j=y+1;if(j<=3 ) CV(16,x,j)
   j=y-1;if(j>=1 ) CV(16,x,j)
   i=x+1;if(i<=6 ) CV(16,i,y)
   i=x-1;if(i>=4 ) CV(16,i,y)
   break;
  case 1:
  case 2:
   i=x+1;j=y+1;if(i<=6 && j<=10 ) CV(n,i,j)
   i=x+1;j=y-1;if(i<=6 && j>=8  ) CV(n,i,j)
   i=x-1;j=y+1;if(i>=4 && j<=10 ) CV(n,i,j)
   i=x-1;j=y-1;if(i>=4 && j>=8  ) CV(n,i,j)
   break;
  case 17:
  case 18:
   i=x+1;j=y+1;if(i<=6 && j<=3 ) CV(n,i,j)
   i=x+1;j=y-1;if(i<=6 && j>=1 ) CV(n,i,j)
   i=x-1;j=y+1;if(i>=4 && j<=3 ) CV(n,i,j)
   i=x-1;j=y-1;if(i>=4 && j>=1 ) CV(n,i,j)
   break;
  case 3:
  case 4:
   i=x+2;j=y+2;if(i<=9 && j<=10  ) if(NOMAN(x+1,y+1)) CV(n,i,j)
   i=x+2;j=y-2;if(i<=9 && j>=6   ) if(NOMAN(x+1,y-1)) CV(n,i,j)
   i=x-2;j=y+2;if(i>=1 && j<=10  ) if(NOMAN(x-1,y+1)) CV(n,i,j)
   i=x-2;j=y-2;if(i>=1 && j>=6   ) if(NOMAN(x-1,y-1)) CV(n,i,j)
   break;
  case 19:
  case 20:
   i=x+2;j=y+2;if(i<=9 && j<=5 ) if(NOMAN(x+1,y+1)) CV(n,i,j)
   i=x+2;j=y-2;if(i<=9 && j>=1 ) if(NOMAN(x+1,y-1)) CV(n,i,j)
   i=x-2;j=y+2;if(i>=1 && j<=5 ) if(NOMAN(x-1,y+1)) CV(n,i,j)
   i=x-2;j=y-2;if(i>=1 && j>=1 ) if(NOMAN(x-1,y-1)) CV(n,i,j)
   break;
  case 5:
  case 6:
   i=x+1;
   if(NOMAN(i,y))
   {
    i=x+2;j=y+1;if(i<=9 && j<=10 ) CV(n,i,j)
    i=x+2;j=y-1;if(i<=9 && j>=1  ) CV(n,i,j)
   }
   i=x-1;
   if(NOMAN(i,y))
   {
    i=x-2;j=y+1;if(i>=1 && j<=10 ) CV(n,i,j)
    i=x-2;j=y-1;if(i>=1 && j>=1  ) CV(n,i,j)
   }
   j=y+1;
   if(NOMAN(x,j))
   {
    i=x+1;j=y+2;if(i<=9 && j<=10 ) CV(n,i,j)
    i=x-1;j=y+2;if(i>=1 && j<=10 ) CV(n,i,j)
   }
   j=y-1;
   if(NOMAN(x,j))
   {
    i=x+1;j=y-2;if(i<=9 && j>=1 ) CV(n,i,j)
    i=x-1;j=y-2;if(i>=1 && j>=1 ) CV(n,i,j)
   }
   break;
  case 21:
  case 22:
   i=x+1;
   if(NOMAN(i,y))
   {
    i=x+2;j=y+1;if(i<=9 && j<=10 ) CV(n,i,j)
    i=x+2;j=y-1;if(i<=9 && j>=1  ) CV(n,i,j)
   }
   i=x-1;
   if(NOMAN(i,y))
   {
    i=x-2;j=y+1;if(i>=1 && j<=10 ) CV(n,i,j)
    i=x-2;j=y-1;if(i>=1 && j>=1  ) CV(n,i,j)
   }
   j=y+1;
   if(NOMAN(x,j))
   {
    i=x+1;j=y+2;if(i<=9 && j<=10 ) CV(n,i,j)
    i=x-1;j=y+2;if(i>=1 && j<=10 ) CV(n,i,j)
   }
   j=y-1;
   if(NOMAN(x,j))
   {
    i=x+1;j=y-2;if(i<=9 && j>=1 ) CV(n,i,j)
    i=x-1;j=y-2;if(i>=1 && j>=1 ) CV(n,i,j)
   }
   break;
  case 7:
  case 8:
    i=x+1;
    while(i<=9)
    {
     if (NOMAN(i,y)) CV(n,i,y)
     else
     {
      CV(n,i,y)
      break;
     }
     i++;
    }
    i=x-1;
    while(i>=1)
    {
     if (NOMAN(i,y)) CV(n,i,y)
     else
     {
      CV(n,i,y)
      break;
     }
     i--;
    }
    j=y+1;
    while(j<=10)
    {
     if (NOMAN(x,j)) CV(n,x,j)
     else
     {
      CV(n,x,j)
      break;
     }
     j++;
    }
    j=y-1;
    while(j>=1)
    {
     if (NOMAN(x,j)) CV(n,x,j)
     else
     {
      CV(n,x,j)
      break;
     }
     j--;
    }
    break;
  case 23:
  case 24:
    i=x+1;
    while(i<=9)
    {
     if (NOMAN(i,y)) CV(n,i,y)
     else
     {
      CV(n,i,y)
      break;
     }
     i++;
    }
    i=x-1;
    while(i>=1)
    {
     if (NOMAN(i,y)) CV(n,i,y)
     else
     {
      CV(n,i,y)
      break;
     }
     i--;
    }
    j=y+1;
    while(j<=10)
    {
     if (NOMAN(x,j)) CV(n,x,j)
     else
     {
      CV(n,x,j)
      break;
     }
     j++;
    }
    j=y-1;
    while(j>=1)
    {
     if (NOMAN(x,j)) CV(n,x,j)
     else
     {
      CV(n,x,j)
      break;
     }
     j--;
    }
    break;
  case 9:
  case 10:
   i=x+1;flag=FALSE;
   while(i<=9)
   {
    if(NOMAN(i,y))
    {
     if(!flag) CV(n,i,y)
    }
    else
    {
     if(!flag)flag=TRUE;
     else
     {
      CV(n,i,y)
      break;
     }
    }
    i++;
   }
   i=x-1;flag=FALSE;
   while(i>=1)
   {
    if(NOMAN(i,y))
    {
     if(!flag) CV(n,i,y)
    }
    else
    {
     if(!flag)flag=TRUE;
     else
     {
      CV(n,i,y)
      break;
     }
    }
    i--;
   }
   j=y+1;flag=FALSE;
   while(j<=10)
   {
    if(NOMAN(x,j))
    {
     if(!flag) CV(n,x,j)
    }
    else
    {
     if(!flag)flag=TRUE;
     else
     {
      CV(n,x,j)
      break;
     }
    }
    j++;
   }
   j=y-1;flag=FALSE;
   while(j>=1)
   {
    if(NOMAN(x,j))
    {
     if(!flag) CV(n,x,j)
    }
    else
    {
     if(!flag)flag=TRUE;
     else
     {
      CV(n,x,j)
      break;
     }
    }
    j--;
   }
   break;
  case 25:
  case 26:
   i=x+1;flag=FALSE;
   while(i<=9)
   {
    if(NOMAN(i,y))
    {
     if(!flag) CV(n,i,y)
    }
    else
    {
     if(!flag)flag=TRUE;
     else
     {
      CV(n,i,y)
      break;
     }
    }
    i++;
   }
   i=x-1;flag=FALSE;
   while(i>=1)
   {
    if(NOMAN(i,y))
    {
     if(!flag) CV(n,i,y)
    }
    else
    {
     if(!flag)flag=TRUE;
     else
     {
      CV(n,i,y)
      break;
     }
    }
    i--;
   }
   j=y+1;flag=FALSE;
   while(j<=10)
   {
    if(NOMAN(x,j))
    {
     if(!flag) CV(n,x,j)
    }
    else
    {
     if(!flag)flag=TRUE;
     else
     {
      CV(n,x,j)
      break;
     }
    }
    j++;
   }
   j=y-1;flag=FALSE;
   while(j>=1)
   {
    if(NOMAN(x,j))
    {
     if(!flag) CV(n,x,j)
    }
    else
    {
     if(!flag)flag=TRUE;
     else
     {
      CV(n,x,j)
      break;
     }
    }
    j--;
   }
   break;
  case 11:
  case 12:
  case 13:
  case 14:
  case 15:
   j=y-1;
   if(j>=1 ) CV(n,x,j)
   if(y<=5)
   {
    i=x+1;if(i<=9 ) CV(n,i,y)
    i=x-1;if(i>=1 ) CV(n,i,y)
   }
   break;
  case 27:
  case 28:
  case 29:
  case 30:
  case 31:
   j=y+1;
   if(j<=10 ) CV(n,x,j)
   if(y>=6)
   {
    i=x+1;if(i<=9 ) CV(n,i,y)
    i=x-1;if(i>=1 ) CV(n,i,y)
   }
   break;
  default :
   break;
  }
 }
}
int CThinker::SubThink(int man, int tx, int ty)
{
 int ate,i,j,cur,maxvalue,curvalue,xs,ys;
 char *bman,*btox,*btoy;
 int *pcount;
 ate=32;
 tdeep++;
 //
 //移动棋子:
 xs=tmanx[man];ys=tmany[man];    //原坐标
 if (SideOfMan[tmap[tx][ty]]==!tside) //目标点有对方的棋子
 {
  ate=tmap[tx][ty];     //记录下被吃掉的棋子
  if(ate==0 || ate==16)
  {
   tdeep--;
   return 9999;
  }
  tmanx[ate]=0;      //目标点的棋子被吃掉
 }
 tmap[tx][ty]=man;      //这两行是:
 tmap[xs][ys]=32;       //在map上的移动
 tmanx[man]=tx;       //这两行是:
 tmany[man]=ty;       //在face上的移动
 tside=!tside;
 if(tdeep != tlevel)
 {
  //初始化:
  bman=tman[tdeep];
  btox=ttox[tdeep];
  btoy=ttoy[tdeep];
  pcount=& tcount[tdeep];
  *pcount=0;
  cur=0;
  if(EnumList())
  {
   maxvalue=-10000;
   i=*pcount;
   while(cur< i)
   {
    curvalue=SubThink(bman[cur],btox[cur],btoy[cur]);
    if(curvalue>maxvalue)maxvalue=curvalue;
    cur ++;
   }
  }
  else maxvalue=9800;
 }
 else
 {
  memset(v2,0,sizeof(int)<<10);
  memset(v1,0,sizeof(int)<<5);
  memset(v3,0,sizeof(int)<<5);
  memset(v4,0,sizeof(int)<<5);
  maxvalue=0;
  ContactV();
//己方将军
  for(i=FistOfSide[tside];i<=LastOfSide[tside];i++)
  {
   if(v2[i][FistOfSide[!tside]])
   {
    maxvalue=9700;
    goto _ENDSUB;
   }
  }
  for(i=0;i<32;i++)
  {
   k=ManToType7[i];
   v1[i]=BV1[k]+v1[i]*BV2[k];
   if(k==6)  v1[i]+=BV3[ BA[SideOfMan[i]][tmany[i]][tmanx[i]] ];
  }
  for(i=0;i<32;i++)
  {
   for(j=0;j<32;j++)
   {
    if(v2[i][j])
    {
     if(SideOfMan[i]==SideOfMan[j])
     {
      v3[i]+=v1[j]>>5;//己方
      v4[j]++;
     }
     else
     {
      v3[i]+=v1[j]>>3;//对方
      v4[j]--;
     }
    }
   }
  }
  for(i=FistOfSide[tside];i<=LastOfSide[tside];i++)
  {
   if(tmanx[i])maxvalue+=v1[i]+v3[i];
  }
  static BOOL flag;
  flag=FALSE;k=32;
  for(i=FistOfSide[!tside];i<=LastOfSide[!tside];i++)
  {
   if(tmanx[i])maxvalue-=v1[i]+v3[i];
//对方将军
   if(v2[i][FistOfSide[tside]])
   {
    flag=TRUE;
    k=i;
    break;
   }
  }
  if(flag)//被将
  {
   if(v4[k]>=0)//所将军的棋子不能被吃掉
   {
    j=0;
    for(i=FistOfSide[tside];i<=LastOfSide[tside];i++)
    {
     if(v4[i]<0 && v1[i]>j) j=v1[i];
    }
    maxvalue -=j;
   }
  }
  else
  {
   j=0;
   for(i=FistOfSide[!tside];i<=LastOfSide[!tside];i++)
   {
    if(v4[i]<0 && v1[i]>j)
     j=v1[i];
   }
   maxvalue +=j;
  }
 }
_ENDSUB: tmanx[man]=xs;       //这两行是:
 tmany[man]=ys;       //在face上的恢复
 tmap[xs][ys]=man;      //在map上的恢复
 if(ate!=32)
 {
  tmanx[ate]=tx;
  tmany[ate]=ty;
  tmap[tx][ty]=ate;
 }
 else tmap[tx][ty]=32;
 tside=!tside;
 tdeep--;
 return -maxvalue;
}
BOOL CThinker::LoadThinkSetting()
{
 CFile file;
 if(file.Open( "Thinker.set",CFile::modeRead))
 {
  file.SeekToBegin();
  file.Read(BV1,7*sizeof(int));
  file.Read(BV2,7*sizeof(int));
  file.Read(BV3,5*sizeof(int));
  file.Close();
  if(BVIsNormal())return TRUE;
  else
  {
   ResetBV();
   SaveThinkSetting();
   return FALSE;
  }
 }
 MessageBox(NULL, "没找到 Thinker.set 文件\n\n这个文件并不是必需的,但它记录了
你的设置内容,\n\n请不要删掉\n\n你现在可以通过菜单 \"文件\" -> \"参数\" 重新设
定.","提醒",MB_OK|MB_ICONINFORMATION);
 ResetBV();
 SaveThinkSetting();
 return FALSE;
}
void CThinker::ResetBV()
{
 BV1[0]=0; BV2[0]=0;
 BV1[1]=250; BV2[1]=1;
 BV1[2]=250; BV2[2]=1;
 BV1[3]=300; BV2[3]=12;
 BV1[4]=400; BV2[4]=6;
 BV1[5]=300; BV2[5]=6;
 BV1[6]=100; BV2[6]=15;
 BV3[0]=0;
 BV3[1]=70;
 BV3[2]=90;
 BV3[3]=110;
 BV3[4]=120;
}
BOOL CThinker::BVIsNormal()
{
 int i;
 for(i=0;i<=6;i++)
 {
  if(BV1[i]<0||BV1[i]>1000||BV2[i]<0||BV2[i]>1000)return FALSE;
 }
 for(i=0;i<=4;i++)
 {
  if(BV3[i]<0||BV3[i]>1000)return FALSE;
 }
 return TRUE;
}
BOOL CThinker::SaveThinkSetting()
{
 CFile file;
 if(file.Open("Thinker.set",CFile::modeWrite|CFile::modeCreate))
 {
  file.SeekToBegin();
  file.Write(BV1,7*sizeof(int));
  file.Write(BV2,7*sizeof(int));
  file.Write(BV3,5*sizeof(int));
  file.Close();
  return TRUE;
 }
 else return FALSE;
}

...


// Thinker.h: interface for the CThinker class.
//
//////////////////////////////////////////////////////////////////////
#include "BaseClasses.h"
#if !defined(AFX_THINKER_H__994E259B_1A23_11D4_9933_BB99EA787221__INCLUDED_)
 
#define AFX_THINKER_H__994E259B_1A23_11D4_9933_BB99EA787221__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CThinker
{
public:
 BOOL SaveThinkSetting();
 BOOL LoadThinkSetting();
 int BV1[7];
 int BV2[7];
 int BV3[5];
 UINT GetPercent(void);
 void Cut(void);
 CThinker();
 void SetLevel(int level);
 virtual ~CThinker();
 void Think(CFace face);
 void Exit();
 BOOL IsThinkOver();
 BOOL GetMove(CMove& move,CFace facetothink);
 static UINT _bogusthreadfunc(LPVOID lpparam);
private:
 void ContactV(void);
 int SubThink(int man,int tx,int ty);
 BOOL EnumList(void);
 UINT ThinkProc(void);
protected:
 BOOL BVIsNormal();
 void ResetBV();
 CMove m_moveResult;
 BOOL m_bThinking;
 BOOL m_bThinkOver;
 BOOL m_bWaitForExit;
 BOOL m_bWaitForCut;
 BOOL m_bExited;
 UINT m_nLevel;
 UINT m_nPercent;
 CFace m_FaceToThink;
 CCriticalSection cs;
 CEvent m_Stoped;
 CEvent m_Cut;
 CWinThread* m_pThinkThread;
};
#endif // !defined(AFX_THINKER_H__994E259B_1A23_11D4_9933_BB99EA787221__INCL
UDED_)
 

别说我侵权


人工智能 def部分
thinkerdef.h
#if !defined CCT_CHESSTHINKER_DEF
#define CCT_CHESSTHINKER_DEF
//       k,  s,  x,  m,  j,  p,  b
const int BA[2][12][11]=
{
 {
  {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
  {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
  {  0,  2,  2,  3,  4,  4,  4,  3,  2,  2,  0},
  {  0,  2,  2,  3,  4,  4,  4,  3,  2,  2,  0},
  {  0,  1,  2,  3,  3,  3,  3,  3,  2,  1,  0},
  {  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0},
  {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
  {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
  {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
  {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
  {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
  {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
 },
 {
  {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
  {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
  {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
  {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
  {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
  {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
  {  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0},
  {  0,  1,  2,  3,  3,  3,  3,  3,  2,  1,  0},
  {  0,  2,  2,  3,  4,  4,  4,  3,  2,  2,  0},
  {  0,  2,  2,  3,  4,  4,  4,  3,  2,  2,  0},
  {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
  {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
 }
};
//movelists:
 char tman[6][125],ttox[6][125],ttoy[6][125];
 int  tcount[6];
//face
 char tmanx[32], tmany[32];
 int  tside;
//map
 int tmap[11][12];
//
 int tlevel,tdeep;
//只在enumlist中调用
 char *lman,*ltox,*ltoy;
#define NORED(i,j) (SideOfMan[tmap[i][j]]!=0)
#define NOBLACK(i,j) (SideOfMan[tmap[i][j]]!=1)
#define NOMAN(i,j) (tmap[i][j]==32)
 int k;
 int v1[32];
 int v2[32][32];
 int v3[32];
 int v4[32];
#endif
 
 
2月7日

备忘5


procedure TFrmSearch.btnSearchClick(Sender : Tobject);
var
  SerachPhrase : TaaSearchParser;
  RPNWalker    : TaaRPNNode;
  Stack        : TBitSetStack;
  BS1          : TaaBitSet;
  BS2          : TaaBitSet;
  i            : integer;
begin
  {prepare for the evaluation}
  lbxResults.Items.Clear;
  SearchPhrase := nil;
  Stack := nil;
  BS1 := nil;
  try
    {parse the search phrase}
    SearchPhrase := TaaSearchPhrase.Create(edtSearchPhrase.Text);
    RPNWalker := SearchPhrase.RPN;
    {create the stack for evaluating the RPN expression}
    Stack := TBitSetStack.Create;
    while (RPNWalker <> nil) do
      begin
        if RPNWalker is TaaRPNWord then
          begin
            BS1 := TaaBitSet.Create(DocList.Count);
            BS2 := WordIndex.Find(TaaRPNWord(RPNWalker).PhraseWord);
            if (BS2 <> nil) then
              BS1.Assign(BS2);
            Stack.Push(BS1);
          end
        else if RPNWalker is TaaRPN_AND then
          begin
            BS1 := Stack.Pop;
            BS2 := Stack.Pop;
            BS1.AndBitSet(BS2);
            Stack.Push(BS1);
            BS2.Free;
          end
        else if RPNWalker is TaaRPN_OR then
          begin
            BS1 := Stack.Pop;
            BS2 := Stack.Pop;
            BS1.OrBitSet(BS@);
            StackPush(BS1);
            BS2.Free;
          end
        else {RPNWalker is TaaRPN_NOT}
          begin
            BS1 := Stack.Pop;
            BS1.NOTBitSet;
            Stack.Push(BS1);
          end;
        BS1 := nil;
        RPNWalker := RPNWalker.Next;
      end;
    {display the results}
    BS1 := Stack.Pop;
    for i :=0 to pred(DocList.Count) do
      begin
        if BS1[i] then
          lbxResult.Items.Add(DocList[i]);
      end;
  finally
    Stack.Free;
    SearchPhrase.Free;
  end;
end;
 

备忘4


 
type
  TaaWordIndex = class
    private
      FTable : TaaHashTableLinear;
      FSaveStream : TStream;
    protected
      procedure wiSaveAction(const S : string; aObject : pointer; var
sStopNow : boolean);
    public
      constructor Create(aWordCount : integer);
      destructor  Destroy : override;
      procedure   Add(const aWord : string; aBitSet : TaaBitSet);
      function    Find(const aWord : string) : TaaBitSet;
      procedure   LoadFromStream(aStream : TStream);
      procedure   LoadFromFile(const aFileName : string);
      procedure   StoreToStream(aStream : TStream);
      procedure   StoreToFile(const aFileName : string);
end;
 
procedure DestroyTableEntry(const S : string; aObject : pointer);
begin
  TaaBitSet(aObject).Free;
end;
 
constructor TaaWordIndex.Create(aWordCount : integer);
begin
  inherited Create;
  FTable := TaaHashTableLinear.Create(aWordCount , AAELFHash);
  FTable.OnDeleteString := DestroyTableEntry;
end;
 
destructor TaaWordIndex.Destroy;
begin
  FTable.Free;
  inherited Destroy;
end;
 
procedure TaaWordIndex.Add(const aWord : string; aBitSet : TaaBitSet);
begin
  FTable.Insert(aWord , aBitSet);
end;
 
function TaaWordIndex.Find( const aWord : string) : TaaBitSet;
var
  Obj : pointer;
begin
  if not FTable.Find(aWord , Obj) then
    Result := nil
  else
    Result := TaaBitSet(Obj);
end;
 
procedure TaaWordIndex.LoadFromStream(aStream : TStream);
var
  i         : integer;
  WordCount : integer;
  Len       : integer;
  S         : string;
  BitSet    : TaaBitSet;
begin
  aStream.ReadBuffer()WordCount , sizeof(WordCount));
  S := '';
  BitSet := nil;
  try
    for i:= 1 to WordCount do
      begin
        aStream.ReadBuffer(Len , sizeof(Len));
        SetLength(S , Len);
        aStream.ReadBuffer(S[1] , Len);
        BitSet := TaaBitSet.Create(1);
        BitSet.LoadFromStream(aStream);
        Add(S , BitSet);
        S := '';
        BitSet := nil;
      end;
    except
      s := '';
      BitSet.Free;
      raise;
    end;
end;
 
procedure TaaWordIndexStoreToStream(aStream : TStream);
var
  WordCount : integer;
begin
  WordCount := FTable.Count;
  aStream.WriteBuffer(WordCount , sizeof(WordCount));
  FSaveStream := aStream;
  FTable.Iterate(wiSaveAction);
  FSaveStream := nil;
end;
 
procedure TaaWordIndex.wiSaveAction(const S :string; aObject : pointer var
aStopNow : boolean);
var
  Len : integer;
begin
  Len := length(S);
  FSaveStream.WriteBuffer(Len , sizeof(Len));
  FSaveStream.WriteBuffer(S[1] , Len);
  TaaBitSet(aObject).StoreToStream(FSaveStream);
end;
 

备忘3


 
type
  TRLEData = packed record
    rdLen : byte;
    rdVal : byte;
  end;
  TRLEPacker = class
    private
      FRLEData : array[0..7] of TRLEData;
      FRLEInx  : integer;
      FBuffer  : PByteArray;
      FBufInx  : integer;
    protected
      procedure rpWriteEncoding(aCount : integer);
    public
      constructoe Create(aBufSize : integer);
      destructor  Destroy : override;
      procedure   Add(aLen : byte; aValue : byte);
      procedure   MarkComplete;
      procedure   CopyBuffer(var aDest);
      property    BufferLen : integer read FBufInx;
    end;
 
constructor TRLEPacker.Create(aBufSize : integer);
begin
  inherited Create;
  GetMem(FBuffer , aBufSize);
end;
 
destructor TRLEPacker.Destroy;
begin
  if (FBuffer <> nil) then
    FreeMem(FBuffer);
  inherited Destroy;
end;
 
procedure TRLEPacker.CopyBuffer(var aDest);
begin
  Move(FBuffer^ , aDest, FBufInx);
end;
 
procedure TRLEPacker.Add(aLen : byte; aAalue : byte);
begin
  FRLEDara[FRLEInx].rdLen := aLen;
  FRLEData[FRLEInx].rdVal := aValue;
  inc(FRLEInx);
    if (FRLEInx = 8 ) then
      rpWriteEncoding(8);
end;
 
procedure TRLEPacker.MarkComplete;
begin
  {add the sentinel to indicate end-off-compressed-data(a code for a length
of zerodoes this)}
  Add(0,0);
  {write out any final encoding}
  if (FRLEInx <> 0) then
    rpWriteEncoding(FRLEInx);
end;
 
procedure TRLEPacker.rpWriteEncoding(aCount : integer);
var
  i : integer;
  ControlByte : byte;
begin
  {initialize the control byte}
  ControlByte := 0;
  {for all the encodings, set the relevant bit of the control byte if a
run, leave it clear otherwise (note: the end-of-data sentinel has a length
of zero and this code treats it as an actual length)}
  for i := 0 to pred(aCount) do
    begin
      ControlByte := ControlByte shl 1;
      if (FRLEData[i].rdLen <> 1) then inc(ControlByte);
    end;
  {if the number of encoding is less than 8, set the rest of the bits as
clear}
  if (aCount <> 8) then
    for i := aCount to 7 do
      ControlByte := ControlByte shl 1;
  {write out the control byte}
  FBuffer^[FBufInx] := ControlByte;
  inc(FBufInx);
  {write out the encodings, either as run length followed by the byte or as
the byte itself if the runlength were 1}
  for i := 0 to pred(aCount) do
    begin
      case FRLEData[i].rdLen of
        0 : begin
              FBuffer^[FBufInx] := 0;
              inc(FBufInx);
            end;
        1 : begin
              FBuffer^[FBufInx[ := FRLEData[i].rdVal;
              inc(FBufInx);
            end;
        else  {any other value :2..255}
            FBuffer^[FBufInx] := FRLEData[i].rdLen;
            inc(FBufInx);
            FBuffer^[FBufInx] := FRLEData[i].rdVal;
            inc(FBufInx);
      end;
    end;
  FRLEInx := 0;
end;
 
procedure TaaBitSet.bsPack;
var
  i      : integer;
  B      : byte;
  PrevB  : byte;
  RunLEn : byte;
  PAcker : TRLEPacker;
begin
  {allocate a packer object with a buffer big enough for the worst case, in
which all runs are of length one—that is, packing will grow the data by 1
byte for each 8 unapcked bytes, plus one byte over for the sentinel}
  Packer := TRLEPacker.Create(FBitArraySize + ((FBitArraysize + 8) div 8));
  try
    {set it up so previous byte is the first byte and current run length is
zero: marks loop code easier}
    PrevB := FBitArray^[0];
    RunLen := 0;
    {process the rest of the bytes}
    for i := 0 to pred(FBitArraySize) do
      begin
        {get the next byte}
        B := FBitArray^[i];
        {if it is different from the previous byte, close off the previous
run and start a new one}
        if (B <> PrevB) then
          begin
            Packer.Add(RunLen , PrevB);
            PrevB := B;
            RunLen := 1;
          end
        {otherwise, continue this run}
        else
          begin
            {if we've already reached 255 bytes in this run before adding
this byte, close it off and start a new one}
            if (RunLen = 255) then
              begin
                Packer.Add(RunLen , PrevB);
                RunLen := 0;
              end;
            inc(RunLen);
          end;
      end;
    {close off the final run}
    Packer.Add(RunLen , PrevB);
    {mark the packer object as being complete (this adds the sentinel and
calculates the compressed buffer size}
    Packer.MarkComplete;
    {reallocate our buffer and copy over the compressed data}
    FBitArraySize := PAcker.BufferLen;
    ReallocMem(FBitArray , FBitArraySize);
    Packer.CopyBuffer(FBitArray^);
    FPacked := ture;
  finally
    Packer.Free;
  end;
end;
 
procedure TaaBitSet.bsUnpack;
var
  i      : integer;
  Buf    : PButeArray;
  RunLen : integer;
  InInx  : integer;
  OutInx : integer;
  Done   : boolean;
  Value  : byte;
  Mask   : byte;
  ControlByte : byte;
begin
  {allocate output buffer large enough to hold all the bits}
  GetMem(Buf , (FBitCount + 7) div 8);
  try
    {initialize for the loop}
    Done := false;
    InInx := 0;
    OutInx := 0;
    {continue unpacking until the end of compressed data is found}
    repeat
      {set the mask for the control byte}
      Mask := $80;
      {read the control byte}
      ControlByte := FBitArray^[InInx];
      inc(InInx);
      {repeat until all the bits in the control byte have been used}
      while (Mask <> 0) do
        begin
          {if the control bit says that the next byte is literal, copy it
over to the output buffer}
          if ((ControlByte and Mask) = 0) then
            begin
              Buf^[OutInx] := FBitArray^[InInx];
              inc(OutInx);
              inc(InInx);
            end
          {otherwise it's an FLE instruction; get the run length and the
value to copy and duplivate it {note: a runlength of zero indicates the end
of the compressed data)}
          else
            begin
              RunLen := FBitArray^[InInx];
              inc(InInx);
              if (RunLen = 0) then
                begin
                  Done := true;
                  Break;
                end
              else
                begin
                  Value := FBitArray^[InInx];
                  inc(InInx);
                  for i := 1 to RunLen do
                    begin
                      Buf^[OutInx] := Value;
                      inc(OutInx);
                    end;
                end;
            end;
          {set mask to get the next bit}
          Mask L= Mask shr 1;
        end;
      until Done;
      {throw away the old packed buffer, and set it (and other fields) for
the new unpacked one}
      FreeMem(FBitArray);
      FBitArray := Buf;
      FBitArraySize := (FBitCount + 7) div 8;
      FPacked := false;

    except
      FreeMem(Buf);
      raise;
    end;
end;
 

备忘2


 
fuction IsDelimiter(aCh : Char; const aDelims : string) : boolean;
var
  i : integer;
begin
  Result := true;
  if (aCh > ' ') then
    begin
      for i := 1 to length(aDelims) do
        if (aDellims[i] = aCh then Exit;
      Result := false;
    end;
end;
 
procedure AAParseWords(aText : TStream; const aDelims : string; aAction :
TaaWordParseAction);
const
  BufSize = 16 * 1024;
var
  State   : (ScanWord , ScanOther);
  Buffer  : PChar;
  BufPos  : PChar;
  BufLeft : integer;
  Ch      : char;
  StopNow : boolean;
  CharQ   : TaaCharQueue;
begin
  //perpare for the memory allocations
  Buffer := nil;
  CharQ := nil;
  try
    //create a character queue with which to bulid words
    CharQ := TaaCharQueue.Create;
    //allocate a buffer to hold data from the stream
    GetMem(Buffer , BufferSize);
    //force the stream to be read first time through
    BufLeft := 1;
    BufPos := Buffer;
    //we'll start in the scanning delimiter state
    State := ScanOther;
    StopNow := false;
    //continue until there is no more data in the stream
    while (not StopNow) and (BufLeft <> 0) do
      begin
        //advance the buffer variables (reading more data if needed)
        dec(BufLeft);
        if (BufLeft <> 0) then
          inc(BufPos)
        else
          begin
            BufLeft := aText.Read(Buffer^ , BufSize);
            BufPos := Buffer;
          end;
        //get the next character
        Ch := BufPos^;
        //process the character according to the state
        case State of
          ScanWord :
            begin
              if IsDelimiter(Ch , aDelims) then
                begin
                  aAction(CharQ.AsString , StopNow);
                  State := ScanOther;
                end
              else
                CharQ.Append(Ch);
            end;
          ScanOther :
            begin
              if not IsDelimiter(Ch , aDelims) then
                begin
                  CharQ.Clear;
                  CharQ.Append(Ch);
                  State := ScanWord;
                end;
            end;
        end;
      end;
  finally
    if (Buffer <> nil) then
      FreeMem(Buffer);
    CharQ.Free;
  end;
end;
 

备忘1

搜索短语解析器类
type
  // a base node that helps form RPN string
  TaaRPNNode = class
    private
      FNext : TaaRPNNode;
    public
      destructor Destroy: override;
      procedure  Append(aNode : TaaRPNNode);
  end;
 
  TaaRPNWord = class(TaaNNode) // an RPN node for a word
    private
      FWord : string;
    public
      constructor Create(const aPhraseWord : string);
      property PhraseWord : string read FWord;
    end;
 
  // an RPN node for the AND operator
  TaaRPN_AND = class(TaaRPNNode);
  // an RPN node for the OR operator
  TaaRPN_OR = class(TaaRPNNode);
  // an RPN node for the NOT operator
  TaaRPN_NOT = class(TaaRPNNode);
 
  TaaSearchParse = class // a parser for search phrases
    private
      FCurWord : string;
      FPhrase  : string;
      FPosn    : integer;
      FRPN     : TaaRPNNode;
    protected
      function  spGetRPN : TaaRPNNode;
      procedure spSetPhrase(const aPhrase : string);
      function  spParseExpr : TaaRPNNode;
      function  spParseFactor : TaaRPNNode;
      function  spParseTerm : TaaRPNNode;
      procedure spParsePhrase;
      procedure spGetNextWord;
    public
      constructor Create(const aPhrase : string);
      destructor Destroy; override;
      property Phrase : string read FPhrase write spSetPhrase;
      property RPN : TaaRPNNode read spGetRPN;
  end;
 
destructor TaaRPNNode.Destroy;
begin
  Next.Free;
  inherited Destroy;
end;
 
procedure TaaRPNNode.Append(aNode : TaaRPNNode);
var
  Walker : TaaRPNNode;
begin
  Walker := Self;
  while (Walker.Next <> nil)do
    Walker := Walker.Next;
  Walker.FNext := aNode;
end;
 
constructor TaaRPNWord.Create(const aPhraseWord : string);
begin
  inherited Create;
  FWord := aPhraseWord;
end;
 
constructor TaaSearchParser.Create(const aPhrase : string);
begin
  inherited Create;
  Phrase := aPhrase;
end;
 
destructor TaaSearchParser.Destroy;
begin
  FRPN.Free;
  inherited Destroy;
end;
 
procedure TaaSearchParser.spGetNextWord;
var
  Walker    : PAnsiChar;
  WordStart : PAnsiChar;
begin
  inc(FPosn , length(FCurWord));
  FCurWord := '';
  Walker := @FPhrase[FPosn];
  while (Walker^ =' ') do
    begin
      inc(FPosn);
      inc(Walker);
    end;
  if (Walker^ = '(') then
    FCurWord := '('
  else if (Walker^ = '(') then
    FCurWord := '('
  else
    begin
      WordStart := Walker;
      while (Walker^ <> #0) and (Walker^ <> ' ') and (Walker^ <> '(') and
(Walker^ <> ')') do
        inc(Walker);
      FCurWord := Copy(FPhrase, FPosn, Walker - WordStart);
    end;
end;
 
function TaaSearchParser.spGetRPN : TaaRPNNode;
begin
  if (FRPN = nil) then
    spParsePhrase;
  Result := FRPN;
end;
 
function TaaSearchParser.spParseExpr : TaaRPNNode;
begin
  Result := spParseFactor;
  spGetNextWord;
  if (FCurWord = 'and') then
    begin
      spGetNextWord;
      Result.Append(spParseExpr);
      Result.Append(TaaRPN_AND.Create);
    end
  else if (FCurWord = 'or') then
    begin
      spGetNextWord;
      Result.Append(spParseExpr);
      Result.Append(TaaRPN_OR.Create);
    end
  else if (FCurWord <> '') and (FCurWord <> ')') then
    begin
      Result.Append(spParseExpr);
      Result.Append(TaaRPN_AND.Create);
    end;
end;
 
function TaaSearchParser.spParseFactor : TaaRPNNode;
begin
  if (FCurWord <> 'not' ) then
    Result := spParseTerm
  else
    begin
      spGetNextWord;
      Result.Append(spParseExpr);
      Result.Append(TaaRPN_NOT.Create);
    end;
end;
 
procedure TaaSearchParser.spParsePhrase;
begin
  if (FPhrase <> '') then
    begin
      FPosn := 1;
      spGetNextWord;
      if (FCurWord <> '') then
        FRPN := spParseExpr;
    end;
end;
 
function TaaSearchParser.spParseTerm : TaaRPNNode;
begin
  if (FCurWord = '(') then
    begin
      spGetNextWord;
      Result := spParseExpr;
      if (FCurWord <> ')') then
        raise Exception('TaaSearchParser : missing close parenthsis in
phrase');
    end
  else
    begin
        raise Exception.Create('TaaSearchParse : missing final search
word');
      if (FCurWord = 'add') or (FCurWord = 'or') or (FCurWord = 'not' ) then
        raise Exception.Create('TaaSearchParser : operator used as search
word');
      Result := TaaRPNWord.Create(FCurWord);
    end;
end;
 
procedure TaaSearchParser.spSetPhrase(const aPhrase : string);
begin
  FPhrase := LowerCase(aPhrase);
  FRPN.Free;
  FRPN := nil;
end;
--
 
没有相册。