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

📄 bwchessdlg.cpp

📁 这是我用vc编写的一个黑白棋网络游戏的使用程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
									wsp.push (i,j);
								}
							}
							else
							{
								if(btp_x!=i || btp_y!=j)
								{
									btp_x=i,btp_y=j;
									bn++;
									bsp.push (i,j);
								}
							}
							break;
						}
					}
				}

				//斜向左下
				if(Check(i+1,j-1) && Check(i+2,j-2))
				{
					x=i,y=j;
					temp=kernel[x+1][y-1];
					for(x+=2,y-=2;(x<NUM) && (y>=0);x++,y--)
					{
						temp2=kernel[x][y];
						if(temp2==0)
							break;
						if(temp2!=temp)
						{
							if(temp2==1)
							{
								if(wtp_x!=i || wtp_y!=j)
								{
									wtp_x=i,wtp_y=j;
									wn++;
									wsp.push (i,j);
								}
							}
							else
							{
								if(btp_x!=i || btp_y!=j)
								{
									btp_x=i,btp_y=j;
									bn++;
									bsp.push (i,j);
								}
							}
							break;
						}
					}
				}

				//斜向右下
				if(Check(i+1,j+1) && Check(i+2,j+2))
				{
					x=i,y=j;
					temp=kernel[x+1][y+1];
					for(x+=2,y+=2;(x<NUM) && (y<NUM);x++,y++)
					{
						temp2=kernel[x][y];
						if(temp2==0)
							break;
						if(temp2!=temp)
						{
							if(temp2==1)
							{
								if(wtp_x!=i || wtp_y!=j)
								{
									wtp_x=i,wtp_y=j;
									wn++;
									wsp.push (i,j);
								}
							}
							else
							{
								if(btp_x!=i || btp_y!=j)
								{
									btp_x=i,btp_y=j;
									bn++;
									bsp.push (i,j);
								}
							}
							break;
						}
					}
				}

			}//end if
		}//end second for
	if((bn==0) && (wn==0))
		return -1;//return -1 for both
	if((bn>=2) && (wn>=2))
		return 2;///return 2 for have more than one
	switch(whogo)
	{
	//whogo 1:代表黑色,2代表白色
	case 1://代表黑色
		if(wn==0)
		return 0;//return 0 for the int have no position
		break;
		case 2://2代表白色
		if(bn==0)
		return 0;//return 0 for the int have no position
		break;
	}
	return 2;//return 2 for have more than one
}

int CBWChessDlg::Check(int x, int y)
{
	if(x<0 || x>=NUM || y<0 || y>=NUM)
		return 0;//越界为0
	if(kernel[x][y]==0)
		return 0;//无子为0
	return 1;

}

int CBWChessDlg::Walk1(int *x1, int *y1, int flag)//寻找最佳位置给(x1,x2)
{
	int fv=flag;//棋子颜色 2 黑 1 白
	int k,n;
		if(fv==1)//1:白色
			n=wsp.Len();
		else// 2:黑色
			n=bsp.Len();
       srand( (unsigned)time( NULL ) );
		k=rand()%n+1;		

	//算法开始!! 本算法采用随机法
	for(n=1;n<=k;n++)
	{
		if(fv==1)//1:白色
			wsp.pop(x1,y1);
		else// 2:黑色
			bsp.pop(x1,y1);
		//i,j是可以放棋子的坐标
	}	
	if(fv==1)//1:白色
		wsp. destroy();
		else// 2:黑色
		bsp. destroy();
	return 0;
}


void CBWChessDlg::Calcu_BW()//棋子计数
{
	int nw=0,nb=0;
	int i,j;
	for(i=0;i<NUM;i++)
		for(j=0;j<NUM;j++)
			if(kernel[i][j]==1)
				nw++;
			else if(kernel[i][j]==2)
				nb++;

	num_black=nb;
	num_white=nw;
}

int CBWChessDlg::IsInPanel(CPoint &pt)//判断是否在棋盘上
{
	if(pt.x<=m_wXNull || pt.x>=(m_wXNull + NUM*m_wStoneWidth))
		return 0;
	if(pt.y<=m_wYNull || pt.y>=(m_wYNull + NUM*m_wStoneHeight))
		return 0;
	return 1;
}

void CBWChessDlg::ShowNumber(int isTime)//刷新  时间和棋子的个数
{
	BCount.SetNumber(num_black);
	WCount.SetNumber(num_white);
	if(isTime)
	{
		TimeCount.SetNumber(m_PassedTime);
		TimeCount0.SetNumber(m_PassedTime0);
	}
}

