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

📄 bwchessdlg.cpp

📁 这是我用vc编写的一个黑白棋网络游戏的使用程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		if(m_byColor)
			DrawBitmap(dc,xx1,yy1,IDB_CANPLACE2, SRCCOPY);
		else
			DrawBitmap(dc,xx1,yy1,IDB_CANPLACE1, SRCCOPY);

	}while(length);
	if(m_byColor)
		wsp.CopyBackIndex();
	else
		bsp.CopyBackIndex();
	m_PeekOnce=1;
	ReleaseDC(dc);
}

void CBWChessDlg::OnSetting() //响应“设置”命令
{
	CSettingDlg dlg;
	dlg.DoModal ();//显示“设置”对话框
	if(g_bTopMost)
		SetWindowPos(&wndTopMost,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE);
	else
		SetWindowPos(&wndNoTopMost,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE);
}

void CBWChessDlg::OnOpen() //响应“OPEN”命令
{
	if(!m_bGameOver && g_bPrompt)
		if(MsgBox(IDS_ABORT,IDS_TITLE_CHINESE,2)==IDCANCEL)
			return ;

	TCHAR sFilter[50]="BWChess File (*.BWS)|*.BWS||";
	CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
					sFilter);
	int result=dlg.DoModal();
	if(result==IDOK)
	{
		CFile file(dlg.GetPathName(), CFile::modeRead);
		int buffer[9000],len,t;
		unsigned int reallen=file.Read(buffer,9000*sizeof(int));
		if((reallen!=(buffer[0]*sizeof(int))) || (reallen<140))
		{
			MsgBox(IDS_OPENERROR1,IDS_TITLE_CHINESE);
			return;
		}
		if(buffer[1]!=EDITION)
		{
			MsgBox(IDS_OPENERROR2,IDS_TITLE_CHINESE);
			return;
		}
		if(buffer[2])
		{
			MsgBox(IDS_OPENERROR3,IDS_TITLE_CHINESE);
			return;
		}
        int i,j;
		len=buffer[0]/2-1;
		BOOL changeI=FALSE;
		for(t=0;t<len;t++)
		{
			if(buffer[t+3]!=buffer[3+len+t])
			{
				changeI=TRUE;
				break;
			}
		}
		if(changeI)
		{
			MsgBox(IDS_OPENERROR1,IDS_TITLE_CHINESE);
			return;
		}

		if(m_TimerOn)
		{
			KillTimer(PASSEDTIME);
			m_TimerOn=0;
		}
		m_bGameOver = FALSE;	              
		m_Skip=0;
		i=0;
		g_nStoneNum=0;
		m_HintOnce=0;//0 for have not hinted yet,1 for have hinted
		m_PeekOnce=g_bPeepOften;
		m_IsGameStart=0;
		ListInfo.destroy();
		m_ListInfo.ResetContent();
		if(!m_UndoPoint.IsEmpty())
			m_UndoPoint.Destroy();
		len=3;///important
		m_byColor=buffer[len++];
		g_nRunMode=buffer[len++];
		m_PassedTime=buffer[len++];
		m_PassedTime0=buffer[len++];
		g_nSkill=buffer[len++];
		g_bUserBlack=buffer[len++];
		m_HintTime0=buffer[len++];
		m_HintTime1=buffer[len++];
		g_nTimeLimit=buffer[len++];
		g_nIsNoTimeLimit=buffer[len++];
		len+=5;		
		for(i=0;i<NUM;i++)
			for(j=0;j<NUM;j++)
				kernel[i][j]=buffer[len++];
		int x,y,num,tc;
		num=buffer[len++];
		while(num>0)
		{
			x=buffer[len++];
			y=buffer[len++];
			tc=buffer[len++];
			AddStringToList(x,y,tc);
			num--;
		}
		//read m_UndoPoint
		num=buffer[len++];
		while(num>0)
		{
			int temp[NUM*NUM];
			for(x=0;x<NUM*NUM;x++)
				temp[x]=buffer[len++];
			tc=buffer[len++];
			m_UndoPoint.push(temp,tc);
			num--;
		}
		IsEnd(1);
		Calcu_BW();
		SetChessTitle();
		m_pMenu->EnableMenuItem(IDM_SAVEINFO,MF_GRAYED);
		m_pMenu->EnableMenuItem(IDM_SAVE,MF_ENABLED);
		m_pMenu->EnableMenuItem(IDM_HINT,MF_ENABLED);
		m_pMenu->EnableMenuItem(IDM_UNDO,MF_ENABLED);
		m_pMenu->EnableMenuItem(IDM_CANPLACE,MF_ENABLED);
		m_pMenu->EnableMenuItem(IDM_REPLAY,MF_GRAYED);
		InvalidateRect(NULL,TRUE);
		SetTimer(PASSEDTIME,1000,NULL);
		m_TimerOn=1;
	}	
}

void CBWChessDlg::OnSave() //响应“SAVE”命令
{
	TCHAR sFilter[50]=_T("BWChess File (*.BWS)|*.BWS||");
	TCHAR sExt[10]=_T("BWS");
	CFileDialog dlg(FALSE,sExt,NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
					sFilter);
	if(dlg.DoModal()==IDOK)
	{
		CFile file(dlg.GetPathName(),CFile::modeCreate | CFile::modeWrite);
		int buffer[9000],len=3;// the buffer need about 4000 size
		for(int ii=0;ii<2;ii++)//copy twice
		{
			buffer[len++]=m_byColor;
			buffer[len++]=g_nRunMode;
			buffer[len++]=m_PassedTime;
			buffer[len++]=m_PassedTime0;
			buffer[len++]=g_nSkill;
			buffer[len++]=g_bUserBlack;
			buffer[len++]=m_HintTime0;
			buffer[len++]=m_HintTime1;
			buffer[len++]=g_nTimeLimit;
			buffer[len++]=g_nIsNoTimeLimit;
			//restore 5 position for future use
			buffer[len++]=0;
			buffer[len++]=0;
			buffer[len++]=0;
			buffer[len++]=0;
			buffer[len++]=0;
			int i,j;
			for(i=0;i<NUM;i++)
				for(j=0;j<NUM;j++)
					buffer[len++]=kernel[i][j];
			int num=ListInfo.Len();
			buffer[len++]=num;
			int x,y,tc;
			int re;
			stack ts;
			do
			{
				re=ListInfo.GetNextPos(&x,&y,&tc);
				ts.push(x,y);
				ts.SetMarks (tc);
			}
			while(re);
			do
			{
				re=ts.GetNextPos(&x,&y,&tc);
				buffer[len++]=x;
				buffer[len++]=y;
				buffer[len++]=tc;
			}
			while(re);
			ListInfo.CopyBackIndex();
			// store m_UndoPoint
			int tlen=m_UndoPoint.Len();
			buffer[len++]=tlen;
			int tempUndo[NUM*NUM];
			do
			{
				re=m_UndoPoint.GetNextPos(tempUndo,&tc);
				for(x=0;x<NUM*NUM;x++)
					buffer[len++]=tempUndo[x];
				buffer[len++]=tc;
			}
			while(re);
			m_UndoPoint.CopyBackIndex();
		}
		buffer[0]=len;
		buffer[1]=EDITION;//this the edition of the banben
		buffer[2]=(int)m_bGameOver;
		file.Write(buffer,len*sizeof(int));
	}	
}

void CBWChessDlg::AddStringToList(int x, int y, int color,int win)//加入信息于列表框
{
	CString str;
	int result=m_ListInfo.GetCount();
	if(!win)
	{
		if(color)
			str.LoadString(IDS_SBLACK);// “%2d.黑棋: %c %d”
		else
			str.LoadString(IDS_SWHITE);
		TCHAR s[100];
		wsprintf(s, str.GetBuffer(256),result+1, y+65,x+1);
		m_ListInfo.AddString(s);
		ListInfo.push(x,y);
		ListInfo.SetMarks(color);
	}
	else
	{
		if(win==1)//白 win
			str.LoadString(IDS_WHITEWIN_CHINESE);
		else if(win==2)//黑 win
			str.LoadString(IDS_BLACKWIN_CHINESE);
		else//本局平局
			str.LoadString(IDS_TIE);
		m_ListInfo.AddString(str);
	}
	m_ListInfo.SetCurSel(result);//将当前新加入的显色(兰色)
	m_ListInfo.SetFocus();
}

void CBWChessDlg::RemoveStringFromList()//于列表框删除信息
{
	int index=m_ListInfo.GetCount();
	m_ListInfo.DeleteString(index-1);
	int x,y;
	ListInfo.pop(&x,&y);
	ListInfo.GetTop(x,y);
	m_CurPt.x =x,m_CurPt.y=y;
	index=m_ListInfo.GetCount();
	if(index)
	{
		m_ListInfo.SetCurSel(index-1);
		m_ListInfo.SetFocus();
	}
}

void CBWChessDlg::OnSaveinfo() //响应“导出走棋信息”
{
	TCHAR sFilter[50]=_T("文本文件(*.TXT)|*.TXT||");
	TCHAR sExt[10]=_T("txt");
	CFileDialog dlg(FALSE,sExt,NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
					sFilter);
	if(dlg.DoModal()==IDOK)
	{
		CFile file(dlg.GetPathName(),CFile::modeCreate | CFile::modeWrite | CFile::typeText);
		TCHAR buffer[300];
		int len=0,index=0;
		len=GetWindowText(buffer,300);
		buffer[len++]=13;
		buffer[len++]=10;
		file.Write(buffer,len);
		len=m_ListInfo.GetCount();
		while(index<len)
		{
			int slen=m_ListInfo.GetText(index++,buffer);
			buffer[slen]=13;
			buffer[slen+1]=10;
			file.Write(buffer,slen+2);
		}
	}	
}

BOOL CBWChessDlg::PreTranslateMessage(MSG* pMsg) //检测加速键消息是否被处理了
{//The TranslateAccelerator function processes accelerator keys for menu commands
    if(!::TranslateAccelerator(m_hWnd,hAccelerator,	pMsg))
		return CDialog::PreTranslateMessage(pMsg);
	return TRUE;
}


void CBWChessDlg::SetChessTitle()//载入标题
{
	CString str;
	if (g_nRunMode==MODE_WITH_COMPUTER && g_bUserBlack)
		str.LoadString(IDS_SINGLE_USER_CHINESE);//“黑白棋: 与计算机对弈, 你执黑先下”
	else if (g_nRunMode==MODE_WITH_COMPUTER && !g_bUserBlack)
		str.LoadString(IDS_SINGLE_COMPUTER_CHINESE);//“黑白棋: 与计算机对弈, 计算机执黑先下”
	else if	(g_nRunMode==MODE_2PLAYER)
	{
		if(g_nIsNoTimeLimit)
			str.LoadString(IDS_DOUBLE_NOLIMIT_CHINESE);//“黑白棋: 双人同机对弈,不限时”
		else
		{
			str.LoadString(IDS_DOUBLE_LIMIT_CHINESE);//“黑白棋: 双人同机对弈,限时%d秒”
			TCHAR str1[200];
			wsprintf(str1, str.GetBuffer(256), g_nTimeLimit);
			str=str1;
		}
	}
	SetWindowText(str);//显示标题
}

void CBWChessDlg::OnListDoubleClicked()//双击列表,撤消操作
{
	if(m_bGameOver || g_nIsDemo)//游戏已结束或正在演示
		return;
	int nSel=m_ListInfo.GetCurSel();
	int length=m_ListInfo.GetCount()-1;
		while(length>=nSel)//依次进行撤消
		{
			OnUndo();
			length=m_ListInfo.GetCount()-1;
		}
}

void CBWChessDlg::DrawFrame(CDC *dc)//画棋盘
{
	const int Sx=1;
	const int Sy=1;
	int i,j;
	int wx0,wy0,wx1,wy1;
	wx0=Sx,wy0=Sy;
	DrawBitmap(dc,wx0,wy0,IDB_F1_1,SRCCOPY);
	wx0=Sx+m_wFrameHeight+NUM*m_wFrameWidth,wy0=Sy;
	DrawBitmap(dc,wx0,wy0,IDB_F1_10,SRCCOPY);
	wx0=Sx,wy0=Sy+m_wFrameHeight+NUM*m_wStoneHeight;
	DrawBitmap(dc,wx0,wy0,IDB_F10_1,SRCCOPY);
	wx0=Sx+m_wFrameHeight+NUM*m_wStoneWidth,wy0=Sy+m_wFrameHeight+NUM*m_wStoneHeight;
    DrawBitmap(dc,wx0,wy0,IDB_F10_10,SRCCOPY);
    wx0=Sx+m_wFrameHeight,wy0=Sy,wx1=Sx+m_wFrameHeight,wy1=Sy+m_wFrameHeight+m_wStoneWidth*NUM;
	for(i=1,wx0=Sx+m_wFrameHeight,wy0=Sy,wx1=Sx+m_wFrameHeight,wy1=Sy+m_wFrameHeight+m_wStoneWidth*NUM;i<NUM+1;i++)
	{//画水平的边框8格
        DrawBitmap(dc,wx0,wy0,IDB_F1_2+i-1,SRCCOPY);
		DrawBitmap(dc,wx1,wy1,IDB_F10_2+i-1,SRCCOPY);		
		wx0+=m_wFrameWidth;
		wx1+=m_wFrameWidth;
	}
	for(i=0,wx0=Sx,wy0=Sy+m_wFrameHeight,wx1=Sx+m_wFrameHeight+NUM*m_wStoneWidth,wy1=Sy+m_wFrameHeight;i<NUM;i++)
	{//画垂直的边框8格	
        DrawBitmap(dc,wx0,wy0,IDB_F2_1+i,SRCCOPY);
		DrawBitmap(dc,wx1,wy1,IDB_F2_10+i,SRCCOPY);
		wy0+=m_wStoneHeight;
		wy1+=m_wStoneHeight;
	}
	for(i=0,wx0=Sx+m_wFrameHeight,wy0=Sy+m_wFrameHeight;i<NUM;i++,wx0=Sx+m_wFrameHeight,wy0=i*m_wStoneHeight+Sy+m_wFrameHeight)
		for(j=0;j<NUM;j++,wx0+=m_wStoneWidth)
		{//画棋盘8*8
			if(!kernel[i][j])
			{
				CPoint pt(wx0,wy0);
				DrawBitmap(dc,wx0,wy0,IDB_EMPTY,SRCCOPY);
			}
		}		
}

void CBWChessDlg::OnDemo() //响应“计算机演示/终止计算机对弈”命令
{
	CString str;
	if(g_nIsDemo)//响应“终止计算机对弈”命令
	{
		::TerminateThread(m_CcThread->m_hThread,0);
		m_pMenu->EnableMenuItem(IDM_NEW,MF_ENABLED);
		m_pMenu->EnableMenuItem(IDM_OPEN,MF_ENABLED);
		m_pMenu->EnableMenuItem(IDM_SAVE,MF_ENABLED);
		m_pMenu->EnableMenuItem(IDM_NETPLAY,MF_ENABLED);
		m_pMenu->EnableMenuItem(IDM_REPLAY,MF_ENABLED);
		str.LoadString(IDS_DEMOTITLE0);//“计算机演示[&M]...\tCtrl+M”
		m_pMenu->ModifyMenu(IDM_DEMO,MF_BYCOMMAND | MF_STRING,IDM_DEMO,str);
        //程序已经在“演示”,菜单已被改为“终止计算机对弈”,因此现在要恢复为“计算机演示”
		g_nIsDemo=0;
		m_bGameOver=TRUE;
	}
	else//响应“计算机演示”命令
	{
		int HaveKilled=0;
		if(m_TimerOn)//终止计时
		{
			HaveKilled=1;
			KillTimer(PASSEDTIME);
			m_TimerOn=0;
		}

		if(!m_bGameOver && g_bPrompt)//游戏没有结束
		{
			if(MsgBox(IDS_ABORT,IDS_TITLE_CHINESE,2)==IDCANCEL)
			{//弹出对话框询问
				if(HaveKilled)//取消对话框,恢复计时
				{					
					SetTimer(PASSEDTIME,1000,NULL);
					m_TimerOn=1;
				}
				return;
			}
		}
       //OK对话框
		CDemo dlg;//弹出计算机对弈对话框
		if(dlg.DoModal()==IDCANCEL)
		{
			if(HaveKilled)
			{				
				SetTimer(PASSEDTIME,1000,NULL);
				m_TimerOn=1;
			}
			return;
		}
		//修改菜单
		m_pMenu->EnableMenuItem(IDM_HINT,MF_GRAYED);
		m_pMenu->EnableMenuItem(IDM_UNDO,MF_GRAYED);
		m_pMenu->EnableMenuItem(IDM_CANPLACE,MF_GRAYED);
		m_pMenu->EnableMenuItem(IDM_SAVE,MF_GRAYED);
		m_pMenu->EnableMenuItem(IDM_SAVEINFO,MF_GRAYED);
		m_pMenu->EnableMenuItem(IDM_NEW,MF_GRAYED);
		m_pMenu->EnableMenuItem(IDM_OPEN,MF_GRAYED);
		m_pMenu->EnableMenuItem(IDM_NETPLAY,MF_GRAYED);
		m_pMenu->EnableMenuItem(IDM_REPLAY,MF_GRAYED);
		str.LoadString(IDS_DEMOTITLE1);
		m_pMenu->ModifyMenu(IDM_DEMO,MF_BYCOMMAND | MF_STRING,IDM_DEMO,str);
        //修改菜单为“终止计算机对弈”
		int flag=0;//标志是否为历史棋局
		if(dlg.m_IsFile)//演示历史棋局
		{
			CFile file(dlg.m_FilePath, CFile::modeRead);
			int buffer[9000],len;
			file.Read(buffer,9000*sizeof(int));
			len=18+NUM*NUM;///important
			m_PointGo.destroy();
			int x,y,num,tc;
			stack tt;
			num=buffer[len++];//num代表走棋的步数
			while(num>0)//进栈
			{
				x=buffer[len++];
				y=buffer[len++];
				tc=buffer[len++];
				tt.push(x,y);
				tt.SetMarks(tc);
				num--;
			}
			while(!tt.isempty ())//再出栈入栈,顺序演示
			{
				tc=tt.GetMarks (0);
				tt.pop (&x,&y);
				m_PointGo.push(x,y);
				m_PointGo.SetMarks(tc);
			}
			flag=0;
		}
		else//不是历史棋局
		{
			CString str1;
			switch(g_nCbSkill)//黑方级别
			{
			case 1://黑方:初级
				switch(g_nCwSkill)//白方级别
				{
				case 1://白方:初级
					str1.LoadString(IDS_DEMO_TITLE_11);
					//“黑白棋:计算机演示->黑方:初级;白方:初级”
					break;
				case 2://白方:中级
					str1.LoadString(IDS_DEMO_TITLE_12);
				

⌨️ 快捷键说明

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