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

📄 minearea.cpp

📁 一个机器自己学习玩扫雷游戏的程序!快试试!
💻 CPP
📖 第 1 页 / 共 3 页
字号:
				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 + -