void CBWChessDlg::OnTimer(UINT nIDEvent) //计时
{
	if(nIDEvent==PASSEDTIME)//尚未更新
	{
		if(!m_byColor)//白色
			m_PassedTime++;
		else//黑色
			m_PassedTime0++;
		ShowNumber(1);//“1”代表时间也要刷新
		if(g_nRunMode == MODE_2PLAYER && !g_nIsNoTimeLimit)//人对人,限时
		{
			if((m_PassedTime>=g_nTimeLimit) || (m_PassedTime0>=g_nTimeLimit))
			{//超时!!游戏结束
				m_bGameOver=TRUE;
				if(m_TimerOn)
				{
					KillTimer(PASSEDTIME);
					m_TimerOn=0;
				}
				m_pMenu->EnableMenuItem(IDM_HINT,MF_GRAYED);
				m_pMenu->EnableMenuItem(IDM_UNDO,MF_GRAYED);
				m_pMenu->EnableMenuItem(IDM_CANPLACE,MF_GRAYED);
				AddStringToList(0,0,0,(m_PassedTime>=g_nTimeLimit)? 1 : 2);
				PlaySounds(IDSOUND_USERWIN);
                //弹出游戏结束的对话框
				MsgBox((m_PassedTime>=g_nTimeLimit)? IDS_BLACK_LIMIT : IDS_WHITE_LIMIT ,IDS_TITLE_CHINESE);
			}
		}
	}
	CDialog::OnTimer(nIDEvent);
}

void CBWChessDlg::OnUndo() 
{
	if(g_nRunMode==MODE_NETWORK)//网络2
	{
		AfxMessageBox("你不能作弊!");
	    return;
	}
	
	
	m_PeekOnce=0;
	if(m_UndoPoint.IsEmpty())//已为空,m_UndoPoint的类名是 Cundo
	{
		PlaySounds(IDSOUND_ERROR);
		MsgBox(IDS_CANNOT_UNDO1_CHINESE, IDS_TITLE_CHINESE);//弹出无法悔棋的对话框
		return;
	}
	if (m_bGameOver)   
		return;

	int c1,c2,i,j,k=0;
	c1=m_UndoPoint.GetTopColor();//获取颜色
	int temp[NUM*NUM];
	m_UndoPoint.pop(temp);//获取棋盘
	RemoveStringFromList();
	if(g_nRunMode == MODE_WITH_COMPUTER)//人机对战
	{
		if(c1==m_byColor)
		{
			while(!m_UndoPoint.IsEmpty())
			{
				c2=m_UndoPoint.GetTopColor();
				RemoveStringFromList();
				if(c1!=c2)
				{
					m_UndoPoint.pop(temp);
					break;
				}
				else
				{
					int again_pop[NUM*NUM];
					m_UndoPoint.pop(again_pop);
				}
			}// end while
		}//end if
	}
	else
	{
		if(m_UndoPoint.IsEmpty())
		{
			if(g_bUserBlack)
				m_byColor=0;
			else
				m_byColor=1;
		}
		else
		{
			m_byColor=m_UndoPoint.GetTopColor ();
		}
	}
	for(i=0;i<NUM;i++)
		for(j=0;j<NUM;j++)
		{
			kernel[i][j]=temp[k];
			k++;
		}

	IsEnd(!m_byColor+1);
	if(!m_bGameOver && g_bPeepOften)
		OnCanplace();
	m_HintOnce=0;
	Calcu_BW();
	ShowNumber();
	PlaySounds(IDSOUND_UNDO);
	InvalidateRect(m_Client, TRUE);
	UpdateWindow();
}

void CBWChessDlg::duplicate()//保存当前棋盘和当前颜色,为悔棋作准备
{
	int temp[NUM*NUM];
	int i,j,k=0;
	for(i=0;i<NUM;i++)
		for(j=0;j<NUM;j++)
			temp[k++]=kernel[i][j];
	m_UndoPoint.push(temp,m_byColor);
}

void CBWChessDlg::Place(int *x, int *y,int color)
{//获取最佳位置
	int mx=0,my=0;
	Walk1(&mx,&my,color);
	*x=mx;
	*y=my;		
}

void CBWChessDlg::OnBest() //显示英雄榜
{
    CBestDlg bestDlg;
    bestDlg.DoModal();	
}

void CBWChessDlg::OnHint() // 响应“提示”
{
	const int HINTSIZE=7;
	if (m_bGameOver)  
		return;
	if(m_HintOnce)
		return;
	if(g_nRunMode == MODE_2PLAYER)//人对人
	{
		if(((m_HintTime0>=g_nCanHintTimeW) && m_byColor) ||
			((m_HintTime1>=g_nCanHintTimeB) && !m_byColor))
		{
			CString str1,str2;
			TCHAR s[200];
			str1.LoadString(IDS_MORETHANTHREE_CHINESE);//代表“我已提示了你%d次,不能再提示了!”
			str2.LoadString(IDS_TITLE_CHINESE);//代表“黑白棋”
			if(m_HintTime0>=g_nCanHintTimeW)
				wsprintf(s,str1.GetBuffer(256),g_nCanHintTimeW);
			else
				wsprintf(s,str1.GetBuffer(256),g_nCanHintTimeB);
			CString str(s);
			MsgBox(str,str2);//给出对话框
			return;// 退出提示
		}
		if(m_byColor)//次数累加
			m_HintTime0++;
		else
			m_HintTime1++;
	}
	else // 人对机
	{
		if(m_HintTime0>=g_nCanHintTimeW || m_HintTime1>=g_nCanHintTimeB)//0 白 1黑
		{
			CString str1,str2;
			TCHAR s[200];
			str1.LoadString(IDS_MORETHANTHREE_CHINESE);
			str2.LoadString(IDS_TITLE_CHINESE);
			if(m_HintTime0>=g_nCanHintTimeW)
				wsprintf(s,str1.GetBuffer(256),g_nCanHintTimeW);
			else
				wsprintf(s,str1.GetBuffer(256),g_nCanHintTimeB);
			CString str(s);
			MsgBox(str,str2);
			return;
		}
		else
		{
			if(m_byColor)
				m_HintTime0++;
			else
				m_HintTime1++;
		}
	}
	int px,py;
	Walk1(&py,&px,!m_byColor+1);//寻找最佳点
	x1 = px*m_wStoneWidth + m_wXNull-HINTSIZE + m_wStoneWidth / 2;
	y1 = py*m_wStoneHeight + m_wYNull-HINTSIZE + m_wStoneHeight / 2;
	x2 = px*m_wStoneWidth + m_wXNull+HINTSIZE + m_wStoneWidth / 2;
	y2 = py*m_wStoneHeight + m_wYNull+HINTSIZE + m_wStoneHeight / 2;
    //矩形:(x1,y1,x2,y2)
	CClientDC dc(this);//画 “X"
	COLORREF crColor = m_byColor ? RGB(255,255,255) : RGB(0,0,0);//1 画 白
	CPen pen(PS_SOLID, 2, crColor);
	CPen *pOldPen = dc.SelectObject(&pen);	
	dc.MoveTo(x1, y1);
	dc.LineTo(x2, y1);
	dc.LineTo(x2, y2);
	dc.LineTo(x1, y2);
	dc.LineTo(x1, y1);
	dc.LineTo(x2, y2);
	dc.MoveTo(x2, y1);
	dc.LineTo(x1, y2);
	dc.SelectObject(pOldPen);
	m_HintOnce=1;
}

void CBWChessDlg::MoveCursor(int x, int y)
{//从当前(m,n)位置向(x,y)走,x,y 是以像素为单位的,所使用的平面是窗口平面
	//每次移动鼠标之前,系统都会根据 m_byColor 的值载入光标,0载入黑手,1载入白手,之所以相反(0白1黑),
	//是因为系统载入光标时,用户还没有点击棋盘,m_byColor代表的前一个棋手的颜色。
	//但是本函数在调用时,m_byColor代表的是当前棋手的颜色
	//轮流到计算机下时,在计算机下棋之前,由于计算机不移动鼠标,也不敲击键盘,因此光标不会更新,
	//仍使用前一个棋手的光标,故在此处必须修正!!
	 m_byColor=!m_byColor;
     ::SetCursor(AfxGetApp()->LoadCursor(m_byColor ? IDC_WHITE_HAND:IDC_BLACK_HAND));//修正部分
      m_byColor=!m_byColor;
	if(!g_bMovePlace)
	{
		return;
	}
	CPoint pt;
	GetCursorPos(&pt);
	int m,n;
	int sleep_interval=2;
	m=pt.x ;
	n=pt.y ;
	if(m >x)
	{
		while(m>x)//向左走
		{
			m-=g_nMoveSpeeds;
			Sleep(sleep_interval);
			SetCursorPos(m,n);
		}
	}
	else if(m<x)//向右走
	{
		while(m<x)
		{
			m+=g_nMoveSpeeds;
			Sleep(sleep_interval);
			SetCursorPos(m,n);
		}
	}

	if(n >y)
	{
		while(n>y)//向上走
		{
			n-=g_nMoveSpeeds;
			Sleep(sleep_interval);
			SetCursorPos(m,n);
		}
	}
	else if(n < y)//向下走
	{
		while(n < y)
		{
			n+=g_nMoveSpeeds;
			Sleep(sleep_interval);
			SetCursorPos(m,n);
		}
	}
}

void CBWChessDlg::OnCanplace() //本函数计算当前棋手可下的位置,并标志出来!(X)
{
	if (m_bGameOver)     
		return;
	if(m_PeekOnce)
		return;
	int px,py;
	int xx1,yy1;
	int length,hy;
	//CClientDC dc(this);;
	CDC *dc=GetDC();
	if(m_byColor)//判断是否有位置可填
		length=wsp.isempty();
	else
		length=bsp.isempty();
	if(length)//无,结束
		return;
	do
	{
		if(m_byColor)
			length=wsp.GetNextPos(&py,&px,&hy);
		else
			length=bsp.GetNextPos(&py,&px,&hy);
		xx1 = px*m_wStoneWidth + m_wXNull;//-4 + m_cxGrid / 2;
		yy1 = py*m_wStoneHeight + m_wYNull;//-4 + m_cyGrid / 2;

⌨️ 快捷键说明

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