📄 minearea.cpp
字号:
ChangeFlag( pos );
}
}
}
}
void CMineArea::ChangeFlag( int pos ) //
{
RECT rectClick;
CRect rectMineNum(17,16,55,38);
if(pMines[pos].uDraw == DRAW_FLAG)
{
if(theApp.bMarked)
pMines[pos].uDraw = DRAW_QUESTION_MARK_FLAG;
else
pMines[pos].uDraw = DRAW_NOT_OPEN;
theApp.uRemainMines++;
InvalidateRect(rectMineNum);
}
else if(pMines[pos].uDraw == DRAW_NOT_OPEN)
{
pMines[pos].uDraw = DRAW_FLAG;
theApp.uRemainMines--;
InvalidateRect(rectMineNum);
}
else if(pMines[pos].uDraw == DRAW_QUESTION_MARK_FLAG)
{
pMines[pos].uDraw = DRAW_NOT_OPEN;
}
MyInvalidateRect( rectClick, pos );
}
void CMineArea::RButtonUp(UINT nFlags, CPoint point)
{
if( (uGameState == WAIT || uGameState == RUN) &&
uButtonState == BUTTON_CLICK )
{
uButtonState = BUTTON_NORMAL;
CRect rectButton(uButtonPos[1],15,uButtonPos[2],42);
InvalidateRect(rectButton);
}
if( !bInMineArea )
{
bDoubleClick = FALSE;
bRBUPOutMineArea = TRUE;
}
else if( nFlags != MK_LBUTTON )
{
bRBUPOutMineArea = FALSE;
}
if( uGameState == RUN || uGameState == WAIT )
{
CRect rectMineArea(MINE_AREA_X, MINE_AREA_Y,
MINE_AREA_X+uWidth*MINE_WIDTH, MINE_AREA_Y+uHeight*MINE_HEIGHT);
if( rectMineArea.PtInRect(point) )
{
if( nFlags == MK_LBUTTON )
{
if( uGameState == WAIT )
{
uGameState = RUN; // start game
}
ProcessLeftRightButtonUp( nNewPos );//
}
}
}
}
void CMineArea::SetMineBox(int i, int j, int draw, int state)
{
pMines[i*uWidth+j].uDraw = draw;
pMines[i*uWidth+j].uState= state;
if(draw >= EMPTY_AREA_START )
{
DrawEmptyArea( draw );
}
Invalidate();
}
void CMineArea::LinkNewEqua(CArray<int,int> &row, CArray<int,int> &col, int result,int i,int j)
{
PEQUATION equa;
equa=new EQUATION;
for(int k=0;k<480;k++)
equa->vars[k]=0;
for(k=0;k<row.GetSize();k++)
equa->vars[row.GetAt(k)*uWidth+col.GetAt(k)]=1;
equa->vars[uTotle]=result;
equa->org.x=i;
equa->org.y=j;
equa->varnum=row.GetSize();
if(pequahead==NULL)
{
pequahead=equa;
pequahead->prev=pequahead->next=pequahead;
}
else
{
equa->next=pequahead;
equa->prev=pequahead->prev;
pequahead->prev->next=equa;
pequahead->prev=equa;
}
AlertEquas(i,j);
}
void CMineArea::DelEqua()
{
PEQUATION plist=pequahead;
BOOL tt=false;
again:
tt=false;
plist=pequahead;
if (plist==NULL)
return;
do
{
int t=0;
for(UINT k=0;k<uTotle;k++)
t+=plist->vars[k];
plist=(t==0)?(DelEqua(plist)):(plist->next);
tt=(t==0)?(true):(false);
} while(plist!=pequahead);
if(tt)
goto again;
return;
}
PEQUATION CMineArea::DelEqua(PEQUATION equa)
{
PEQUATION prev=equa->prev;
PEQUATION next=equa->next;
if(equa!=prev)
{
if(equa==pequahead)
pequahead=pequahead->next;
prev->next=equa->next;
next->prev=prev;
}
else
{
pequahead=NULL;
}
delete equa;
return (pequahead==NULL)?(NULL):(next);
}
void CMineArea::AlertEquas(int i, int j)
{
PEQUATION tmp=pequahead;
PEQUATION newpos=NULL,next=NULL;
if(tmp==NULL)
return;
do
{
if(tmp->vars[i*uWidth+j]==1)
{
tmp->vars[i*uWidth+j]=0;
tmp->varnum--;
if(pMines[i*uWidth+j].uState==STATE_MINE && tmp->vars[uTotle]>0)
tmp->vars[uTotle]--;
/* if(tmp->vars[uTotle]<0)
{
CString str,str2;
for(UINT k=0;k<uTotle;k++)
{
if(tmp->vars[k]!=0)
{
str2.Format(":%d %d ",k/uWidth,k%uWidth);
str+=str2;
}
}
str2.Format("\t %d",tmp->vars[uTotle]);
str+=str2;
MessageBox(str);
}*/
}
tmp=tmp->next;
}while(tmp!=pequahead);
}
void CMineArea::AddEquations(int i, int j)
{
int posx=0,posy=0,pos=0,k=0;
UINT mines=0;
CArray<int,int> variable[2];
CString str="";
if(closed[i*uWidth+j])
return;
for(k=0;k<NEIGHBORS;k++)
{
posx=i+neighbor[k][0];
posy=j+neighbor[k][1];
if(posx>=0 && posy>=0 && posx< uHeight&& posy< uWidth)
{
if(pMines[posx*uWidth+posy].uDraw==DRAW_NOT_OPEN)
{
variable[0].Add(posx);
variable[1].Add(posy);
}
else if(pMines[posx*uWidth+posy].uDraw==DRAW_FLAG)
mines++;
}
}
closed[i*uWidth+j]=1;
if(pMines[i*uWidth+j].uDraw>=mines || variable[0].GetSize()>0 )//need to add equation
LinkNewEqua(variable[0],variable[1],DRAW_NUMBER_1-pMines[i*uWidth+j].uDraw+1-mines,i,j);
return;
}
CString CMineArea::GetEquaTxt()
{
CString str="",equainfo="";
BOOL t=false;
int k=0;
//format equation text
PEQUATION tmp=pequahead;
if(tmp==NULL)
return equainfo;
do
{
t=false;
for(k=0;k<480;k++)
{
if(tmp->vars[k]==1)
{
str.Format("(%d,%d)",k/uWidth+1,k%uWidth+1);
equainfo+=str+"+";
t=true;
}
}
// if(t)
{
str.Format("=%d\r\n",tmp->vars[uTotle]);
equainfo=equainfo.Left(equainfo.GetLength()-1)+str;
}
tmp=tmp->next;
}while(tmp!=pequahead);
return equainfo;
}
void CMineArea::InferSimple()
{
PEQUATION list=NULL;
int m=0;
again:
m=change;
list=pequahead;
if(list==NULL)
{
// stock.Empty();
return;
}
do
{
int t=0;
for(UINT k=0;k<uTotle;k++)
t+=list->vars[k];
if(t==list->vars[uTotle]) //conclusion: is mine
{
if(t==0)
{
AlertEquas(list->org.x,list->org.y);//????
m++;
}
else
{
for(k=0;k<uTotle;k++)
{
if (list->vars[k]==1)
{
stock.Push(k,STATE_MINE);//push stack
SetMineBox(k/uWidth,k%uWidth,DRAW_FLAG,STATE_MINE);
AlertEquas(k/uWidth,k%uWidth);
m++;
}
}
}
}
else if(list->vars[uTotle]==0) //conclusion: not mine
{
for(k=0;k<uTotle;k++)
{
if (list->vars[k]==1)
{
stock.Push(k,STATE_NOTMINE);//push stack
SetMineBox(k/uWidth,k%uWidth,pMines[k].uState,pMines[k].uState);
AddEquations(k/uWidth,k%uWidth);
m++;
}
}
}
list=list->next;
}while(list!=pequahead);
DelEqua();
while(!stock.IsEmpty())
{
int idx,val,t=0;
list=pequahead;
if(list==NULL)
{
stock.Empty();
return;
}
stock.Popup(&idx,&val);
val=(val==STATE_MINE)?(1):(0);
do
{
if(list->vars[idx]==1)
{
list->vars[idx]=0;
list->vars[uTotle]-=val;
}
for(UINT k=0;k<uTotle;k++)
t+=list->vars[k];
if(t>0 && t==list->vars[uTotle]) //conclusion: is mine
{
for(k=0;k<uTotle;k++)
{
if (list->vars[k]==1)
{
stock.Push(k,STATE_MINE);//push stack
SetMineBox(k/uWidth,k%uWidth,DRAW_FLAG,STATE_MINE);
AlertEquas(k/uWidth,k%uWidth);
m++;
}
}
}
else if(list->vars[uTotle]==0) //conclusion: not mine
{
for(k=0;k<uTotle;k++)
{
if (list->vars[k]==1)
{
stock.Push(k,STATE_NOTMINE);//push stack
SetMineBox(k/uWidth,k%uWidth,pMines[k].uState,pMines[k].uState);
AddEquations(k/uWidth,k%uWidth);
m++;
}
}
}
list=list->next;
}while(list!=pequahead);
}
DelEqua();
if(m!=change)
{
change=m;
goto again;
}
}
void CMineArea::InferDoble()
{
int m=0;
PEQUATION list,tmp;
PEQUATION t=new EQUATION;
m=change;
again:
list=pequahead;
tmp=pequahead;
if(list==NULL)
return;
do
{
tmp=pequahead;
if(tmp==NULL)
return;
if(list->vars[uTotle]<0)
{
list=list->next;
continue;
}
do
{
if(tmp->vars[uTotle]<0)
{
tmp=tmp->next;
continue;
}
if(tmp!=list)
{
int p=0,q=0;
for(UINT k=0;k<=uTotle;k++)
{
t->vars[k]=list->vars[k]-tmp->vars[k];
p=(t->vars[k]==1 && k<uTotle)?(p+1):(p);
q=(t->vars[k]==-1 && k<uTotle)?(q-1):(q);
}
if(t->vars[uTotle]==0)
{
if( /*(p==0 && q!=0) || */(p!=0 && q==0) )
for(k=0;k<uTotle;k++)
if(t->vars[k]==((p==0)?(-1):(1)))
{
stock.Push(k,STATE_NOTMINE);//push stack
SetMineBox(k/uWidth,k%uWidth,pMines[k].uState,pMines[k].uState);
AddEquations(k/uWidth,k%uWidth);
AlertEquas(k/uWidth,k%uWidth);
m++;
}
}
else
{
if(t->vars[uTotle]==p)
{
for(k=0;k<uTotle;k++)
{
if(t->vars[k]==1)
{
stock.Push(k,STATE_MINE);//push stack
SetMineBox(k/uWidth,k%uWidth,DRAW_FLAG,STATE_MINE);
AlertEquas(k/uWidth,k%uWidth);
}
else if(t->vars[k]==-1)
{
stock.Push(k,STATE_NOTMINE);//push stack
SetMineBox(k/uWidth,k%uWidth,pMines[k].uState,pMines[k].uState);
AddEquations(k/uWidth,k%uWidth);
AlertEquas(k/uWidth,k%uWidth);
}
m++;
}
}
}
}
tmp=tmp->next;
} while(tmp!=pequahead);
list=list->next;
} while(list!=pequahead);
DelEqua();
if(m!=change)
{
change=m;
goto again;
}
delete t;
}
void CMineArea::Infer()
{
int m;
m=change;
again:
InferSimple();
InferDoble();
if(m!=change)
{
change=m;
goto again;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -